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::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
-
.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
LIMIT
andOFFSET
options 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
sql
statement in the context of this connection usingbinds
as 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, connection_params = 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_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.
-
#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
true
for 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? PostgreSQL and MySQL do, SQLite does not.
-
#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, 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
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.
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_name ⇒ Object
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, = {}) 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, ) execute(add_column_sql) 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
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, ) # :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).
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, = {}) sql = "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} TYPE #{type_to_sql(type, [:limit], [:precision], [:scale])}" sql = (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)
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_length ⇒ Object
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_transaction ⇒ Object
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_savepoint ⇒ Object
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, = {}) # :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
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, = {}) # :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.
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((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_limit ⇒ Object
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_length ⇒ Object
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, ) #: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
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_table ⇒ Object
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_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.
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.
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.
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) (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 (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:
520 521 522 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 520 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
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_savepoint ⇒ Object
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_transaction ⇒ Object
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_savepoint ⇒ Object
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_length ⇒ Object
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.
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.
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
.
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
.
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.
294 295 296 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 294 def supports_savepoints? true end |
#table_alias_length ⇒ Object
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_length ⇒ Object
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 |