Module: Sequel::Fdbsql::DatabaseMethods

Included in:
Database, JDBC::Fdbsql::DatabaseMethods
Defined in:
lib/sequel/adapters/shared/fdbsql.rb

Overview

Methods shared by Database instances that connect to the FoundationDB SQL Layer

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#conversion_procsObject (readonly)

A hash of conversion procs, keyed by type integer (oid) and having callable values for the conversion proc for that type.



19
20
21
# File 'lib/sequel/adapters/shared/fdbsql.rb', line 19

def conversion_procs
  @conversion_procs
end

Instance Method Details

#bound_variable_arg(arg, conn) ⇒ Object

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.



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/sequel/adapters/shared/fdbsql.rb', line 25

def bound_variable_arg(arg, conn)
  case arg
  # TODO TDD it:
  when Sequel::SQL::Blob
    # the 1 means treat this as a binary blob
    {:value => arg, :format => 1}
  when Sequel::SQLTime
    # the literal methods put quotes around things, but this is a bound variable, so we can't use those
    arg.strftime(BOUND_VARIABLE_SQLTIME_FORMAT)
  when DateTime, Time
    # the literal methods put quotes around things, but this is a bound variable, so we can't use those
    from_application_timestamp(arg).strftime(BOUND_VARIABLE_TIMESTAMP_FORMAT)
  else
     arg
  end
end

#database_typeObject

Fdbsql uses the :fdbsql database type.



43
44
45
# File 'lib/sequel/adapters/shared/fdbsql.rb', line 43

def database_type
  :fdbsql
end

#foreign_key_list(table, opts = OPTS) ⇒ Object

Return full foreign key information, including Postgres returns hash like: {:name=>:b_e_fkey, :columns=>, :on_update=>:no_action, :on_delete=>:no_action, :deferrable=>false, :table=>:a, :key=>}



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/sequel/adapters/shared/fdbsql.rb', line 125

def foreign_key_list(table, opts=OPTS)
  out_identifier, in_identifier = identifier_convertors(opts)
  schema, table = schema_or_current_and_table(table, opts)
  sql_table = in_identifier.call(table)
  columns_dataset = .
    select(:tc__table_name___table_name,
           :tc__table_schema___table_schema,
           :tc__is_deferrable___deferrable,
           :kc__column_name___column_name,
           :kc__constraint_schema___schema,
           :kc__constraint_name___name,
           :rc__update_rule___on_update,
           :rc__delete_rule___on_delete).
    from(Sequel.as(:information_schema__table_constraints, 'tc')).
    join(Sequel.as(:information_schema__key_column_usage, 'kc'),
         [:constraint_schema, :constraint_name]).
    join(Sequel.as(:information_schema__referential_constraints, 'rc'),
         [:constraint_name, :constraint_schema]).
    where(:tc__table_name => sql_table,
          :tc__table_schema => schema,
          :tc__constraint_type => 'FOREIGN KEY')

  keys_dataset = .
    select(:rc__constraint_schema___schema,
           :rc__constraint_name___name,
           :kc__table_name___key_table,
           :kc__column_name___key_column).
    from(Sequel.as(:information_schema__table_constraints, 'tc')).
    join(Sequel.as(:information_schema__referential_constraints, 'rc'),
         [:constraint_schema, :constraint_name]).
    join(Sequel.as(:information_schema__key_column_usage, 'kc'),
         :kc__constraint_schema => :rc__unique_constraint_schema,
         :kc__constraint_name => :rc__unique_constraint_name).
    where(:tc__table_name => sql_table,
          :tc__table_schema => schema,
          :tc__constraint_type => 'FOREIGN KEY')
  foreign_keys = {}
  columns_dataset.each do |row|
    foreign_key = foreign_keys.fetch(row[:name]) do |key|
      foreign_keys[row[:name]] = row
      row[:name] = out_identifier.call(row[:name])
      row[:columns] = []
      row[:key] = []
      row
    end
    foreign_key[:columns] << out_identifier.call(row[:column_name])
  end
  keys_dataset.each do |row|
    foreign_key = foreign_keys[row[:name]]
    foreign_key[:table] = out_identifier.call(row[:key_table])
    foreign_key[:key] << out_identifier.call(row[:key_column])
  end
  foreign_keys.values
end

#global_index_namespace?Boolean

indexes are namespaced per table

Returns:

  • (Boolean)


