Module: ArJdbc::Firebird
- Included in:
- ActiveRecord::ConnectionAdapters::FirebirdAdapter
- Defined in:
- lib/arjdbc/firebird/adapter.rb
Defined Under Namespace
Modules: Column
Constant Summary collapse
- ADAPTER_NAME =
'Firebird'.freeze
- 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" }, :datetime => { :name => "timestamp" }, :timestamp => { :name => "timestamp" }, :time => { :name => "time" }, :date => { :name => "date" }, :binary => { :name => "blob" }, :boolean => { :name => 'char', :limit => 1 }, :numeric => { :name => "numeric" }, :decimal => { :name => "decimal" }, :char => { :name => "char" }, }
- IDENTIFIER_LENGTH =
usual DB meta-identifier: 31 chars maximum
31
- @@update_lob_values =
true
Class Method Summary collapse
-
.arel2_visitors(config = nil) ⇒ Object
deprecated
Deprecated.
no longer used
- .arel_visitor_type(config = nil) ⇒ Object
- .column_selector ⇒ Object
-
.emulate_booleans ⇒ Object
deprecated
Deprecated.
Use #emulate_booleans? instead.
- .emulate_booleans=(emulate) ⇒ Object
-
.emulate_booleans? ⇒ Boolean
Boolean emulation can be disabled using :.
- .jdbc_connection_class ⇒ Object
- .update_lob_values=(update) ⇒ Object
-
.update_lob_values? ⇒ Boolean
Updating records with LOB values (binary/text columns) in a separate statement can be disabled using :.
Instance Method Summary collapse
- #adapter_name ⇒ Object
- #add_limit_offset!(sql, options) ⇒ Object
- #change_column(table_name, column_name, type, options = {}) ⇒ Object
- #clear_cache! ⇒ Object
- #column_name_length ⇒ Object
- #create_table(name, options = {}) ⇒ Object
- #default_sequence_name(table_name, column = nil) ⇒ Object
- #drop_table(name, options = {}) ⇒ Object
-
#ids_in_list_limit ⇒ Object
Does this adapter restrict the number of IDs you can use in a list.
- #index_name_length ⇒ Object
- #initialize_type_map(m) ⇒ Object
- #insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = []) ⇒ Object
- #insert_limit_offset!(sql, limit, offset) ⇒ Object
- #jdbc_column_class ⇒ Object
- #native_database_types ⇒ Object
- #next_sequence_value(sequence_name) ⇒ Object
-
#prefetch_primary_key?(table_name = nil) ⇒ Boolean
Should primary key values be selected from their corresponding sequence before the insert statement?.
- #quote(value, column = nil) ⇒ Object
- #quote_column_name(column_name) ⇒ Object
- #quote_string(string) ⇒ Object
- #quote_table_name_for_assignment(table, attr) ⇒ Object
- #quoted_date(value) ⇒ Object
- #quoted_false ⇒ Object
- #quoted_true ⇒ Object
- #remove_index(table_name, options) ⇒ Object
- #rename_column(table_name, column_name, new_column_name) ⇒ Object
- #rename_table(name, new_name) ⇒ Object
-
#reset_sequence!(table, column, sequence = nil) ⇒ Object
Set the sequence to the max value of the table's column.
-
#supports_count_distinct? ⇒ Boolean
Does this adapter support using DISTINCT within COUNT?.
-
#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?.
-
#supports_primary_key? ⇒ Boolean
Can this adapter determine the primary key for tables not attached to an Active Record class, such as join tables?.
- #table_alias_length ⇒ Object
- #table_name_length ⇒ Object
- #type_to_sql(type, limit = nil, precision = nil, scale = nil) ⇒ Object
- #update_lob_values? ⇒ Boolean
Class Method Details
.arel2_visitors(config = nil) ⇒ Object
no longer used
71 72 73 |
# File 'lib/arjdbc/firebird/adapter.rb', line 71 def self.arel2_visitors(config = nil) { 'firebird' => arel_visitor_type, 'firebirdsql' => arel_visitor_type } end |
.arel_visitor_type(config = nil) ⇒ Object
66 67 68 |
# File 'lib/arjdbc/firebird/adapter.rb', line 66 def self.arel_visitor_type(config = nil) require 'arel/visitors/firebird'; ::Arel::Visitors::Firebird end |
.column_selector ⇒ Object
26 27 28 |
# File 'lib/arjdbc/firebird/adapter.rb', line 26 def self.column_selector [ /firebird/i, lambda { |cfg, column| column.extend(Column) } ] end |
.emulate_booleans ⇒ Object
Use #emulate_booleans? instead.
84 |
# File 'lib/arjdbc/firebird/adapter.rb', line 84 def self.emulate_booleans; @@emulate_booleans; end |
.emulate_booleans=(emulate) ⇒ Object
86 |
# File 'lib/arjdbc/firebird/adapter.rb', line 86 def self.emulate_booleans=(emulate); @@emulate_booleans = emulate; end |
.emulate_booleans? ⇒ Boolean
Boolean emulation can be disabled using :
ArJdbc::Firebird.emulate_booleans = false
82 |
# File 'lib/arjdbc/firebird/adapter.rb', line 82 def self.emulate_booleans?; @@emulate_booleans; end |
.jdbc_connection_class ⇒ Object
21 22 23 |
# File 'lib/arjdbc/firebird/adapter.rb', line 21 def self.jdbc_connection_class ::ActiveRecord::ConnectionAdapters::FirebirdJdbcConnection end |
.update_lob_values=(update) ⇒ Object
97 |
# File 'lib/arjdbc/firebird/adapter.rb', line 97 def self.update_lob_values=(update); @@update_lob_values = update; end |
.update_lob_values? ⇒ Boolean
Updating records with LOB values (binary/text columns) in a separate statement can be disabled using :
ArJdbc::Firebird.update_lob_values = false
95 |
# File 'lib/arjdbc/firebird/adapter.rb', line 95 def self.update_lob_values?; @@update_lob_values; end |
Instance Method Details
#adapter_name ⇒ Object
108 109 110 |
# File 'lib/arjdbc/firebird/adapter.rb', line 108 def adapter_name ADAPTER_NAME end |
#add_limit_offset!(sql, options) ⇒ Object
250 251 252 253 254 |
# File 'lib/arjdbc/firebird/adapter.rb', line 250 def add_limit_offset!(sql, ) if limit = [:limit] insert_limit_offset!(sql, limit, [:offset]) end end |
#change_column(table_name, column_name, type, options = {}) ⇒ Object
316 317 318 |
# File 'lib/arjdbc/firebird/adapter.rb', line 316 def change_column(table_name, column_name, type, = {}) execute "ALTER TABLE #{table_name} ALTER #{column_name} TYPE #{type_to_sql(type, [:limit])}" end |
#clear_cache! ⇒ Object
173 174 175 176 |
# File 'lib/arjdbc/firebird/adapter.rb', line 173 def clear_cache! super reload_type_map end |
#column_name_length ⇒ Object
283 |
# File 'lib/arjdbc/firebird/adapter.rb', line 283 def column_name_length; IDENTIFIER_LENGTH; end |
#create_table(name, options = {}) ⇒ Object
300 301 302 303 |
# File 'lib/arjdbc/firebird/adapter.rb', line 300 def create_table(name, = {}) super(name, ) execute "CREATE GENERATOR #{default_sequence_name(name)}" end |
#default_sequence_name(table_name, column = nil) ⇒ Object
285 286 287 288 |
# File 'lib/arjdbc/firebird/adapter.rb', line 285 def default_sequence_name(table_name, column = nil) len = IDENTIFIER_LENGTH - 4 table_name.to_s.gsub (/(^|\.)([\w$-]{1,#{len}})([\w$-]*)$/), '\1\2_seq' end |
#drop_table(name, options = {}) ⇒ Object
311 312 313 314 |
# File 'lib/arjdbc/firebird/adapter.rb', line 311 def drop_table(name, = {}) super(name) execute_quietly "DROP GENERATOR #{default_sequence_name(name)}" 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.
241 242 243 |
# File 'lib/arjdbc/firebird/adapter.rb', line 241 def ids_in_list_limit 1499 end |
#index_name_length ⇒ Object
282 |
# File 'lib/arjdbc/firebird/adapter.rb', line 282 def index_name_length; IDENTIFIER_LENGTH; end |
#initialize_type_map(m) ⇒ Object
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/arjdbc/firebird/adapter.rb', line 133 def initialize_type_map(m) register_class_with_limit m, %r(binary)i, ActiveRecord::Type::Binary register_class_with_limit m, %r(text)i, ActiveRecord::Type::Text register_class_with_limit m, %r(date(?:\(.*?\))?$)i, DateType register_class_with_limit m, %r(time(?:\(.*?\))?$)i, ActiveRecord::Type::Time register_class_with_limit m, %r(float)i, ActiveRecord::Type::Float register_class_with_limit m, %r(int)i, ActiveRecord::Type::Integer m.alias_type %r(blob)i, 'binary' m.alias_type %r(clob)i, 'text' m.alias_type %r(double)i, 'float' m.register_type(%r(decimal)i) do |sql_type| scale = extract_scale(sql_type) precision = extract_precision(sql_type) if scale == 0 ActiveRecord::Type::Integer.new(precision: precision) else ActiveRecord::Type::Decimal.new(precision: precision, scale: scale) end end m.alias_type %r(numeric)i, 'decimal' register_class_with_limit m, %r(varchar)i, ActiveRecord::Type::String m.register_type(%r(^char)i) do |sql_type| precision = extract_precision(sql_type) if Firebird.emulate_booleans? && precision == 1 ActiveRecord::Type::Boolean.new else ActiveRecord::Type::String.new(:precision => precision) end end register_class_with_limit m, %r(datetime)i, ActiveRecord::Type::DateTime register_class_with_limit m, %r(timestamp)i, TimestampType end |
#insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = []) ⇒ Object
245 246 247 248 |
# File 'lib/arjdbc/firebird/adapter.rb', line 245 def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = []) execute(sql, name, binds) id_value end |
#insert_limit_offset!(sql, limit, offset) ⇒ Object
259 260 261 262 263 264 265 266 |
# File 'lib/arjdbc/firebird/adapter.rb', line 259 def insert_limit_offset!(sql, limit, offset) lim_off = '' lim_off << "FIRST #{limit}" if limit lim_off << " SKIP #{offset}" if offset lim_off.strip! sql.sub!(SELECT_RE, "\\&#{lim_off} ") unless lim_off.empty? end |
#jdbc_column_class ⇒ Object
63 |
# File 'lib/arjdbc/firebird/adapter.rb', line 63 def jdbc_column_class; ::ActiveRecord::ConnectionAdapters::FirebirdColumn end |
#native_database_types ⇒ Object
129 130 131 |
# File 'lib/arjdbc/firebird/adapter.rb', line 129 def native_database_types NATIVE_DATABASE_TYPES end |
#next_sequence_value(sequence_name) ⇒ Object
296 297 298 |
# File 'lib/arjdbc/firebird/adapter.rb', line 296 def next_sequence_value(sequence_name) select_one("SELECT GEN_ID(#{sequence_name}, 1 ) FROM RDB$DATABASE;")["gen_id"] end |
#prefetch_primary_key?(table_name = nil) ⇒ Boolean
Should primary key values be selected from their corresponding sequence before the insert statement?
272 273 274 275 276 |
# File 'lib/arjdbc/firebird/adapter.rb', line 272 def prefetch_primary_key?(table_name = nil) return true if table_name.nil? primary_keys(table_name.to_s).size == 1 # columns(table_name).count { |column| column.primary } == 1 end |
#quote(value, column = nil) ⇒ Object
329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 |
# File 'lib/arjdbc/firebird/adapter.rb', line 329 def quote(value, column = nil) return value.quoted_id if value.respond_to?(:quoted_id) return value if sql_literal?(value) type = column && column.type # BLOBs are updated separately by an after_save trigger. if type == :binary || type == :text if update_lob_values? return value.nil? ? "NULL" : BLOB_VALUE_MARKER else return "'#{quote_string(value)}'" end end case value when String, ActiveSupport::Multibyte::Chars value = value.to_s if type == :integer value.to_i.to_s elsif type == :float value.to_f.to_s else "'#{quote_string(value)}'" end when NilClass then 'NULL' when TrueClass then (type == :integer ? '1' : quoted_true) when FalseClass then (type == :integer ? '0' : quoted_false) when Float, Fixnum, Bignum then value.to_s # BigDecimals need to be output in a non-normalized form and quoted. when BigDecimal then value.to_s('F') when Symbol then "'#{quote_string(value.to_s)}'" else if type == :time && value.acts_like?(:time) return "'#{get_time(value).strftime("%H:%M:%S")}'" end if type == :date && value.acts_like?(:date) return "'#{value.strftime("%Y-%m-%d")}'" end super end end |
#quote_column_name(column_name) ⇒ Object
404 405 406 407 |
# File 'lib/arjdbc/firebird/adapter.rb', line 404 def quote_column_name(column_name) column_name = column_name.to_s %Q("#{column_name =~ /[[:upper:]]/ ? column_name : column_name.upcase}") end |
#quote_string(string) ⇒ Object
384 385 386 |
# File 'lib/arjdbc/firebird/adapter.rb', line 384 def quote_string(string) string.gsub(/'/, "''") end |
#quote_table_name_for_assignment(table, attr) ⇒ Object
399 400 401 |
# File 'lib/arjdbc/firebird/adapter.rb', line 399 def quote_table_name_for_assignment(table, attr) quote_column_name(attr) end |
#quoted_date(value) ⇒ Object
373 374 375 376 377 378 379 380 381 |
# File 'lib/arjdbc/firebird/adapter.rb', line 373 def quoted_date(value) if value.acts_like?(:time) && value.respond_to?(:usec) usec = sprintf "%04d", (value.usec / 100.0).round value = ::ActiveRecord::Base.default_timezone == :utc ? value.getutc : value.getlocal "#{value.strftime("%Y-%m-%d %H:%M:%S")}.#{usec}" else super end end |
#quoted_false ⇒ Object
394 395 396 |
# File 'lib/arjdbc/firebird/adapter.rb', line 394 def quoted_false quote(0) end |
#quoted_true ⇒ Object
389 390 391 |
# File 'lib/arjdbc/firebird/adapter.rb', line 389 def quoted_true quote(1) end |
#remove_index(table_name, options) ⇒ Object
324 325 326 |
# File 'lib/arjdbc/firebird/adapter.rb', line 324 def remove_index(table_name, ) execute "DROP INDEX #{index_name(table_name, )}" end |
#rename_column(table_name, column_name, new_column_name) ⇒ Object
320 321 322 |
# File 'lib/arjdbc/firebird/adapter.rb', line 320 def rename_column(table_name, column_name, new_column_name) execute "ALTER TABLE #{table_name} ALTER #{column_name} TO #{new_column_name}" end |
#rename_table(name, new_name) ⇒ Object
305 306 307 308 309 |
# File 'lib/arjdbc/firebird/adapter.rb', line 305 def rename_table(name, new_name) execute "RENAME #{name} TO #{new_name}" name_seq, new_name_seq = default_sequence_name(name), default_sequence_name(new_name) execute_quietly "UPDATE RDB$GENERATORS SET RDB$GENERATOR_NAME='#{new_name_seq}' WHERE RDB$GENERATOR_NAME='#{name_seq}'" end |
#reset_sequence!(table, column, sequence = nil) ⇒ Object
Set the sequence to the max value of the table's column.
291 292 293 294 |
# File 'lib/arjdbc/firebird/adapter.rb', line 291 def reset_sequence!(table, column, sequence = nil) max_id = select_value("SELECT max(#{column}) FROM #{table}") execute("ALTER SEQUENCE #{default_sequence_name(table, column)} RESTART WITH #{max_id}") end |
#supports_count_distinct? ⇒ Boolean
Does this adapter support using DISTINCT within COUNT?
228 229 230 |
# File 'lib/arjdbc/firebird/adapter.rb', line 228 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.
235 236 237 |
# File 'lib/arjdbc/firebird/adapter.rb', line 235 def supports_ddl_transactions? false end |
#supports_migrations? ⇒ Boolean
Does this adapter support migrations?
217 218 219 |
# File 'lib/arjdbc/firebird/adapter.rb', line 217 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?
223 224 225 |
# File 'lib/arjdbc/firebird/adapter.rb', line 223 def supports_primary_key? true end |
#table_alias_length ⇒ Object
280 |
# File 'lib/arjdbc/firebird/adapter.rb', line 280 def table_alias_length; IDENTIFIER_LENGTH; end |
#table_name_length ⇒ Object
281 |
# File 'lib/arjdbc/firebird/adapter.rb', line 281 def table_name_length; IDENTIFIER_LENGTH; end |
#type_to_sql(type, limit = nil, precision = nil, scale = nil) ⇒ Object
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/arjdbc/firebird/adapter.rb', line 195 def type_to_sql(type, limit = nil, precision = nil, scale = nil) case type when :integer case limit when nil then 'integer' when 1..2 then 'smallint' when 3..4 then 'integer' when 5..8 then 'bigint' else raise(ActiveRecordError, "No integer type has byte size #{limit}. "<< "Use a NUMERIC with PRECISION 0 instead.") end when :float if limit.nil? || limit <= 4 'float' else 'double precision' end else super end end |
#update_lob_values? ⇒ Boolean
100 |
# File 'lib/arjdbc/firebird/adapter.rb', line 100 def update_lob_values?; Firebird.update_lob_values?; end |