Class: ActiveRecord::ConnectionAdapters::FbAdapter

Inherits:
AbstractAdapter
  • Object
show all
Defined in:
lib/active_record/connection_adapters/fb_adapter.rb

Overview

The Fb adapter relies on the Fb extension.

Usage Notes

Sequence (Generator) Names

The Fb adapter supports the same approach adopted for the Oracle adapter. See ActiveRecord::Base#set_sequence_name for more details.

Note that in general there is no need to create a BEFORE INSERT trigger corresponding to a Firebird sequence generator when using ActiveRecord. In other words, you don’t have to try to make Firebird simulate an AUTO_INCREMENT or IDENTITY column. When saving a new record, ActiveRecord pre-fetches the next sequence value for the table and explicitly includes it in the INSERT statement. (Pre-fetching the next primary key value is the only reliable method for the Fb adapter to report back the id after a successful insert.)

BOOLEAN Domain

Firebird 2.5 does not provide a native BOOLEAN type (Only in Firebird 3.x). But you can easily define a BOOLEAN domain for this purpose, e.g.:

CREATE DOMAIN D_BOOLEAN AS SMALLINT CHECK (VALUE IN (0, 1));

When the Fb adapter encounters a column that is based on a domain that includes “BOOLEAN” in the domain name, it will attempt to treat the column as a BOOLEAN.

By default, the Fb adapter will assume that the BOOLEAN domain is defined as above. This can be modified if needed. For example, if you have a legacy schema with the following BOOLEAN domain defined:

CREATE DOMAIN BOOLEAN AS CHAR(1) CHECK (VALUE IN ('T', 'F'));

…you can add the following line to your environment.rb file:

ActiveRecord::ConnectionAdapters::FbAdapter.boolean_domain = { :true => 'T', :false => 'F', :name => 'BOOLEAN', :type => 'char' }

Column Name Case Semantics

Firebird and ActiveRecord have somewhat conflicting case semantics for column names.

Firebird

The standard practice is to use unquoted column names, which can be thought of as case-insensitive. (In fact, Firebird converts them to uppercase.) Quoted column names (not typically used) are case-sensitive.

ActiveRecord

Attribute accessors corresponding to column names are case-sensitive. The defaults for primary key and inheritance columns are lowercase, and in general, people use lowercase attribute names.

In order to map between the differing semantics in a way that conforms to common usage for both Firebird and ActiveRecord, uppercase column names in Firebird are converted to lowercase attribute names in ActiveRecord, and vice-versa. Mixed-case column names retain their case in both directions. Lowercase (quoted) Firebird column names are not supported. This is similar to the solutions adopted by other adapters.

In general, the best approach is to use unquoted (case-insensitive) column names in your Firebird DDL (or if you must quote, use uppercase column names). These will correspond to lowercase attributes in ActiveRecord.

For example, a Firebird table based on the following DDL:

CREATE TABLE products (
  id BIGINT NOT NULL PRIMARY KEY,
  "TYPE" VARCHAR(50),
  name VARCHAR(255) );

…will correspond to an ActiveRecord model class called Product with the following attributes: id, type, name.

Quoting "TYPE" and other Firebird reserved words:

In ActiveRecord, the default inheritance column name is type. The word type is a Firebird reserved word, so it must be quoted in any Firebird SQL statements. Because of the case mapping described above, you should always reference this column using quoted-uppercase syntax ("TYPE") within Firebird DDL or other SQL statements (as in the example above). This holds true for any other Firebird reserved words used as column names as well.

Migrations

The Fb adapter currently support Migrations.

Connection Options

The following options are supported by the Fb adapter.

:database

Required option. Specifies one of: (i) a Firebird database alias; (ii) the full path of a database file; or (iii) a full Firebird connection string. Do not specify :host, :service or :port as separate options when using a full connection string.

:username

Specifies the database user. Defaults to ‘sysdba’.

:password

Specifies the database password. Defaults to ‘masterkey’.

:charset

Specifies the character set to be used by the connection. Refer to the Firebird documentation for valid options.

Constant Summary collapse

@@boolean_domain =
{ :true => 1, :false => 0, :name => 'BOOLEAN', :type => 'integer' }

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(connection, logger, connection_params = nil) ⇒ FbAdapter

Returns a new instance of FbAdapter.



250
251
252
253
254
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 250

def initialize(connection, logger, connection_params=nil)
  super(connection, logger)
  @connection_params = connection_params
  @visitor = Arel::Visitors::FB.new(self)
end

Class Method Details

.visitor_for(pool) ⇒ Object

