Module | Sequel::Fdbsql::DatabaseMethods |
In: |
lib/sequel/adapters/shared/fdbsql.rb
|
BOUND_VARIABLE_TIMESTAMP_FORMAT | = | "%Y-%m-%d %H:%M:%S".freeze | the literal methods put quotes around things, but when we bind a variable there shouldn‘t be quotes around it it should just be the timestamp, so we need whole new formats here. | |
BOUND_VARIABLE_SQLTIME_FORMAT | = | "%H:%M:%S".freeze | ||
STALE_STATEMENT_SQLSTATE | = | '0A50A'.freeze | ||
NOT_NULL_CONSTRAINT_SQLSTATES | = | %w'23502'.freeze.each{|s| s.freeze} | ||
FOREIGN_KEY_CONSTRAINT_SQLSTATES | = | %w'23503 23504'.freeze.each{|s| s.freeze} | ||
UNIQUE_CONSTRAINT_SQLSTATES | = | %w'23501'.freeze.each{|s| s.freeze} | ||
DATABASE_ERROR_REGEXPS | = | [ # Add this check first, since otherwise it's possible for users to control # which exception class is generated. [/invalid input syntax/, DatabaseError], # the rest of these are backups in case the sqlstate fails [/[dD]uplicate key violates unique constraint/, UniqueConstraintViolation], [/due (?:to|for) foreign key constraint/, ForeignKeyConstraintViolation], [/NULL value not permitted/, NotNullConstraintViolation], ].freeze | This is a fallback used by the base class if the sqlstate fails to figure out what error type it is. |
conversion_procs | [R] | A hash of conversion procs, keyed by type integer (oid) and having callable values for the conversion proc for that type. |
Convert given argument so that it can be used directly by pg. Currently, pg doesn‘t handle fractional seconds in Time/DateTime or blobs with "\0", and it won‘t ever handle Sequel::SQLTime values correctly. Only public for use by the adapter, shouldn‘t be used by external code.
# File lib/sequel/adapters/shared/fdbsql.rb, line 25 25: def bound_variable_arg(arg, conn) 26: case arg 27: # TODO TDD it: 28: when Sequel::SQL::Blob 29: # the 1 means treat this as a binary blob 30: {:value => arg, :format => 1} 31: when Sequel::SQLTime 32: # the literal methods put quotes around things, but this is a bound variable, so we can't use those 33: arg.strftime(BOUND_VARIABLE_SQLTIME_FORMAT) 34: when DateTime, Time 35: # the literal methods put quotes around things, but this is a bound variable, so we can't use those 36: from_application_timestamp(arg).strftime(BOUND_VARIABLE_TIMESTAMP_FORMAT) 37: else 38: arg 39: end 40: end
Return full foreign key information, including Postgres returns hash like: {"b_e_fkey"=> {:name=>:b_e_fkey, :columns=>[:e], :on_update=>:no_action, :on_delete=>:no_action, :deferrable=>false, :table=>:a, :key=>[:c]}}
# File lib/sequel/adapters/shared/fdbsql.rb, line 125 125: def foreign_key_list(table, opts=OPTS) 126: out_identifier, in_identifier = identifier_convertors(opts) 127: schema, table = schema_or_current_and_table(table, opts) 128: sql_table = in_identifier.call(table) 129: columns_dataset = metadata_dataset. 130: select(:tc__table_name___table_name, 131: :tc__table_schema___table_schema, 132: :tc__is_deferrable___deferrable, 133: :kc__column_name___column_name, 134: :kc__constraint_schema___schema, 135: :kc__constraint_name___name, 136: :rc__update_rule___on_update, 137: :rc__delete_rule___on_delete). 138: from(Sequel.as(:information_schema__table_constraints, 'tc')). 139: join(Sequel.as(:information_schema__key_column_usage, 'kc'), 140: [:constraint_schema, :constraint_name]). 141: join(Sequel.as(:information_schema__referential_constraints, 'rc'), 142: [:constraint_name, :constraint_schema]). 143: where(:tc__table_name => sql_table, 144: :tc__table_schema => schema, 145: :tc__constraint_type => 'FOREIGN KEY') 146: 147: keys_dataset = metadata_dataset. 148: select(:rc__constraint_schema___schema, 149: :rc__constraint_name___name, 150: :kc__table_name___key_table, 151: :kc__column_name___key_column). 152: from(Sequel.as(:information_schema__table_constraints, 'tc')). 153: join(Sequel.as(:information_schema__referential_constraints, 'rc'), 154: [:constraint_schema, :constraint_name]). 155: join(Sequel.as(:information_schema__key_column_usage, 'kc'), 156: :kc__constraint_schema => :rc__unique_constraint_schema, 157: :kc__constraint_name => :rc__unique_constraint_name). 158: where(:tc__table_name => sql_table, 159: :tc__table_schema => schema, 160: :tc__constraint_type => 'FOREIGN KEY') 161: foreign_keys = {} 162: columns_dataset.each do |row| 163: foreign_key = foreign_keys.fetch(row[:name]) do |key| 164: foreign_keys[row[:name]] = row 165: row[:name] = out_identifier.call(row[:name]) 166: row[:columns] = [] 167: row[:key] = [] 168: row 169: end 170: foreign_key[:columns] << out_identifier.call(row[:column_name]) 171: end 172: keys_dataset.each do |row| 173: foreign_key = foreign_keys[row[:name]] 174: foreign_key[:table] = out_identifier.call(row[:key_table]) 175: foreign_key[:key] << out_identifier.call(row[:key_column]) 176: end 177: foreign_keys.values 178: end
Return indexes for the table postgres returns: {:blah_blah_index=>{:columns=>[:n], :unique=>true, :deferrable=>nil},
:items_n_a_index=>{:columns=>[:n, :a], :unique=>false, :deferrable=>nil}}
# File lib/sequel/adapters/shared/fdbsql.rb, line 184 184: def indexes(table, opts=OPTS) 185: out_identifier, in_identifier = identifier_convertors(opts) 186: schema, table = schema_or_current_and_table(table, opts) 187: dataset = metadata_dataset. 188: select(:is__is_unique, 189: Sequel.as({:is__is_unique => 'YES'}, 'unique'), 190: :is__index_name, 191: :ic__column_name). 192: from(Sequel.as(:information_schema__indexes, 'is')). 193: join(Sequel.as(:information_schema__index_columns, 'ic'), 194: :ic__index_table_schema => :is__table_schema, 195: :ic__index_table_name => :is__table_name, 196: :ic__index_name => :is__index_name). 197: where(:is__table_schema => schema, 198: :is__table_name => in_identifier.call(table)). 199: exclude(:is__index_type => 'PRIMARY') 200: indexes = {} 201: dataset.each do |row| 202: index = indexes.fetch(out_identifier.call(row[:index_name])) do |key| 203: h = { :unique => row[:unique], :columns => [] } 204: indexes[key] = h 205: h 206: end 207: index[:columns] << out_identifier.call(row[:column_name]) 208: end 209: indexes 210: end
Return primary key for the given table.
# File lib/sequel/adapters/shared/fdbsql.rb, line 59 59: def primary_key(table_name, opts=OPTS) 60: quoted_table = quote_schema_table(table_name) 61: Sequel.synchronize{return @primary_keys[quoted_table] if @primary_keys.has_key?(quoted_table)} 62: out_identifier, in_identifier = identifier_convertors(opts) 63: schema, table = schema_or_current_and_table(table_name, opts) 64: dataset = metadata_dataset. 65: select(:kc__column_name). 66: from(Sequel.as(:information_schema__key_column_usage, 'kc')). 67: join(Sequel.as(:information_schema__table_constraints, 'tc'), 68: [:table_name, :table_schema, :constraint_name]). 69: where(:kc__table_name => in_identifier.call(table), 70: :kc__table_schema => schema, 71: :tc__constraint_type => 'PRIMARY KEY') 72: value = dataset.map do |row| 73: out_identifier.call(row.delete(:column_name)) 74: end 75: value = case value.size 76: when 0 then nil 77: when 1 then value.first 78: else value 79: end 80: Sequel.synchronize{@primary_keys[quoted_table] = value} 81: end
like PostgreSQL fdbsql uses SERIAL psuedo-type instead of AUTOINCREMENT for managing incrementing primary keys.
# File lib/sequel/adapters/shared/fdbsql.rb, line 49 49: def serial_primary_key_options 50: {:primary_key => true, :serial => true, :type=>Integer} 51: end
the sql layer supports CREATE TABLE IF NOT EXISTS syntax,
# File lib/sequel/adapters/shared/fdbsql.rb, line 84 84: def supports_create_table_if_not_exists? 85: true 86: end
the sql layer supports DROP TABLE IF EXISTS
# File lib/sequel/adapters/shared/fdbsql.rb, line 94 94: def supports_drop_table_if_exists? 95: true 96: end
Array of symbols specifying table names in the current database. The dataset used is yielded to the block if one is provided, otherwise, an array of symbols of table names is returned.
Options:
:qualify : | Return the tables as Sequel::SQL::QualifiedIdentifier instances, using the schema the table is located in as the qualifier. |
:schema : | The schema to search |
:server : | The server to use |
# File lib/sequel/adapters/shared/fdbsql.rb, line 107 107: def tables(opts=OPTS, &block) 108: tables_or_views('TABLE', opts, &block) 109: end
Array of symbols specifying view names in the current database.
Options:
:qualify : | Return the views as Sequel::SQL::QualifiedIdentifier instances, using the schema the view is located in as the qualifier. |
:schema : | The schema to search |
:server : | The server to use |
# File lib/sequel/adapters/shared/fdbsql.rb, line 118 118: def views(opts=OPTS, &block) 119: tables_or_views('VIEW', opts, &block) 120: end