diff --git a/lib/active_record/connection_adapters/fb/quoting.rb b/lib/active_record/connection_adapters/fb/quoting.rb index 16c2a9b..038fdbd 100644 --- a/lib/active_record/connection_adapters/fb/quoting.rb +++ b/lib/active_record/connection_adapters/fb/quoting.rb @@ -27,6 +27,14 @@ def quote_string(string) # :nodoc: string.gsub(/'/, "''") end + def quoted_date(time) + if time.is_a?(Time) + time.strftime("%m-%d-%Y %H:%M:%S") + else + time.strftime("%m-%d-%Y") + end + end + def quote_column_name(column_name) # :nodoc: name = ar_to_fb_case(column_name.to_s).gsub('"', '') @connection.dialect == 1 ? %Q(#{name}) : %Q("#{name}") @@ -67,10 +75,12 @@ def _quote(value) case value when Type::Binary::Data "@BINDBINARY#{Base64.encode64(value.to_s)}BINDBINARY@" - when Date, Time - "@BINDDATE#{quoted_date(value)}BINDDATE@" + when Time + "'#{value.strftime("%m-%d-%Y %H:%M")}'" + when Date + "'#{value.strftime("%m-%d-%Y")}'" else - super + super #TODO fix date that present in string end end diff --git a/lib/active_record/connection_adapters/fb/schema_statements.rb b/lib/active_record/connection_adapters/fb/schema_statements.rb index 556edea..27060c5 100644 --- a/lib/active_record/connection_adapters/fb/schema_statements.rb +++ b/lib/active_record/connection_adapters/fb/schema_statements.rb @@ -79,6 +79,23 @@ def create_table(name, options = {}) # :nodoc: return if options[:sequence] == false || !needs_sequence create_sequence(options[:sequence] || default_sequence_name(name)) + trg_sql = <<-END_SQL + CREATE TRIGGER N$#{name.upcase} FOR #{name.upcase} + ACTIVE BEFORE INSERT + AS + declare variable gen_val bigint; + BEGIN + if (new.ID is null) then + new.ID = next value for #{options[:sequence] || default_sequence_name(name)}; + else begin + gen_val = gen_id(#{options[:sequence] || default_sequence_name(name)}, 0); + if (new.ID > gen_val) then + gen_val = gen_id(#{options[:sequence] || default_sequence_name(name)}, new.ID - gen_val); + end + END + END_SQL + execute(trg_sql) + commit_db_transaction end def rename_table(name, new_name) @@ -86,12 +103,14 @@ def rename_table(name, new_name) end def drop_table(name, options = {}) # :nodoc: + super + unless options[:sequence] == false sequence_name = options[:sequence] || default_sequence_name(name) drop_sequence(sequence_name) if sequence_exists?(sequence_name) end - super + commit_db_transaction end # Creates a sequence @@ -99,6 +118,7 @@ def drop_table(name, options = {}) # :nodoc: # create_sequence('DOGS_SEQ') def create_sequence(sequence_name) execute("CREATE SEQUENCE #{sequence_name}") rescue nil + commit_db_transaction end # Drops a sequence @@ -106,6 +126,7 @@ def create_sequence(sequence_name) # drop_sequence('DOGS_SEQ') def drop_sequence(sequence_name) execute("DROP SEQUENCE #{sequence_name}") rescue nil + commit_db_transaction end # Adds a new column to the named table. @@ -117,6 +138,7 @@ def add_column(table_name, column_name, type, options = {}) create_sequence(options[:sequence] || default_sequence_name(table_name)) end + commit_db_transaction return unless options[:position] # position is 1-based but add 1 to skip id column execute(squish_sql(<<-end_sql)) @@ -124,6 +146,7 @@ def add_column(table_name, column_name, type, options = {}) ALTER COLUMN #{quote_column_name(column_name)} POSITION #{options[:position] + 1} end_sql + commit_db_transaction end def remove_column(table_name, column_name, type = nil, options = {}) @@ -134,6 +157,7 @@ def remove_column(table_name, column_name, type = nil, options = {}) end super + commit_db_transaction end # Changes the column's definition according to the new options. @@ -144,13 +168,19 @@ def remove_column(table_name, column_name, type = nil, options = {}) def change_column(table_name, column_name, type, options = {}) type_sql = type_to_sql(type, *options.values_at(:limit, :precision, :scale)) - execute(squish_sql(<<-end_sql)) + if type == :text + remove_column table_name, column_name + add_column table_name, column_name, type, options + else + execute(squish_sql(<<-end_sql)) ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} TYPE #{type_sql} - end_sql + end_sql + change_column_null(table_name, column_name, !!options[:null]) if options.key?(:null) + change_column_default(table_name, column_name, options[:default]) if options.key?(:default) + end - change_column_null(table_name, column_name, !!options[:null]) if options.key?(:null) - change_column_default(table_name, column_name, options[:default]) if options.key?(:default) + commit_db_transaction end # Sets a new default value for a column. If you want to set the default @@ -165,6 +195,7 @@ def change_column_default(table_name, column_name, default) ALTER #{quote_column_name(column_name)} SET DEFAULT #{quote(default)} end_sql + commit_db_transaction end def change_column_null(table_name, column_name, null, default = nil) @@ -176,6 +207,7 @@ def change_column_null(table_name, column_name, null, default = nil) WHERE RDB$FIELD_NAME='#{ar_to_fb_case(column_name)}' AND RDB$RELATION_NAME='#{ar_to_fb_case(table_name)}' end_sql + commit_db_transaction end # Renames a column. @@ -189,16 +221,23 @@ def rename_column(table_name, column_name, new_column_name) end_sql rename_column_indexes(table_name, column_name, new_column_name) + commit_db_transaction end def remove_index!(_table_name, index_name) #:nodoc: execute "DROP INDEX #{quote_column_name(index_name)}" + commit_db_transaction end def index_name(table_name, options) #:nodoc: if options.respond_to?(:keys) # legacy support if options[:column] - "#{table_name}_#{Array.wrap(options[:column]) * '_'}" + index_name = "#{table_name}_#{Array.wrap(options[:column]) * '_'}" + if index_name.length > 31 + "IDX_#{Digest::SHA256.hexdigest(index_name)[0..22]}" + else + index_name + end elsif options[:name] options[:name] else