54
55
56
# File 'lib/sequel/adapters/shared/fdbsql.rb', line 54

def global_index_namespace?
  false
end

#indexes(table, opts = OPTS) ⇒ Object

Return indexes for the table postgres returns: href=":n">columns=>, :unique=>true, :deferrable=>nil,

:items_n_a_index=>{:columns=>[:n, :a], :unique=>false, :deferrable=>nil}}


184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/sequel/adapters/shared/fdbsql.rb', line 184

def indexes(table, opts=OPTS)
  out_identifier, in_identifier = identifier_convertors(opts)
  schema, table = schema_or_current_and_table(table, opts)
  dataset = .
    select(:is__is_unique,
           Sequel.as({:is__is_unique => 'YES'}, 'unique'),
           :is__index_name,
           :ic__column_name).
    from(Sequel.as(:information_schema__indexes, 'is')).
    join(Sequel.as(:information_schema__index_columns, 'ic'),
         :ic__index_table_schema => :is__table_schema,
         :ic__index_table_name => :is__table_name,
         :ic__index_name => :is__index_name).
    where(:is__table_schema => schema,
          :is__table_name => in_identifier.call(table)).
    exclude(:is__index_type => 'PRIMARY')
  indexes = {}
  dataset.each do |row|
    index = indexes.fetch(out_identifier.call(row[:index_name])) do |key|
      h = { :unique => row[:unique], :columns => [] }
      indexes[key] = h
      h
    end
    index[:columns] << out_identifier.call(row[:column_name])
  end
  indexes
end

#primary_key(table_name, opts = OPTS) ⇒ Object

Return primary key for the given table.



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/sequel/adapters/shared/fdbsql.rb', line 59

def primary_key(table_name, opts=OPTS)
  quoted_table = quote_schema_table(table_name)
  Sequel.synchronize{return @primary_keys[quoted_table] if @primary_keys.has_key?(quoted_table)}
  out_identifier, in_identifier = identifier_convertors(opts)
  schema, table = schema_or_current_and_table(table_name, opts)
  dataset = .
    select(:kc__column_name).
    from(Sequel.as(:information_schema__key_column_usage, 'kc')).
    join(Sequel.as(:information_schema__table_constraints, 'tc'),
         [:table_name, :table_schema, :constraint_name]).
    where(:kc__table_name => in_identifier.call(table),
          :kc__table_schema => schema,
          :tc__constraint_type => 'PRIMARY KEY')
  value = dataset.map do |row|
    out_identifier.call(row.delete(:column_name))
  end
  value = case value.size
            when 0 then nil
            when 1 then value.first
            else value
          end
  Sequel.synchronize{@primary_keys[quoted_table] = value}
end

#serial_primary_key_optionsObject

like PostgreSQL fdbsql uses SERIAL psuedo-type instead of AUTOINCREMENT for managing incrementing primary keys.



49
50
51
# File 'lib/sequel/adapters/shared/fdbsql.rb', line 49

def serial_primary_key_options
  {:primary_key => true, :serial => true, :type=>Integer}
end

#supports_create_table_if_not_exists?Boolean

the sql layer supports CREATE TABLE IF NOT EXISTS syntax,

Returns:

  • (Boolean)


84
85
86
# File 'lib/sequel/adapters/shared/fdbsql.rb', line 84

def supports_create_table_if_not_exists?
  true
end

#supports_deferrable_foreign_key_constraints?Boolean

Fdbsql supports deferrable fk constraints

Returns:

  • (Boolean)


89
90
91
# File 'lib/sequel/adapters/shared/fdbsql.rb', line 89

def supports_deferrable_foreign_key_constraints?
  true
end

#supports_drop_table_if_exists?Boolean

the sql layer supports DROP TABLE IF EXISTS

Returns:

  • (Boolean)


94
95
96
# File 'lib/sequel/adapters/shared/fdbsql.rb', line 94

def supports_drop_table_if_exists?
  true
end

#tables(opts = OPTS, &block) ⇒ Object

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



107
108
109
# File 'lib/sequel/adapters/shared/fdbsql.rb', line 107

def tables(opts=OPTS, &block)
  tables_or_views('TABLE', opts, &block)
end

#views(opts = OPTS, &block) ⇒ Object

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



118
119
120
# File 'lib/sequel/adapters/shared/fdbsql.rb', line 118

def views(opts=OPTS, &block)
  tables_or_views('VIEW', opts, &block)
end