Class: ActiveRecord::ConnectionAdapters::FbAdapter
- Inherits:
-
AbstractAdapter
- Object
- AbstractAdapter
- ActiveRecord::ConnectionAdapters::FbAdapter
- Includes:
- ActiveRecord::ConnectionAdapters::Fb::DatabaseLimits, ActiveRecord::ConnectionAdapters::Fb::DatabaseStatements, ActiveRecord::ConnectionAdapters::Fb::Quoting, ActiveRecord::ConnectionAdapters::Fb::SchemaStatements
- 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
,: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.
Defined Under Namespace
Classes: BindSubstitution
Constant Summary collapse
- @@boolean_domain =
{ :true => 1, :false => 0, :name => 'BOOLEAN', :type => 'integer' }
- @@default_transaction_isolation =
:read_committed
Class Method Summary collapse
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.
- #create_savepoint(name = current_savepoint_name) ⇒ Object
-
#disconnect! ⇒ Object
Disconnects from the database if already connected.
-
#ids_in_list_limit ⇒ Object
Does this adapter restrict the number of ids you can use in a list.
-
#initialize(connection, logger, config = nil) ⇒ FbAdapter
constructor
A new instance of FbAdapter.
-
#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.
-
#reconnect! ⇒ Object
Disconnects from the database if already connected, and establishes a new connection with the database.
- #release_savepoint(name = current_savepoint_name) ⇒ Object
-
#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.
- #rollback_to_savepoint(name = current_savepoint_name) ⇒ Object
-
#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? FirebirdSQL does.
- #supports_transaction_isolation? ⇒ Boolean
Methods included from ActiveRecord::ConnectionAdapters::Fb::SchemaStatements
#add_column, #change_column, #change_column_default, #change_column_null, #columns, #create_sequence, #create_table, #drop_sequence, #drop_table, #index_name, #indexes, #native_database_types, #primary_key, #remove_column, #remove_index!, #rename_column, #rename_table, #tables, #type_to_sql
Methods included from ActiveRecord::ConnectionAdapters::Fb::Quoting
#quote, #quote_column_name, #quote_string, #quote_table_name_for_assignment, #quoted_false, #quoted_true, #type_cast, #unquoted_false, #unquoted_true
Methods included from ActiveRecord::ConnectionAdapters::Fb::DatabaseStatements
#begin_db_transaction, #begin_isolated_db_transaction, #commit_db_transaction, #default_sequence_name, #exec_query, #execute, #explain, #next_sequence_value, #reset_sequence!, #rollback_db_transaction, #select_rows, #transaction_isolation_levels
Methods included from ActiveRecord::ConnectionAdapters::Fb::DatabaseLimits
#column_name_length, #in_clause_length, #index_name_length, #indexes_per_table, #sql_query_length, #table_alias_length, #table_name_length
Constructor Details
#initialize(connection, logger, config = nil) ⇒ FbAdapter
Returns a new instance of FbAdapter.
150 151 152 153 154 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 150 def initialize(connection, logger, config=nil) super(connection, logger) @config = config @visitor = Arel::Visitors::Fb.new(self) end |
Class Method Details
.boolean_domain=(domain) ⇒ Object
138 139 140 141 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 138 def self.boolean_domain=(domain) FbColumn::TRUE_VALUES << domain[:true] @@boolean_domain = domain 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.
215 216 217 218 219 220 221 222 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 215 def active? return false unless @connection.open? # return true if @connection.transaction_started @connection.query("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.
158 159 160 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 158 def adapter_name 'Fb' end |
#create_savepoint(name = current_savepoint_name) ⇒ Object
254 255 256 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 254 def create_savepoint(name = current_savepoint_name) execute("SAVEPOINT #{name}") end |
#disconnect! ⇒ Object
Disconnects from the database if already connected. Otherwise, this method does nothing.
233 234 235 236 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 233 def disconnect! super @connection.close rescue nil 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.
206 207 208 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 206 def ids_in_list_limit 1499 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.
201 202 203 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 201 def prefetch_primary_key?(table_name = nil) true end |
#reconnect! ⇒ Object
Disconnects from the database if already connected, and establishes a new connection with the database.
226 227 228 229 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 226 def reconnect! disconnect! @connection = ::Fb::Database.connect(@config) end |
#release_savepoint(name = current_savepoint_name) ⇒ Object
262 263 264 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 262 def release_savepoint(name = current_savepoint_name) execute("RELEASE SAVEPOINT #{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.
250 251 252 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 250 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.
244 245 246 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 244 def reset! reconnect! end |
#rollback_to_savepoint(name = current_savepoint_name) ⇒ Object
258 259 260 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 258 def rollback_to_savepoint(name = current_savepoint_name) execute("ROLLBACK TO SAVEPOINT #{name}") end |
#supports_count_distinct? ⇒ Boolean
Does this adapter support using DISTINCT within COUNT? This is true
for all adapters except sqlite.
177 178 179 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 177 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.
184 185 186 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 184 def supports_ddl_transactions? true end |
#supports_migrations? ⇒ Boolean
Does this adapter support migrations? Backend specific, as the abstract adapter always returns false
.
164 165 166 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 164 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
.
171 172 173 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 171 def supports_primary_key? true end |
#supports_savepoints? ⇒ Boolean
Does this adapter support savepoints? FirebirdSQL does
193 194 195 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 193 def supports_savepoints? true end |
#supports_transaction_isolation? ⇒ Boolean
188 189 190 |
# File 'lib/active_record/connection_adapters/fb_adapter.rb', line 188 def supports_transaction_isolation? true end |