:nodoc:



256
257
258
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 256

def self.visitor_for(pool) # :nodoc:
  Arel::Visitors::FB.new(pool)
end

Instance Method Details

#active?Boolean

Checks whether the connection to the database is still active. This includes checking whether the database is actually capable of responding, i.e. whether the connection isn’t stale.

Returns:

  • (Boolean)


323
324
325
326
327
328
329
330
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 323

def active?
  return false unless @connection.open?
  # return true if @connection.transaction_started
  select("SELECT 1 FROM RDB$DATABASE")
  true
rescue
  false
end

#adapter_nameObject

Returns the human-readable name of the adapter. Use mixed case - one can always use downcase if needed.



262
263
264
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 262

def adapter_name
  'Fb'
end

#add_column(table_name, column_name, type, options = {}) ⇒ Object

Adds a new column to the named table. See TableDefinition#column for details of the options you can use.



828
829
830
831
832
833
834
835
836
837
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 828

def add_column(table_name, column_name, type, options = {})
  add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
  add_column_options!(add_column_sql, options)
  execute(add_column_sql)
  if options[:position]
    # position is 1-based but add 1 to skip id column
    alter_position_sql = "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} POSITION #{options[:position] + 1}"
    execute(alter_position_sql)
  end
end

#add_limit_offset!(sql, options) ⇒ Object

Appends LIMIT and OFFSET options to an SQL statement, or some SQL fragment that has the same semantics as LIMIT and OFFSET.

options must be a Hash which contains a :limit option and an :offset option.

This method modifies the sql parameter.

Examples
add_limit_offset!('SELECT * FROM suppliers', {:limit => 10, :offset => 50})

generates

SELECT * FROM suppliers LIMIT 10 OFFSET 50


662
663
664
665
666
667
668
669
670
671
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 662

def add_limit_offset!(sql, options) # :nodoc:
  if limit = options[:limit]
    if offset = options[:offset]
      sql << " ROWS #{offset.to_i + 1} TO #{offset.to_i + limit.to_i}"
    else
      sql << " ROWS #{limit.to_i}"
    end
  end
  sql
end

#begin_db_transactionObject

Begins the transaction (and turns off auto-committing).



635
636
637
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 635

def begin_db_transaction
  @transaction = @connection.transaction('READ COMMITTED')
end

#change_column(table_name, column_name, type, options = {}) ⇒ Object

Changes the column’s definition according to the new options. See TableDefinition#column for details of the options you can use.

Examples
change_column(:suppliers, :name, :string, :limit => 80)
change_column(:accounts, :description, :text)


844
845
846
847
848
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 844

def change_column(table_name, column_name, type, options = {})
  sql = "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} TYPE #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
  sql = add_column_options(sql, options)
  execute(sql)
end

#change_column_default(table_name, column_name, default) ⇒ Object

Sets a new default value for a column. If you want to set the default value to NULL, you are out of luck. You need to DatabaseStatements#execute the appropriate SQL statement yourself.

Examples
change_column_default(:suppliers, :qualification, 'new')
change_column_default(:accounts, :authorized, 1)


856
857
858
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 856

def change_column_default(table_name, column_name, default)
  execute("ALTER TABLE #{quote_table_name(table_name)} ALTER #{quote_column_name(column_name)} SET DEFAULT #{quote(default)}")
end

#column_name_lengthObject

the maximum length of a column name



946
947
948
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 946

def column_name_length
  31
end

#columns(table_name, name = nil) ⇒ Object

Returns an array of Column objects for the table specified by table_name. See the concrete implementation for details on the expected parameter values.



782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 782

def columns(table_name, name = nil)
  sql = <<-END_SQL
    SELECT r.rdb$field_name, r.rdb$field_source, f.rdb$field_type, f.rdb$field_sub_type,
           f.rdb$field_length, f.rdb$field_precision, f.rdb$field_scale,
           COALESCE(r.rdb$default_source, f.rdb$default_source) rdb$default_source,
           COALESCE(r.rdb$null_flag, f.rdb$null_flag) rdb$null_flag
    FROM rdb$relation_fields r
    JOIN rdb$fields f ON r.rdb$field_source = f.rdb$field_name
    WHERE r.rdb$relation_name = '#{ar_to_fb_case(table_name)}'
    ORDER BY r.rdb$field_position
  END_SQL
  select_rows(sql, name).collect do |field|
    field_values = field.collect do |value|
      case value
        when String then value.rstrip
        else value
      end
    end
    FbColumn.new(*field_values)
  end
end

#commit_db_transactionObject

