Class: ActiveRecord::ConnectionAdapters::YugabyteDBAdapter
- Inherits:
-
AbstractAdapter
- Object
- AbstractAdapter
- ActiveRecord::ConnectionAdapters::YugabyteDBAdapter
- Includes:
- ActiveRecord::ConnectionAdapters::YugabyteDB::DatabaseStatements, ActiveRecord::ConnectionAdapters::YugabyteDB::Quoting, ActiveRecord::ConnectionAdapters::YugabyteDB::ReferentialIntegrity, ActiveRecord::ConnectionAdapters::YugabyteDB::SchemaStatements
- Defined in:
- lib/active_record/connection_adapters/yugabytedb_adapter.rb
Overview
Active Record YugabyteDB Adapter
The PostgreSQL adapter works with the native C (github.com/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 username. -
: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: MoneyDecoder, StatementPool
Constant Summary collapse
- ADAPTER_NAME =
"YugabyteDB"
- NATIVE_DATABASE_TYPES =
{ primary_key: "bigserial primary key", string: { name: "character varying" }, text: { name: "text" }, integer: { name: "integer", limit: 4 }, bigint: { name: "bigint" }, float: { name: "float" }, decimal: { name: "decimal" }, datetime: {}, # set dynamically based on datetime_type timestamp: { name: "timestamp" }, timestamptz: { name: "timestamptz" }, time: { name: "time" }, date: { name: "date" }, daterange: { name: "daterange" }, numrange: { name: "numrange" }, tsrange: { name: "tsrange" }, tstzrange: { name: "tstzrange" }, int4range: { name: "int4range" }, int8range: { name: "int8range" }, binary: { name: "bytea" }, boolean: { name: "boolean" }, xml: { name: "xml" }, tsvector: { name: "tsvector" }, hstore: { name: "hstore" }, inet: { name: "inet" }, cidr: { name: "cidr" }, macaddr: { name: "macaddr" }, uuid: { name: "uuid" }, json: { name: "json" }, jsonb: { name: "jsonb" }, ltree: { name: "ltree" }, citext: { name: "citext" }, point: { name: "point" }, line: { name: "line" }, lseg: { name: "lseg" }, box: { name: "box" }, path: { name: "path" }, polygon: { name: "polygon" }, circle: { name: "circle" }, bit: { name: "bit" }, bit_varying: { name: "bit varying" }, money: { name: "money" }, interval: { name: "interval" }, oid: { name: "oid" }, enum: {} # special type https://www.postgresql.org/docs/current/datatype-enum.html }
- OID =
:nodoc:
YugabyteDB::OID
Constants included from ActiveRecord::ConnectionAdapters::YugabyteDB::Quoting
ActiveRecord::ConnectionAdapters::YugabyteDB::Quoting::QUOTED_COLUMN_NAMES, ActiveRecord::ConnectionAdapters::YugabyteDB::Quoting::QUOTED_TABLE_NAMES
Class Method Summary collapse
- .dbconsole(config, options = {}) ⇒ Object
-
.initialize_type_map(m) ⇒ Object
:nodoc:.
-
.native_database_types ⇒ Object
:nodoc:.
- .new_client(conn_params) ⇒ Object
Instance Method Summary collapse
-
#active? ⇒ Boolean
Is this connection alive and ready for queries?.
-
#add_enum_value(type_name, value, options = {}) ⇒ Object
Add enum value to an existing enum type.
-
#build_insert_sql(insert) ⇒ Object
:nodoc:.
-
#check_version ⇒ Object
:nodoc:.
-
#create_enum(name, values, **options) ⇒ Object
Given a name and an array of values, creates an enum type.
-
#create_unlogged_tables ⇒ Object
:singleton-method: PostgreSQL allows the creation of “unlogged” tables, which do not record data in the PostgreSQL Write-Ahead Log.
-
#datetime_type ⇒ Object
:singleton-method: PostgreSQL supports multiple types for DateTimes.
-
#default_index_type?(index) ⇒ Boolean
:nodoc:.
-
#disable_extension(name, force: false) ⇒ Object
Removes an extension from the database.
-
#discard! ⇒ Object
:nodoc:.
-
#disconnect! ⇒ Object
Disconnects from the database if already connected.
-
#drop_enum(name, values = nil, **options) ⇒ Object
Drops an enum type.
- #enable_extension(name) ⇒ Object
-
#enum_types ⇒ Object
Returns a list of defined enum types, and their values.
- #extension_available?(name) ⇒ Boolean
- #extension_enabled?(name) ⇒ Boolean
- #extensions ⇒ Object
-
#get_advisory_lock(lock_id) ⇒ Object
:nodoc:.
-
#get_database_version ⇒ Object
Returns the version of the connected YugabyteDB server.
- #index_algorithms ⇒ Object
-
#initialize ⇒ YugabyteDBAdapter
constructor
Initializes and connects a YugabyteDB adapter.
-
#max_identifier_length ⇒ Object
Returns the configured supported identifier length supported by PostgreSQL.
-
#native_database_types ⇒ Object
:nodoc:.
-
#release_advisory_lock(lock_id) ⇒ Object
:nodoc:.
-
#reload_type_map ⇒ Object
:nodoc:.
-
#rename_enum(name, options = {}) ⇒ Object
Rename an existing enum type to something else.
-
#rename_enum_value(type_name, options = {}) ⇒ Object
Rename enum value on an existing enum type.
- #reset! ⇒ Object
-
#return_value_after_insert?(column) ⇒ Boolean
:nodoc:.
-
#session_auth=(user) ⇒ Object
Set the authorized user for this session.
- #set_standard_conforming_strings ⇒ Object
- #supports_advisory_locks? ⇒ Boolean
- #supports_bulk_alter? ⇒ Boolean
- #supports_check_constraints? ⇒ Boolean
- #supports_comments? ⇒ Boolean
- #supports_common_table_expressions? ⇒ Boolean
- #supports_datetime_with_precision? ⇒ Boolean
- #supports_ddl_transactions? ⇒ Boolean
- #supports_deferrable_constraints? ⇒ Boolean
- #supports_exclusion_constraints? ⇒ Boolean
- #supports_explain? ⇒ Boolean
- #supports_expression_index? ⇒ Boolean
- #supports_extensions? ⇒ Boolean
- #supports_foreign_keys? ⇒ Boolean
- #supports_foreign_tables? ⇒ Boolean
-
#supports_identity_columns? ⇒ Boolean
:nodoc:.
- #supports_index_include? ⇒ Boolean
- #supports_index_sort_order? ⇒ Boolean
- #supports_insert_on_conflict? ⇒ Boolean (also: #supports_insert_on_duplicate_skip?, #supports_insert_on_duplicate_update?, #supports_insert_conflict_target?)
- #supports_insert_returning? ⇒ Boolean
- #supports_json? ⇒ Boolean
- #supports_lazy_transactions? ⇒ Boolean
- #supports_materialized_views? ⇒ Boolean
- #supports_nulls_not_distinct? ⇒ Boolean
- #supports_optimizer_hints? ⇒ Boolean
- #supports_partial_index? ⇒ Boolean
- #supports_partitioned_indexes? ⇒ Boolean
- #supports_pgcrypto_uuid? ⇒ Boolean
- #supports_restart_db_transaction? ⇒ Boolean
- #supports_savepoints? ⇒ Boolean
- #supports_transaction_isolation? ⇒ Boolean
- #supports_unique_constraints? ⇒ Boolean
- #supports_validate_constraints? ⇒ Boolean
- #supports_views? ⇒ Boolean
- #supports_virtual_columns? ⇒ Boolean
- #use_insert_returning? ⇒ Boolean
Methods included from ActiveRecord::ConnectionAdapters::YugabyteDB::DatabaseStatements
#begin_db_transaction, #begin_isolated_db_transaction, #build_explain_clause, #commit_db_transaction, #exec_delete, #exec_insert, #exec_restart_db_transaction, #exec_rollback_db_transaction, #execute, #explain, #high_precision_current_timestamp, #internal_exec_query, #query, #raw_execute, #write_query?
Methods included from ActiveRecord::ConnectionAdapters::YugabyteDB::SchemaStatements
#add_column, #add_exclusion_constraint, #add_foreign_key, #add_index, #add_index_options, #add_unique_constraint, #build_change_column_default_definition, #build_change_column_definition, #build_create_index_definition, #change_column, #change_column_comment, #change_column_default, #change_column_null, #change_table_comment, #check_constraints, #client_min_messages, #client_min_messages=, #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, #exclusion_constraint_options, #exclusion_constraints, #foreign_key_column_for, #foreign_keys, #foreign_table_exists?, #foreign_tables, #index_name, #index_name_exists?, #indexes, #pk_and_sequence_for, #primary_keys, #quoted_include_columns_for_index, #recreate_database, #remove_exclusion_constraint, #remove_index, #remove_unique_constraint, #rename_column, #rename_index, #rename_table, #reset_pk_sequence!, #schema_creation, #schema_exists?, #schema_names, #schema_search_path, #schema_search_path=, #serial_sequence, #set_pk_sequence!, #table_comment, #table_options, #type_to_sql, #unique_constraint_options, #unique_constraints, #update_table_definition, #validate_check_constraint, #validate_constraint, #validate_foreign_key
Methods included from ActiveRecord::ConnectionAdapters::YugabyteDB::ReferentialIntegrity
#check_all_foreign_keys_valid!, #disable_referential_integrity
Methods included from ActiveRecord::ConnectionAdapters::YugabyteDB::Quoting
#check_int_in_range, #column_name_matcher, #column_name_with_order_matcher, #escape_bytea, #lookup_cast_type_from_column, #quote, #quote_column_name, #quote_default_expression, #quote_schema_name, #quote_string, #quote_table_name, #quote_table_name_for_assignment, #quoted_binary, #quoted_date, #type_cast, #unescape_bytea
Constructor Details
#initialize ⇒ YugabyteDBAdapter
Initializes and connects a YugabyteDB adapter.
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 323 def initialize(...) super conn_params = @config.compact # Map ActiveRecords param names to PGs. conn_params[:user] = conn_params.delete(:username) if conn_params[:username] conn_params[:dbname] = conn_params.delete(:database) if conn_params[:database] # Forward only valid config params to PG::Connection.connect. valid_conn_param_keys = YSQL::Connection.conndefaults_hash.keys + [:requiressl] conn_params.slice!(*valid_conn_param_keys) @connection_parameters = conn_params @max_identifier_length = nil @type_map = nil @raw_connection = nil @notice_receiver_sql_warnings = [] @use_insert_returning = @config.key?(:insert_returning) ? self.class.type_cast_config_to_boolean(@config[:insert_returning]) : true end |
Class Method Details
.dbconsole(config, options = {}) ⇒ Object
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 85 def dbconsole(config, = {}) pg_config = config.configuration_hash ENV["PGUSER"] = pg_config[:username] if pg_config[:username] ENV["PGHOST"] = pg_config[:host] if pg_config[:host] ENV["PGPORT"] = pg_config[:port].to_s if pg_config[:port] ENV["PGPASSWORD"] = pg_config[:password].to_s if pg_config[:password] && [:include_password] ENV["PGSSLMODE"] = pg_config[:sslmode].to_s if pg_config[:sslmode] ENV["PGSSLCERT"] = pg_config[:sslcert].to_s if pg_config[:sslcert] ENV["PGSSLKEY"] = pg_config[:sslkey].to_s if pg_config[:sslkey] ENV["PGSSLROOTCERT"] = pg_config[:sslrootcert].to_s if pg_config[:sslrootcert] if pg_config[:variables] ENV["PGOPTIONS"] = pg_config[:variables].filter_map do |name, value| "-c #{name}=#{value.to_s.gsub(/[ \\]/, '\\\\\0')}" unless value == ":default" || value == :default end.join(" ") end find_cmd_and_exec("psql", config.database) end |
.initialize_type_map(m) ⇒ Object
:nodoc:
651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 651 def initialize_type_map(m) # :nodoc: m.register_type "int2", Type::Integer.new(limit: 2) m.register_type "int4", Type::Integer.new(limit: 4) m.register_type "int8", Type::Integer.new(limit: 8) m.register_type "oid", OID::Oid.new m.register_type "float4", Type::Float.new m.alias_type "float8", "float4" m.register_type "text", Type::Text.new register_class_with_limit m, "varchar", Type::String m.alias_type "char", "varchar" m.alias_type "name", "varchar" m.alias_type "bpchar", "varchar" m.register_type "bool", Type::Boolean.new register_class_with_limit m, "bit", OID::Bit register_class_with_limit m, "varbit", OID::BitVarying m.register_type "date", OID::Date.new m.register_type "money", OID::Money.new m.register_type "bytea", OID::Bytea.new m.register_type "point", OID::Point.new m.register_type "hstore", OID::Hstore.new m.register_type "json", Type::Json.new m.register_type "jsonb", OID::Jsonb.new m.register_type "cidr", OID::Cidr.new m.register_type "inet", OID::Inet.new m.register_type "uuid", OID::Uuid.new m.register_type "xml", OID::Xml.new m.register_type "tsvector", OID::SpecializedString.new(:tsvector) m.register_type "macaddr", OID::Macaddr.new m.register_type "citext", OID::SpecializedString.new(:citext) m.register_type "ltree", OID::SpecializedString.new(:ltree) m.register_type "line", OID::SpecializedString.new(:line) m.register_type "lseg", OID::SpecializedString.new(:lseg) m.register_type "box", OID::SpecializedString.new(:box) m.register_type "path", OID::SpecializedString.new(:path) m.register_type "polygon", OID::SpecializedString.new(:polygon) m.register_type "circle", OID::SpecializedString.new(:circle) m.register_type "numeric" do |_, fmod, sql_type| precision = extract_precision(sql_type) scale = extract_scale(sql_type) # The type for the numeric depends on the width of the field, # so we'll do something special here. # # When dealing with decimal columns: # # places after decimal = fmod - 4 & 0xffff # places before decimal = (fmod - 4) >> 16 & 0xffff if fmod && (fmod - 4 & 0xffff).zero? # FIXME: Remove this class, and the second argument to # lookups on PG Type::DecimalWithoutScale.new(precision: precision) else OID::Decimal.new(precision: precision, scale: scale) end end m.register_type "interval" do |*args, sql_type| precision = extract_precision(sql_type) OID::Interval.new(precision: precision) end end |
.native_database_types ⇒ Object
:nodoc:
402 403 404 405 406 407 408 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 402 def self.native_database_types # :nodoc: @native_database_types ||= begin types = NATIVE_DATABASE_TYPES.dup types[:datetime] = types[datetime_type] types end end |
.new_client(conn_params) ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 69 def new_client(conn_params) YSQL.connect(**conn_params) rescue ::YSQL::Error => error if conn_params && conn_params[:dbname] == "postgres" raise ActiveRecord::ConnectionNotEstablished, error. elsif conn_params && conn_params[:dbname] && error..include?(conn_params[:dbname]) raise ActiveRecord::NoDatabaseError.db_error(conn_params[:dbname]) elsif conn_params && conn_params[:user] && error..include?(conn_params[:user]) raise ActiveRecord::DatabaseConnectionError.username_error(conn_params[:user]) elsif conn_params && conn_params[:host] && error..include?(conn_params[:host]) raise ActiveRecord::DatabaseConnectionError.hostname_error(conn_params[:host]) else raise ActiveRecord::ConnectionNotEstablished, error. end end |
Instance Method Details
#active? ⇒ Boolean
Is this connection alive and ready for queries?
347 348 349 350 351 352 353 354 355 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 347 def active? @lock.synchronize do return false unless @raw_connection @raw_connection.query ";" end true rescue YSQL::Error false end |
#add_enum_value(type_name, value, options = {}) ⇒ Object
Add enum value to an existing enum type.
571 572 573 574 575 576 577 578 579 580 581 582 583 584 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 571 def add_enum_value(type_name, value, = {}) before, after = .values_at(:before, :after) sql = +"ALTER TYPE #{quote_table_name(type_name)} ADD VALUE '#{value}'" if before && after raise ArgumentError, "Cannot have both :before and :after at the same time" elsif before sql << " BEFORE '#{before}'" elsif after sql << " AFTER '#{after}'" end execute(sql).tap { reload_type_map } end |
#build_insert_sql(insert) ⇒ Object
:nodoc:
625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 625 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 " if insert.raw_update_sql? sql << insert.raw_update_sql else sql << insert. { |column| "#{insert.model.quoted_table_name}.#{column} IS NOT DISTINCT FROM excluded.#{column}" } sql << insert.updatable_columns.map { |column| "#{column}=excluded.#{column}" }.join(",") end end sql << " RETURNING #{insert.returning}" if insert.returning sql end |
#check_version ⇒ Object
:nodoc:
644 645 646 647 648 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 644 def check_version # :nodoc: if database_version < 9_03_00 # < 9.3 raise "Your version of YugabyteDB (#{database_version}) is too old. Active Record supports YugabyteDB >= 9.3." end end |
#create_enum(name, values, **options) ⇒ Object
Given a name and an array of values, creates an enum type.
526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 526 def create_enum(name, values, **) sql_values = values.map { |s| quote(s) }.join(", ") scope = quoted_scope(name) query = <<~SQL DO $$ BEGIN IF NOT EXISTS ( SELECT 1 FROM pg_type t JOIN pg_namespace n ON t.typnamespace = n.oid WHERE t.typname = #{scope[:name]} AND n.nspname = #{scope[:schema]} ) THEN CREATE TYPE #{quote_table_name(name)} AS ENUM (#{sql_values}); END IF; END $$; SQL internal_exec_query(query).tap { reload_type_map } end |
#create_unlogged_tables ⇒ Object
:singleton-method: PostgreSQL allows the creation of “unlogged” tables, which do not record data in the PostgreSQL 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 to your test.rb file:
ActiveSupport.on_load(:active_record_postgresqladapter) do
self.create_unlogged_tables = true
end
117 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 117 class_attribute :create_unlogged_tables, default: false |
#datetime_type ⇒ Object
:singleton-method: PostgreSQL supports multiple types for DateTimes. By default, if you use datetime
in migrations, Rails will translate this to a PostgreSQL “timestamp without time zone”. Change this in an initializer to use another NATIVE_DATABASE_TYPES. For example, to store DateTimes as “timestamp with time zone”:
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.datetime_type = :timestamptz
Or if you are adding a custom type:
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::NATIVE_DATABASE_TYPES[:my_custom_type] = { name: "my_custom_type_name" }
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.datetime_type = :my_custom_type
If you’re using :ruby
as your config.active_record.schema_format
and you change this setting, you should immediately run bin/rails db:migrate
to update the types in your schema.rb.
135 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 135 class_attribute :datetime_type, default: :timestamp |
#default_index_type?(index) ⇒ Boolean
:nodoc:
621 622 623 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 621 def default_index_type?(index) # :nodoc: index.using == :btree || super end |
#disable_extension(name, force: false) ⇒ Object
Removes an extension from the database.
:force
-
Set to
:cascade
to drop dependent objects as well. Defaults to false.
484 485 486 487 488 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 484 def disable_extension(name, force: false) internal_exec_query("DROP EXTENSION IF EXISTS \"#{name}\"#{' CASCADE' if force == :cascade}").tap { reload_type_map } end |
#discard! ⇒ Object
:nodoc:
392 393 394 395 396 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 392 def discard! # :nodoc: super @raw_connection&.socket_io&.reopen(IO::NULL) rescue nil @raw_connection = nil end |
#disconnect! ⇒ Object
Disconnects from the database if already connected. Otherwise, this method does nothing.
384 385 386 387 388 389 390 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 384 def disconnect! @lock.synchronize do super @raw_connection&.close rescue nil @raw_connection = nil end end |
#drop_enum(name, values = nil, **options) ⇒ Object
Drops an enum type.
If the if_exists: true
option is provided, the enum is dropped only if it exists. Otherwise, if the enum doesn’t exist, an error is raised.
The values
parameter will be ignored if present. It can be helpful to provide this in a migration’s change
method so it can be reverted. In that case, values
will be used by #create_enum.
556 557 558 559 560 561 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 556 def drop_enum(name, values = nil, **) query = <<~SQL DROP TYPE#{' IF EXISTS' if [:if_exists]} #{quote_table_name(name)}; SQL internal_exec_query(query).tap { reload_type_map } end |
#enable_extension(name) ⇒ Object
471 472 473 474 475 476 477 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 471 def enable_extension(name, **) schema, name = name.to_s.split(".").values_at(-2, -1) sql = +"CREATE EXTENSION IF NOT EXISTS \"#{name}\"" sql << " SCHEMA #{schema}" if schema internal_exec_query(sql).tap { reload_type_map } end |
#enum_types ⇒ Object
Returns a list of defined enum types, and their values.
503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 503 def enum_types query = <<~SQL SELECT type.typname AS name, type.OID AS oid, n.nspname AS schema, string_agg(enum.enumlabel, ',' ORDER BY enum.enumsortorder) AS value FROM pg_enum AS enum JOIN pg_type AS type ON (type.oid = enum.enumtypid) JOIN pg_namespace n ON type.typnamespace = n.oid WHERE n.nspname = ANY (current_schemas(false)) GROUP BY type.OID, n.nspname, type.typname; SQL internal_exec_query(query, "SCHEMA", allow_retry: true, materialize_transactions: false).cast_values.each_with_object({}) do |row, memo| name, schema = row[0], row[2] schema = nil if schema == current_schema full_name = [schema, name].compact.join(".") memo[full_name] = row.last end.to_a end |
#extension_available?(name) ⇒ Boolean
490 491 492 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 490 def extension_available?(name) query_value("SELECT true FROM pg_available_extensions WHERE name = #{quote(name)}", "SCHEMA") end |
#extension_enabled?(name) ⇒ Boolean
494 495 496 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 494 def extension_enabled?(name) query_value("SELECT installed_version IS NOT NULL FROM pg_available_extensions WHERE name = #{quote(name)}", "SCHEMA") end |
#extensions ⇒ Object
498 499 500 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 498 def extensions internal_exec_query("SELECT extname FROM pg_extension", "SCHEMA", allow_retry: true, materialize_transactions: false).cast_values end |
#get_advisory_lock(lock_id) ⇒ Object
:nodoc:
457 458 459 460 461 462 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 457 def get_advisory_lock(lock_id) # :nodoc: unless lock_id.is_a?(Integer) && lock_id.bit_length <= 63 raise(ArgumentError, "PostgreSQL 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 YugabyteDB server.
616 617 618 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 616 def get_database_version # :nodoc: valid_raw_connection.server_version end |
#index_algorithms ⇒ Object
290 291 292 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 290 def index_algorithms { concurrently: "CONCURRENTLY" } end |
#max_identifier_length ⇒ Object
Returns the configured supported identifier length supported by PostgreSQL
601 602 603 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 601 def max_identifier_length @max_identifier_length ||= query_value("SHOW max_identifier_length", "SCHEMA").to_i end |
#native_database_types ⇒ Object
:nodoc:
398 399 400 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 398 def native_database_types # :nodoc: self.class.native_database_types end |
#release_advisory_lock(lock_id) ⇒ Object
:nodoc:
464 465 466 467 468 469 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 464 def release_advisory_lock(lock_id) # :nodoc: unless lock_id.is_a?(Integer) && lock_id.bit_length <= 63 raise(ArgumentError, "PostgreSQL requires advisory lock ids to be a signed 64 bit integer") end query_value("SELECT pg_advisory_unlock(#{lock_id})") end |
#reload_type_map ⇒ Object
:nodoc:
357 358 359 360 361 362 363 364 365 366 367 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 357 def reload_type_map # :nodoc: @lock.synchronize do if @type_map type_map.clear else @type_map = Type::HashLookupTypeMap.new end initialize_type_map end end |
#rename_enum(name, options = {}) ⇒ Object
Rename an existing enum type to something else.
564 565 566 567 568 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 564 def rename_enum(name, = {}) to = .fetch(:to) { raise ArgumentError, ":to is required" } exec_query("ALTER TYPE #{quote_table_name(name)} RENAME TO #{to}").tap { reload_type_map } end |
#rename_enum_value(type_name, options = {}) ⇒ Object
Rename enum value on an existing enum type.
587 588 589 590 591 592 593 594 595 596 597 598 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 587 def rename_enum_value(type_name, = {}) unless database_version >= 10_00_00 # >= 10.0 raise ArgumentError, "Renaming enum values is only supported in PostgreSQL 10 or later" end from = .fetch(:from) { raise ArgumentError, ":from is required" } to = .fetch(:to) { raise ArgumentError, ":to is required" } execute("ALTER TYPE #{quote_table_name(type_name)} RENAME VALUE '#{from}' TO '#{to}'").tap { reload_type_map } end |
#reset! ⇒ Object
369 370 371 372 373 374 375 376 377 378 379 380 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 369 def reset! @lock.synchronize do return connect! unless @raw_connection unless @raw_connection.transaction_status == ::YSQL::PQTRANS_IDLE @raw_connection.query "ROLLBACK" end @raw_connection.query "DISCARD ALL" super end end |
#return_value_after_insert?(column) ⇒ Boolean
:nodoc:
294 295 296 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 294 def return_value_after_insert?(column) # :nodoc: column.auto_populated? end |
#session_auth=(user) ⇒ Object
Set the authorized user for this session
606 607 608 609 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 606 def session_auth=(user) clear_cache! internal_execute("SET SESSION AUTHORIZATION #{user}", nil, materialize_transactions: true) end |
#set_standard_conforming_strings ⇒ Object
410 411 412 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 410 def set_standard_conforming_strings internal_execute("SET standard_conforming_strings = on") end |
#supports_advisory_locks? ⇒ Boolean
418 419 420 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 418 def supports_advisory_locks? false end |
#supports_bulk_alter? ⇒ Boolean
191 192 193 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 191 def supports_bulk_alter? true end |
#supports_check_constraints? ⇒ Boolean
223 224 225 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 223 def supports_check_constraints? true end |
#supports_comments? ⇒ Boolean
255 256 257 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 255 def supports_comments? true end |
#supports_common_table_expressions? ⇒ Boolean
449 450 451 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 449 def supports_common_table_expressions? true end |
#supports_datetime_with_precision? ⇒ Boolean
247 248 249 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 247 def supports_datetime_with_precision? true end |
#supports_ddl_transactions? ⇒ Boolean
414 415 416 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 414 def supports_ddl_transactions? false end |
#supports_deferrable_constraints? ⇒ Boolean
239 240 241 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 239 def supports_deferrable_constraints? true end |
#supports_exclusion_constraints? ⇒ Boolean
227 228 229 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 227 def supports_exclusion_constraints? true end |
#supports_explain? ⇒ Boolean
422 423 424 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 422 def supports_explain? true end |
#supports_expression_index? ⇒ Boolean
211 212 213 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 211 def supports_expression_index? true end |
#supports_extensions? ⇒ Boolean
426 427 428 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 426 def supports_extensions? true end |
#supports_foreign_keys? ⇒ Boolean
219 220 221 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 219 def supports_foreign_keys? true end |
#supports_foreign_tables? ⇒ Boolean
434 435 436 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 434 def supports_foreign_tables? true end |
#supports_identity_columns? ⇒ Boolean
:nodoc:
282 283 284 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 282 def supports_identity_columns? # :nodoc: database_version >= 10_00_00 # >= 10.0 end |
#supports_index_include? ⇒ Boolean
207 208 209 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 207 def supports_index_include? database_version >= 11_00_00 # >= 11.0 end |
#supports_index_sort_order? ⇒ Boolean
195 196 197 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 195 def supports_index_sort_order? true end |
#supports_insert_on_conflict? ⇒ Boolean Also known as: supports_insert_on_duplicate_skip?, supports_insert_on_duplicate_update?, supports_insert_conflict_target?
271 272 273 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 271 def supports_insert_on_conflict? database_version >= 9_05_00 # >= 9.5 end |
#supports_insert_returning? ⇒ Boolean
267 268 269 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 267 def supports_insert_returning? true end |
#supports_json? ⇒ Boolean
251 252 253 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 251 def supports_json? true end |
#supports_lazy_transactions? ⇒ Boolean
453 454 455 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 453 def supports_lazy_transactions? true end |
#supports_materialized_views? ⇒ Boolean
430 431 432 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 430 def supports_materialized_views? true end |
#supports_nulls_not_distinct? ⇒ Boolean
286 287 288 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 286 def supports_nulls_not_distinct? database_version >= 15_00_00 # >= 15.0 end |
#supports_optimizer_hints? ⇒ Boolean
442 443 444 445 446 447 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 442 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_partial_index? ⇒ Boolean
203 204 205 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 203 def supports_partial_index? true end |
#supports_partitioned_indexes? ⇒ Boolean
199 200 201 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 199 def supports_partitioned_indexes? database_version >= 11_00_00 # >= 11.0 end |
#supports_pgcrypto_uuid? ⇒ Boolean
438 439 440 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 438 def supports_pgcrypto_uuid? database_version >= 9_04_00 # >= 9.4 end |
#supports_restart_db_transaction? ⇒ Boolean
263 264 265 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 263 def supports_restart_db_transaction? database_version >= 12_00_00 # >= 12.0 end |
#supports_savepoints? ⇒ Boolean
259 260 261 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 259 def supports_savepoints? true end |
#supports_transaction_isolation? ⇒ Boolean
215 216 217 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 215 def supports_transaction_isolation? true end |
#supports_unique_constraints? ⇒ Boolean
231 232 233 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 231 def supports_unique_constraints? true end |
#supports_validate_constraints? ⇒ Boolean
235 236 237 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 235 def supports_validate_constraints? true end |
#supports_views? ⇒ Boolean
243 244 245 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 243 def supports_views? true end |
#supports_virtual_columns? ⇒ Boolean
278 279 280 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 278 def supports_virtual_columns? database_version >= 12_00_00 # >= 12.0 end |
#use_insert_returning? ⇒ Boolean
611 612 613 |
# File 'lib/active_record/connection_adapters/yugabytedb_adapter.rb', line 611 def use_insert_returning? @use_insert_returning end |