Module: ArJdbc::Firebird
- Included in:
- ActiveRecord::ConnectionAdapters::FirebirdAdapter
- Defined in:
- lib/arjdbc/firebird/adapter.rb
Defined Under Namespace
Modules: Column
Constant Summary collapse
- ADAPTER_NAME =
'Firebird'.freeze
- NATIVE_DATABASE_TYPES =
{ :primary_key => "integer not null primary key", :string => { :name => "varchar", :limit => 255 }, :text => { :name => "blob sub_type text" }, :integer => { :name => "integer" }, :float => { :name => "float" }, :datetime => { :name => "timestamp" }, :timestamp => { :name => "timestamp" }, :time => { :name => "time" }, :date => { :name => "date" }, :binary => { :name => "blob" }, :boolean => { :name => 'char', :limit => 1 }, :numeric => { :name => "numeric" }, :decimal => { :name => "decimal" }, :char => { :name => "char" }, }
- IDENTIFIER_LENGTH =
usual DB meta-identifier: 31 chars maximum
31
- @@update_lob_values =
true
Class Method Summary collapse
- .column_selector ⇒ Object
-
.emulate_booleans ⇒ Object
deprecated
Deprecated.
Use #emulate_booleans? instead.
- .emulate_booleans=(emulate) ⇒ Object
-
.emulate_booleans? ⇒ Boolean
Boolean emulation can be disabled using :.
- .jdbc_connection_class ⇒ Object
- .update_lob_values=(update) ⇒ Object
-
.update_lob_values? ⇒ Boolean
Updating records with LOB values (binary/text columns) in a separate statement can be disabled using :.
Instance Method Summary collapse
- #adapter_name ⇒ Object
- #add_limit_offset!(sql, options) ⇒ Object
- #change_column(table_name, column_name, type, options = {}) ⇒ Object
- #clear_cache! ⇒ Object
- #column_name_length ⇒ Object
- #create_table(name, options = {}) ⇒ Object
- #default_sequence_name(table_name, column = nil) ⇒ Object
- #drop_table(name, options = {}) ⇒ Object
-
#ids_in_list_limit ⇒ Object
Does this adapter restrict the number of IDs you can use in a list.
- #index_name_length ⇒ Object
- #initialize_type_map(m) ⇒ Object
- #insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = []) ⇒ Object
- #insert_limit_offset!(sql, limit, offset) ⇒ Object
- #jdbc_column_class ⇒ Object
- #native_database_types ⇒ Object
- #next_sequence_value(sequence_name) ⇒ Object
-
#prefetch_primary_key?(table_name = nil) ⇒ Boolean
Should primary key values be selected from their corresponding sequence before the insert statement?.
- #quote(value, column = nil) ⇒ Object
- #quote_column_name(column_name) ⇒ Object
- #quote_string(string) ⇒ Object
- #quote_table_name_for_assignment(table, attr) ⇒ Object
- #quoted_date(value) ⇒ Object
- #quoted_false ⇒ Object
- #quoted_true ⇒ Object
- #remove_index(table_name, options) ⇒ Object
- #rename_column(table_name, column_name, new_column_name) ⇒ Object
- #rename_table(name, new_name) ⇒ Object
-
#reset_sequence!(table, column, sequence = nil) ⇒ Object
Set the sequence to the max value of the table's column.
-
#supports_ddl_transactions? ⇒ Boolean
Does this adapter support DDL rollbacks in transactions? That is, would CREATE TABLE or ALTER TABLE get rolled back by a transaction? PostgreSQL, SQL Server, and others support this.
-
#supports_migrations? ⇒ Boolean
Does this adapter support migrations?.
-
#supports_primary_key? ⇒ Boolean
Can this adapter determine the primary key for tables not attached to an Active Record class, such as join tables?.
- #table_alias_length ⇒ Object
- #table_name_length ⇒ Object
- #type_to_sql(type, limit = nil, precision = nil, scale = nil) ⇒ Object
- #update_lob_values? ⇒ Boolean
Class Method Details
.column_selector ⇒ Object
28 29 30 |
# File 'lib/arjdbc/firebird/adapter.rb', line 28 def self.column_selector [ /firebird/i, lambda { |cfg, column| column.extend(Column) } ] end |
.emulate_booleans ⇒ Object
Use #emulate_booleans? instead.
76 |
# File 'lib/arjdbc/firebird/adapter.rb', line 76 def self.emulate_booleans; @@emulate_booleans; end |
.emulate_booleans=(emulate) ⇒ Object
78 |
# File 'lib/arjdbc/firebird/adapter.rb', line 78 def self.emulate_booleans=(emulate); @@emulate_booleans = emulate; end |
.emulate_booleans? ⇒ Boolean
Boolean emulation can be disabled using :
ArJdbc::Firebird.emulate_booleans = false
74 |
# File 'lib/arjdbc/firebird/adapter.rb', line 74 def self.emulate_booleans?; @@emulate_booleans; end |
.jdbc_connection_class ⇒ Object
23 24 25 |
# File 'lib/arjdbc/firebird/adapter.rb', line 23 def self.jdbc_connection_class ::ActiveRecord::ConnectionAdapters::FirebirdJdbcConnection end |
.update_lob_values=(update) ⇒ Object
89 |
# File 'lib/arjdbc/firebird/adapter.rb', line 89 def self.update_lob_values=(update); @@update_lob_values = update; end |
.update_lob_values? ⇒ Boolean
Updating records with LOB values (binary/text columns) in a separate statement can be disabled using :
ArJdbc::Firebird.update_lob_values = false
87 |
# File 'lib/arjdbc/firebird/adapter.rb', line 87 def self.update_lob_values?; @@update_lob_values; end |
Instance Method Details
#adapter_name ⇒ Object
100 101 102 |
# File 'lib/arjdbc/firebird/adapter.rb', line 100 def adapter_name ADAPTER_NAME end |
#add_limit_offset!(sql, options) ⇒ Object
237 238 239 240 241 |
# File 'lib/arjdbc/firebird/adapter.rb', line 237 def add_limit_offset!(sql, ) if limit = [:limit] insert_limit_offset!(sql, limit, [:offset]) end end |
#change_column(table_name, column_name, type, options = {}) ⇒ Object
303 304 305 |
# File 'lib/arjdbc/firebird/adapter.rb', line 303 def change_column(table_name, column_name, type, = {}) execute "ALTER TABLE #{table_name} ALTER #{column_name} TYPE #{type_to_sql(type, [:limit])}" end |
#clear_cache! ⇒ Object
165 166 167 168 |
# File 'lib/arjdbc/firebird/adapter.rb', line 165 def clear_cache! super reload_type_map end |
#column_name_length ⇒ Object
270 |
# File 'lib/arjdbc/firebird/adapter.rb', line 270 def column_name_length; IDENTIFIER_LENGTH; end |
#create_table(name, options = {}) ⇒ Object
287 288 289 290 |
# File 'lib/arjdbc/firebird/adapter.rb', line 287 def create_table(name, = {}) super(name, ) execute "CREATE GENERATOR #{default_sequence_name(name)}" end |
#default_sequence_name(table_name, column = nil) ⇒ Object
272 273 274 275 |
# File 'lib/arjdbc/firebird/adapter.rb', line 272 def default_sequence_name(table_name, column = nil) len = IDENTIFIER_LENGTH - 4 table_name.to_s.gsub (/(^|\.)([\w$-]{1,#{len}})([\w$-]*)$/), '\1\2_seq' end |
#drop_table(name, options = {}) ⇒ Object
298 299 300 301 |
# File 'lib/arjdbc/firebird/adapter.rb', line 298 def drop_table(name, = {}) super(name) execute_quietly "DROP GENERATOR #{default_sequence_name(name)}" end |
#ids_in_list_limit ⇒ Object
Does this adapter restrict the number of IDs you can use in a list. Oracle has a limit of 1000.
228 229 230 |
# File 'lib/arjdbc/firebird/adapter.rb', line 228 def ids_in_list_limit 1499 end |
#index_name_length ⇒ Object
269 |
# File 'lib/arjdbc/firebird/adapter.rb', line 269 def index_name_length; IDENTIFIER_LENGTH; end |
#initialize_type_map(m) ⇒ Object
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 |
# File 'lib/arjdbc/firebird/adapter.rb', line 125 def initialize_type_map(m) register_class_with_limit m, %r(binary)i, ActiveRecord::Type::Binary register_class_with_limit m, %r(text)i, ActiveRecord::Type::Text register_class_with_limit m, %r(date(?:\(.*?\))?$)i, DateType register_class_with_limit m, %r(time(?:\(.*?\))?$)i, ActiveRecord::Type::Time register_class_with_limit m, %r(float)i, ActiveRecord::Type::Float register_class_with_limit m, %r(int)i, ActiveRecord::Type::Integer m.alias_type %r(blob)i, 'binary' m.alias_type %r(clob)i, 'text' m.alias_type %r(double)i, 'float' m.register_type(%r(decimal)i) do |sql_type| scale = extract_scale(sql_type) precision = extract_precision(sql_type) if scale == 0 ActiveRecord::Type::Integer.new(precision: precision) else ActiveRecord::Type::Decimal.new(precision: precision, scale: scale) end end m.alias_type %r(numeric)i, 'decimal' register_class_with_limit m, %r(varchar)i, ActiveRecord::Type::String m.register_type(%r(^char)i) do |sql_type| precision = extract_precision(sql_type) if Firebird.emulate_booleans? && precision == 1 ActiveRecord::Type::Boolean.new else ActiveRecord::Type::String.new(:precision => precision) end end register_class_with_limit m, %r(datetime)i, ActiveRecord::Type::DateTime register_class_with_limit m, %r(timestamp)i, TimestampType end |
#insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = []) ⇒ Object
232 233 234 235 |
# File 'lib/arjdbc/firebird/adapter.rb', line 232 def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = []) execute(sql, name, binds) id_value end |
#insert_limit_offset!(sql, limit, offset) ⇒ Object
246 247 248 249 250 251 252 253 |
# File 'lib/arjdbc/firebird/adapter.rb', line 246 def insert_limit_offset!(sql, limit, offset) lim_off = '' lim_off << "FIRST #{limit}" if limit lim_off << " SKIP #{offset}" if offset lim_off.strip! sql.sub!(SELECT_RE, "\\&#{lim_off} ") unless lim_off.empty? end |
#jdbc_column_class ⇒ Object
65 |
# File 'lib/arjdbc/firebird/adapter.rb', line 65 def jdbc_column_class; ::ActiveRecord::ConnectionAdapters::FirebirdColumn end |
#native_database_types ⇒ Object
121 122 123 |
# File 'lib/arjdbc/firebird/adapter.rb', line 121 def native_database_types NATIVE_DATABASE_TYPES end |
#next_sequence_value(sequence_name) ⇒ Object
283 284 285 |
# File 'lib/arjdbc/firebird/adapter.rb', line 283 def next_sequence_value(sequence_name) select_one("SELECT GEN_ID(#{sequence_name}, 1 ) FROM RDB$DATABASE;")["gen_id"] end |
#prefetch_primary_key?(table_name = nil) ⇒ Boolean
Should primary key values be selected from their corresponding sequence before the insert statement?
259 260 261 262 263 |
# File 'lib/arjdbc/firebird/adapter.rb', line 259 def prefetch_primary_key?(table_name = nil) return true if table_name.nil? primary_keys(table_name.to_s).size == 1 # columns(table_name).count { |column| column.primary } == 1 end |
#quote(value, column = nil) ⇒ Object
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 |
# File 'lib/arjdbc/firebird/adapter.rb', line 316 def quote(value, column = nil) return value.quoted_id if value.respond_to?(:quoted_id) return value if sql_literal?(value) type = column && column.type # BLOBs are updated separately by an after_save trigger. if type == :binary || type == :text if update_lob_values? return value.nil? ? "NULL" : BLOB_VALUE_MARKER else return "'#{quote_string(value)}'" end end case value when String, ActiveSupport::Multibyte::Chars value = value.to_s if type == :integer value.to_i.to_s elsif type == :float value.to_f.to_s else "'#{quote_string(value)}'" end when NilClass then 'NULL' when TrueClass then (type == :integer ? '1' : quoted_true) when FalseClass then (type == :integer ? '0' : quoted_false) when Float, Fixnum, Bignum then value.to_s # BigDecimals need to be output in a non-normalized form and quoted. when BigDecimal then value.to_s('F') when Symbol then "'#{quote_string(value.to_s)}'" else if type == :time && value.acts_like?(:time) return "'#{get_time(value).strftime("%H:%M:%S")}'" end if type == :date && value.acts_like?(:date) return "'#{value.strftime("%Y-%m-%d")}'" end super end end |
#quote_column_name(column_name) ⇒ Object
391 392 393 394 |
# File 'lib/arjdbc/firebird/adapter.rb', line 391 def quote_column_name(column_name) column_name = column_name.to_s %Q("#{column_name =~ /[[:upper:]]/ ? column_name : column_name.upcase}") end |
#quote_string(string) ⇒ Object
371 372 373 |
# File 'lib/arjdbc/firebird/adapter.rb', line 371 def quote_string(string) string.gsub(/'/, "''") end |
#quote_table_name_for_assignment(table, attr) ⇒ Object
386 387 388 |
# File 'lib/arjdbc/firebird/adapter.rb', line 386 def quote_table_name_for_assignment(table, attr) quote_column_name(attr) end |
#quoted_date(value) ⇒ Object
360 361 362 363 364 365 366 367 368 |
# File 'lib/arjdbc/firebird/adapter.rb', line 360 def quoted_date(value) if value.acts_like?(:time) && value.respond_to?(:usec) usec = sprintf "%04d", (value.usec / 100.0).round value = ::ActiveRecord::Base.default_timezone == :utc ? value.getutc : value.getlocal "#{value.strftime("%Y-%m-%d %H:%M:%S")}.#{usec}" else super end end |
#quoted_false ⇒ Object
381 382 383 |
# File 'lib/arjdbc/firebird/adapter.rb', line 381 def quoted_false quote(0) end |
#quoted_true ⇒ Object
376 377 378 |
# File 'lib/arjdbc/firebird/adapter.rb', line 376 def quoted_true quote(1) end |
#remove_index(table_name, options) ⇒ Object
311 312 313 |
# File 'lib/arjdbc/firebird/adapter.rb', line 311 def remove_index(table_name, ) execute "DROP INDEX #{index_name(table_name, )}" end |
#rename_column(table_name, column_name, new_column_name) ⇒ Object
307 308 309 |
# File 'lib/arjdbc/firebird/adapter.rb', line 307 def rename_column(table_name, column_name, new_column_name) execute "ALTER TABLE #{table_name} ALTER #{column_name} TO #{new_column_name}" end |
#rename_table(name, new_name) ⇒ Object
292 293 294 295 296 |
# File 'lib/arjdbc/firebird/adapter.rb', line 292 def rename_table(name, new_name) execute "RENAME #{name} TO #{new_name}" name_seq, new_name_seq = default_sequence_name(name), default_sequence_name(new_name) execute_quietly "UPDATE RDB$GENERATORS SET RDB$GENERATOR_NAME='#{new_name_seq}' WHERE RDB$GENERATOR_NAME='#{name_seq}'" end |
#reset_sequence!(table, column, sequence = nil) ⇒ Object
Set the sequence to the max value of the table's column.
278 279 280 281 |
# File 'lib/arjdbc/firebird/adapter.rb', line 278 def reset_sequence!(table, column, sequence = nil) max_id = select_value("SELECT max(#{column}) FROM #{table}") execute("ALTER SEQUENCE #{default_sequence_name(table, column)} RESTART WITH #{max_id}") end |
#supports_ddl_transactions? ⇒ Boolean
Does this adapter support DDL rollbacks in transactions? That is, would CREATE TABLE or ALTER TABLE get rolled back by a transaction? PostgreSQL, SQL Server, and others support this. MySQL and others do not.
222 223 224 |
# File 'lib/arjdbc/firebird/adapter.rb', line 222 def supports_ddl_transactions? false end |
#supports_migrations? ⇒ Boolean
Does this adapter support migrations?
209 210 211 |
# File 'lib/arjdbc/firebird/adapter.rb', line 209 def supports_migrations? true end |
#supports_primary_key? ⇒ Boolean
Can this adapter determine the primary key for tables not attached to an Active Record class, such as join tables?
215 216 217 |
# File 'lib/arjdbc/firebird/adapter.rb', line 215 def supports_primary_key? true end |
#table_alias_length ⇒ Object
267 |
# File 'lib/arjdbc/firebird/adapter.rb', line 267 def table_alias_length; IDENTIFIER_LENGTH; end |
#table_name_length ⇒ Object
268 |
# File 'lib/arjdbc/firebird/adapter.rb', line 268 def table_name_length; IDENTIFIER_LENGTH; end |
#type_to_sql(type, limit = nil, precision = nil, scale = nil) ⇒ Object
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/arjdbc/firebird/adapter.rb', line 187 def type_to_sql(type, limit = nil, precision = nil, scale = nil) case type when :integer case limit when nil then 'integer' when 1..2 then 'smallint' when 3..4 then 'integer' when 5..8 then 'bigint' else raise(ActiveRecordError, "No integer type has byte size #{limit}. "<< "Use a NUMERIC with PRECISION 0 instead.") end when :float if limit.nil? || limit <= 4 'float' else 'double precision' end else super end end |
#update_lob_values? ⇒ Boolean
92 |
# File 'lib/arjdbc/firebird/adapter.rb', line 92 def update_lob_values?; Firebird.update_lob_values?; end |