Class: ActiveRecord::ConnectionAdapters::MaterializeAdapter
- Inherits:
-
AbstractAdapter
- Object
- AbstractAdapter
- ActiveRecord::ConnectionAdapters::MaterializeAdapter
- Includes:
- ActiveRecord::ConnectionAdapters::Materialize::DatabaseStatements, ActiveRecord::ConnectionAdapters::Materialize::Quoting, ActiveRecord::ConnectionAdapters::Materialize::ReferentialIntegrity, ActiveRecord::ConnectionAdapters::Materialize::Schema::SourceStatements, ActiveRecord::ConnectionAdapters::Materialize::Schema::ViewStatements, ActiveRecord::ConnectionAdapters::Materialize::SchemaStatements
- Defined in:
- lib/active_record/connection_adapters/materialize_adapter.rb
Overview
The Materialize adapter works with the native C (bitbucket.org/ged/ruby-pg) driver.
Options:
-
:host
- Defaults to a Unix-domain socket in /tmp. On machines without Unix-domain sockets, the default is to connect to localhost. -
:port
- Defaults to 5432. -
:username
- Defaults to be the same as the operating system name of the user running the application. -
:password
- Password to be used if the server demands password authentication. -
:database
- Defaults to be the same as the user name. -
:schema_search_path
- An optional schema search path for the connection given as a string of comma-separated schema names. This is backward-compatible with the:schema_order
option. -
:encoding
- An optional client encoding that is used in aSET client_encoding TO <encoding>
call on the connection. -
:min_messages
- An optional client min messages that is used in aSET client_min_messages TO <min_messages>
call on the connection. -
:variables
- An optional hash of additional parameters that will be used inSET SESSION key = val
calls on the connection. -
:insert_returning
- An optional boolean to control the use ofRETURNING
forINSERT
statements defaults to true.
Any further options are used as connection parameters to libpq. See www.postgresql.org/docs/current/static/libpq-connect.html for the list of parameters.
In addition, default connection parameters of libpq can be set per environment variables. See www.postgresql.org/docs/current/static/libpq-envars.html .
Defined Under Namespace
Classes: StatementPool
Constant Summary collapse
- ADAPTER_NAME =
"Materialize"
- NATIVE_DATABASE_TYPES =
{ primary_key: "bigint", string: { name: "character varying" }, text: { name: "text" }, integer: { name: "integer" }, bigint: { name: "int8" }, float: { name: "float4" }, double: { name: "float8" }, decimal: { name: "decimal" }, datetime: { name: "timestamp" }, timestampz: { name: "timestamp with time zone" }, time: { name: "time" }, date: { name: "date" }, binary: { name: "bytea" }, boolean: { name: "boolean" }, map: { name: "map" }, json: { name: "jsonb" }, interval: { name: "interval" }, record: { name: "record" }, oid: { name: "oid" }, }
- OID =
:nodoc:
Materialize::OID
- OPERATION_ALIASES =
:nodoc:
{ # :nodoc: "maximum" => "max", "minimum" => "min", "average" => "avg", }
Constants included from ActiveRecord::ConnectionAdapters::Materialize::DatabaseStatements
ActiveRecord::ConnectionAdapters::Materialize::DatabaseStatements::BYTEA_COLUMN_TYPE_OID, ActiveRecord::ConnectionAdapters::Materialize::DatabaseStatements::MONEY_COLUMN_TYPE_OID
Class Method Summary collapse
Instance Method Summary collapse
-
#active? ⇒ Boolean
Is this connection alive and ready for queries?.
-
#build_insert_sql(insert) ⇒ Object
:nodoc:.
-
#check_version ⇒ Object
:nodoc:.
-
#column_name_for_operation(operation, node) ⇒ Object
:nodoc:.
-
#create_unlogged_tables ⇒ Object
:singleton-method: Materialize allows the creation of “unlogged” tables, which do not record data in the Materialize Write-Ahead Log.
-
#default_index_type?(index) ⇒ Boolean
:nodoc:.
-
#discard! ⇒ Object
:nodoc:.
-
#disconnect! ⇒ Object
Disconnects from the database if already connected.
-
#get_advisory_lock(lock_id) ⇒ Object
:nodoc:.
-
#get_database_version ⇒ Object
Returns the version of the connected Materialize server.
-
#initialize(connection, logger, connection_parameters, config) ⇒ MaterializeAdapter
constructor
Initializes and connects a Materialize adapter.
-
#max_identifier_length ⇒ Object
Returns the configured supported identifier length supported by Materialize.
-
#native_database_types ⇒ Object
:nodoc:.
-
#reconnect! ⇒ Object
Close then reopen the connection.
-
#release_advisory_lock(lock_id) ⇒ Object
:nodoc:.
- #reset! ⇒ Object
-
#session_auth=(user) ⇒ Object
Set the authorized user for this session.
- #supports_advisory_locks? ⇒ Boolean
- #supports_bulk_alter? ⇒ Boolean
- #supports_common_table_expressions? ⇒ Boolean
- #supports_ddl_transactions? ⇒ Boolean
- #supports_explain? ⇒ Boolean
-
#supports_insert_returning? ⇒ Boolean
TODO: test insert returning.
- #supports_json? ⇒ Boolean
- #supports_lazy_transactions? ⇒ Boolean
- #supports_materialized_views? ⇒ Boolean
- #supports_optimizer_hints? ⇒ Boolean
- #supports_ranges? ⇒ Boolean
-
#supports_transaction_isolation? ⇒ Boolean
TODO: test transaction isolation.
- #supports_views? ⇒ Boolean
Methods included from ActiveRecord::ConnectionAdapters::Materialize::Schema::ViewStatements
#materialized_views, #view_sql
Methods included from ActiveRecord::ConnectionAdapters::Materialize::Schema::SourceStatements
#create_source, #drop_source, #select_database_config, #source_exists?, #source_options, #sources
Methods included from ActiveRecord::ConnectionAdapters::Materialize::DatabaseStatements
#begin_db_transaction, #begin_isolated_db_transaction, #commit_db_transaction, #exec_delete, #exec_query, #exec_rollback_db_transaction, #execute, #explain, #query, #result_as_array, #write_query?
Methods included from ActiveRecord::ConnectionAdapters::Materialize::SchemaStatements
#add_column, #add_index, #change_column, #change_column_default, #change_column_null, #collation, #columns_for_distinct, #create_database, #create_schema, #create_schema_dumper, #ctype, #current_database, #current_schema, #default_sequence_name, #drop_database, #drop_schema, #drop_table, #encoding, #index_name_exists?, #indexes, #primary_keys, #recreate_database, #remove_index, #rename_column, #rename_index, #rename_table, #schema_exists?, #schema_names, #schema_search_path, #table_comment, #table_options, #type_to_sql, #update_table_definition, #validate_constraint, #validate_foreign_key
Methods included from ActiveRecord::ConnectionAdapters::Materialize::ReferentialIntegrity
#disable_referential_integrity
Methods included from ActiveRecord::ConnectionAdapters::Materialize::Quoting
#column_name_matcher, #column_name_with_order_matcher, #escape_bytea, #lookup_cast_type_from_column, #quote_column_name, #quote_default_expression, #quote_schema_name, #quote_string, #quote_table_name, #quote_table_name_for_assignment, #quoted_binary, #quoted_date, #unescape_bytea
Constructor Details
#initialize(connection, logger, connection_parameters, config) ⇒ MaterializeAdapter
Initializes and connects a Materialize adapter.
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/active_record/connection_adapters/materialize_adapter.rb', line 192 def initialize(connection, logger, connection_parameters, config) super(connection, logger, config) @connection_parameters = connection_parameters # @local_tz is initialized as nil to avoid warnings when connect tries to use it @local_tz = nil @max_identifier_length = nil configure_connection add_pg_encoders add_pg_decoders @type_map = Type::HashLookupTypeMap.new initialize_type_map @local_tz = execute("SHOW TIMEZONE", "SCHEMA").first["TimeZone"] end |
Class Method Details
.database_exists?(config) ⇒ Boolean
210 211 212 213 214 |
# File 'lib/active_record/connection_adapters/materialize_adapter.rb', line 210 def self.database_exists?(config) !!ActiveRecord::Base.materialize_connection(config) rescue ActiveRecord::NoDatabaseError false end |
Instance Method Details
#active? ⇒ Boolean
Is this connection alive and ready for queries?
217 218 219 220 221 222 223 224 |
# File 'lib/active_record/connection_adapters/materialize_adapter.rb', line 217 def active? @lock.synchronize do @connection.query "SELECT 1" end true rescue PG::Error false end |
#build_insert_sql(insert) ⇒ Object
:nodoc:
349 350 351 352 353 354 355 356 357 358 359 360 361 |
# File 'lib/active_record/connection_adapters/materialize_adapter.rb', line 349 def build_insert_sql(insert) # :nodoc: sql = +"INSERT #{insert.into} #{insert.values_list}" if insert.skip_duplicates? sql << " ON CONFLICT #{insert.conflict_target} DO NOTHING" elsif insert.update_duplicates? sql << " ON CONFLICT #{insert.conflict_target} DO UPDATE SET " sql << insert.updatable_columns.map { |column| "#{column}=excluded.#{column}" }.join(",") end sql << " RETURNING #{insert.returning}" if insert.returning sql end |
#check_version ⇒ Object
:nodoc:
363 364 365 366 367 |
# File 'lib/active_record/connection_adapters/materialize_adapter.rb', line 363 def check_version # :nodoc: if database_version < 90300 raise "Your version of Materialize (#{database_version}) is too old. Active Record supports Materialize >= 9.3." end end |
#column_name_for_operation(operation, node) ⇒ Object
:nodoc:
329 330 331 |
# File 'lib/active_record/connection_adapters/materialize_adapter.rb', line 329 def column_name_for_operation(operation, node) # :nodoc: OPERATION_ALIASES.fetch(operation) { operation.downcase } end |
#create_unlogged_tables ⇒ Object
:singleton-method: Materialize allows the creation of “unlogged” tables, which do not record data in the Materialize Write-Ahead Log. This can make the tables faster, but significantly increases the risk of data loss if the database crashes. As a result, this should not be used in production environments. If you would like all created tables to be unlogged in the test environment you can add the following line to your test.rb file:
ActiveRecord::ConnectionAdapters::MaterializeAdapter.create_unlogged_tables = true
108 |
# File 'lib/active_record/connection_adapters/materialize_adapter.rb', line 108 class_attribute :create_unlogged_tables, default: false |
#default_index_type?(index) ⇒ Boolean
:nodoc:
345 346 347 |
# File 'lib/active_record/connection_adapters/materialize_adapter.rb', line 345 def default_index_type?(index) # :nodoc: index.using == :btree || super end |
#discard! ⇒ Object
:nodoc:
258 259 260 261 262 |
# File 'lib/active_record/connection_adapters/materialize_adapter.rb', line 258 def discard! # :nodoc: super @connection.socket_io.reopen(IO::NULL) rescue nil @connection = nil end |
#disconnect! ⇒ Object
Disconnects from the database if already connected. Otherwise, this method does nothing.
251 252 253 254 255 256 |
# File 'lib/active_record/connection_adapters/materialize_adapter.rb', line 251 def disconnect! @lock.synchronize do super @connection.close rescue nil end end |
#get_advisory_lock(lock_id) ⇒ Object
:nodoc:
304 305 306 307 308 309 |
# File 'lib/active_record/connection_adapters/materialize_adapter.rb', line 304 def get_advisory_lock(lock_id) # :nodoc: unless lock_id.is_a?(Integer) && lock_id.bit_length <= 63 raise(ArgumentError, "Materialize requires advisory lock ids to be a signed 64 bit integer") end query_value("SELECT pg_try_advisory_lock(#{lock_id})") end |
#get_database_version ⇒ Object
Returns the version of the connected Materialize server.
340 341 342 |
# File 'lib/active_record/connection_adapters/materialize_adapter.rb', line 340 def get_database_version # :nodoc: @connection.server_version end |
#max_identifier_length ⇒ Object
Returns the configured supported identifier length supported by Materialize
319 320 321 |
# File 'lib/active_record/connection_adapters/materialize_adapter.rb', line 319 def max_identifier_length @max_identifier_length || 64 end |
#native_database_types ⇒ Object
:nodoc:
264 265 266 |
# File 'lib/active_record/connection_adapters/materialize_adapter.rb', line 264 def native_database_types #:nodoc: NATIVE_DATABASE_TYPES end |
#reconnect! ⇒ Object
Close then reopen the connection.
227 228 229 230 231 232 233 234 235 |
# File 'lib/active_record/connection_adapters/materialize_adapter.rb', line 227 def reconnect! @lock.synchronize do super @connection.reset configure_connection rescue PG::ConnectionBad connect end end |
#release_advisory_lock(lock_id) ⇒ Object
:nodoc:
311 312 313 314 315 316 |
# File 'lib/active_record/connection_adapters/materialize_adapter.rb', line 311 def release_advisory_lock(lock_id) # :nodoc: unless lock_id.is_a?(Integer) && lock_id.bit_length <= 63 raise(ArgumentError, "Materialize requires advisory lock ids to be a signed 64 bit integer") end query_value("SELECT pg_advisory_unlock(#{lock_id})") end |
#reset! ⇒ Object
237 238 239 240 241 242 243 244 245 246 247 |
# File 'lib/active_record/connection_adapters/materialize_adapter.rb', line 237 def reset! @lock.synchronize do clear_cache! reset_transaction unless @connection.transaction_status == ::PG::PQTRANS_IDLE @connection.query "ROLLBACK" end @connection.query "DISCARD ALL" configure_connection end end |
#session_auth=(user) ⇒ Object
Set the authorized user for this session
324 325 326 327 |
# File 'lib/active_record/connection_adapters/materialize_adapter.rb', line 324 def session_auth=(user) clear_cache! execute("SET SESSION AUTHORIZATION #{user}") end |
#supports_advisory_locks? ⇒ Boolean
272 273 274 |
# File 'lib/active_record/connection_adapters/materialize_adapter.rb', line 272 def supports_advisory_locks? true end |
#supports_bulk_alter? ⇒ Boolean
141 142 143 |
# File 'lib/active_record/connection_adapters/materialize_adapter.rb', line 141 def supports_bulk_alter? true end |
#supports_common_table_expressions? ⇒ Boolean
296 297 298 |
# File 'lib/active_record/connection_adapters/materialize_adapter.rb', line 296 def supports_common_table_expressions? true end |
#supports_ddl_transactions? ⇒ Boolean
268 269 270 |
# File 'lib/active_record/connection_adapters/materialize_adapter.rb', line 268 def supports_ddl_transactions? true end |
#supports_explain? ⇒ Boolean
276 277 278 |
# File 'lib/active_record/connection_adapters/materialize_adapter.rb', line 276 def supports_explain? true end |
#supports_insert_returning? ⇒ Boolean
TODO: test insert returning
159 160 161 |
# File 'lib/active_record/connection_adapters/materialize_adapter.rb', line 159 def supports_insert_returning? true end |
#supports_json? ⇒ Boolean
154 155 156 |
# File 'lib/active_record/connection_adapters/materialize_adapter.rb', line 154 def supports_json? true end |
#supports_lazy_transactions? ⇒ Boolean
300 301 302 |
# File 'lib/active_record/connection_adapters/materialize_adapter.rb', line 300 def supports_lazy_transactions? true end |
#supports_materialized_views? ⇒ Boolean
285 286 287 |
# File 'lib/active_record/connection_adapters/materialize_adapter.rb', line 285 def supports_materialized_views? true end |
#supports_optimizer_hints? ⇒ Boolean
289 290 291 292 293 294 |
# File 'lib/active_record/connection_adapters/materialize_adapter.rb', line 289 def supports_optimizer_hints? unless defined?(@has_pg_hint_plan) @has_pg_hint_plan = extension_available?("pg_hint_plan") end @has_pg_hint_plan end |
#supports_ranges? ⇒ Boolean
280 281 282 |
# File 'lib/active_record/connection_adapters/materialize_adapter.rb', line 280 def supports_ranges? true end |
#supports_transaction_isolation? ⇒ Boolean
TODO: test transaction isolation
146 147 148 |
# File 'lib/active_record/connection_adapters/materialize_adapter.rb', line 146 def supports_transaction_isolation? true end |
#supports_views? ⇒ Boolean
150 151 152 |
# File 'lib/active_record/connection_adapters/materialize_adapter.rb', line 150 def supports_views? true end |