#primary_key
[ GitHub ]# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 178
def primary_key(...) remote_dispatch(:primary_key, ...) end
123456789_123456789_123456789_123456789_123456789_
"RactorProxy"
/\Asupports_.*\?\z/
Object.new.freeze
/\A(?:quote|type_to_sql\z|valid_type\?\z|supports_)/
::ActiveSupport::Callbacks - Included::ActiveRecord::ConnectionAdapters::SchemaStatements - Included::ActiveRecord::ConnectionAdapters::DatabaseStatements - IncludedDEFAULT_INSERT_VALUE, HIGH_PRECISION_CURRENT_TIMESTAMP, TRANSACTION_ISOLATION_LEVELS
::ActiveRecord::ConnectionAdapters::AbstractAdapter - InheritedADAPTER_NAME, COMMENT_REGEX, DEFAULT_READ_QUERY, EXTENDED_TYPE_MAPS, MAX_JITTER, SIMPLE_INT, TYPE_MAP
::ActiveRecord::ConnectionAdapters::AbstractAdapter - Inherited| .__callbacks, | |
| .migration_strategy | Allows configuration of migration strategy per adapter type. |
| .migration_strategy? | |
::ActiveRecord::ConnectionAdapters::AbstractAdapter - Inherited| .database_exists? | Does the database for this adapter exist? |
| .dbconsole | Opens a database console session. |
| .find_cmd_and_exec, .type_cast_config_to_boolean, .type_cast_config_to_integer, .validate_default_timezone, .extract_limit, .extract_precision, .extract_scale, .initialize_type_map, .register_class_with_limit, .build_read_query_regexp, .extended_type_map, .new, | |
| .ractor_connection_proxy_class | The |
| .register_class_with_precision, .valid_type? | |
::ActiveSupport::DescendantsTracker - InheritedRegardless of whether the main-side connection invalidates its own transaction, we need the rollback to keep us in sync.
::ActiveRecord::ConnectionAdapters::AbstractAdapter - Inherited| #__callbacks, | |
| #active? | Checks whether the connection to the database is still active. |
| #connected? | Checks whether the connection to the database was established. |
| #database_exists?, | |
| #in_use? | Alias for AbstractAdapter#owner. |
| #lock, #logger, #migration_strategy, #migration_strategy?, #owner, #pool, #pool=, | |
| #prepared_statements | Alias for AbstractAdapter#prepared_statements?. |
| #preventing_writes? | Determines whether writes are currently being prevented. |
| #replica?, | |
| #requires_reloading? | Returns true if its required to reload the connection between requests for development mode. |
| #savepoint_errors_invalidate_transactions? | Do TransactionRollbackErrors on savepoints affect the parent transaction? |
| #sql_notifications?, | |
| #supports_advisory_locks? | Does this adapter support application-enforced advisory locking? |
| #supports_bulk_alter?, | |
| #supports_check_constraints? | Does this adapter support creating check constraints? |
| #supports_comments? | Does this adapter support metadata comments on database objects (tables, columns, indexes)? |
| #supports_comments_in_create? | Can comments for tables, columns, and indexes be specified in create/alter table statements? |
| #supports_common_table_expressions?, #supports_concurrent_connections?, #supports_datetime_with_precision?, | |
| #supports_ddl_transactions? | Does this adapter support DDL rollbacks in transactions? That is, would CREATE TABLE or ALTER TABLE get rolled back by a transaction? |
| #supports_deferrable_constraints? | Does this adapter support creating deferrable constraints? |
| #supports_disabling_indexes?, | |
| #supports_enforced_foreign_keys? | Does this adapter support NOT ENFORCED foreign key constraints? |
| #supports_exclusion_constraints? | Does this adapter support creating exclusion constraints? |
| #supports_explain? | Does this adapter support explain? |
| #supports_expression_index? | Does this adapter support expression indices? |
| #supports_extensions? | Does this adapter support database extensions? |
| #supports_foreign_keys? | Does this adapter support creating foreign key constraints? |
| #supports_foreign_tables? | Does this adapter support foreign/external tables? |
| #supports_index_include? | Does this adapter support including non-key columns? |
| #supports_index_sort_order? | Does this adapter support index sort order? |
| #supports_indexes_in_create? | Does this adapter support creating indexes in the same statement as creating the table? |
| #supports_insert_conflict_target?, #supports_insert_on_duplicate_skip?, #supports_insert_on_duplicate_update?, #supports_insert_returning?, | |
| #supports_json? | Does this adapter support JSON data type? |
| #supports_lazy_transactions?, | |
| #supports_materialized_views? | Does this adapter support materialized views? |
| #supports_nulls_not_distinct?, | |
| #supports_optimizer_hints? | Does this adapter support optimizer hints? |
| #supports_partial_index? | Does this adapter support partial indices? |
| #supports_partitioned_indexes?, #supports_restart_db_transaction?, | |
| #supports_savepoints? | Does this adapter support savepoints? |
| #supports_transaction_isolation? | Does this adapter support setting the isolation level for a transaction? |
| #supports_unique_constraints? | Does this adapter support creating unique constraints? |
| #supports_update_returning?, | |
| #supports_validate_constraints? | Does this adapter support creating invalid constraints? |
| #supports_views? | Does this adapter support views? |
| #supports_virtual_columns? | Does this adapter support virtual columns? |
| #visitor, #reconnect_can_restore_state?, #advisory_locks_enabled?, #allow_preconnect, #allow_preconnect=, #async_enabled?, #lock_thread=, #needs_reconnect?, #pinned, | |
| #proxied= | When true, this connection is the backend of a ractor proxy connection. |
| #proxied?, #verified? | |
::ActiveRecord::ConnectionAdapters::DatabaseStatements - Included| #begin_transaction, #commit_transaction, #current_transaction, #dirty_current_transaction, #materialize_transactions, #open_transactions, #rollback_transaction, #transaction_open?, #within_new_transaction, | |
| #restart_parent_transactions? | Whether a nested transaction may be emulated by restarting its parent, instead of nesting a savepoint. |
| #transaction_manager | |
::ActiveRecord::ConnectionAdapters::SchemaStatements - IncludedCheckout/checkin callbacks are class-level state that is not Ractor-shareable; the concrete adapter runs them main-side when the connection returns to its pool.
The main-side connection replaces its transaction manager whenever it resets its transactions without restoring them, so we record its identity to later notice if we get out of sync.
Yields the main-side connection on the main Ractor, first checking it still has the transaction manager identified by transaction_manager_id, if given.
Runs a connection management method on the main-side connection.
A lazily begun worker transaction must reach the main connection before remote work that may write through it (e.g.
Local casting must match the concrete adapter (e.g.
Proxy - Included| #boundary_safe_bind | Attribute types may close over procs, so the database value is resolved locally. |
| #checkin_all_connections | For supervisors tearing down worker Ractors, which cannot release their own tokens when they die. |
| #checkin_token, #connection_pinned?, #discard_token, #dump_binds, #dump_column_types, #dump_object, | |
| #main_operation |
|
| #remove_token | |
::ActiveRecord::ConnectionAdapters::AbstractAdapter - Inherited| #adapter_name | Returns the human-readable name of the adapter. |
| #check_all_foreign_keys_valid! | Override to check all foreign key constraints in a database. |
| #clear_cache! | Clear any caching the database adapter may be doing. |
| #close | Check the connection back in to the connection pool. |
| #connect!, #connection_retries, #default_timezone, | |
| #disable_extension | This is meant to be implemented by the adapters that support extensions. |
| #disable_referential_integrity | Override to turn off referential integrity while executing |
| #discard! | Immediately forget this connection ever existed. |
| #disconnect! | Disconnects from the database if already connected. |
| #enable_extension | This is meant to be implemented by the adapters that support extensions. |
| #extensions | A list of extensions, to be filled in by adapters that support them. |
| #index_algorithms | A list of index algorithms, to be filled by adapters that support them. |
| #lease | this method must only be called while holding connection pool's mutex. |
| #max_jitter, #pool_jitter, | |
| #prefetch_primary_key? | Should primary key values be selected from their corresponding sequence before the insert statement? If true, next_sequence_value is called before each insert to set the record's primary key. |
| #prepared_statements?, | |
| #raw_connection | Provides access to the underlying database driver for this adapter. |
| #reconnect! | Disconnects from the database if already connected, and establishes a new connection with the database. |
| #reset! | Reset the state of this connection, directing the DBMS to clear transactions and other connection-related server-side state. |
| #retry_deadline, #return_value_after_update?, | |
| #role | The role (e.g. |
| #schema_cache, | |
| #schema_version | Returns the version identifier of the schema currently available in the database. |
| #shard | The shard (e.g. |
| #throw_away! | Removes the connection from the pool and disconnect it. |
| #unprepared_statement, #verify, | |
| #verify! | Checks whether the connection to the database is still active (i.e. not stale). |
| #verify_timeout, | |
| #any_raw_connection | Returns a raw connection for internal use with methods that are known to both be thread-safe and not rely upon actual server communication. |
| #arel_visitor, #attempt_configure_connection, #backoff, #build_retry_budget, #build_statement_pool, #can_perform_case_insensitive_comparison_for?, #collector, #column_for, #column_for_attribute, | |
| #configure_connection | Perform any necessary initialization upon the newly-established connection settings, run queries to configure any application-global "session" variables, etc. |
| #default_prepared_statements, | |
| #ensure_connection_ready | Ensure the connection is ready to execute a query. |
| #extended_type_map_key, #invalidate_transaction, #log, #reconnect, #retryable_connection_error?, #retryable_query_error?, | |
| #skip_verification? | Decide whether the connection can be used without verification. |
| #translate_exception, #translate_exception_class, #type_map, | |
| #valid_raw_connection | Similar to any_raw_connection, but ensures it is validated and connected. |
| #verified! | Mark the connection as verified. |
| #warning_ignored?, | |
| #with_raw_connection | Lock the monitor, ensure we're properly connected and transactions are materialized, and then yield the underlying raw connection object. |
| #add_enum_value | This is meant to be implemented by the adapters that support custom enum types. |
| #attempt_retry | Consume from |
| #build_insert_sql | Called by |
| #case_insensitive_comparison, #case_sensitive_comparison, #check_version, #clean!, | |
| #connection_age | Seconds since this connection was established. |
| #connection_descriptor, | |
| #create_enum | This is meant to be implemented by the adapters that support custom enum types. |
| #create_or_find_by_lock | Lock used to read an existing record after a duplicate INSERT in a transaction. |
| #create_virtual_table | This is meant to be implemented by the adapters that support virtual tables. |
| #database_version, #default_index_type?, #downgrade_connection_after_error, | |
| #drop_enum | This is meant to be implemented by the adapters that support custom enum types. |
| #drop_virtual_table | This is meant to be implemented by the adapters that support virtual tables. |
| #expire | this method must only be called while holding connection pool's mutex. |
| #force_retirement | Mark the connection as needing to be retired, as if the age has exceeded the maximum allowed. |
| #get_advisory_lock | This is meant to be implemented by the adapters that support advisory locks. |
| #get_database_version, #inspect, #native_database_types, #prepared_statements_disabled_cache, #ractor_connection_capabilities, #ractor_connection_profile, | |
| #release_advisory_lock | This is meant to be implemented by the adapters that support advisory locks. |
| #rename_enum | This is meant to be implemented by the adapters that support custom enum types. |
| #rename_enum_value | This is meant to be implemented by the adapters that support custom enum types. |
| #retryable_failure?, #return_value_after_insert?, | |
| #seconds_idle | Seconds since this connection was returned to the pool. |
| #seconds_since_last_activity | Seconds since this connection last communicated with the server. |
| #steal! | this method must only be called while holding connection pool's mutex (and a desire for segfaults). |
| #valid_type?, #instrumenter | |
::ActiveRecord::ConnectionAdapters::Savepoints - Included::ActiveRecord::ConnectionAdapters::DatabaseLimits - Included| #index_name_length | Returns the maximum length of an index name. |
| #table_alias_length | Returns the maximum length of a table alias. |
| #table_name_length | Returns the maximum length of a table name. |
| #bind_params_length, #max_identifier_length | |
::ActiveRecord::ConnectionAdapters::Quoting - Included| #quote | Quotes the column value to help preventSQL injection attacks. |
| #quote_column_name | Quotes the column name. |
| #quote_string | Quotes a string, escaping any ' (single quote) and \ (backslash) characters. |
| #quote_table_name | Quotes the table name. |
| #quote_table_name_for_assignment | Override to return the quoted table name for assignment. |
| #quoted_date | Quote date/time values for use in SQL input. |
| #quoted_false, #quoted_true, | |
| #type_cast | Cast a |
| #unquoted_false, #unquoted_true, | |
| #cast_bound_value | Cast a value to be used as a bound parameter of unknown type. |
| #lookup_cast_type, #quote_default_expression, #quoted_binary, #quoted_time, #sanitize_as_sql_comment, #type_casted_binds | |
::ActiveRecord::ConnectionAdapters::DatabaseStatements - Included| #add_transaction_record | Register a record with the current transaction so that its after_commit and after_rollback callbacks can be called. |
| #begin_db_transaction | Begins the transaction (and turns off auto-committing). |
| #begin_isolated_db_transaction | Begins the transaction with the isolation level set. |
| #commit_db_transaction | Commits the transaction (and turns on auto-committing). |
| #create | Alias for DatabaseStatements#insert. |
| #default_sequence_name, | |
| #delete | Executes the delete statement and returns the number of rows affected. |
| #disable_lazy_transactions!, #empty_insert_statement_value, #enable_lazy_transactions!, | |
| #exec_delete | Executes delete |
| #exec_insert | Executes insert |
| #exec_query | Executes |
| #exec_update | Executes update |
| #execute | Executes the SQL statement in the context of this connection and returns the raw result from the connection adapter. |
| #high_precision_current_timestamp | Returns an |
| #initialize, | |
| #insert | Executes an INSERT query and returns the new record's ID. |
| #insert_fixture | Inserts the given fixture into the table. |
| #insert_fixtures_set, | |
| #reset_isolation_level | Hook point called after an isolated DB transaction is committed or rolled back. |
| #reset_sequence! | Set the sequence to the max value of the table's column. |
| #restart_db_transaction, | |
| #rollback_db_transaction | Rolls back the transaction (and turns on auto-committing). |
| #rollback_to_savepoint, | |
| #select_all | Returns an |
| #select_one | Returns a record hash with the column names as keys and column values as values. |
| #select_rows | Returns an array of arrays containing the field values. |
| #select_value | Returns a single value from a record. |
| #select_values | Returns an array of the values of the first column in a select: |
| #to_sql, | |
| #transaction | Runs the given block in a database transaction, and returns the result of the block. |
| #transaction_isolation_levels, | |
| #truncate | Executes the truncate statement. |
| #update | Executes the update statement and returns the number of rows affected. |
| #write_query? | Determines whether the SQL statement is a write query. |
| #affected_rows, #apply_returning_to!, #arel_from_relation, #build_delete_from_statements, #build_fixture_sql, #build_fixture_statements, #build_truncate_statement, #build_truncate_statements, | |
| #cast_result | Receive a native adapter result object and returns an |
| #collect_warnings, #combine_multi_statements, #extract_table_ref_from_insert_sql, #internal_build_intent, #last_inserted_id, #perform_query, #primary_key_for_insert, | |
| #raw_intent_last_inserted_id | The last inserted id computed eagerly for a raw intent: the raw driver result cannot cross the Ractor boundary, so it is read before the response is marshaled. |
| #returning_column_values, #single_value_from_rows, #table_ref_for_insert, #_exec_insert, #begin_deferred_transaction, #begin_savepoint_transaction, | |
| #cacheable_query | This is used in the |
| #commit_savepoint_transaction, #default_insert_value, #empty_all_tables, #exec_insert_all, #exec_restart_db_transaction, #exec_rollback_db_transaction, | |
| #execute_batch | Executes SQL statements in the context of this connection without returning a result. |
| #execute_intent | Lowest-level abstract execution of a query, called only from the intent itself. |
| #execute_raw_intent | Executes |
| #explain, #finalize_remaining_intents, #finish_intent_log, #handle_warnings, #perform_sync_attempt, #query_all, #query_command, #query_one, #query_rows, #query_value, #query_values, #reset_transaction, #rollback_savepoint_transaction, #start_intent_log, #tables_to_truncate, #to_sql_and_binds, #truncate_tables, | |
| #update_with_result | Executes the update statement and returns an |
| #with_yaml_fallback |
|
::ActiveRecord::ConnectionAdapters::SchemaStatements - Included| #add_belongs_to | Alias for SchemaStatements#add_reference. |
| #add_check_constraint | Adds a new check constraint to the table. |
| #add_column | Add a new |
| #add_foreign_key | Adds a new foreign key. |
| #add_index | Adds a new index to the table. |
| #add_reference | Adds a reference. |
| #add_timestamps | Adds timestamps ( |
| #assume_migrated_upto_version, | |
| #build_create_table_definition | Returns a |
| #change_column | Changes the column's definition according to the new options. |
| #change_column_comment | Changes the comment for a column or removes it if |
| #change_column_default | Sets a new default value for a column: |
| #change_column_null | Sets or removes a NOT NULL constraint on a column. |
| #change_foreign_key | Changes an existing foreign key on a table. |
| #change_table | A block for changing columns in |
| #change_table_comment | Changes the comment for a table or removes it if |
| #check_constraint_exists? | Checks to see if a check constraint exists on a table for a given check constraint definition. |
| #check_constraints | |
| #column_exists? | Checks to see if a column exists in a given table. |
| #columns | Returns an array of |
| #create_join_table | Creates a new join table with the name created using the lexical order of the first two arguments. |
| #create_table | Creates a new table with the name |
| #data_source_exists? | Checks to see if the data source |
| #data_sources | Returns the relation names usable to back Active Record models. |
| #disable_index | Prevents an index from being used by queries. |
| #drop_join_table | Drops the join table specified by the given arguments. |
| #drop_table | Drops a table or tables from the database. |
| #enable_index | Enables an index to be used by queries. |
| #foreign_key_exists? | Checks to see if a foreign key exists on a table for a given foreign key definition. |
| #foreign_keys | |
| #index_exists? | Checks to see if an index exists on a table for a given index definition. |
| #index_name_exists? | Verifies the existence of an index with a given name. |
| #indexes | |
| #max_index_name_size | Returns the maximum length of an index name in bytes. |
| #native_database_types | Returns a hash of mappings from the abstract data types to the native database types. |
| #options_include_default?, | |
| #primary_key | Returns just a table's primary key. |
| #remove_belongs_to | Alias for SchemaStatements#remove_reference. |
| #remove_check_constraint | Removes the given check constraint from the table. |
| #remove_column | Removes the column from the table definition. |
| #remove_columns | Removes the given columns from the table definition. |
| #remove_foreign_key | Removes the given foreign key from the table. |
| #remove_index | Removes the given index from the table. |
| #remove_reference | Removes the reference(s). |
| #remove_timestamps | Removes the timestamp columns ( |
| #rename_column | Renames a column. |
| #rename_index | Renames an index. |
| #rename_table | Renames a table. |
| #table_alias_for | Truncates a table alias according to the limits of the current adapter. |
| #table_comment | Returns the table comment that's stored in database metadata. |
| #table_exists? | Checks to see if the table |
| #table_options | |
| #tables | Returns an array of table names defined in the database. |
| #view_exists? | Checks to see if the view |
| #views | Returns an array of view names defined in the database. |
| #add_index_sort_order, | |
| #add_options_for_index_columns | Overridden by the |
| #can_remove_index_by_name?, #change_column_comment_sql, #change_index_comment_sql, #change_table_comment_sql, #check_constraint_for, #check_constraint_for!, #check_constraint_name, #column_options_keys, #create_alter_table, #create_index_definition, #create_table_definition, #data_source_sql, #drop_table_sql, #execute_alter_table, | |
| #expression_column_name? | Try to identify whether the given column name is an expression. |
| #extract_foreign_key_action, | |
| #extract_new_comment_value | Alias for SchemaStatements#extract_new_default_value. |
| #extract_new_default_value, | |
| #fetch_by_schema | One read filters by one schema, so tables naming different schemas are read a schema at a time. |
| #fetch_column_definitions, #fetch_table_options, #fetch_type_metadata, #foreign_key_for, #foreign_key_for!, #foreign_key_name, #generate_index_name, #has_expression_column_name?, #index_column_names, #index_name_for_remove, #index_name_options, #insert_versions_sql, #options_for_index_columns, #quoted_scope, #quoted_table_names, #reference_name_for_table, #rename_column_indexes, #rename_table_indexes, #rows_for, #strip_table_name_prefix_and_suffix, #valid_index_options, #validate_change_column_null_argument!, #validate_create_table_options!, #validate_index_length!, #validate_table_length!, #add_columns, #add_index_options, | |
| #build_alter_table_definition | Returns an |
| #build_create_index_definition | Builds a |
| #build_create_join_table_definition | Builds a |
| #bulk_change_table, #check_constraint_options, | |
| #columns_for_distinct | Given a set of columns and an ORDER BY clause, returns the columns for a SELECT DISTINCT. |
| #compatibility_behavior_for, #create_schema_dumper, #distinct_relation_for_primary_key, #dump_schema_versions, #foreign_key_column_for, #foreign_key_options, #index_algorithm, #index_name, | |
| #inject_legacy_primary_key_default? | Whether to inject |
| #internal_string_options_for_primary_key, #quoted_columns_for_index, #remove_constraint, | |
| #schema_creation | Returns an instance of |
| #type_to_sql, #update_table_definition, #valid_column_definition_options, #valid_primary_key_options, #valid_table_definition_options | |
::ActiveSupport::Callbacks - Included| #run_callbacks | Runs the callbacks for the given event. |
| #halted_callback_hook | A hook invoked every time a before callback is halted. |
AbstractProxyAdapter
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 22
def initialize(pool, connection_token, profile, config) @adapter_profile = profile super(nil, PLACEHOLDER_LOGGER, nil, config) @connection_token = connection_token @logger = nil @pool = pool @prepared_statements = profile[:prepared_statements] @main_transaction_manager_id = nil @capabilities = profile[:capabilities].dup @quoted_column_names = {} @quoted_table_names = {} end
This class handles dynamic methods through the method_missing method
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 446
def method_missing(name, *args, **kwargs, &block) return super if name == :marshal_dump || name == :_dump if block raise ActiveRecordError, "Cannot forward a block to #{name} on the main-Ractor connection" end if PURE_REMOTE_METHOD_PATTERN.match?(name) remote_adapter_call(name, args, kwargs) else materialize_transactions remote_adapter_call(name, args, kwargs, transaction_manager_id: @main_transaction_manager_id) end end
Boolean (readonly)
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 45
def active? !!(@connection_token && call_main_connection(:active?)) end
Boolean (readonly)
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 41
def connected? !!(@connection_token && call_main_connection(:connected?)) end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 39
attr_reader :connection_token # :nodoc:
Boolean (readonly)
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 110
def holds_main_connection? # :nodoc: !!(@connection_token && connection_pinned?(@connection_token)) end
Boolean (readonly)
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 247
def restart_parent_transactions? # :nodoc: false end
Boolean (readonly)
Regardless of whether the main-side connection invalidates its own transaction, we need the rollback to keep us in sync.
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 253
def savepoint_errors_invalidate_transactions? # :nodoc: false end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 198
def _exec_insert(intent, sequence_name = nil, returning: nil) # :nodoc: apply_returning_to!(intent, returning) intent.execute! intent.raw_result end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 283
def adapter_class @adapter_profile[:adapter_class] end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 35
def adapter_name @adapter_profile[:adapter_name] end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 327
def affected_rows(response) response.affected_rows end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 267
def arel_visitor @adapter_profile[:arel_visitor_class].new(self) end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 204
def begin_db_transaction # :nodoc: begin_main_transaction(nil, true) end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 212
def begin_deferred_transaction(isolation_level = nil) # :nodoc: begin_main_transaction(isolation_level, false) end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 208
def begin_isolated_db_transaction(isolation) # :nodoc: begin_main_transaction(isolation, true) end
The main-side connection replaces its transaction manager whenever it resets its transactions without restoring them, so we record its identity to later notice if we get out of sync.
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 394
def begin_main_transaction(isolation, joinable) @main_transaction_manager_id = main_transaction_operation(nil) do |connection| connection.begin_transaction(isolation: isolation, joinable: joinable, _lazy: false) connection.transaction_manager.object_id end end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 230
def begin_savepoint_transaction(name) # :nodoc: main_transaction_operation(@main_transaction_manager_id) do |connection| connection.begin_transaction(_lazy: false) nil end end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 271
def bind_params_length @adapter_profile[:bind_params_length] end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 190
def build_insert_sql(insert) # :nodoc: raise ActiveRecordError, "insert_all/upsert_all can only be executed on the main Ractor" end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 263
def build_retry_budget(allow_retry:, reconnectable:) super(allow_retry: false, reconnectable: false) end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 298
def build_statement_pool nil end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 368
def call_main_connection(method_name, args = [], kwargs = {}, transaction_manager_id: nil) main_args = ActiveSupport::Ractors.make_shareable(args) main_kwargs = ActiveSupport::Ractors.make_shareable(kwargs) main_transaction_operation(transaction_manager_id) do |connection| connection.__send__(method_name, *main_args, **main_kwargs) end end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 323
def cast_result(response) ActiveRecord::Result.new(response.columns, response.rows, response.column_types, affected_rows: response.affected_rows) end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 105
def clear_cache!(new_connection: false) super remote_adapter_call(:clear_cache!, [], { new_connection: new_connection }) if @connection_token end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 331
def collect_warnings(response) response&.warnings end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 162
def columns(...) remote_dispatch(:columns, ...) end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 216
def commit_db_transaction # :nodoc: commit_main_transaction ensure # Main-side transaction is gone, even if the commit failed @main_transaction_manager_id = nil end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 401
def commit_main_transaction transaction_manager_id = @main_transaction_manager_id main_transaction_operation(nil) do |connection| unless connection.transaction_manager.object_id == transaction_manager_id raise ConnectionNotEstablished, "Cannot commit: the Ractor-pinned connection was reset while the transaction was open, and the server rolled it back" end transaction = connection.current_transaction begin connection.commit_transaction rescue ConnectionFailed # The transaction has already gone with the connection, so there's # nothing to roll back. raise rescue Exception connection.rollback_transaction(transaction) unless transaction.state.completed? raise end nil end end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 237
def commit_savepoint_transaction(name) # :nodoc: commit_main_transaction end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 54
def connect! manage_main_connection(:connect!) self end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 275
def create_table_definition(name, **) table_definition_class.new(self, name, **) end
Boolean
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 170
def data_source_exists?(...) remote_dispatch(:data_source_exists?, ...) end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 166
def data_sources remote_dispatch(:data_sources) end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 73
def discard! if token = @connection_token @connection_token = nil discard_token(token) end reset_transaction end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 64
def disconnect! # Disconnect the physical connection while maintaining the lease of that same instance. if @connection_token manage_main_connection(:disconnect!) else reset_transaction end end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 258
def ensure_connection_ready(allow_retry:, materialize_transactions:) self.materialize_transactions if materialize_transactions false end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 223
def exec_rollback_db_transaction # :nodoc: # Already gone if this follows a failed commit rollback_main_transaction if @main_transaction_manager_id ensure @main_transaction_manager_id = nil end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 194
def execute(...) cast_result(super) end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 174
def indexes(...) remote_dispatch(:indexes, ...) end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 335
def last_inserted_id(response) response.last_inserted_id end
Yields the main-side connection on the main Ractor, first checking it
still has the transaction manager identified by
transaction_manager_id, if given.
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 380
def main_transaction_operation(transaction_manager_id, &block) unless token = @connection_token raise ConnectionNotEstablished, "The Ractor-pinned connection has been released" end operation = ActiveSupport::Ractors.shareable_proc(self: nil, &block) main_operation(connection_pool: @pool) do operation.call(fetch_transaction_connection(token, transaction_manager_id)) end end
Runs a connection management method on the main-side connection. If we notice that the main transaction manager has been replaced, we reset ours to match.
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 434
def manage_main_connection(method_name, **kwargs) main_kwargs = ActiveSupport::Ractors.make_shareable(kwargs) transaction_manager_id = @main_transaction_manager_id kept = main_transaction_operation(nil) do |connection| transaction_manager = connection.transaction_manager connection.public_send(method_name, **main_kwargs) connection.transaction_manager.equal?(transaction_manager) && (transaction_manager_id.nil? || transaction_manager.object_id == transaction_manager_id) end reset_transaction unless kept end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 114
def native_database_types remote_adapter_call(:native_database_types) end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 302
def perform_query(_raw_connection, intent) request = QueryRequest.new( sql: intent.processed_sql, binds: intent.binds, name: intent.name, prepare: intent.prepare, batch: intent.batch, allow_retry: intent.allow_retry, materialize_transactions: intent.materialize_transactions, ) token = @connection_token transaction_manager_id = @main_transaction_manager_id if intent.materialize_transactions response = main_operation(connection_pool: @pool) do request.perform(fetch_transaction_connection(token, transaction_manager_id)) end intent.notification_payload[:affected_rows] = response.affected_rows intent.notification_payload[:row_count] = response.row_count response end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 178
def primary_key(...) remote_dispatch(:primary_key, ...) end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 350
def pure_remote_dispatch(method_name, *args, **kwargs, &block) if block raise ActiveRecordError, "Cannot forward a block to #{method_name} on the main-Ractor connection" end remote_adapter_call(method_name, args, kwargs) end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 122
def quote_column_name(name) @quoted_column_names[name] ||= remote_adapter_call(:quote_column_name, [name]) end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 126
def quote_table_name(name) @quoted_table_names[name] ||= remote_adapter_call(:quote_table_name, [name]) end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 140
def raw_connection unless ActiveSupport::Ractors.main? raise ActiveRecordError, "The raw connection of a Ractor-proxied connection can only be accessed from the main Ractor" end unless @connection_token raise ConnectionNotEstablished, "The Ractor-pinned connection has been released" end disable_lazy_transactions! Proxy.fetch_transaction_connection(@connection_token, @main_transaction_manager_id).raw_connection end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 59
def reconnect!(restore_transactions: false) manage_main_connection(:reconnect!, restore_transactions: restore_transactions) self end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 91
def release_connection if token = @connection_token @connection_token = nil checkin_token(token) end end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 358
def remote_adapter_call(method_name, args = [], kwargs = {}, transaction_manager_id: nil) if args.empty? && kwargs.empty? && CAPABILITY_METHOD_PATTERN.match?(method_name) @capabilities.fetch(method_name) do @capabilities[method_name] = call_main_connection(method_name, args, kwargs) end else call_main_connection(method_name, args, kwargs, transaction_manager_id: transaction_manager_id) end end
A lazily begun worker transaction must reach the main connection before
remote work that may write through it (e.g. SQLite3#add_column).
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 341
def remote_dispatch(method_name, *args, **kwargs, &block) if block raise ActiveRecordError, "Cannot forward a block to #{method_name} on the main-Ractor connection" end materialize_transactions remote_adapter_call(method_name, args, kwargs, transaction_manager_id: @main_transaction_manager_id) end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 186
def remote_schema_creation_accept(node) # :nodoc: raise ActiveRecordError, "Schema statements can only be executed on the main Ractor" end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 98
def remove_connection if token = @connection_token @connection_token = nil remove_token(token) end end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 81
def reset! manage_main_connection(:reset!) self end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 86
def reset_transaction(...) # :nodoc: @main_transaction_manager_id = nil super end
Boolean (private)
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 461
def respond_to_missing?(name, include_private = false) return false if name == :marshal_dump || name == :_dump super end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 423
def rollback_main_transaction transaction_manager_id = @main_transaction_manager_id main_transaction_operation(nil) do |connection| connection.rollback_transaction if connection.transaction_manager.object_id == transaction_manager_id nil end end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 241
def rollback_savepoint_transaction(name) # :nodoc: if current_transaction.savepoint_name == name rollback_main_transaction end end
Checkout/checkin callbacks are class-level state that is not Ractor-shareable; the concrete adapter runs them main-side when the connection returns to its pool.
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 154
def run_callbacks(kind, &block) # :nodoc: if kind == :checkin || kind == :checkout block ? yield : nil else super end end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 182
def schema_creation # :nodoc: SchemaCreationProxy.new(self) end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 279
def table_definition_class @adapter_profile[:table_definition_class] end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 130
def type_casted_binds(binds) return [] if binds.nil? || binds.empty? token = @connection_token binds_payload = dump_binds(binds) main_operation(connection_pool: @pool) do fetch_connection(token).type_casted_binds(Marshal.load(binds_payload)) end end
Local casting must match the concrete adapter (e.g. SQLite3's integer limit).
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 288
def type_map if key = extended_type_map_key adapter_class::EXTENDED_TYPE_MAPS.compute_if_absent(key) do adapter_class.extended_type_map(**key) end else adapter_class::TYPE_MAP end end
Boolean
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 118
def valid_type?(type) !native_database_types[type].nil? end
# File 'activerecord/lib/active_record/connection_adapters/ractor_connection_handler/abstract_proxy_adapter.rb', line 49
def verify! manage_main_connection(:verify!) self end