TODO kind of standard AR configuration option for this would be nice :
only record precision and scale for types that can set them via CREATE TABLE: publib.boulder.ibm.com/infocenter/db2luw/v9r7/topic/com.ibm.db2.luw.sql.ref.doc/doc/r0000927.html
# File lib/arjdbc/db2/adapter.rb, line 55 def self.arel2_visitors(config) require 'arel/visitors/db2' { 'db2' => ::Arel::Visitors::DB2, 'as400' => ::Arel::Visitors::DB2 } end
# File lib/arjdbc/db2/adapter.rb, line 47 def self.column_selector [ /(db2|as400|zos)/, lambda { |cfg, column| column.extend(::ArJdbc::DB2::Column) } ] end
# File lib/arjdbc/db2/adapter.rb, line 22 def self.extended(base) if ADD_LOB_CALLBACK && ! lob_callback_added? ActiveRecord::Base.class_eval do def after_save_with_db2_lob lob_columns = self.class.columns.select { |c| c.sql_type =~ /blob|clob/ } lob_columns.each do |column| value = ::ArJdbc::SerializedAttributesHelper.dump_column_value(self, column) next if value.nil? # already set NULL connection.write_large_object( column.type == :binary, column.name, self.class.table_name, self.class.primary_key, quote_value(id), value ) end end alias after_save_with_db2zos_blob after_save_with_db2_lob # <-compat end # TODO this should be changed to :after_save_with_db2_lob : ActiveRecord::Base.after_save :after_save_with_db2zos_blob # <-compat lob_callback_added! end end
# File lib/arjdbc/db2/adapter.rb, line 51 def self.jdbc_connection_class ::ActiveRecord::ConnectionAdapters::DB2JdbcConnection end
# File lib/arjdbc/db2/adapter.rb, line 219 def _execute(sql, name = nil) if self.class.select?(sql) @connection.execute_query(sql) elsif self.class.insert?(sql) (@connection.execute_insert(sql) or last_insert_id(sql)).to_i else @connection.execute_update(sql) end end
# File lib/arjdbc/db2/adapter.rb, line 60 def adapter_name 'DB2' end
# File lib/arjdbc/db2/adapter.rb, line 429 def add_index(table_name, column_name, options = {}) if ! zos? || ( table_name.to_s == ActiveRecord::Migrator.schema_migrations_table_name.to_s ) column_name = column_name.to_s if column_name.is_a?(Symbol) super else statement = 'CREATE' statement << ' UNIQUE ' if options[:unique] statement << " INDEX #{ActiveRecord::Base.table_name_prefix}#{options[:name]} " statement << " ON #{table_name}(#{column_name})" execute statement end end
# File lib/arjdbc/db2/adapter.rb, line 368 def add_limit_offset!(sql, options) replace_limit_offset!(sql, options[:limit], options[:offset]) end
# File lib/arjdbc/db2/adapter.rb, line 552 def add_quotes(name) return name unless name %{"#{name}"} end
# File lib/arjdbc/db2/adapter.rb, line 25 def after_save_with_db2_lob lob_columns = self.class.columns.select { |c| c.sql_type =~ /blob|clob/ } lob_columns.each do |column| value = ::ArJdbc::SerializedAttributesHelper.dump_column_value(self, column) next if value.nil? # already set NULL connection.write_large_object( column.type == :binary, column.name, self.class.table_name, self.class.primary_key, quote_value(id), value ) end end
# File lib/arjdbc/db2/adapter.rb, line 647 def as400? return @as400 unless @as400.nil? @as400 = if url = @config[:url] !!( url =~ /^jdbc:as400:/ ) else nil end end
# File lib/arjdbc/db2/adapter.rb, line 478 def change_column(table_name, column_name, type, options = {}) data_type = type_to_sql(type, options[:limit], options[:precision], options[:scale]) sql = "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET DATA TYPE #{data_type}" as400? ? execute_and_auto_confirm(sql) : execute(sql) reorg_table(table_name) if options.include?(:default) and options.include?(:null) # which to run first? if options[:null] or options[:default].nil? change_column_null(table_name, column_name, options[:null]) change_column_default(table_name, column_name, options[:default]) else change_column_default(table_name, column_name, options[:default]) change_column_null(table_name, column_name, options[:null]) end elsif options.include?(:default) change_column_default(table_name, column_name, options[:default]) elsif options.include?(:null) change_column_null(table_name, column_name, options[:null]) end end
# File lib/arjdbc/db2/adapter.rb, line 468 def change_column_default(table_name, column_name, default) if default.nil? sql = "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} DROP DEFAULT" else sql = "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET WITH DEFAULT #{quote(default)}" end as400? ? execute_and_auto_confirm(sql) : execute(sql) reorg_table(table_name) end
# File lib/arjdbc/db2/adapter.rb, line 458 def change_column_null(table_name, column_name, null) if null sql = "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} DROP NOT NULL" else sql = "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET NOT NULL" end as400? ? execute_and_auto_confirm(sql) : execute(sql) reorg_table(table_name) end
# File lib/arjdbc/db2/adapter.rb, line 525 def columns(table_name, name = nil) columns = @connection.columns(table_name.to_s, name, db2_schema) if zos? # Remove the mighty db2_generated_rowid_for_lobs from the list of columns columns = columns.reject { |col| "db2_generated_rowid_for_lobs" == col.name } end # scrub out sizing info when CREATE TABLE doesn't support it # but JDBC reports it (doh!) for column in columns base_sql_type = column.sql_type.sub(/\(.*/, "").upcase column.limit = nil unless HAVE_LIMIT.include?(base_sql_type) column.precision = nil unless HAVE_PRECISION.include?(base_sql_type) #column.scale = nil unless HAVE_SCALE.include?(base_sql_type) end columns end
holy moly batman! all this to tell AS400 "yes i am sure"
# File lib/arjdbc/db2/adapter.rb, line 198 def execute_and_auto_confirm(sql) begin @connection.execute_update "call qsys.qcmdexc('QSYS/CHGJOB INQMSGRPY(*SYSRPYL)',0000000031.00000)" @connection.execute_update "call qsys.qcmdexc('ADDRPYLE SEQNBR(9876) MSGID(CPA32B2) RPY(''I'')',0000000045.00000)" rescue Exception => e raise "Could not call CHGJOB INQMSGRPY(*SYSRPYL) and ADDRPYLE SEQNBR(9876) MSGID(CPA32B2) RPY('I').\n" + "Do you have authority to do this?\n\n" + e.to_s end result = execute sql begin @connection.execute_update "call qsys.qcmdexc('QSYS/CHGJOB INQMSGRPY(*DFT)',0000000027.00000)" @connection.execute_update "call qsys.qcmdexc('RMVRPYLE SEQNBR(9876)',0000000021.00000)" rescue Exception => e raise "Could not call CHGJOB INQMSGRPY(*DFT) and RMVRPYLE SEQNBR(9876).\n" + "Do you have authority to do this?\n\n" + e.to_s end result end
# File lib/arjdbc/db2/adapter.rb, line 563 def expand_double_quotes(name) return name unless name && name['"'] name.gsub(/"/,'""') end
# File lib/arjdbc/db2/adapter.rb, line 18 def explain(query, *binds) # TODO: Explain this! Do not remove ! end
# File lib/arjdbc/db2/adapter.rb, line 548 def indexes(table_name, name = nil) @connection.indexes(table_name, name, db2_schema) end
# File lib/arjdbc/db2/adapter.rb, line 544 def jdbc_columns(table_name, name = nil) columns(table_name, name) end
# File lib/arjdbc/db2/adapter.rb, line 229 def last_insert_id(sql) table_name = sql.split(/\s/)[2] result = select(ActiveRecord::Base.send(:sanitize_sql, %[SELECT IDENTITY_VAL_LOCAL() AS last_insert_id FROM #{table_name}], nil)) result.last['last_insert_id'] end
# File lib/arjdbc/db2/adapter.rb, line 354 def modify_types(types) super(types) types[:primary_key] = 'int not null generated by default as identity (start with 1) primary key' types[:string][:limit] = 255 types[:integer][:limit] = nil types[:boolean] = {:name => "decimal(1)"} types end
# File lib/arjdbc/db2/adapter.rb, line 82 def native_database_types super.merge(NATIVE_DATABASE_TYPES) end
# File lib/arjdbc/db2/adapter.rb, line 193 def next_sequence_value(sequence_name) select_value("SELECT NEXT VALUE FOR #{sequence_name} FROM sysibm.sysdummy1") end
# File lib/arjdbc/db2/adapter.rb, line 292 def pk_and_sequence_for(table) # In JDBC/DB2 side, only upcase names of table and column are handled. keys = super(table.upcase) if keys && keys[0] # In ActiveRecord side, only downcase names of table and column are handled. keys[0] = keys[0].downcase end keys end
# File lib/arjdbc/db2/adapter.rb, line 177 def prefetch_primary_key?(table_name = nil) # TRUE if the table has no identity column names = table_name.upcase.split(".") sql = "" if as400? sql = "SELECT 1 FROM SYSIBM.SQLPRIMARYKEYS WHERE " sql += "TABLE_SCHEM = '#{names.first}' AND " if names.size == 2 sql += "TABLE_NAME = '#{names.last}'" else sql = "SELECT 1 FROM SYSCAT.COLUMNS WHERE IDENTITY = 'Y' " sql += "AND TABSCHEMA = '#{names.first}' " if names.size == 2 sql += "AND TABNAME = '#{names.last}'" end select_one(sql).nil? end
# File lib/arjdbc/db2/adapter.rb, line 350 def quote_column_name(column_name) column_name.to_s end
# File lib/arjdbc/db2/adapter.rb, line 425 def recreate_database(name, options = {}) tables.each { |table| drop_table("#{db2_schema}.#{table}") } end
# File lib/arjdbc/db2/adapter.rb, line 443 def remove_index(table_name, options = { }) execute "DROP INDEX #{quote_column_name(index_name(table_name, options))}" end
# File lib/arjdbc/db2/adapter.rb, line 396 def replace_limit_offset!(sql, limit, offset) if limit limit = limit.to_i if !offset if limit == 1 sql << " FETCH FIRST ROW ONLY" else sql << " FETCH FIRST #{limit} ROWS ONLY" end else offset = offset.to_i sql.sub!(/SELECT/, 'SELECT B.* FROM (SELECT A.*, row_number() over () AS internal$rownum FROM (SELECT') sql << ") A ) B WHERE B.internal$rownum > #{offset} AND B.internal$rownum <= #{limit + offset}" end end sql end
# File lib/arjdbc/db2/adapter.rb, line 421 def runstats_for_table(tablename, priority=10) @connection.execute_update "call sysproc.admin_cmd('RUNSTATS ON TABLE #{tablename} WITH DISTRIBUTION AND DETAILED INDEXES ALL UTIL_IMPACT_PRIORITY #{priority}')" end
# File lib/arjdbc/db2/adapter.rb, line 557 def strip_quotes(str) return str unless str return str unless /^(["']).*\11$$/ =~ str str[1..-2] end
# File lib/arjdbc/db2/adapter.rb, line 515 def tables @connection.tables(nil, db2_schema, nil, ["TABLE"]) end
Generated with the Darkfish Rdoc Generator 2.