| Class | ActiveRecord::ConnectionAdapters::FrontBaseAdapter |
| In: |
vendor/rails/activerecord/lib/active_record/connection_adapters/frontbase_adapter.rb
|
| Parent: | AbstractAdapter |
| update | -> | delete |
# File vendor/rails/activerecord/lib/active_record/connection_adapters/frontbase_adapter.rb, line 237
237: def compare_versions(v1, v2)
238: v1_seg = v1.split(".")
239: v2_seg = v2.split(".")
240: 0.upto([v1_seg.length,v2_seg.length].min) do |i|
241: step = (v1_seg[i].to_i <=> v2_seg[i].to_i)
242: return step unless step == 0
243: end
244: return v1_seg.length <=> v2_seg.length
245: end
# File vendor/rails/activerecord/lib/active_record/connection_adapters/frontbase_adapter.rb, line 248
248: def initialize(connection, logger, connection_options, config)
249: super(connection, logger)
250: @connection_options, @config = connection_options, config
251: @transaction_mode = :pessimistic
252:
253: # Start out in auto-commit mode
254: self.rollback_db_transaction
255:
256: # threaded_connections_test.rb will fail unless we set the session
257: # to optimistic locking mode
258: # set_pessimistic_transactions
259: # execute "SET TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ WRITE, LOCKING OPTIMISTIC"
260: end
CONNECTION MANAGEMENT ====================================
# File vendor/rails/activerecord/lib/active_record/connection_adapters/frontbase_adapter.rb, line 432
432: def active?
433: true if @connection.status == 1
434: rescue => e
435: false
436: end
Adds a new column to the named table. See TableDefinition#column for details of the options you can use.
# File vendor/rails/activerecord/lib/active_record/connection_adapters/frontbase_adapter.rb, line 792
792: def add_column(table_name, column_name, type, options = {})
793: add_column_sql = "ALTER TABLE #{table_name} ADD #{column_name} #{type_to_sql(type, options[:limit])}"
794: options[:type] = type
795: add_column_options!(add_column_sql, options)
796: execute(add_column_sql)
797: end
# File vendor/rails/activerecord/lib/active_record/connection_adapters/frontbase_adapter.rb, line 567
567: def add_limit_offset!(sql, options) #:nodoc
568: if limit = options[:limit]
569: offset = options[:offset] || 0
570:
571: # Here is the full syntax FrontBase supports:
572: # (from gclem@frontbase.com)
573: #
574: # TOP <limit - unsigned integer>
575: # TOP ( <offset expr>, <limit expr>)
576:
577: # "TOP 0" is not allowed, so we have
578: # to use a cheap trick.
579: if limit.zero?
580: case sql
581: when /WHERE/i
582: sql.sub!(/WHERE/i, 'WHERE 0 = 1 AND ')
583: when /ORDER\s+BY/i
584: sql.sub!(/ORDER\s+BY/i, 'WHERE 0 = 1 ORDER BY')
585: else
586: sql << 'WHERE 0 = 1'
587: end
588: else
589: if offset.zero?
590: sql.replace sql.gsub("SELECT ","SELECT TOP #{limit} ")
591: else
592: sql.replace sql.gsub("SELECT ","SELECT TOP(#{offset},#{limit}) ")
593: end
594: end
595: end
596: end
# File vendor/rails/activerecord/lib/active_record/connection_adapters/frontbase_adapter.rb, line 625
625: def classes_for_table_name(table)
626: ActiveRecord::Base.send(:subclasses).select {|klass| klass.table_name == table}
627: end
# File vendor/rails/activerecord/lib/active_record/connection_adapters/frontbase_adapter.rb, line 748
748: def create_table(name, options = {})
749: table_definition = TableDefinition.new(self)
750: table_definition.primary_key(options[:primary_key] || "id") unless options[:id] == false
751:
752: yield table_definition
753:
754: if options[:force]
755: drop_table(name) rescue nil
756: end
757:
758: create_sql = "CREATE#{' TEMPORARY' if options[:temporary]} TABLE "
759: create_sql << "#{name} ("
760: create_sql << table_definition.to_sql
761: create_sql << ") #{options[:options]}"
762: begin_db_transaction
763: execute create_sql
764: commit_db_transaction
765: rescue ActiveRecord::StatementInvalid => e
766: raise e unless e.message.match(/Table name - \w* - exists/)
767: end
# File vendor/rails/activerecord/lib/active_record/connection_adapters/frontbase_adapter.rb, line 660
660: def current_database
661: select_value('SELECT "CATALOG_NAME" FROM INFORMATION_SCHEMA.CATALOGS').downcase
662: end
# File vendor/rails/activerecord/lib/active_record/connection_adapters/frontbase_adapter.rb, line 611
611: def default_sequence_name(table, column)
612: table
613: end
Close this connection
# File vendor/rails/activerecord/lib/active_record/connection_adapters/frontbase_adapter.rb, line 444
444: def disconnect!
445: @connection.close rescue nil
446: @active = false
447: end
Drops a table from the database.
# File vendor/rails/activerecord/lib/active_record/connection_adapters/frontbase_adapter.rb, line 784
784: def drop_table(name)
785: execute "DROP TABLE #{name} RESTRICT"
786: rescue ActiveRecord::StatementInvalid => e
787: raise e unless e.message.match(/Referenced TABLE - \w* - does not exist/)
788: end
# File vendor/rails/activerecord/lib/active_record/connection_adapters/frontbase_adapter.rb, line 274
274: def native_database_types #:nodoc
275: {
276: :primary_key => "INTEGER DEFAULT UNIQUE PRIMARY KEY",
277: :string => { :name => "VARCHAR", :limit => 255 },
278: :text => { :name => "CLOB" },
279: :integer => { :name => "INTEGER" },
280: :float => { :name => "FLOAT" },
281: :decimal => { :name => "DECIMAL" },
282: :datetime => { :name => "TIMESTAMP" },
283: :timestamp => { :name => "TIMESTAMP" },
284: :time => { :name => "TIME" },
285: :date => { :name => "DATE" },
286: :binary => { :name => "BLOB" },
287: :boolean => { :name => "BOOLEAN" },
288: :twelvebytekey => { :name => "BYTE", :limit => 12}
289: }
290: end
Returns the next sequence value from a sequence generator. Not generally called directly; used by ActiveRecord to get the next primary key value when inserting a new database record (see prefetch_primary_key?).
# File vendor/rails/activerecord/lib/active_record/connection_adapters/frontbase_adapter.rb, line 605
605: def next_sequence_value(sequence_name)
606: unique = select_value("SELECT UNIQUE FROM #{sequence_name}","Next Sequence Value")
607: # The test cases cannot handle a zero primary key
608: unique.zero? ? select_value("SELECT UNIQUE FROM #{sequence_name}","Next Sequence Value") : unique
609: end
# File vendor/rails/activerecord/lib/active_record/connection_adapters/frontbase_adapter.rb, line 598
598: def prefetch_primary_key?(table_name = nil)
599: true
600: end
Quotes the column value to help prevent SQL injection attacks.
# File vendor/rails/activerecord/lib/active_record/connection_adapters/frontbase_adapter.rb, line 297
297: def quote(value, column = nil)
298: return value.quoted_id if value.respond_to?(:quoted_id)
299:
300: retvalue = "<INVALID>"
301:
302: puts "quote(#{value.inspect}(#{value.class}),#{column.type.inspect})" if FB_TRACE
303: # If a column was passed in, use column type information
304: unless value.nil?
305: if column
306: retvalue = case column.type
307: when :string
308: if value.kind_of?(String)
309: "'#{quote_string(value.to_s)}'" # ' (for ruby-mode)
310: else
311: "'#{quote_string(value.to_yaml)}'"
312: end
313: when :integer
314: if value.kind_of?(TrueClass)
315: '1'
316: elsif value.kind_of?(FalseClass)
317: '0'
318: else
319: value.to_i.to_s
320: end
321: when :float
322: value.to_f.to_s
323: when :decimal
324: value.to_d.to_s("F")
325: when :datetime, :timestamp
326: "TIMESTAMP '#{value.strftime("%Y-%m-%d %H:%M:%S")}'"
327: when :time
328: "TIME '#{value.strftime("%H:%M:%S")}'"
329: when :date
330: "DATE '#{value.strftime("%Y-%m-%d")}'"
331: when :twelvebytekey
332: value = value.to_s.unpack("H*").first unless value.kind_of?(TwelveByteKey)
333: "X'#{value.to_s}'"
334: when :boolean
335: value = quoted_true if value.kind_of?(TrueClass)
336: value = quoted_false if value.kind_of?(FalseClass)
337: value
338: when :binary
339: blob_handle = @connection.create_blob(value.to_s)
340: puts "SQL -> Insert #{value.to_s.length} byte blob as #{retvalue}" if FB_TRACE
341: blob_handle.handle
342: when :text
343: if value.kind_of?(String)
344: clobdata = value.to_s # ' (for ruby-mode)
345: else
346: clobdata = value.to_yaml
347: end
348: clob_handle = @connection.create_clob(clobdata)
349: puts "SQL -> Insert #{value.to_s.length} byte clob as #{retvalue}" if FB_TRACE
350: clob_handle.handle
351: else
352: raise "*** UNKNOWN TYPE: #{column.type.inspect}"
353: end # case
354: # Since we don't have column type info, make a best guess based
355: # on the Ruby class of the value
356: else
357: retvalue = case value
358: when ActiveRecord::ConnectionAdapters::TwelveByteKey
359: s = value.unpack("H*").first
360: "X'#{s}'"
361: when String
362: if column && column.type == :binary
363: s = value.unpack("H*").first
364: "X'#{s}'"
365: elsif column && [:integer, :float, :decimal].include?(column.type)
366: value.to_s
367: else
368: "'#{quote_string(value)}'" # ' (for ruby-mode)
369: end
370: when NilClass
371: "NULL"
372: when TrueClass
373: (column && column.type == :integer ? '1' : quoted_true)
374: when FalseClass
375: (column && column.type == :integer ? '0' : quoted_false)
376: when Float, Fixnum, Bignum, BigDecimal
377: value.to_s
378: when Time, Date, DateTime
379: if column
380: case column.type
381: when :date
382: "DATE '#{value.strftime("%Y-%m-%d")}'"
383: when :time
384: "TIME '#{value.strftime("%H:%M:%S")}'"
385: when :timestamp
386: "TIMESTAMP '#{value.strftime("%Y-%m-%d %H:%M:%S")}'"
387: else
388: raise NotImplementedError, "Unknown column type!"
389: end # case
390: else # Column wasn't passed in, so try to guess the right type
391: if value.kind_of? Date
392: "DATE '#{value.strftime("%Y-%m-%d")}'"
393: else
394: if [:hour, :min, :sec].all? {|part| value.send(:part).zero? }
395: "TIME '#{value.strftime("%H:%M:%S")}'"
396: else
397: "TIMESTAMP '#{quoted_date(value)}'"
398: end
399: end
400: end #if column
401: else
402: "'#{quote_string(value.to_yaml)}'"
403: end #case
404: end
405: else
406: retvalue = "NULL"
407: end
408:
409: retvalue
410: end
Quotes a string, escaping any ’ (single quote) characters.
# File vendor/rails/activerecord/lib/active_record/connection_adapters/frontbase_adapter.rb, line 413
413: def quote_string(s)
414: s.gsub(/'/, "''") # ' (for ruby-mode)
415: end
# File vendor/rails/activerecord/lib/active_record/connection_adapters/frontbase_adapter.rb, line 425
425: def quoted_false
426: "false"
427: end
# File vendor/rails/activerecord/lib/active_record/connection_adapters/frontbase_adapter.rb, line 421
421: def quoted_true
422: "true"
423: end
# File vendor/rails/activerecord/lib/active_record/connection_adapters/frontbase_adapter.rb, line 438
438: def reconnect!
439: @connection.close rescue nil
440: @connection = FBSQL_Connect.connect(*@connection_options.first(7))
441: end
Removes the column from the table definition.
remove_column(:suppliers, :qualification)
# File vendor/rails/activerecord/lib/active_record/connection_adapters/frontbase_adapter.rb, line 813
813: def remove_column(table_name, column_name)
814: execute "ALTER TABLE #{table_name} DROP #{column_name} RESTRICT"
815: end
# File vendor/rails/activerecord/lib/active_record/connection_adapters/frontbase_adapter.rb, line 769
769: def rename_table(name, new_name)
770: columns = columns(name)
771: pkcol = columns.find {|c| c.fb_autogen}
772: execute "ALTER TABLE NAME #{name} TO #{new_name}"
773: if pkcol
774: change_column_default(new_name,pkcol.name,"UNIQUE")
775: begin_db_transaction
776: mpk = select_value("SELECT MAX(#{pkcol.name}) FROM #{new_name}")
777: mpk = 0 if mpk.nil?
778: execute "SET UNIQUE=#{mpk} FOR #{new_name}"
779: commit_db_transaction
780: end
781: end
# File vendor/rails/activerecord/lib/active_record/connection_adapters/frontbase_adapter.rb, line 629
629: def reset_pk_sequence!(table, pk = nil, sequence = nil)
630: klasses = classes_for_table_name(table)
631: klass = klasses.nil? ? nil : klasses.first
632: pk = klass.primary_key unless klass.nil?
633: if pk && klass.columns_hash[pk].type == :integer
634: mpk = select_value("SELECT MAX(#{pk}) FROM #{table}")
635: execute("SET UNIQUE FOR #{klass.table_name}(#{pk})")
636: end
637: end
Set the sequence to the max value of the table’s column.
# File vendor/rails/activerecord/lib/active_record/connection_adapters/frontbase_adapter.rb, line 616
616: def reset_sequence!(table, column, sequence = nil)
617: klasses = classes_for_table_name(table)
618: klass = klasses.nil? ? nil : klasses.first
619: pk = klass.primary_key unless klass.nil?
620: if pk && klass.columns_hash[pk].type == :integer
621: execute("SET UNIQUE FOR #{klass.table_name}(#{pk})")
622: end
623: end
# File vendor/rails/activerecord/lib/active_record/connection_adapters/frontbase_adapter.rb, line 544
544: def set_optimistic_transactions
545: if @transaction_mode == :pessimistic
546: execute "SET TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ WRITE, LOCKING OPTIMISTIC"
547: @transaction_mode = :optimistic
548: end
549: end
# File vendor/rails/activerecord/lib/active_record/connection_adapters/frontbase_adapter.rb, line 537
537: def set_pessimistic_transactions
538: if @transaction_mode == :optimistic
539: execute "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, LOCKING PESSIMISTIC, READ WRITE"
540: @transaction_mode = :pessimistic
541: end
542: end