module ArJdbc::Firebird

Constants

ADAPTER_NAME
BLOB_VALUE_MARKER

@see quote @private

IDENTIFIER_LENGTH
NATIVE_DATABASE_TYPES
SELECT_RE

@private

Public Class Methods

column_selector() click to toggle source

@see ActiveRecord::ConnectionAdapters::JdbcColumn#column_types

# File lib/arjdbc/firebird/adapter.rb, line 28
def self.column_selector
  [ /firebird/i, lambda { |cfg, column| column.extend(Column) } ]
end
emulate_booleans() click to toggle source

@deprecated Use {#emulate_booleans?} instead.

# File lib/arjdbc/firebird/adapter.rb, line 76
def self.emulate_booleans; @@emulate_booleans; end
emulate_booleans=(emulate) click to toggle source

@see emulate_booleans?

# File lib/arjdbc/firebird/adapter.rb, line 78
def self.emulate_booleans=(emulate); @@emulate_booleans = emulate; end
emulate_booleans?() click to toggle source

Boolean emulation can be disabled using :

ArJdbc::Firebird.emulate_booleans = false
# File lib/arjdbc/firebird/adapter.rb, line 74
def self.emulate_booleans?; @@emulate_booleans; end
extended(adapter) click to toggle source

@private

# File lib/arjdbc/firebird/adapter.rb, line 9
def self.extended(adapter); initialize!; end
initialize!() click to toggle source

@private

# File lib/arjdbc/firebird/adapter.rb, line 15
def self.initialize!
  return if @@_initialized; @@_initialized = true

  require 'arjdbc/util/serialized_attributes'
  Util::SerializedAttributes.setup /blob/i
end
jdbc_connection_class() click to toggle source

@see ActiveRecord::ConnectionAdapters::JdbcAdapter#jdbc_connection_class

# File lib/arjdbc/firebird/adapter.rb, line 23
def self.jdbc_connection_class
  ::ActiveRecord::ConnectionAdapters::FirebirdJdbcConnection
end
update_lob_values=(update) click to toggle source

@see update_lob_values?

# File lib/arjdbc/firebird/adapter.rb, line 89
def self.update_lob_values=(update); @@update_lob_values = update; end
update_lob_values?() click to toggle source

Updating records with LOB values (binary/text columns) in a separate statement can be disabled using :

ArJdbc::Firebird.update_lob_values = false
# File lib/arjdbc/firebird/adapter.rb, line 87
def self.update_lob_values?; @@update_lob_values; end

Public Instance Methods

adapter_name() click to toggle source
# File lib/arjdbc/firebird/adapter.rb, line 100
def adapter_name
  ADAPTER_NAME
end
add_limit_offset!(sql, options) click to toggle source
# File lib/arjdbc/firebird/adapter.rb, line 237
def add_limit_offset!(sql, options)
  if limit = options[:limit]
    insert_limit_offset!(sql, limit, options[:offset])
  end
end
change_column(table_name, column_name, type, options = {}) click to toggle source
# File lib/arjdbc/firebird/adapter.rb, line 303
def change_column(table_name, column_name, type, options = {})
  execute "ALTER TABLE #{table_name} ALTER  #{column_name} TYPE #{type_to_sql(type, options[:limit])}"
end
clear_cache!() click to toggle source
Calls superclass method
# File lib/arjdbc/firebird/adapter.rb, line 165
def clear_cache!
  super
  reload_type_map
end
column_name_length() click to toggle source
# File lib/arjdbc/firebird/adapter.rb, line 270
def column_name_length; IDENTIFIER_LENGTH; end
create_table(name, options = {}) click to toggle source
Calls superclass method
# File lib/arjdbc/firebird/adapter.rb, line 287
def create_table(name, options = {})
  super(name, options)
  execute "CREATE GENERATOR #{default_sequence_name(name)}"
end
default_sequence_name(table_name, column = nil) click to toggle source
# 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 = {}) click to toggle source
Calls superclass method
# File lib/arjdbc/firebird/adapter.rb, line 298
def drop_table(name, options = {})
  super(name)
  execute_quietly "DROP GENERATOR #{default_sequence_name(name)}"
end
ids_in_list_limit() click to toggle source

Does this adapter restrict the number of IDs you can use in a list. Oracle has a limit of 1000.

# File lib/arjdbc/firebird/adapter.rb, line 228
def ids_in_list_limit
  1499
end
index_name_length() click to toggle source
# File lib/arjdbc/firebird/adapter.rb, line 269
def index_name_length;  IDENTIFIER_LENGTH; end
initialize_type_map(m) click to toggle source
# 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 = []) click to toggle source
# 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) click to toggle source
# 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() click to toggle source

@see ActiveRecord::ConnectionAdapters::JdbcAdapter#jdbc_column_class

# File lib/arjdbc/firebird/adapter.rb, line 65
def jdbc_column_class; ::ActiveRecord::ConnectionAdapters::FirebirdColumn end
native_database_types() click to toggle source
# File lib/arjdbc/firebird/adapter.rb, line 121
def native_database_types
  NATIVE_DATABASE_TYPES
end
next_sequence_value(sequence_name) click to toggle source
# 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) click to toggle source

Should primary key values be selected from their corresponding sequence before the insert statement? @see next_sequence_value @override

# 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) click to toggle source

@override

Calls superclass method
# 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) click to toggle source

@override

# 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) click to toggle source

@override

# File lib/arjdbc/firebird/adapter.rb, line 371
def quote_string(string)
  string.gsub(/'/, "''")
end
quote_table_name_for_assignment(table, attr) click to toggle source

@override

# File lib/arjdbc/firebird/adapter.rb, line 386
def quote_table_name_for_assignment(table, attr)
  quote_column_name(attr)
end
quoted_date(value) click to toggle source

@override

Calls superclass method
# 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() click to toggle source

@override

# File lib/arjdbc/firebird/adapter.rb, line 381
def quoted_false
  quote(0)
end
quoted_true() click to toggle source

@override

# File lib/arjdbc/firebird/adapter.rb, line 376
def quoted_true
  quote(1)
end
remove_index(table_name, options) click to toggle source
# File lib/arjdbc/firebird/adapter.rb, line 311
def remove_index(table_name, options)
  execute "DROP INDEX #{index_name(table_name, options)}"
end
rename_column(table_name, column_name, new_column_name) click to toggle source
# 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) click to toggle source
# 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) click to toggle source

Set the sequence to the max value of the table's column.

# 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?() click to toggle source

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.

# File lib/arjdbc/firebird/adapter.rb, line 222
def supports_ddl_transactions?
  false
end
supports_migrations?() click to toggle source

Does this adapter support migrations?

# File lib/arjdbc/firebird/adapter.rb, line 209
def supports_migrations?
  true
end
supports_primary_key?() click to toggle source

Can this adapter determine the primary key for tables not attached to an Active Record class, such as join tables?

# File lib/arjdbc/firebird/adapter.rb, line 215
def supports_primary_key?
  true
end
table_alias_length() click to toggle source
# File lib/arjdbc/firebird/adapter.rb, line 267
def table_alias_length; IDENTIFIER_LENGTH; end
table_name_length() click to toggle source
# 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) click to toggle source
Calls superclass method
# 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?() click to toggle source

@see update_lob_values?

# File lib/arjdbc/firebird/adapter.rb, line 92
def update_lob_values?; Firebird.update_lob_values?; end