Class: ActiveRecord::ConnectionAdapters::FbAdapter
- Inherits:
-
AbstractAdapter
- Object
- AbstractAdapter
- ActiveRecord::ConnectionAdapters::FbAdapter
- 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::ModelSchema::ClassMethods#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,:serviceor:portas 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
-
.visitor_for(pool) ⇒ Object
:nodoc:.
Instance Method Summary collapse
-
#active? ⇒ Boolean
Checks whether the connection to the database is still active.
-
#adapter_name ⇒ Object
Returns the human-readable name of the adapter.
-
#add_column(table_name, column_name, type, options = {}) ⇒ Object
Adds a new column to the named table.
-
#add_limit_offset!(sql, options) ⇒ Object
Appends
LIMITandOFFSEToptions to an SQL statement, or some SQL fragment that has the same semantics as LIMIT and OFFSET. -
#begin_db_transaction ⇒ Object
Begins the transaction (and turns off auto-committing).
-
#change_column(table_name, column_name, type, options = {}) ⇒ Object
Changes the column’s definition according to the new options.
-
#change_column_default(table_name, column_name, default) ⇒ Object
Sets a new default value for a column.
-
#column_name_length ⇒ Object
the maximum length of a column name.
-
#columns(table_name, name = nil) ⇒ Object
Returns an array of Column objects for the table specified by
table_name. -
#commit_db_transaction ⇒ Object
Commits the transaction (and turns on auto-committing).
-
#create_savepoint ⇒ Object
def transaction_joinable=(joinable) @transaction_joinable = joinable end.
-
#create_table(name, options = {}) ⇒ Object
:nodoc:.
- #default_sequence_name(table_name, column = nil) ⇒ Object
-
#disconnect! ⇒ Object
Disconnects from the database if already connected.
-
#drop_table(name, options = {}) ⇒ Object
:nodoc:.
-
#exec_query(sql, name = 'SQL', binds = []) ⇒ Object
Executes
sqlstatement in the context of this connection usingbindsas the bind substitutes. -
#execute(sql, name = nil, skip_logging = false) ⇒ Object
Executes the SQL statement in the context of this connection.
- #explain(arel, binds = []) ⇒ Object
-
#ids_in_list_limit ⇒ Object
Does this adapter restrict the number of ids you can use in a list.
-
#in_clause_length ⇒ Object
the maximum number of elements in an IN (x,y,z) clause.
-
#index_name(table_name, options) ⇒ Object
:nodoc:.
-
#index_name_length ⇒ Object
the maximum length of an index name.
-
#indexes(table_name, name = nil) ⇒ Object
Returns an array of indexes for the given table.
-
#indexes_per_table ⇒ Object
the maximum number of indexes per table.
-
#initialize(connection, logger, config = nil) ⇒ FbAdapter
constructor
A new instance of FbAdapter.
-
#insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = []) ⇒ Object
Returns the last auto-generated ID from the affected table.
-
#native_database_types ⇒ Object
Returns a Hash of mappings from the abstract data types to the native database types.
- #next_sequence_value(sequence_name) ⇒ Object
-
#outside_transaction? ⇒ Boolean
Checks whether there is currently no transaction active.
-
#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.
-
#primary_key(table_name) ⇒ Object
:nodoc:.
-
#quote(value, column = nil) ⇒ Object
from module Quoting.
-
#quote_column_name(column_name) ⇒ Object
:nodoc:.
- #quote_date(value) ⇒ Object
- #quote_object(obj) ⇒ Object
-
#quote_string(string) ⇒ Object
:nodoc:.
- #quote_table_name_for_assignment(table, attr) ⇒ Object
- #quote_timestamp(value) ⇒ Object
-
#quoted_false ⇒ Object
:nodoc:.
-
#quoted_true ⇒ Object
Quotes the table name.
-
#reconnect! ⇒ Object
Disconnects from the database if already connected, and establishes a new connection with the database.
- #release_savepoint ⇒ Object
-
#remove_index!(table_name, index_name) ⇒ Object
:nodoc:.
-
#rename_column(table_name, column_name, new_column_name) ⇒ Object
Renames a column.
-
#requires_reloading? ⇒ Boolean
Returns true if its required to reload the connection between requests for development mode.
-
#reset! ⇒ Object
Reset the state of this connection, directing the DBMS to clear transactions and other connection-related server-side state.
-
#reset_sequence!(table, column, sequence = nil) ⇒ Object
Set the sequence to the max value of the table’s column.
-
#rollback_db_transaction ⇒ Object
Rolls back the transaction (and turns on auto-committing).
- #rollback_to_savepoint ⇒ Object
-
#select_all(arel, name = nil, binds = []) ⇒ Object
Returns an array of record hashes with the column names as keys and column values as values.
-
#select_rows(sql, name = nil) ⇒ Object
Returns an array of arrays containing the field values.
-
#sql_query_length ⇒ Object
the maximum length of an SQL query.
-
#supports_count_distinct? ⇒ Boolean
Does this adapter support using DISTINCT within COUNT? This is
truefor all adapters except sqlite. -
#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? Backend specific, as the abstract adapter always returns
false. -
#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. -
#supports_savepoints? ⇒ Boolean
Does this adapter support savepoints? FirebirdSQL does.
-
#table_alias_length ⇒ Object
the maximum length of a table alias.
-
#table_name_length ⇒ Object
the maximum length of a table name.
-
#tables(name = nil) ⇒ Object
def tables(name = nil) end.
- #type_cast(value, column) ⇒ Object
- #type_to_sql(type, limit = nil, precision = nil, scale = nil) ⇒ Object
Constructor Details
#initialize(connection, logger, config = nil) ⇒ FbAdapter
Returns a new instance of FbAdapter.
259 260 261 262 263 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 259 def initialize(connection, logger, config=nil) super(connection, logger) @config = config @visitor = Arel::Visitors::FB.new(self) end |
Class Method Details
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.
331 332 333 334 335 336 337 338 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 331 def active? return false unless @connection.open? # return true if @connection.transaction_started select("SELECT 1 FROM RDB$DATABASE") true rescue false end |
#adapter_name ⇒ Object
Returns the human-readable name of the adapter. Use mixed case - one can always use downcase if needed.
271 272 273 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 271 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.
838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 838 def add_column(table_name, column_name, type, = {}) add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} #{type_to_sql(type, [:limit], [:precision], [:scale])}" (add_column_sql, ) begin execute(add_column_sql) rescue raise unless non_existent_domain_error? create_boolean_domain execute(add_column_sql) end if [: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 #{[: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
680 681 682 683 684 685 686 687 688 689 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 680 def add_limit_offset!(sql, ) # :nodoc: if limit = [:limit] if offset = [: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_transaction ⇒ Object
Begins the transaction (and turns off auto-committing).
653 654 655 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 653 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)
860 861 862 863 864 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 860 def change_column(table_name, column_name, type, = {}) sql = "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} TYPE #{type_to_sql(type, [:limit], [:precision], [:scale])}" (sql, ) 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)
872 873 874 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 872 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_length ⇒ Object
the maximum length of a column name
962 963 964 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 962 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.
792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 792 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_transaction ⇒ Object
Commits the transaction (and turns on auto-committing).
658 659 660 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 658 def commit_db_transaction @transaction = @connection.commit end |
#create_savepoint ⇒ Object
def transaction_joinable=(joinable)
@transaction_joinable = joinable
end
403 404 405 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 403 def create_savepoint execute("SAVEPOINT #{current_savepoint_name}") end |
#create_table(name, options = {}) ⇒ Object
:nodoc:
814 815 816 817 818 819 820 821 822 823 824 825 826 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 814 def create_table(name, = {}) # :nodoc: begin super rescue raise unless non_existent_domain_error? create_boolean_domain super end unless [:id] == false or [:sequence] == false sequence_name = [:sequence] || default_sequence_name(name) create_sequence(sequence_name) end end |
#default_sequence_name(table_name, column = nil) ⇒ Object
691 692 693 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 691 def default_sequence_name(table_name, column = nil) "#{table_name.to_s[0, table_name_length - 4]}_seq" end |
#disconnect! ⇒ Object
Disconnects from the database if already connected. Otherwise, this method does nothing.
349 350 351 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 349 def disconnect! @connection.close rescue nil end |
#drop_table(name, options = {}) ⇒ Object
:nodoc:
828 829 830 831 832 833 834 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 828 def drop_table(name, = {}) # :nodoc: super(name) unless [:sequence] == false sequence_name = [: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.
601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 601 def exec_query(sql, name = 'SQL', binds = []) translate(sql) do |sql, args| unless binds.empty? args = binds.map { |col, val| type_cast(val, col) } + args end log((sql, args), name) do result, rows = @connection.execute(sql, *args) { |cursor| [cursor.fields, cursor.fetchall] } if result.respond_to?(:map) cols = result.map { |col| col.name } ActiveRecord::Result.new(cols, rows) else result end end end end |
#execute(sql, name = nil, skip_logging = false) ⇒ Object
Executes the SQL statement in the context of this connection.
586 587 588 589 590 591 592 593 594 595 596 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 586 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
618 619 620 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 618 def explain(arel, binds = []) to_sql(arel, binds) 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.
315 316 317 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 315 def ids_in_list_limit 1499 end |
#in_clause_length ⇒ Object
the maximum number of elements in an IN (x,y,z) clause
992 993 994 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 992 def in_clause_length 1499 end |
#index_name(table_name, options) ⇒ Object
:nodoc:
887 888 889 890 891 892 893 894 895 896 897 898 899 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 887 def index_name(table_name, ) #:nodoc: if Hash === # legacy support if [:column] "#{table_name}_#{Array.wrap([:column]) * '_'}" elsif [:name] [:name] else raise ArgumentError, "You must specify the index name" end else index_name(table_name, :column => ) end end |
#index_name_length ⇒ Object
the maximum length of an index name
972 973 974 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 972 def index_name_length 31 end |
#indexes(table_name, name = nil) ⇒ Object
Returns an array of indexes for the given table.
772 773 774 775 776 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 772 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_table ⇒ Object
the maximum number of indexes per table
982 983 984 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 982 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.
623 624 625 626 627 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 623 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_types ⇒ Object
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.
744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 744 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
701 702 703 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 701 def next_sequence_value(sequence_name) select_one("SELECT NEXT VALUE FOR #{sequence_name} 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.
648 649 650 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 648 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.
310 311 312 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 310 def prefetch_primary_key?(table_name = nil) true end |
#primary_key(table_name) ⇒ Object
:nodoc:
778 779 780 781 782 783 784 785 786 787 788 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 778 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
460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 460 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) (value) else quote_object(value) end end end |
#quote_column_name(column_name) ⇒ Object
:nodoc:
515 516 517 518 519 520 521 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 515 def quote_column_name(column_name) # :nodoc: if @connection.dialect == 1 %Q(#{ar_to_fb_case(column_name.to_s)}) else %Q("#{ar_to_fb_case(column_name.to_s)}") end end |
#quote_date(value) ⇒ Object
493 494 495 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 493 def quote_date(value) "@#{Base64.encode64(value.strftime('%Y-%m-%d')).chop}@" end |
#quote_object(obj) ⇒ Object
507 508 509 510 511 512 513 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 507 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:
503 504 505 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 503 def quote_string(string) # :nodoc: string.gsub(/'/, "''") end |
#quote_table_name_for_assignment(table, attr) ⇒ Object
523 524 525 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 523 def quote_table_name_for_assignment(table, attr) quote_column_name(attr) end |
#quote_timestamp(value) ⇒ Object
497 498 499 500 501 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 497 def (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_false ⇒ Object
:nodoc:
536 537 538 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 536 def quoted_false # :nodoc: quote(boolean_domain[:false]) end |
#quoted_true ⇒ Object
Quotes the table name. Defaults to column name quoting. def quote_table_name(table_name)
quote_column_name(table_name)
end
532 533 534 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 532 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.
342 343 344 345 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 342 def reconnect! disconnect! @connection = Fb::Database.connect(@config) end |
#release_savepoint ⇒ Object
411 412 413 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 411 def release_savepoint execute("RELEASE SAVEPOINT #{current_savepoint_name}") end |
#remove_index!(table_name, index_name) ⇒ Object
:nodoc:
883 884 885 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 883 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)
879 880 881 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 879 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 |
#requires_reloading? ⇒ Boolean
Returns true if its required to reload the connection between requests for development mode. This is not the case for FirebirdSQL and it’s not necessary for any adapters except SQLite.
365 366 367 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 365 def requires_reloading? false 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.
359 360 361 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 359 def reset! reconnect! end |
#reset_sequence!(table, column, sequence = nil) ⇒ Object
Set the sequence to the max value of the table’s column.
696 697 698 699 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 696 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_transaction ⇒ Object
Rolls back the transaction (and turns on auto-committing). Must be done if the transaction block raises an exception or returns false.
664 665 666 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 664 def rollback_db_transaction @transaction = @connection.rollback end |
#rollback_to_savepoint ⇒ Object
407 408 409 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 407 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.
573 574 575 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 573 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.
579 580 581 582 583 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 579 def select_rows(sql, name = nil) log(sql, name) do @connection.query(:array, sql) end end |
#sql_query_length ⇒ Object
the maximum length of an SQL query
997 998 999 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 997 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.
290 291 292 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 290 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.
297 298 299 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 297 def supports_ddl_transactions? false end |
#supports_migrations? ⇒ Boolean
Does this adapter support migrations? Backend specific, as the abstract adapter always returns false.
277 278 279 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 277 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.
284 285 286 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 284 def supports_primary_key? true end |
#supports_savepoints? ⇒ Boolean
Does this adapter support savepoints? FirebirdSQL does
302 303 304 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 302 def supports_savepoints? true end |
#table_alias_length ⇒ Object
the maximum length of a table alias
957 958 959 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 957 def table_alias_length 31 end |
#table_name_length ⇒ Object
the maximum length of a table name
967 968 969 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 967 def table_name_length 31 end |
#tables(name = nil) ⇒ Object
def tables(name = nil) end
767 768 769 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 767 def tables(name = nil) @connection.table_names end |
#type_cast(value, column) ⇒ Object
540 541 542 543 544 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 540 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
901 902 903 904 905 906 907 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 901 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 |