Commits the transaction (and turns on auto-committing).



640
641
642
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 640

def commit_db_transaction
  @transaction = @connection.commit
end

#create_savepointObject

def transaction_joinable=(joinable)

@transaction_joinable = joinable

end



395
396
397
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 395

def create_savepoint
  execute("SAVEPOINT #{current_savepoint_name}")
end

#create_table(name, options = {}) ⇒ Object

:nodoc:



804
805
806
807
808
809
810
811
812
813
814
815
816
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 804

def create_table(name, options = {}) # :nodoc:
  begin
    super
  rescue
    raise unless non_existent_domain_error?
    create_boolean_domain
    super
  end
  unless options[:id] == false or options[:sequence] == false
    sequence_name = options[:sequence] || default_sequence_name(name)
    create_sequence(sequence_name)
  end
end

#default_sequence_name(table_name, column = nil) ⇒ Object



673
674
675
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 673

def default_sequence_name(table_name, column=nil)
  "#{table_name}_seq"
end

#disconnect!Object

Disconnects from the database if already connected. Otherwise, this method does nothing.



341
342
343
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 341

def disconnect!
  @connection.close rescue nil
end

#drop_table(name, options = {}) ⇒ Object

:nodoc:



818
819
820
821
822
823
824
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 818

def drop_table(name, options = {}) # :nodoc:
  super(name)
  unless options[:sequence] == false
    sequence_name = options[:sequence] || default_sequence_name(name)
    drop_sequence(sequence_name) if sequence_exists?(sequence_name)
  end
end

#exec_query(sql, name = 'SQL', binds = []) ⇒ Object

Executes sql statement in the context of this connection using binds as the bind substitutes. name is logged along with the executed sql statement.



585
586
587
588
589
590
591
592
593
594
595
596
597
598
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 585

def exec_query(sql, name = 'SQL', binds = [])
  if binds.empty?
    translate(sql) do |sql, args|
      log(expand(sql, args), name) do
        @connection.execute(sql, *args)
      end
    end
  else
    log(sql, name, binds) do
      args = binds.map { |col, val| type_cast(val, col) }
      @connection.execute(sql, *args)
    end
  end
end

#execute(sql, name = nil, skip_logging = false) ⇒ Object

Executes the SQL statement in the context of this connection.



570
571
572
573
574
575
576
577
578
579
580
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 570

def execute(sql, name = nil, skip_logging = false)
  translate(sql) do |sql, args|
    if (name == :skip_logging) or skip_logging
      @connection.execute(sql, *args)
    else
      log(sql, args, name) do
        @connection.execute(sql, *args)
      end
    end
  end
end

#explain(arel, binds = []) ⇒ Object



600
601
602
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 600

def explain(arel, binds = [])
  to_sql(arel, binds)
end

#ids_in_list_limitObject

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



307
308
309
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 307

def ids_in_list_limit
  1499
end

#in_clause_lengthObject

the maximum number of elements in an IN (x,y,z) clause



976
977
978
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 976

def in_clause_length
  1499
end

#index_name(table_name, options) ⇒ Object

:nodoc:



871
872
873
874
875
876
877
878
879
880
881
882
883
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 871

def index_name(table_name, options) #:nodoc:
  if Hash === options # legacy support
    if options[:column]
      "#{table_name}_#{Array.wrap(options[:column]) * '_'}"
    elsif options[:name]
      options[:name]
    else
      raise ArgumentError, "You must specify the index name"
    end
  else
    index_name(table_name, :column => options)
  end
end

#index_name_lengthObject

the maximum length of an index name



956
957
958
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 956

def index_name_length
  31
end

#indexes(table_name, name = nil) ⇒ Object

Returns an array of indexes for the given table.



762
763
764
765
766
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 762

def indexes(table_name, name = nil)
  result = @connection.indexes.values.select {|ix| ix.table_name == table_name && ix.index_name !~ /^rdb\$/ }
  indexes = result.map {|ix| IndexDefinition.new(table_name, ix.index_name, ix.unique, ix.columns) }
  indexes
end

#indexes_per_tableObject

the maximum number of indexes per table



966
967
968
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 966

def indexes_per_table
  65_535
end

#insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = []) ⇒ Object

Returns the last auto-generated ID from the affected table.



605
606
607
608
609
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 605

def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
  sql, binds = sql_for_insert(to_sql(arel, binds), pk, id_value, sequence_name, binds)
  value      = exec_insert(sql, name, binds)
  id_value
end

#native_database_typesObject

Returns a Hash of mappings from the abstract data types to the native database types. See TableDefinition#column for details on the recognized abstract data types.



734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 734

def 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" },
    :decimal     => { :name => "decimal" },
    :datetime    => { :name => "timestamp" },
    :timestamp   => { :name => "timestamp" },
    :time        => { :name => "time" },
    :date        => { :name => "date" },
    :binary      => { :name => "blob" },
    :boolean     => { :name => boolean_domain[:name] }
  }
end

#next_sequence_value(sequence_name) ⇒ Object



683
684
685
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 683

def next_sequence_value(sequence_name)
  select_one("SELECT GEN_ID(#{sequence_name}, 1) FROM RDB$DATABASE").values.first
end

#outside_transaction?Boolean

Checks whether there is currently no transaction active. This is done by querying the database driver, and does not use the transaction house-keeping information recorded by #increment_open_transactions and friends.

Returns true if there is no transaction active, false if there is a transaction active, and nil if this information is unknown.

Returns:

  • (Boolean)


630
631
632
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 630

def outside_transaction?
  !@connection.transaction_started
end

#prefetch_primary_key?(table_name = nil) ⇒ Boolean

Should primary key values be selected from their corresponding sequence before the insert statement? If true, next_sequence_value is called before each insert to set the record’s primary key. This is false for all adapters but Firebird.

Returns:

  • (Boolean)


302
303
304
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 302

def prefetch_primary_key?(table_name = nil)
  true
end

#primary_key(table_name) ⇒ Object

:nodoc:



768
769
770
771
772
773
774
775
776
777
778
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 768

def primary_key(table_name) #:nodoc:
  sql = <<-END_SQL
    SELECT s.rdb$field_name
    FROM rdb$indices i
    JOIN rdb$index_segments s ON i.rdb$index_name = s.rdb$index_name
    LEFT JOIN rdb$relation_constraints c ON i.rdb$index_name = c.rdb$index_name
    WHERE i.rdb$relation_name = '#{ar_to_fb_case(table_name)}' and c.rdb$constraint_type = 'PRIMARY KEY';
  END_SQL
  row = select_one(sql)
  row && fb_to_ar_case(row.values.first.rstrip)
end

#quote(value, column = nil) ⇒ Object

from module Quoting



452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 452

def quote(value, column = nil)
  # records are quoted as their primary key
  return value.quoted_id if value.respond_to?(:quoted_id)

  case value
  when String, ActiveSupport::Multibyte::Chars
    value = value.to_s
    if column && [:integer, :float].include?(column.type)
      value = column.type == :integer ? value.to_i : value.to_f
      value.to_s
    elsif column && column.type != :binary && value.size < 256 && !value.include?('@')
      "'#{quote_string(value)}'"
    else
      "@#{Base64.encode64(value).chop}@"
    end
  when NilClass              then "NULL"
  when TrueClass             then (column && column.type == :integer ? '1' : quoted_true)
  when FalseClass            then (column && column.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 value.acts_like?(:date)
      quote_date(value)
    elsif value.acts_like?(:time)
      quote_timestamp(value)
    else
      quote_object(value)
    end
  end
end

#quote_column_name(column_name) ⇒ Object

:nodoc:



507
508
509
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 507

def quote_column_name(column_name) # :nodoc:
  %Q("#{ar_to_fb_case(column_name.to_s)}")
end

#quote_date(value) ⇒ Object



485
486
487
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 485

def quote_date(value)
  "@#{Base64.encode64(value.strftime('%Y-%m-%d')).chop}@"
end

#quote_object(obj) ⇒ Object



499
500
501
502
503
504
505
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 499

def quote_object(obj)
  if obj.respond_to?(:to_str)
    "@#{Base64.encode64(obj.to_str).chop}@"
  else
    "@#{Base64.encode64(obj.to_yaml).chop}@"
  end
end

#quote_string(string) ⇒ Object

:nodoc:



495
496
497
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 495

def quote_string(string) # :nodoc:
  string.gsub(/'/, "''")
end

#quote_timestamp(value) ⇒ Object



489
490
491
492
493
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 489

def quote_timestamp(value)
  zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
  value = value.respond_to?(zone_conversion_method) ? value.send(zone_conversion_method) : value
  "@#{Base64.encode64(value.strftime('%Y-%m-%d %H:%M:%S')).chop}@"
end

#quoted_falseObject

:nodoc:



520
521
522
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 520

def quoted_false # :nodoc:
  quote(boolean_domain[:false])
end

#quoted_trueObject

Quotes the table name. Defaults to column name quoting. def quote_table_name(table_name)

quote_column_name(table_name)

end



516
517
518
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 516

def quoted_true # :nodoc:
  quote(boolean_domain[:true])
end

#reconnect!Object

Disconnects from the database if already connected, and establishes a new connection with the database.



334
335
336
337
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 334

def reconnect!
  disconnect!
  @connection = Fb::Database.connect(@connection_params)
end

#release_savepointObject



403
404
405
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 403

def release_savepoint
  execute("RELEASE SAVEPOINT #{current_savepoint_name}")
end

#remove_index!(table_name, index_name) ⇒ Object

:nodoc:



867
868
869
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 867

def remove_index!(table_name, index_name) #:nodoc:
  execute("DROP INDEX #{quote_column_name(index_name)}")
end

#rename_column(table_name, column_name, new_column_name) ⇒ Object

Renames a column.

Example
rename_column(:suppliers, :description, :name)


863
864
865
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 863

def rename_column(table_name, column_name, new_column_name)
  execute "ALTER TABLE #{quote_table_name(table_name)} ALTER #{quote_column_name(column_name)} TO #{quote_column_name(new_column_name)}"
end

#reset!Object

Reset the state of this connection, directing the DBMS to clear transactions and other connection-related server-side state. Usually a database-dependent operation.

The default implementation does nothing; the implementation should be overridden by concrete adapters.



351
352
353
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 351

def reset!
  reconnect!
end

#reset_sequence!(table, column, sequence = nil) ⇒ Object

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



678
679
680
681
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 678

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

#rollback_db_transactionObject

Rolls back the transaction (and turns on auto-committing). Must be done if the transaction block raises an exception or returns false.



646
647
648
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 646

def rollback_db_transaction
  @transaction = @connection.rollback
end

#rollback_to_savepointObject



399
400
401
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 399

def rollback_to_savepoint
  execute("ROLLBACK TO SAVEPOINT #{current_savepoint_name}")
end

#select_all(arel, name = nil, binds = []) ⇒ Object

Returns an array of record hashes with the column names as keys and column values as values. def select_all(sql, name = nil, format = :hash) # :nodoc:

translate(sql) do |sql, args|
  log(sql, args, name) do
    @connection.query(format, sql, *args)
  end
end

end Returns an array of record hashes with the column names as keys and column values as values.



557
558
559
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 557

def select_all(arel, name = nil, binds = [])
  add_column_types(select(to_sql(arel, binds), name, binds))
end

#select_rows(sql, name = nil) ⇒ Object

Returns an array of arrays containing the field values. Order is the same as that returned by columns.



563
564
565
566
567
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 563

def select_rows(sql, name = nil)
  log(sql, name) do
    @connection.query(:array, sql)
  end
end

#sql_query_lengthObject

the maximum length of an SQL query



981
982
983
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 981

def sql_query_length
  32767
end

#supports_count_distinct?Boolean

Does this adapter support using DISTINCT within COUNT? This is true for all adapters except sqlite.

Returns:

  • (Boolean)


281
282
283
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 281

def supports_count_distinct?
  true
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.

Returns:

  • (Boolean)


288
289
290
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 288

def supports_ddl_transactions?
  false
end

#supports_migrations?Boolean

Does this adapter support migrations? Backend specific, as the abstract adapter always returns false.

Returns:

  • (Boolean)


268
269
270
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 268

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? Backend specific, as the abstract adapter always returns false.

Returns:

  • (Boolean)


275
276
277
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 275

def supports_primary_key?
  true
end

#supports_savepoints?Boolean

Does this adapter support savepoints? PostgreSQL and MySQL do, SQLite does not.

Returns:

  • (Boolean)


294
295
296
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 294

def supports_savepoints?
  true
end

#table_alias_lengthObject

the maximum length of a table alias



941
942
943
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 941

def table_alias_length
  31
end

#table_name_lengthObject

the maximum length of a table name



951
952
953
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 951

def table_name_length
  31
end

#tables(name = nil) ⇒ Object

def tables(name = nil) end



757
758
759
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 757

def tables(name = nil)
  @connection.table_names
end

#type_cast(value, column) ⇒ Object



524
525
526
527
528
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 524

def type_cast(value, column)
  return super unless value == true || value == false

  value ? quoted_true : quoted_false
end

#type_to_sql(type, limit = nil, precision = nil, scale = nil) ⇒ Object



885
886
887
888
889
890
891
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 885

def type_to_sql(type, limit = nil, precision = nil, scale = nil)
  case type
  when :integer then integer_to_sql(limit)
  when :float then float_to_sql(limit)
  else super
  end
end