ibm_db 5.5.0-x86-mingw32 → 5.6.1-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/CHANGES +12 -0
 - data/README +1 -0
 - data/ext/Makefile +9 -9
 - data/ext/extconf.rb +12 -3
 - data/ext/ibm_db.c +15 -29
 - data/ext/ibm_db.o +0 -0
 - data/ext/ibm_db.so +0 -0
 - data/ext/mkmf.log +5 -5
 - data/ext/ruby_ibm_db_cli.c +1 -1
 - data/ext/ruby_ibm_db_cli.h +8 -0
 - data/ext/ruby_ibm_db_cli.o +0 -0
 - data/lib/IBM_DB.rb +1 -1
 - data/lib/active_record/connection_adapters/ibm_db_adapter.rb +478 -407
 - data/lib/mswin32/ibm_db.rb +5 -1
 - data/lib/mswin32/rb3x/i386/ruby33/ibm_db.so +0 -0
 - metadata +14 -14
 - data/lib/mswin32/rb3x/i386/ruby32/ibm_db.so +0 -0
 
| 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # +----------------------------------------------------------------------+
         
     | 
| 
       2 
2 
     | 
    
         
             
            # |  Licensed Materials - Property of IBM                                |
         
     | 
| 
       3 
3 
     | 
    
         
             
            # |                                                                      |
         
     | 
| 
       4 
     | 
    
         
            -
            # | (C) Copyright IBM Corporation 2006 -  
     | 
| 
      
 4 
     | 
    
         
            +
            # | (C) Copyright IBM Corporation 2006 - 2025          					 |
         
     | 
| 
       5 
5 
     | 
    
         
             
            # +----------------------------------------------------------------------+
         
     | 
| 
       6 
6 
     | 
    
         
             
            # |  Authors: Antonio Cangiano <cangiano@ca.ibm.com>                     |
         
     | 
| 
       7 
7 
     | 
    
         
             
            # |         : Mario Ds Briggs  <mario.briggs@in.ibm.com>                 |
         
     | 
| 
         @@ -17,6 +17,76 @@ require 'active_record/connection_adapters/sql_type_metadata' 
     | 
|
| 
       17 
17 
     | 
    
         
             
            require 'active_record/connection_adapters/statement_pool'
         
     | 
| 
       18 
18 
     | 
    
         
             
            require 'active_record/connection_adapters'
         
     | 
| 
       19 
19 
     | 
    
         | 
| 
      
 20 
     | 
    
         
            +
            # Ensure ActiveRecord and Rails Generators are loaded
         
     | 
| 
      
 21 
     | 
    
         
            +
            require "active_record"
         
     | 
| 
      
 22 
     | 
    
         
            +
            ActiveRecord::ConnectionAdapters.register(
         
     | 
| 
      
 23 
     | 
    
         
            +
              "ibm_db",
         
     | 
| 
      
 24 
     | 
    
         
            +
              "ActiveRecord::ConnectionAdapters::IBM_DBAdapter",
         
     | 
| 
      
 25 
     | 
    
         
            +
              "active_record/connection_adapters/ibm_db_adapter"
         
     | 
| 
      
 26 
     | 
    
         
            +
            )
         
     | 
| 
      
 27 
     | 
    
         
            +
            require "rails/generators/database"
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            module Rails
         
     | 
| 
      
 30 
     | 
    
         
            +
              module Generators
         
     | 
| 
      
 31 
     | 
    
         
            +
                class Database
         
     | 
| 
      
 32 
     | 
    
         
            +
                  DATABASES << "ibm_db" unless DATABASES.include?("ibm_db")
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                  class << self
         
     | 
| 
      
 35 
     | 
    
         
            +
                    alias_method :original_build, :build
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                    def build(database_name)
         
     | 
| 
      
 38 
     | 
    
         
            +
                      return IBMDB.new if database_name == "ibm_db"
         
     | 
| 
      
 39 
     | 
    
         
            +
                      original_build(database_name)
         
     | 
| 
      
 40 
     | 
    
         
            +
                    end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                    alias_method :original_all, :all
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                    def all
         
     | 
| 
      
 45 
     | 
    
         
            +
                      original_all + [IBMDB.new]
         
     | 
| 
      
 46 
     | 
    
         
            +
                    end
         
     | 
| 
      
 47 
     | 
    
         
            +
                  end
         
     | 
| 
      
 48 
     | 
    
         
            +
                end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                class IBMDB < Database
         
     | 
| 
      
 51 
     | 
    
         
            +
                  def name
         
     | 
| 
      
 52 
     | 
    
         
            +
                    "ibm_db"
         
     | 
| 
      
 53 
     | 
    
         
            +
                  end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                  def service
         
     | 
| 
      
 56 
     | 
    
         
            +
                    {
         
     | 
| 
      
 57 
     | 
    
         
            +
                      "image" => "ibm_db:latest",
         
     | 
| 
      
 58 
     | 
    
         
            +
                      "restart" => "unless-stopped",
         
     | 
| 
      
 59 
     | 
    
         
            +
                      "networks" => ["default"],
         
     | 
| 
      
 60 
     | 
    
         
            +
                      "volumes" => ["ibm-db-data:/var/lib/ibmdb"],
         
     | 
| 
      
 61 
     | 
    
         
            +
                      "environment" => {
         
     | 
| 
      
 62 
     | 
    
         
            +
                        "IBM_DB_ALLOW_EMPTY_PASSWORD" => "true",
         
     | 
| 
      
 63 
     | 
    
         
            +
                      }
         
     | 
| 
      
 64 
     | 
    
         
            +
                    }
         
     | 
| 
      
 65 
     | 
    
         
            +
                  end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                  def port
         
     | 
| 
      
 68 
     | 
    
         
            +
                    nil  # Default DB2 port
         
     | 
| 
      
 69 
     | 
    
         
            +
                  end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                  def gem
         
     | 
| 
      
 72 
     | 
    
         
            +
                    ["ibm_db", [">= 5.5"]]
         
     | 
| 
      
 73 
     | 
    
         
            +
                  end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                  def base_package
         
     | 
| 
      
 76 
     | 
    
         
            +
                    nil
         
     | 
| 
      
 77 
     | 
    
         
            +
                  end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                  def build_package
         
     | 
| 
      
 80 
     | 
    
         
            +
                    nil
         
     | 
| 
      
 81 
     | 
    
         
            +
                  end
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                  def feature_name
         
     | 
| 
      
 84 
     | 
    
         
            +
                    nil
         
     | 
| 
      
 85 
     | 
    
         
            +
                  end
         
     | 
| 
      
 86 
     | 
    
         
            +
                end
         
     | 
| 
      
 87 
     | 
    
         
            +
              end
         
     | 
| 
      
 88 
     | 
    
         
            +
            end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
       20 
90 
     | 
    
         
             
            module CallChain
         
     | 
| 
       21 
91 
     | 
    
         
             
              def self.caller_method(depth = 1)
         
     | 
| 
       22 
92 
     | 
    
         
             
                parse_caller(caller(depth + 1).first).last
         
     | 
| 
         @@ -48,7 +118,7 @@ module ActiveRecord 
     | 
|
| 
       48 
118 
     | 
    
         | 
| 
       49 
119 
     | 
    
         
             
              module Persistence
         
     | 
| 
       50 
120 
     | 
    
         
             
                module ClassMethods
         
     | 
| 
       51 
     | 
    
         
            -
                  def _insert_record(values, returning) # :nodoc:
         
     | 
| 
      
 121 
     | 
    
         
            +
                  def _insert_record(connection, values, returning) # :nodoc:
         
     | 
| 
       52 
122 
     | 
    
         
             
                    primary_key = self.primary_key
         
     | 
| 
       53 
123 
     | 
    
         
             
                    primary_key_value = nil
         
     | 
| 
       54 
124 
     | 
    
         | 
| 
         @@ -61,16 +131,18 @@ module ActiveRecord 
     | 
|
| 
       61 
131 
     | 
    
         | 
| 
       62 
132 
     | 
    
         
             
                    im = Arel::InsertManager.new(arel_table)
         
     | 
| 
       63 
133 
     | 
    
         | 
| 
       64 
     | 
    
         
            -
                     
     | 
| 
       65 
     | 
    
         
            -
                       
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
                       
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
      
 134 
     | 
    
         
            +
                    with_connection do |c|
         
     | 
| 
      
 135 
     | 
    
         
            +
                      if values.empty?
         
     | 
| 
      
 136 
     | 
    
         
            +
                        im.insert(connection.empty_insert_statement_value(primary_key, arel_table[name].relation.name))
         
     | 
| 
      
 137 
     | 
    
         
            +
                      else
         
     | 
| 
      
 138 
     | 
    
         
            +
                        im.insert(values.transform_keys { |name| arel_table[name] })
         
     | 
| 
      
 139 
     | 
    
         
            +
                      end
         
     | 
| 
       69 
140 
     | 
    
         | 
| 
       70 
     | 
    
         
            -
             
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
     | 
    
         
            -
             
     | 
| 
      
 141 
     | 
    
         
            +
                      connection.insert(
         
     | 
| 
      
 142 
     | 
    
         
            +
                        im, "#{self} Create", primary_key || false, primary_key_value,
         
     | 
| 
      
 143 
     | 
    
         
            +
                        returning: returning
         
     | 
| 
      
 144 
     | 
    
         
            +
                      )
         
     | 
| 
      
 145 
     | 
    
         
            +
                    end
         
     | 
| 
       74 
146 
     | 
    
         
             
                  end
         
     | 
| 
       75 
147 
     | 
    
         
             
                end
         
     | 
| 
       76 
148 
     | 
    
         
             
              end
         
     | 
| 
         @@ -145,6 +217,9 @@ module ActiveRecord 
     | 
|
| 
       145 
217 
     | 
    
         
             
                  end
         
     | 
| 
       146 
218 
     | 
    
         | 
| 
       147 
219 
     | 
    
         
             
                  def visit_ColumnDefinition(o)
         
     | 
| 
      
 220 
     | 
    
         
            +
                    if @conn.instance_of? IBM_DBAdapter
         
     | 
| 
      
 221 
     | 
    
         
            +
                      @conn.puts_log "visit_ColumnDefinition #{o.name} #{o} #{@conn} #{@conn.servertype}"
         
     | 
| 
      
 222 
     | 
    
         
            +
                    end
         
     | 
| 
       148 
223 
     | 
    
         
             
                    o.sql_type = type_to_sql(o.type, **o.options)
         
     | 
| 
       149 
224 
     | 
    
         
             
                    column_sql = +"#{quote_column_name(o.name)} #{o.sql_type}"
         
     | 
| 
       150 
225 
     | 
    
         
             
                    add_column_options!(column_sql, column_options(o))
         
     | 
| 
         @@ -220,41 +295,6 @@ module ActiveRecord 
     | 
|
| 
       220 
295 
     | 
    
         
             
                end
         
     | 
| 
       221 
296 
     | 
    
         
             
              end
         
     | 
| 
       222 
297 
     | 
    
         | 
| 
       223 
     | 
    
         
            -
              class Relation
         
     | 
| 
       224 
     | 
    
         
            -
                def insert(values)
         
     | 
| 
       225 
     | 
    
         
            -
                  primary_key_value = nil
         
     | 
| 
       226 
     | 
    
         
            -
             
     | 
| 
       227 
     | 
    
         
            -
                  if primary_key && values.is_a?(Hash)
         
     | 
| 
       228 
     | 
    
         
            -
                    primary_key_value = values[values.keys.find do |k|
         
     | 
| 
       229 
     | 
    
         
            -
                      k.name == primary_key
         
     | 
| 
       230 
     | 
    
         
            -
                    end]
         
     | 
| 
       231 
     | 
    
         
            -
             
     | 
| 
       232 
     | 
    
         
            -
                    if !primary_key_value && connection.prefetch_primary_key?(klass.table_name)
         
     | 
| 
       233 
     | 
    
         
            -
                      primary_key_value = connection.next_sequence_value(klass.sequence_name)
         
     | 
| 
       234 
     | 
    
         
            -
                      values[klass.arel_table[klass.primary_key]] = primary_key_value
         
     | 
| 
       235 
     | 
    
         
            -
                    end
         
     | 
| 
       236 
     | 
    
         
            -
                  end
         
     | 
| 
       237 
     | 
    
         
            -
             
     | 
| 
       238 
     | 
    
         
            -
                  im = arel.create_insert
         
     | 
| 
       239 
     | 
    
         
            -
                  im.into @table
         
     | 
| 
       240 
     | 
    
         
            -
             
     | 
| 
       241 
     | 
    
         
            -
                  conn = @klass.connection
         
     | 
| 
       242 
     | 
    
         
            -
                  substitutes = values.sort_by { |arel_attr, _| arel_attr.name }
         
     | 
| 
       243 
     | 
    
         
            -
                  binds       = substitutes.map do |arel_attr, value|
         
     | 
| 
       244 
     | 
    
         
            -
                    [@klass.columns_hash[arel_attr.name], value]
         
     | 
| 
       245 
     | 
    
         
            -
                  end
         
     | 
| 
       246 
     | 
    
         
            -
             
     | 
| 
       247 
     | 
    
         
            -
                  substitutes, binds = substitute_values values
         
     | 
| 
       248 
     | 
    
         
            -
                  if values.empty? # empty insert
         
     | 
| 
       249 
     | 
    
         
            -
                    im.values = Arel.sql(connection.empty_insert_statement_value(klass.primary_key, klass.table_name))
         
     | 
| 
       250 
     | 
    
         
            -
                  else
         
     | 
| 
       251 
     | 
    
         
            -
                    im.insert substitutes
         
     | 
| 
       252 
     | 
    
         
            -
                  end
         
     | 
| 
       253 
     | 
    
         
            -
             
     | 
| 
       254 
     | 
    
         
            -
                  conn.insert(im, 'SQL', primary_key, primary_key_value, nil, binds)
         
     | 
| 
       255 
     | 
    
         
            -
                end
         
     | 
| 
       256 
     | 
    
         
            -
              end
         
     | 
| 
       257 
     | 
    
         
            -
             
     | 
| 
       258 
298 
     | 
    
         
             
              class Base
         
     | 
| 
       259 
299 
     | 
    
         
             
                # Method required to handle LOBs and XML fields.
         
     | 
| 
       260 
300 
     | 
    
         
             
                # An after save callback checks if a marker has been inserted through
         
     | 
| 
         @@ -262,87 +302,91 @@ module ActiveRecord 
     | 
|
| 
       262 
302 
     | 
    
         
             
                # the actual large object through a prepared statement (param binding).
         
     | 
| 
       263 
303 
     | 
    
         
             
                after_save :handle_lobs
         
     | 
| 
       264 
304 
     | 
    
         
             
                def handle_lobs
         
     | 
| 
       265 
     | 
    
         
            -
                  return unless self.class. 
     | 
| 
       266 
     | 
    
         
            -
             
     | 
| 
       267 
     | 
    
         
            -
                   
     | 
| 
       268 
     | 
    
         
            -
             
     | 
| 
       269 
     | 
    
         
            -
             
     | 
| 
       270 
     | 
    
         
            -
             
     | 
| 
       271 
     | 
    
         
            -
             
     | 
| 
       272 
     | 
    
         
            -
             
     | 
| 
       273 
     | 
    
         
            -
             
     | 
| 
       274 
     | 
    
         
            -
             
     | 
| 
       275 
     | 
    
         
            -
             
     | 
| 
       276 
     | 
    
         
            -
             
     | 
| 
       277 
     | 
    
         
            -
             
     | 
| 
       278 
     | 
    
         
            -
             
     | 
| 
       279 
     | 
    
         
            -
             
     | 
| 
       280 
     | 
    
         
            -
             
     | 
| 
       281 
     | 
    
         
            -
             
     | 
| 
      
 305 
     | 
    
         
            +
            #      return unless self.class.with_connection.is_a?(ConnectionAdapters::IBM_DBAdapter)
         
     | 
| 
      
 306 
     | 
    
         
            +
             
     | 
| 
      
 307 
     | 
    
         
            +
                  self.class.with_connection do |conn|
         
     | 
| 
      
 308 
     | 
    
         
            +
                    if conn.is_a?(ConnectionAdapters::IBM_DBAdapter)
         
     | 
| 
      
 309 
     | 
    
         
            +
                      # Checks that the insert or update had at least a BLOB, CLOB or XML field
         
     | 
| 
      
 310 
     | 
    
         
            +
                      conn.sql.each do |clob_sql|
         
     | 
| 
      
 311 
     | 
    
         
            +
                        next unless clob_sql =~ /BLOB\('(.*)'\)/i ||
         
     | 
| 
      
 312 
     | 
    
         
            +
                                    clob_sql =~ /@@@IBMTEXT@@@/i  ||
         
     | 
| 
      
 313 
     | 
    
         
            +
                                    clob_sql =~ /@@@IBMXML@@@/i   ||
         
     | 
| 
      
 314 
     | 
    
         
            +
                                    clob_sql =~ /@@@IBMBINARY@@@/i
         
     | 
| 
      
 315 
     | 
    
         
            +
             
     | 
| 
      
 316 
     | 
    
         
            +
                        update_query = "UPDATE #{self.class.table_name} SET ("
         
     | 
| 
      
 317 
     | 
    
         
            +
                        counter = 0
         
     | 
| 
      
 318 
     | 
    
         
            +
                        values = []
         
     | 
| 
      
 319 
     | 
    
         
            +
                        params = []
         
     | 
| 
      
 320 
     | 
    
         
            +
                        # Selects only binary, text and xml columns
         
     | 
| 
      
 321 
     | 
    
         
            +
                        self.class.columns.select { |col| col.sql_type.to_s =~ /blob|binary|clob|text|xml/i }.each do |col|
         
     | 
| 
      
 322 
     | 
    
         
            +
                          update_query << if counter.zero?
         
     | 
| 
      
 323 
     | 
    
         
            +
                                            "#{col.name}".to_s
         
     | 
| 
      
 324 
     | 
    
         
            +
                                          else
         
     | 
| 
      
 325 
     | 
    
         
            +
                                            ",#{col.name}".to_s
         
     | 
| 
      
 326 
     | 
    
         
            +
                                          end
         
     | 
| 
      
 327 
     | 
    
         
            +
             
     | 
| 
      
 328 
     | 
    
         
            +
                          # Add a '?' for the parameter or a NULL if the value is nil or empty
         
     | 
| 
      
 329 
     | 
    
         
            +
                          # (except for a CLOB field where '' can be a value)
         
     | 
| 
      
 330 
     | 
    
         
            +
                          if self[col.name].nil?  ||
         
     | 
| 
      
 331 
     | 
    
         
            +
                             self[col.name] == {} ||
         
     | 
| 
      
 332 
     | 
    
         
            +
                             self[col.name] == [] ||
         
     | 
| 
      
 333 
     | 
    
         
            +
                             (self[col.name] == '' && !(col.sql_type.to_s =~ /text|clob/i))
         
     | 
| 
      
 334 
     | 
    
         
            +
                            params << 'NULL'
         
     | 
| 
      
 335 
     | 
    
         
            +
                          else
         
     | 
| 
      
 336 
     | 
    
         
            +
                            values << if col.cast_type.is_a?(::ActiveRecord::Type::Serialized)
         
     | 
| 
      
 337 
     | 
    
         
            +
                                        YAML.dump(self[col.name])
         
     | 
| 
       282 
338 
     | 
    
         
             
                                      else
         
     | 
| 
       283 
     | 
    
         
            -
                                         
     | 
| 
      
 339 
     | 
    
         
            +
                                        self[col.name]
         
     | 
| 
       284 
340 
     | 
    
         
             
                                      end
         
     | 
| 
      
 341 
     | 
    
         
            +
                            params << '?'
         
     | 
| 
      
 342 
     | 
    
         
            +
                          end
         
     | 
| 
      
 343 
     | 
    
         
            +
                          counter += 1
         
     | 
| 
      
 344 
     | 
    
         
            +
                        end
         
     | 
| 
       285 
345 
     | 
    
         | 
| 
       286 
     | 
    
         
            -
             
     | 
| 
       287 
     | 
    
         
            -
             
     | 
| 
       288 
     | 
    
         
            -
                      if self[col.name].nil?  ||
         
     | 
| 
       289 
     | 
    
         
            -
                         self[col.name] == {} ||
         
     | 
| 
       290 
     | 
    
         
            -
                         self[col.name] == [] ||
         
     | 
| 
       291 
     | 
    
         
            -
                         (self[col.name] == '' && !(col.sql_type.to_s =~ /text|clob/i))
         
     | 
| 
       292 
     | 
    
         
            -
                        params << 'NULL'
         
     | 
| 
       293 
     | 
    
         
            -
                      else
         
     | 
| 
       294 
     | 
    
         
            -
                        values << if col.cast_type.is_a?(::ActiveRecord::Type::Serialized)
         
     | 
| 
       295 
     | 
    
         
            -
                                    YAML.dump(self[col.name])
         
     | 
| 
       296 
     | 
    
         
            -
                                  else
         
     | 
| 
       297 
     | 
    
         
            -
                                    self[col.name]
         
     | 
| 
       298 
     | 
    
         
            -
                                  end
         
     | 
| 
       299 
     | 
    
         
            -
                        params << '?'
         
     | 
| 
       300 
     | 
    
         
            -
                      end
         
     | 
| 
       301 
     | 
    
         
            -
                      counter += 1
         
     | 
| 
       302 
     | 
    
         
            -
                    end
         
     | 
| 
       303 
     | 
    
         
            -
             
     | 
| 
       304 
     | 
    
         
            -
                    # no subsequent update is required if no relevant columns are found
         
     | 
| 
       305 
     | 
    
         
            -
                    next if counter.zero?
         
     | 
| 
      
 346 
     | 
    
         
            +
                        # no subsequent update is required if no relevant columns are found
         
     | 
| 
      
 347 
     | 
    
         
            +
                        next if counter.zero?
         
     | 
| 
       306 
348 
     | 
    
         | 
| 
       307 
     | 
    
         
            -
             
     | 
| 
       308 
     | 
    
         
            -
             
     | 
| 
       309 
     | 
    
         
            -
             
     | 
| 
       310 
     | 
    
         
            -
             
     | 
| 
       311 
     | 
    
         
            -
             
     | 
| 
       312 
     | 
    
         
            -
             
     | 
| 
       313 
     | 
    
         
            -
             
     | 
| 
       314 
     | 
    
         
            -
             
     | 
| 
      
 349 
     | 
    
         
            +
                        update_query << ') = '
         
     | 
| 
      
 350 
     | 
    
         
            +
                        # IBM_DB accepts 'SET (column) = NULL'  but not (NULL),
         
     | 
| 
      
 351 
     | 
    
         
            +
                        # therefore the sql needs to be changed for a single NULL field.
         
     | 
| 
      
 352 
     | 
    
         
            +
                        update_query << if params.size == 1 && params[0] == 'NULL'
         
     | 
| 
      
 353 
     | 
    
         
            +
                                          'NULL'
         
     | 
| 
      
 354 
     | 
    
         
            +
                                        else
         
     | 
| 
      
 355 
     | 
    
         
            +
                                          '(' + params.join(',') + ')'
         
     | 
| 
      
 356 
     | 
    
         
            +
                                        end
         
     | 
| 
       315 
357 
     | 
    
         | 
| 
       316 
     | 
    
         
            -
             
     | 
| 
       317 
     | 
    
         
            -
             
     | 
| 
      
 358 
     | 
    
         
            +
                        update_query << " WHERE #{self.class.primary_key} = ?"
         
     | 
| 
      
 359 
     | 
    
         
            +
                        values << self[self.class.primary_key.downcase]
         
     | 
| 
       318 
360 
     | 
    
         | 
| 
       319 
     | 
    
         
            -
             
     | 
| 
       320 
     | 
    
         
            -
             
     | 
| 
       321 
     | 
    
         
            -
             
     | 
| 
       322 
     | 
    
         
            -
             
     | 
| 
       323 
     | 
    
         
            -
             
     | 
| 
       324 
     | 
    
         
            -
             
     | 
| 
       325 
     | 
    
         
            -
             
     | 
| 
       326 
     | 
    
         
            -
             
     | 
| 
      
 361 
     | 
    
         
            +
                        begin
         
     | 
| 
      
 362 
     | 
    
         
            +
                          unless (stmt = IBM_DB.prepare(conn.connection, update_query))
         
     | 
| 
      
 363 
     | 
    
         
            +
                            error_msg = IBM_DB.getErrormsg(conn.connection, IBM_DB::DB_CONN)
         
     | 
| 
      
 364 
     | 
    
         
            +
                            if error_msg && !error_msg.empty?
         
     | 
| 
      
 365 
     | 
    
         
            +
                              raise "Statement prepare for updating LOB/XML column failed : #{error_msg}"
         
     | 
| 
      
 366 
     | 
    
         
            +
                            end
         
     | 
| 
      
 367 
     | 
    
         
            +
                            raise StandardError.new('An unexpected error occurred during update of LOB/XML column')
         
     | 
| 
      
 368 
     | 
    
         
            +
                          end
         
     | 
| 
       327 
369 
     | 
    
         | 
| 
       328 
     | 
    
         
            -
             
     | 
| 
      
 370 
     | 
    
         
            +
                          conn.log_query(update_query, 'update of LOB/XML field(s)in handle_lobs')
         
     | 
| 
       329 
371 
     | 
    
         | 
| 
       330 
     | 
    
         
            -
             
     | 
| 
       331 
     | 
    
         
            -
             
     | 
| 
       332 
     | 
    
         
            -
             
     | 
| 
      
 372 
     | 
    
         
            +
                          # rollback any failed LOB/XML field updates (and remove associated marker)
         
     | 
| 
      
 373 
     | 
    
         
            +
                          unless IBM_DB.execute(stmt, values)
         
     | 
| 
      
 374 
     | 
    
         
            +
                            error_msg = "Failed to insert/update LOB/XML field(s) due to: #{IBM_DB.getErrormsg(stmt,
         
     | 
| 
       333 
375 
     | 
    
         
             
                                                                                                           IBM_DB::DB_STMT)}"
         
     | 
| 
       334 
     | 
    
         
            -
             
     | 
| 
       335 
     | 
    
         
            -
             
     | 
| 
      
 376 
     | 
    
         
            +
                            conn.execute('ROLLBACK')
         
     | 
| 
      
 377 
     | 
    
         
            +
                            raise error_msg
         
     | 
| 
      
 378 
     | 
    
         
            +
                          end
         
     | 
| 
      
 379 
     | 
    
         
            +
                        rescue StandardError => e
         
     | 
| 
      
 380 
     | 
    
         
            +
                          raise e
         
     | 
| 
      
 381 
     | 
    
         
            +
                        ensure
         
     | 
| 
      
 382 
     | 
    
         
            +
                          IBM_DB.free_stmt(stmt) if stmt
         
     | 
| 
      
 383 
     | 
    
         
            +
                        end
         
     | 
| 
      
 384 
     | 
    
         
            +
                        # if clob_sql
         
     | 
| 
      
 385 
     | 
    
         
            +
                      # connection.sql.each
         
     | 
| 
       336 
386 
     | 
    
         
             
                      end
         
     | 
| 
       337 
     | 
    
         
            -
             
     | 
| 
       338 
     | 
    
         
            -
             
     | 
| 
       339 
     | 
    
         
            -
             
     | 
| 
       340 
     | 
    
         
            -
                      IBM_DB.free_stmt(stmt) if stmt
         
     | 
| 
       341 
     | 
    
         
            -
                    end
         
     | 
| 
       342 
     | 
    
         
            -
                    # if clob_sql
         
     | 
| 
       343 
     | 
    
         
            -
                  # connection.sql.each
         
     | 
| 
       344 
     | 
    
         
            -
                  end
         
     | 
| 
       345 
     | 
    
         
            -
                  self.class.connection.handle_lobs_triggered = true
         
     | 
| 
      
 387 
     | 
    
         
            +
                      conn.handle_lobs_triggered = true
         
     | 
| 
      
 388 
     | 
    
         
            +
                    end # if conn.is_a?
         
     | 
| 
      
 389 
     | 
    
         
            +
                  end # with_connection
         
     | 
| 
       346 
390 
     | 
    
         
             
                  # if connection.kind_of?
         
     | 
| 
       347 
391 
     | 
    
         
             
                # handle_lobs
         
     | 
| 
       348 
392 
     | 
    
         
             
                end
         
     | 
| 
         @@ -387,10 +431,6 @@ module ActiveRecord 
     | 
|
| 
       387 
431 
     | 
    
         
             
                  username = config[:username].to_s
         
     | 
| 
       388 
432 
     | 
    
         
             
                  password = config[:password].to_s
         
     | 
| 
       389 
433 
     | 
    
         | 
| 
       390 
     | 
    
         
            -
                  if config.has_key?(:dbops) && config[:dbops] == true
         
     | 
| 
       391 
     | 
    
         
            -
                    return ConnectionAdapters::IBM_DBAdapter.new(nil, isAr3, logger, config, {})
         
     | 
| 
       392 
     | 
    
         
            -
                  end
         
     | 
| 
       393 
     | 
    
         
            -
             
     | 
| 
       394 
434 
     | 
    
         
             
                  # Retrieves the database alias (local catalog name) or remote name
         
     | 
| 
       395 
435 
     | 
    
         
             
                  # (for remote TCP/IP connections) from the +config+ hash
         
     | 
| 
       396 
436 
     | 
    
         
             
                  # or raises ArgumentError in case of failure.
         
     | 
| 
         @@ -453,17 +493,13 @@ module ActiveRecord 
     | 
|
| 
       453 
493 
     | 
    
         
             
                      # No host implies a local catalog-based connection: +database+ represents catalog alias
         
     | 
| 
       454 
494 
     | 
    
         
             
                      connection = IBM_DB.connect(database, username, password, conn_options, set_quoted_literal_replacement)
         
     | 
| 
       455 
495 
     | 
    
         
             
                    end
         
     | 
| 
      
 496 
     | 
    
         
            +
                    return connection, isAr3, config, conn_options
         
     | 
| 
       456 
497 
     | 
    
         
             
                  rescue StandardError => e
         
     | 
| 
       457 
498 
     | 
    
         
             
                    raise "Failed to connect to [#{database}] due to: #{e}"
         
     | 
| 
       458 
499 
     | 
    
         
             
                  end
         
     | 
| 
       459 
500 
     | 
    
         
             
                  # Verifies that the connection was successful
         
     | 
| 
       460 
501 
     | 
    
         
             
                  raise "An unexpected error occured during connect attempt to [#{database}]" unless connection
         
     | 
| 
       461 
502 
     | 
    
         | 
| 
       462 
     | 
    
         
            -
                  # Creates an instance of *IBM_DBAdapter* based on the +connection+
         
     | 
| 
       463 
     | 
    
         
            -
                  # and credentials provided in +config+
         
     | 
| 
       464 
     | 
    
         
            -
                  ConnectionAdapters::IBM_DBAdapter.new(connection, isAr3, logger, config, conn_options)
         
     | 
| 
       465 
     | 
    
         
            -
             
     | 
| 
       466 
     | 
    
         
            -
                  # If the connection failure was not caught previoulsy, it raises a Runtime error
         
     | 
| 
       467 
503 
     | 
    
         
             
                # method self.ibm_db_connection
         
     | 
| 
       468 
504 
     | 
    
         
             
                end
         
     | 
| 
       469 
505 
     | 
    
         | 
| 
         @@ -475,37 +511,26 @@ module ActiveRecord 
     | 
|
| 
       475 
511 
     | 
    
         
             
              end
         
     | 
| 
       476 
512 
     | 
    
         | 
| 
       477 
513 
     | 
    
         
             
              module ConnectionAdapters
         
     | 
| 
       478 
     | 
    
         
            -
                class Column
         
     | 
| 
       479 
     | 
    
         
            -
                  def self.binary_to_string(value)
         
     | 
| 
       480 
     | 
    
         
            -
                    puts_log 'binary_to_string'
         
     | 
| 
       481 
     | 
    
         
            -
                    # Returns a string removing the eventual BLOB scalar function
         
     | 
| 
       482 
     | 
    
         
            -
                    value.to_s.gsub(/"SYSIBM"."BLOB"\('(.*)'\)/i, '\1')
         
     | 
| 
       483 
     | 
    
         
            -
                  end
         
     | 
| 
       484 
     | 
    
         
            -
             
     | 
| 
       485 
     | 
    
         
            -
                  # whether the column is auto-populated by the database using a sequence
         
     | 
| 
       486 
     | 
    
         
            -
                  def auto_incremented_by_db?
         
     | 
| 
       487 
     | 
    
         
            -
                    true
         
     | 
| 
       488 
     | 
    
         
            -
                  end
         
     | 
| 
       489 
     | 
    
         
            -
             
     | 
| 
       490 
     | 
    
         
            -
                  def auto_increment?
         
     | 
| 
       491 
     | 
    
         
            -
                    true
         
     | 
| 
       492 
     | 
    
         
            -
                  end
         
     | 
| 
       493 
     | 
    
         
            -
                  alias_method :auto_incremented_by_db?, :auto_increment?
         
     | 
| 
       494 
     | 
    
         
            -
                end
         
     | 
| 
       495 
     | 
    
         
            -
             
     | 
| 
       496 
514 
     | 
    
         
             
                module Quoting
         
     | 
| 
       497 
515 
     | 
    
         
             
                  def lookup_cast_type_from_column(column) # :nodoc:
         
     | 
| 
       498 
516 
     | 
    
         
             
                    lookup_cast_type(column.sql_type_metadata.sql_type)
         
     | 
| 
       499 
517 
     | 
    
         
             
                  end
         
     | 
| 
       500 
     | 
    
         
            -
                end
         
     | 
| 
       501 
518 
     | 
    
         | 
| 
       502 
     | 
    
         
            -
             
     | 
| 
       503 
     | 
    
         
            -
             
     | 
| 
       504 
     | 
    
         
            -
             
     | 
| 
       505 
     | 
    
         
            -
             
     | 
| 
       506 
     | 
    
         
            -
             
     | 
| 
       507 
     | 
    
         
            -
             
     | 
| 
       508 
     | 
    
         
            -
             
     | 
| 
      
 519 
     | 
    
         
            +
                  module ClassMethods
         
     | 
| 
      
 520 
     | 
    
         
            +
                    def quote_table_name(name)
         
     | 
| 
      
 521 
     | 
    
         
            +
                      if name.start_with? '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
         
     | 
| 
      
 522 
     | 
    
         
            +
                        name = "\"#{name}\""
         
     | 
| 
      
 523 
     | 
    
         
            +
                      else
         
     | 
| 
      
 524 
     | 
    
         
            +
                        name = name.to_s
         
     | 
| 
      
 525 
     | 
    
         
            +
                      end
         
     | 
| 
      
 526 
     | 
    
         
            +
                      name
         
     | 
| 
      
 527 
     | 
    
         
            +
                      # @servertype.check_reserved_words(name).gsub('"', '').gsub("'",'')
         
     | 
| 
      
 528 
     | 
    
         
            +
                    end
         
     | 
| 
      
 529 
     | 
    
         
            +
             
     | 
| 
      
 530 
     | 
    
         
            +
                    def quote_column_name(name)
         
     | 
| 
      
 531 
     | 
    
         
            +
                      name = name.to_s
         
     | 
| 
      
 532 
     | 
    
         
            +
                      name.gsub('"', '').gsub("'", '')
         
     | 
| 
      
 533 
     | 
    
         
            +
                    end
         
     | 
| 
       509 
534 
     | 
    
         
             
                  end
         
     | 
| 
       510 
535 
     | 
    
         
             
                end
         
     | 
| 
       511 
536 
     | 
    
         | 
| 
         @@ -599,209 +624,6 @@ module ActiveRecord 
     | 
|
| 
       599 
624 
     | 
    
         
             
                # class IBM_DBColumn
         
     | 
| 
       600 
625 
     | 
    
         
             
                end
         
     | 
| 
       601 
626 
     | 
    
         | 
| 
       602 
     | 
    
         
            -
                module ColumnMethods
         
     | 
| 
       603 
     | 
    
         
            -
                  def primary_key(name, type = :primary_key, **options)
         
     | 
| 
       604 
     | 
    
         
            -
                    puts_log '16'
         
     | 
| 
       605 
     | 
    
         
            -
                    column(name, type, options.merge(primary_key: true))
         
     | 
| 
       606 
     | 
    
         
            -
                  end
         
     | 
| 
       607 
     | 
    
         
            -
             
     | 
| 
       608 
     | 
    
         
            -
                  # #class Table
         
     | 
| 
       609 
     | 
    
         
            -
                  class Table < ActiveRecord::ConnectionAdapters::Table
         
     | 
| 
       610 
     | 
    
         
            -
                    include ColumnMethods
         
     | 
| 
       611 
     | 
    
         
            -
             
     | 
| 
       612 
     | 
    
         
            -
                    # Method to parse the passed arguments and create the ColumnDefinition object of the specified type
         
     | 
| 
       613 
     | 
    
         
            -
                    def ibm_parse_column_attributes_args(type, *args)
         
     | 
| 
       614 
     | 
    
         
            -
                      puts_log 'ibm_parse_column_attributes_args'
         
     | 
| 
       615 
     | 
    
         
            -
                      options = {}
         
     | 
| 
       616 
     | 
    
         
            -
                      options = args.delete_at(args.length - 1) if args.last.is_a?(Hash)
         
     | 
| 
       617 
     | 
    
         
            -
                      args.each do |name|
         
     | 
| 
       618 
     | 
    
         
            -
                        column name, type.to_sym, options
         
     | 
| 
       619 
     | 
    
         
            -
                       # end args.each
         
     | 
| 
       620 
     | 
    
         
            -
                      end
         
     | 
| 
       621 
     | 
    
         
            -
                    end
         
     | 
| 
       622 
     | 
    
         
            -
                    private :ibm_parse_column_attributes_args
         
     | 
| 
       623 
     | 
    
         
            -
             
     | 
| 
       624 
     | 
    
         
            -
                    # Method to support the new syntax of rails 2.0 migrations (short-hand definitions) for columns of type xml
         
     | 
| 
       625 
     | 
    
         
            -
                    # This method is different as compared to def char (sql is being issued explicitly
         
     | 
| 
       626 
     | 
    
         
            -
                    # as compared to def char where method column(which will generate the sql is being called)
         
     | 
| 
       627 
     | 
    
         
            -
                    # in order to handle the DEFAULT and NULL option for the native XML datatype
         
     | 
| 
       628 
     | 
    
         
            -
                    def xml(*args)
         
     | 
| 
       629 
     | 
    
         
            -
                      puts_log '18'          
         
     | 
| 
       630 
     | 
    
         
            -
                      args.delete_at(args.length - 1) if args.last.is_a?(Hash)
         
     | 
| 
       631 
     | 
    
         
            -
                      sql_segment = "ALTER TABLE #{@base.quote_table_name(@table_name)} ADD COLUMN "
         
     | 
| 
       632 
     | 
    
         
            -
                      args.each do |name|
         
     | 
| 
       633 
     | 
    
         
            -
                        sql = sql_segment + " #{@base.quote_column_name(name)} xml"
         
     | 
| 
       634 
     | 
    
         
            -
                        @base.execute(sql, 'add_xml_column')
         
     | 
| 
       635 
     | 
    
         
            -
                      end
         
     | 
| 
       636 
     | 
    
         
            -
                      self
         
     | 
| 
       637 
     | 
    
         
            -
                    end
         
     | 
| 
       638 
     | 
    
         
            -
             
     | 
| 
       639 
     | 
    
         
            -
                    # Method to support the new syntax of rails 2.0 migrations (short-hand definitions) for columns of type double
         
     | 
| 
       640 
     | 
    
         
            -
                    def double(*args)
         
     | 
| 
       641 
     | 
    
         
            -
                      puts_log '19'
         
     | 
| 
       642 
     | 
    
         
            -
                      ibm_parse_column_attributes_args('double', *args)
         
     | 
| 
       643 
     | 
    
         
            -
                      self
         
     | 
| 
       644 
     | 
    
         
            -
                    end
         
     | 
| 
       645 
     | 
    
         
            -
             
     | 
| 
       646 
     | 
    
         
            -
                    # Method to support the new syntax of rails 2.0 migrations (short-hand definitions) for columns of type decfloat
         
     | 
| 
       647 
     | 
    
         
            -
                    def decfloat(*args)
         
     | 
| 
       648 
     | 
    
         
            -
                      puts_log '20'
         
     | 
| 
       649 
     | 
    
         
            -
                      ibm_parse_column_attributes_args('decfloat', *args)
         
     | 
| 
       650 
     | 
    
         
            -
                      self
         
     | 
| 
       651 
     | 
    
         
            -
                    end
         
     | 
| 
       652 
     | 
    
         
            -
             
     | 
| 
       653 
     | 
    
         
            -
                    def graphic(*args)
         
     | 
| 
       654 
     | 
    
         
            -
                      puts_log '21'
         
     | 
| 
       655 
     | 
    
         
            -
                      ibm_parse_column_attributes_args('graphic', *args)
         
     | 
| 
       656 
     | 
    
         
            -
                      self
         
     | 
| 
       657 
     | 
    
         
            -
                    end
         
     | 
| 
       658 
     | 
    
         
            -
             
     | 
| 
       659 
     | 
    
         
            -
                    def vargraphic(*args)
         
     | 
| 
       660 
     | 
    
         
            -
                      puts_log '22'
         
     | 
| 
       661 
     | 
    
         
            -
                      ibm_parse_column_attributes_args('vargraphic', *args)
         
     | 
| 
       662 
     | 
    
         
            -
                      self
         
     | 
| 
       663 
     | 
    
         
            -
                    end
         
     | 
| 
       664 
     | 
    
         
            -
             
     | 
| 
       665 
     | 
    
         
            -
                    def bigint(*args)
         
     | 
| 
       666 
     | 
    
         
            -
                      puts_log '23'
         
     | 
| 
       667 
     | 
    
         
            -
                      ibm_parse_column_attributes_args('bigint', *args)
         
     | 
| 
       668 
     | 
    
         
            -
                      self
         
     | 
| 
       669 
     | 
    
         
            -
                    end
         
     | 
| 
       670 
     | 
    
         
            -
             
     | 
| 
       671 
     | 
    
         
            -
                    # Method to support the new syntax of rails 2.0 migrations (short-hand definitions) for columns of type char [character]
         
     | 
| 
       672 
     | 
    
         
            -
                    def char(*args)
         
     | 
| 
       673 
     | 
    
         
            -
                      puts_log '24'
         
     | 
| 
       674 
     | 
    
         
            -
                      ibm_parse_column_attributes_args('char', *args)
         
     | 
| 
       675 
     | 
    
         
            -
                      self
         
     | 
| 
       676 
     | 
    
         
            -
                    end
         
     | 
| 
       677 
     | 
    
         
            -
                    alias character char
         
     | 
| 
       678 
     | 
    
         
            -
                  # end of class Table
         
     | 
| 
       679 
     | 
    
         
            -
                  end
         
     | 
| 
       680 
     | 
    
         
            -
             
     | 
| 
       681 
     | 
    
         
            -
                  class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
         
     | 
| 
       682 
     | 
    
         
            -
                    include ColumnMethods
         
     | 
| 
       683 
     | 
    
         
            -
             
     | 
| 
       684 
     | 
    
         
            -
                    def native
         
     | 
| 
       685 
     | 
    
         
            -
                      puts_log '25'
         
     | 
| 
       686 
     | 
    
         
            -
                      @base.native_database_types
         
     | 
| 
       687 
     | 
    
         
            -
                    end
         
     | 
| 
       688 
     | 
    
         
            -
             
     | 
| 
       689 
     | 
    
         
            -
                    # Method to parse the passed arguments and create the ColumnDefinition object of the specified type
         
     | 
| 
       690 
     | 
    
         
            -
                    def ibm_parse_column_attributes_args(type, *args)
         
     | 
| 
       691 
     | 
    
         
            -
                      puts_log '26'
         
     | 
| 
       692 
     | 
    
         
            -
                      options = {}
         
     | 
| 
       693 
     | 
    
         
            -
                      options = args.delete_at(args.length - 1) if args.last.is_a?(Hash)
         
     | 
| 
       694 
     | 
    
         
            -
                      args.each do |name|
         
     | 
| 
       695 
     | 
    
         
            -
                        column(name, type, options)
         
     | 
| 
       696 
     | 
    
         
            -
                      end
         
     | 
| 
       697 
     | 
    
         
            -
                    end
         
     | 
| 
       698 
     | 
    
         
            -
                    private :ibm_parse_column_attributes_args
         
     | 
| 
       699 
     | 
    
         
            -
             
     | 
| 
       700 
     | 
    
         
            -
                    # Method to support the new syntax of rails 2.0 migrations for columns of type xml
         
     | 
| 
       701 
     | 
    
         
            -
                    def xml(*args)
         
     | 
| 
       702 
     | 
    
         
            -
                      puts_log '27'
         
     | 
| 
       703 
     | 
    
         
            -
                      ibm_parse_column_attributes_args('xml', *args)
         
     | 
| 
       704 
     | 
    
         
            -
                      self
         
     | 
| 
       705 
     | 
    
         
            -
                    end
         
     | 
| 
       706 
     | 
    
         
            -
             
     | 
| 
       707 
     | 
    
         
            -
                    # Method to support the new syntax of rails 2.0 migrations (short-hand definitions) for columns of type double
         
     | 
| 
       708 
     | 
    
         
            -
                    def double(*args)
         
     | 
| 
       709 
     | 
    
         
            -
                      puts_log '28'
         
     | 
| 
       710 
     | 
    
         
            -
                      ibm_parse_column_attributes_args('double', *args)
         
     | 
| 
       711 
     | 
    
         
            -
                      self
         
     | 
| 
       712 
     | 
    
         
            -
                    end
         
     | 
| 
       713 
     | 
    
         
            -
             
     | 
| 
       714 
     | 
    
         
            -
                    # Method to support the new syntax of rails 2.0 migrations (short-hand definitions) for columns of type decfloat
         
     | 
| 
       715 
     | 
    
         
            -
                    def decfloat(*args)
         
     | 
| 
       716 
     | 
    
         
            -
                      puts_log '29'
         
     | 
| 
       717 
     | 
    
         
            -
                      ibm_parse_column_attributes_args('decfloat', *args)
         
     | 
| 
       718 
     | 
    
         
            -
                      self
         
     | 
| 
       719 
     | 
    
         
            -
                    end
         
     | 
| 
       720 
     | 
    
         
            -
             
     | 
| 
       721 
     | 
    
         
            -
                    def graphic(*args)
         
     | 
| 
       722 
     | 
    
         
            -
                      puts_log '30'
         
     | 
| 
       723 
     | 
    
         
            -
                      ibm_parse_column_attributes_args('graphic', *args)
         
     | 
| 
       724 
     | 
    
         
            -
                      self
         
     | 
| 
       725 
     | 
    
         
            -
                    end
         
     | 
| 
       726 
     | 
    
         
            -
             
     | 
| 
       727 
     | 
    
         
            -
                    def vargraphic(*args)
         
     | 
| 
       728 
     | 
    
         
            -
                      puts_log '31'
         
     | 
| 
       729 
     | 
    
         
            -
                      ibm_parse_column_attributes_args('vargraphic', *args)
         
     | 
| 
       730 
     | 
    
         
            -
                      self
         
     | 
| 
       731 
     | 
    
         
            -
                    end
         
     | 
| 
       732 
     | 
    
         
            -
             
     | 
| 
       733 
     | 
    
         
            -
                    def bigint(*args)
         
     | 
| 
       734 
     | 
    
         
            -
                      puts_log '32'
         
     | 
| 
       735 
     | 
    
         
            -
                      ibm_parse_column_attributes_args('bigint', *args)
         
     | 
| 
       736 
     | 
    
         
            -
                      self
         
     | 
| 
       737 
     | 
    
         
            -
                    end
         
     | 
| 
       738 
     | 
    
         
            -
             
     | 
| 
       739 
     | 
    
         
            -
                    # Method to support the new syntax of rails 2.0 migrations (short-hand definitions) for columns of type char [character]
         
     | 
| 
       740 
     | 
    
         
            -
                    def char(*args)
         
     | 
| 
       741 
     | 
    
         
            -
                      puts_log '33'
         
     | 
| 
       742 
     | 
    
         
            -
                      ibm_parse_column_attributes_args('char', *args)
         
     | 
| 
       743 
     | 
    
         
            -
                      self
         
     | 
| 
       744 
     | 
    
         
            -
                    end
         
     | 
| 
       745 
     | 
    
         
            -
                    alias character char
         
     | 
| 
       746 
     | 
    
         
            -
             
     | 
| 
       747 
     | 
    
         
            -
                    # Overrides the abstract adapter in order to handle
         
     | 
| 
       748 
     | 
    
         
            -
                    # the DEFAULT option for the native XML datatype
         
     | 
| 
       749 
     | 
    
         
            -
                    def column(name, type, index: nil, **options)
         
     | 
| 
       750 
     | 
    
         
            -
                      puts_log '34 column'
         
     | 
| 
       751 
     | 
    
         
            -
                      name = name.to_s
         
     | 
| 
       752 
     | 
    
         
            -
                      type = type.to_sym if type
         
     | 
| 
       753 
     | 
    
         
            -
             
     | 
| 
       754 
     | 
    
         
            -
                      if @columns_hash[name]
         
     | 
| 
       755 
     | 
    
         
            -
                        unless @columns_hash[name].primary_key?
         
     | 
| 
       756 
     | 
    
         
            -
                          raise ArgumentError, "you can't define an already defined column '#{name}'."
         
     | 
| 
       757 
     | 
    
         
            -
                        end
         
     | 
| 
       758 
     | 
    
         
            -
             
     | 
| 
       759 
     | 
    
         
            -
                        raise ArgumentError,
         
     | 
| 
       760 
     | 
    
         
            -
                              "you can't redefine the primary key column '#{name}'. To define a custom primary key, pass { id: false } to create_table."
         
     | 
| 
       761 
     | 
    
         
            -
             
     | 
| 
       762 
     | 
    
         
            -
                      end
         
     | 
| 
       763 
     | 
    
         
            -
             
     | 
| 
       764 
     | 
    
         
            -
                      # construct a column definition where @base is adaptor instance
         
     | 
| 
       765 
     | 
    
         
            -
                      column = new_column_definition(name, type, **options)
         
     | 
| 
       766 
     | 
    
         
            -
             
     | 
| 
       767 
     | 
    
         
            -
                      # DB2 does not accept DEFAULT NULL option for XML
         
     | 
| 
       768 
     | 
    
         
            -
                      # for table create, but does accept nullable option
         
     | 
| 
       769 
     | 
    
         
            -
                      if type.to_s == 'xml'
         
     | 
| 
       770 
     | 
    
         
            -
                        column.null = options[:null]
         
     | 
| 
       771 
     | 
    
         
            -
                        # Override column object's (instance of ColumnDefinition structure)
         
     | 
| 
       772 
     | 
    
         
            -
                        # to_s which is expected to return the create_table SQL fragment
         
     | 
| 
       773 
     | 
    
         
            -
                        # and bypass DEFAULT NULL option while still appending NOT NULL
         
     | 
| 
       774 
     | 
    
         
            -
                        def column.to_s
         
     | 
| 
       775 
     | 
    
         
            -
                          sql = "#{base.quote_column_name(name)} #{type}"
         
     | 
| 
       776 
     | 
    
         
            -
                          sql << ' NOT NULL' if !null.nil? && (null == false)
         
     | 
| 
       777 
     | 
    
         
            -
                          sql
         
     | 
| 
       778 
     | 
    
         
            -
                        end
         
     | 
| 
       779 
     | 
    
         
            -
                      else
         
     | 
| 
       780 
     | 
    
         
            -
                        column.null = options[:null]
         
     | 
| 
       781 
     | 
    
         
            -
                        column.default = options[:default]
         
     | 
| 
       782 
     | 
    
         
            -
                      end
         
     | 
| 
       783 
     | 
    
         
            -
             
     | 
| 
       784 
     | 
    
         
            -
                      column.scale     = options[:scale]      if options[:scale]
         
     | 
| 
       785 
     | 
    
         
            -
                      column.precision = options[:precision]  if options[:precision]
         
     | 
| 
       786 
     | 
    
         
            -
                      # append column's limit option and yield native limits
         
     | 
| 
       787 
     | 
    
         
            -
                      if options[:limit]
         
     | 
| 
       788 
     | 
    
         
            -
                        column.limit = options[:limit]
         
     | 
| 
       789 
     | 
    
         
            -
                      elsif @base.native_database_types[type.to_sym]
         
     | 
| 
       790 
     | 
    
         
            -
                        if @base.native_database_types[type.to_sym].has_key? :limit
         
     | 
| 
       791 
     | 
    
         
            -
                          column.limit = @base.native_database_types[type.to_sym][:limit]
         
     | 
| 
       792 
     | 
    
         
            -
                        end
         
     | 
| 
       793 
     | 
    
         
            -
                      end
         
     | 
| 
       794 
     | 
    
         
            -
             
     | 
| 
       795 
     | 
    
         
            -
                      @columns << column unless @columns.nil? or @columns.include? column
         
     | 
| 
       796 
     | 
    
         
            -
             
     | 
| 
       797 
     | 
    
         
            -
                      @columns_hash[name] = column
         
     | 
| 
       798 
     | 
    
         
            -
             
     | 
| 
       799 
     | 
    
         
            -
                      self
         
     | 
| 
       800 
     | 
    
         
            -
                    end
         
     | 
| 
       801 
     | 
    
         
            -
             
     | 
| 
       802 
     | 
    
         
            -
                  end # end of class TableDefinition
         
     | 
| 
       803 
     | 
    
         
            -
                end # end of module ColumnMethods
         
     | 
| 
       804 
     | 
    
         
            -
             
     | 
| 
       805 
627 
     | 
    
         
             
                # The IBM_DB Adapter requires the native Ruby driver (ibm_db)
         
     | 
| 
       806 
628 
     | 
    
         
             
                # for IBM data servers (ibm_db.so).
         
     | 
| 
       807 
629 
     | 
    
         
             
                # +config+ the hash passed as an initializer argument content:
         
     | 
| 
         @@ -842,6 +664,42 @@ module ActiveRecord 
     | 
|
| 
       842 
664 
     | 
    
         
             
                    'IBM_DB'
         
     | 
| 
       843 
665 
     | 
    
         
             
                  end
         
     | 
| 
       844 
666 
     | 
    
         | 
| 
      
 667 
     | 
    
         
            +
                  include Savepoints
         
     | 
| 
      
 668 
     | 
    
         
            +
             
     | 
| 
      
 669 
     | 
    
         
            +
                  def create_savepoint(name = current_savepoint_name)
         
     | 
| 
      
 670 
     | 
    
         
            +
                    puts_log 'create_savepoint'
         
     | 
| 
      
 671 
     | 
    
         
            +
                    # Turns off auto-committing
         
     | 
| 
      
 672 
     | 
    
         
            +
                    auto_commit_off
         
     | 
| 
      
 673 
     | 
    
         
            +
                    # Create savepoint
         
     | 
| 
      
 674 
     | 
    
         
            +
                    internal_execute("SAVEPOINT #{name} ON ROLLBACK RETAIN CURSORS", 'TRANSACTION')
         
     | 
| 
      
 675 
     | 
    
         
            +
                  end
         
     | 
| 
      
 676 
     | 
    
         
            +
             
     | 
| 
      
 677 
     | 
    
         
            +
                  class Column < ActiveRecord::ConnectionAdapters::Column
         
     | 
| 
      
 678 
     | 
    
         
            +
                    attr_reader :rowid
         
     | 
| 
      
 679 
     | 
    
         
            +
             
     | 
| 
      
 680 
     | 
    
         
            +
                    def initialize(*, auto_increment: nil, rowid: false, generated_type: nil, **)
         
     | 
| 
      
 681 
     | 
    
         
            +
                      super
         
     | 
| 
      
 682 
     | 
    
         
            +
                      @auto_increment = auto_increment
         
     | 
| 
      
 683 
     | 
    
         
            +
                      @rowid = rowid
         
     | 
| 
      
 684 
     | 
    
         
            +
                      @generated_type = generated_type
         
     | 
| 
      
 685 
     | 
    
         
            +
                    end
         
     | 
| 
      
 686 
     | 
    
         
            +
             
     | 
| 
      
 687 
     | 
    
         
            +
                    def self.binary_to_string(value)
         
     | 
| 
      
 688 
     | 
    
         
            +
                      # Returns a string removing the eventual BLOB scalar function
         
     | 
| 
      
 689 
     | 
    
         
            +
                      value.to_s.gsub(/"SYSIBM"."BLOB"\('(.*)'\)/i, '\1')
         
     | 
| 
      
 690 
     | 
    
         
            +
                    end
         
     | 
| 
      
 691 
     | 
    
         
            +
             
     | 
| 
      
 692 
     | 
    
         
            +
                    # whether the column is auto-populated by the database using a sequence
         
     | 
| 
      
 693 
     | 
    
         
            +
                    def auto_increment?
         
     | 
| 
      
 694 
     | 
    
         
            +
                      @auto_increment
         
     | 
| 
      
 695 
     | 
    
         
            +
                    end
         
     | 
| 
      
 696 
     | 
    
         
            +
             
     | 
| 
      
 697 
     | 
    
         
            +
                    def auto_incremented_by_db?
         
     | 
| 
      
 698 
     | 
    
         
            +
                      auto_increment? || rowid
         
     | 
| 
      
 699 
     | 
    
         
            +
                    end
         
     | 
| 
      
 700 
     | 
    
         
            +
                    alias_method :auto_incremented_by_db?, :auto_increment?
         
     | 
| 
      
 701 
     | 
    
         
            +
                  end
         
     | 
| 
      
 702 
     | 
    
         
            +
             
     | 
| 
       845 
703 
     | 
    
         
             
                  class AlterTable < ActiveRecord::ConnectionAdapters::AlterTable
         
     | 
| 
       846 
704 
     | 
    
         
             
                    attr_reader :constraint_validations, :exclusion_constraint_adds, :exclusion_constraint_drops, :unique_constraint_adds, :unique_constraint_drops
         
     | 
| 
       847 
705 
     | 
    
         
             
                    def initialize(td)
         
     | 
| 
         @@ -889,6 +747,11 @@ module ActiveRecord 
     | 
|
| 
       889 
747 
     | 
    
         
             
                      options = @conn.unique_constraint_options(name, column_name, options)
         
     | 
| 
       890 
748 
     | 
    
         
             
                      UniqueConstraintDefinition.new(name, column_name, options)
         
     | 
| 
       891 
749 
     | 
    
         
             
                    end
         
     | 
| 
      
 750 
     | 
    
         
            +
             
     | 
| 
      
 751 
     | 
    
         
            +
                    def references(*args, **options)
         
     | 
| 
      
 752 
     | 
    
         
            +
                      super(*args, type: :integer, **options)
         
     | 
| 
      
 753 
     | 
    
         
            +
                    end
         
     | 
| 
      
 754 
     | 
    
         
            +
                    alias :belongs_to :references
         
     | 
| 
       892 
755 
     | 
    
         
             
                  end # end of class TableDefinition
         
     | 
| 
       893 
756 
     | 
    
         | 
| 
       894 
757 
     | 
    
         
             
                  UniqueConstraintDefinition = Struct.new(:table_name, :column, :options) do
         
     | 
| 
         @@ -927,8 +790,9 @@ module ActiveRecord 
     | 
|
| 
       927 
790 
     | 
    
         
             
                    StatementPool.new(self.class.type_cast_config_to_integer(@config[:statement_limit]))
         
     | 
| 
       928 
791 
     | 
    
         
             
                  end
         
     | 
| 
       929 
792 
     | 
    
         | 
| 
       930 
     | 
    
         
            -
                  def initialize( 
     | 
| 
      
 793 
     | 
    
         
            +
                  def initialize(args)
         
     | 
| 
       931 
794 
     | 
    
         
             
                    # Caching database connection configuration (+connect+ or +reconnect+ support)\
         
     | 
| 
      
 795 
     | 
    
         
            +
                    connection, ar3, config, conn_options = ActiveRecord::Base.ibm_db_connection(args)
         
     | 
| 
       932 
796 
     | 
    
         
             
                    @config = config
         
     | 
| 
       933 
797 
     | 
    
         
             
                    @connection = connection
         
     | 
| 
       934 
798 
     | 
    
         
             
                    @isAr3 = ar3
         
     | 
| 
         @@ -963,8 +827,7 @@ module ActiveRecord 
     | 
|
| 
       963 
827 
     | 
    
         
             
                    @handle_lobs_triggered = false
         
     | 
| 
       964 
828 
     | 
    
         | 
| 
       965 
829 
     | 
    
         
             
                    # Calls the parent class +ConnectionAdapters+' initializer
         
     | 
| 
       966 
     | 
    
         
            -
                     
     | 
| 
       967 
     | 
    
         
            -
                    super(@connection, logger, @config)
         
     | 
| 
      
 830 
     | 
    
         
            +
                    super(@config)
         
     | 
| 
       968 
831 
     | 
    
         | 
| 
       969 
832 
     | 
    
         
             
                    if @connection
         
     | 
| 
       970 
833 
     | 
    
         
             
                      server_info = IBM_DB.server_info(@connection)
         
     | 
| 
         @@ -1143,6 +1006,15 @@ module ActiveRecord 
     | 
|
| 
       1143 
1006 
     | 
    
         
             
                    true
         
     | 
| 
       1144 
1007 
     | 
    
         
             
                  end
         
     | 
| 
       1145 
1008 
     | 
    
         | 
| 
      
 1009 
     | 
    
         
            +
                  #IBM Db2 does not natively support skipping rows on insert when there's a duplicate key
         
     | 
| 
      
 1010 
     | 
    
         
            +
                  def supports_insert_on_duplicate_skip?
         
     | 
| 
      
 1011 
     | 
    
         
            +
                    false
         
     | 
| 
      
 1012 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1013 
     | 
    
         
            +
             
     | 
| 
      
 1014 
     | 
    
         
            +
                  def supports_insert_on_duplicate_update?
         
     | 
| 
      
 1015 
     | 
    
         
            +
                    false
         
     | 
| 
      
 1016 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1017 
     | 
    
         
            +
             
     | 
| 
       1146 
1018 
     | 
    
         
             
                  # This adapter supports migrations.
         
     | 
| 
       1147 
1019 
     | 
    
         
             
                  # Current limitations:
         
     | 
| 
       1148 
1020 
     | 
    
         
             
                  # +rename_column+ is not currently supported by the IBM data servers
         
     | 
| 
         @@ -1262,6 +1134,7 @@ module ActiveRecord 
     | 
|
| 
       1262 
1134 
     | 
    
         
             
                                                     @set_quoted_literal_replacement)
         
     | 
| 
       1263 
1135 
     | 
    
         
             
                        puts_log "Connection Established B = #{@connection}"
         
     | 
| 
       1264 
1136 
     | 
    
         
             
                      end
         
     | 
| 
      
 1137 
     | 
    
         
            +
                      @raw_connection = @connection
         
     | 
| 
       1265 
1138 
     | 
    
         
             
                    rescue StandardError => e
         
     | 
| 
       1266 
1139 
     | 
    
         
             
                      warn "Connection to database #{@database} failed: #{e}"
         
     | 
| 
       1267 
1140 
     | 
    
         
             
                      puts_log "Connection to database #{@database} failed: #{e}"
         
     | 
| 
         @@ -1318,6 +1191,7 @@ module ActiveRecord 
     | 
|
| 
       1318 
1191 
     | 
    
         
             
                        IBM_DB.close(@connection)
         
     | 
| 
       1319 
1192 
     | 
    
         
             
                        puts_log "Connection closed #{Thread.current}"
         
     | 
| 
       1320 
1193 
     | 
    
         
             
                        @connection = nil
         
     | 
| 
      
 1194 
     | 
    
         
            +
                        @raw_connection = nil
         
     | 
| 
       1321 
1195 
     | 
    
         
             
                      rescue StandardError => e
         
     | 
| 
       1322 
1196 
     | 
    
         
             
                        puts_log "Connection close failure #{e.message}, #{Thread.current}"
         
     | 
| 
       1323 
1197 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -1325,13 +1199,24 @@ module ActiveRecord 
     | 
|
| 
       1325 
1199 
     | 
    
         
             
                    end
         
     | 
| 
       1326 
1200 
     | 
    
         
             
                  end
         
     | 
| 
       1327 
1201 
     | 
    
         | 
| 
      
 1202 
     | 
    
         
            +
                  # Check the connection back in to the connection pool
         
     | 
| 
      
 1203 
     | 
    
         
            +
                  def close
         
     | 
| 
      
 1204 
     | 
    
         
            +
                    pool.checkin self
         
     | 
| 
      
 1205 
     | 
    
         
            +
                    disconnect!
         
     | 
| 
      
 1206 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1207 
     | 
    
         
            +
             
     | 
| 
      
 1208 
     | 
    
         
            +
                  def connected?
         
     | 
| 
      
 1209 
     | 
    
         
            +
                    puts_log "connected? #{@connection}"
         
     | 
| 
      
 1210 
     | 
    
         
            +
                    !(@connection.nil?)
         
     | 
| 
      
 1211 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1212 
     | 
    
         
            +
             
     | 
| 
       1328 
1213 
     | 
    
         
             
                  #==============================================
         
     | 
| 
       1329 
1214 
     | 
    
         
             
                  # DATABASE STATEMENTS
         
     | 
| 
       1330 
1215 
     | 
    
         
             
                  #==============================================
         
     | 
| 
       1331 
1216 
     | 
    
         | 
| 
       1332 
1217 
     | 
    
         
             
                  def create_table(name, id: :primary_key, primary_key: nil, force: nil, **options)
         
     | 
| 
       1333 
1218 
     | 
    
         
             
                    puts_log "create_table name=#{name}, id=#{id}, primary_key=#{primary_key}, force=#{force}"
         
     | 
| 
       1334 
     | 
    
         
            -
                    puts_log "create_table Options = #{options}"
         
     | 
| 
      
 1219 
     | 
    
         
            +
                    puts_log "create_table Options 1 = #{options}"
         
     | 
| 
       1335 
1220 
     | 
    
         
             
                    puts_log "primary_key_prefix_type = #{ActiveRecord::Base.primary_key_prefix_type}"
         
     | 
| 
       1336 
1221 
     | 
    
         
             
                    puts_log caller
         
     | 
| 
       1337 
1222 
     | 
    
         
             
                    @servertype.setup_for_lob_table
         
     | 
| 
         @@ -1356,6 +1241,7 @@ module ActiveRecord 
     | 
|
| 
       1356 
1241 
     | 
    
         
             
                      options[:auto_increment] = true if options[:auto_increment].nil? and %i[integer bigint].include?(id)
         
     | 
| 
       1357 
1242 
     | 
    
         
             
                    end
         
     | 
| 
       1358 
1243 
     | 
    
         | 
| 
      
 1244 
     | 
    
         
            +
                    puts_log "create_table Options 2 = #{options}"
         
     | 
| 
       1359 
1245 
     | 
    
         
             
                    super(name, id: id, primary_key: primary_key, force: force, **options)
         
     | 
| 
       1360 
1246 
     | 
    
         
             
                  end
         
     | 
| 
       1361 
1247 
     | 
    
         | 
| 
         @@ -1381,8 +1267,8 @@ module ActiveRecord 
     | 
|
| 
       1381 
1267 
     | 
    
         
             
                    end
         
     | 
| 
       1382 
1268 
     | 
    
         
             
                  end
         
     | 
| 
       1383 
1269 
     | 
    
         | 
| 
       1384 
     | 
    
         
            -
                  def select(sql, name = nil, binds = [], prepare: false, async: false)
         
     | 
| 
       1385 
     | 
    
         
            -
                    puts_log "select #{sql}"
         
     | 
| 
      
 1270 
     | 
    
         
            +
                  def select(sql, name = nil, binds = [], prepare: false, async: false, allow_retry: false)
         
     | 
| 
      
 1271 
     | 
    
         
            +
                    puts_log "select sql = #{sql}"
         
     | 
| 
       1386 
1272 
     | 
    
         
             
                    puts_log "binds = #{binds}"
         
     | 
| 
       1387 
1273 
     | 
    
         
             
                    puts_log "prepare = #{prepare}"
         
     | 
| 
       1388 
1274 
     | 
    
         | 
| 
         @@ -1414,20 +1300,21 @@ module ActiveRecord 
     | 
|
| 
       1414 
1300 
     | 
    
         
             
                    end
         
     | 
| 
       1415 
1301 
     | 
    
         | 
| 
       1416 
1302 
     | 
    
         
             
                    results = []
         
     | 
| 
      
 1303 
     | 
    
         
            +
                    cols = []
         
     | 
| 
       1417 
1304 
     | 
    
         | 
| 
       1418 
1305 
     | 
    
         
             
                    stmt = if binds.nil? || binds.empty?
         
     | 
| 
       1419 
     | 
    
         
            -
                             internal_execute(sql, name)
         
     | 
| 
      
 1306 
     | 
    
         
            +
                             internal_execute(sql, name, allow_retry: allow_retry)
         
     | 
| 
       1420 
1307 
     | 
    
         
             
                           else
         
     | 
| 
       1421 
     | 
    
         
            -
                             exec_query_ret_stmt(sql, name, binds, prepare: prepare, async: async)
         
     | 
| 
      
 1308 
     | 
    
         
            +
                             exec_query_ret_stmt(sql, name, binds, prepare: prepare, async: async, allow_retry: allow_retry)
         
     | 
| 
       1422 
1309 
     | 
    
         
             
                           end
         
     | 
| 
       1423 
1310 
     | 
    
         | 
| 
       1424 
     | 
    
         
            -
                    cols = IBM_DB.resultCols(stmt)
         
     | 
| 
       1425 
     | 
    
         
            -
             
     | 
| 
       1426 
1311 
     | 
    
         
             
                    if stmt
         
     | 
| 
      
 1312 
     | 
    
         
            +
                      cols = IBM_DB.resultCols(stmt)
         
     | 
| 
       1427 
1313 
     | 
    
         
             
                      results = fetch_data(stmt)
         
     | 
| 
       1428 
     | 
    
         
            -
                      puts_log "Results = #{results}"
         
     | 
| 
       1429 
1314 
     | 
    
         
             
                    end
         
     | 
| 
       1430 
1315 
     | 
    
         | 
| 
      
 1316 
     | 
    
         
            +
                    puts_log "select cols = #{cols}, results = #{results}"
         
     | 
| 
      
 1317 
     | 
    
         
            +
             
     | 
| 
       1431 
1318 
     | 
    
         
             
                    if @isAr3
         
     | 
| 
       1432 
1319 
     | 
    
         
             
                      results
         
     | 
| 
       1433 
1320 
     | 
    
         
             
                    else
         
     | 
| 
         @@ -1437,11 +1324,13 @@ module ActiveRecord 
     | 
|
| 
       1437 
1324 
     | 
    
         
             
                      end
         
     | 
| 
       1438 
1325 
     | 
    
         
             
                    end
         
     | 
| 
       1439 
1326 
     | 
    
         | 
| 
      
 1327 
     | 
    
         
            +
                    puts_log "select final results = #{results} #{caller}"
         
     | 
| 
       1440 
1328 
     | 
    
         
             
                    results
         
     | 
| 
       1441 
1329 
     | 
    
         
             
                  end
         
     | 
| 
       1442 
1330 
     | 
    
         | 
| 
       1443 
1331 
     | 
    
         
             
                  def translate_exception(exception, message:, sql:, binds:)
         
     | 
| 
       1444 
     | 
    
         
            -
                    puts_log "translate_exception - #{message}"
         
     | 
| 
      
 1332 
     | 
    
         
            +
                    puts_log "translate_exception - exception = #{exception}, message = #{message}"
         
     | 
| 
      
 1333 
     | 
    
         
            +
                    puts_log "translate_exception #{caller}"
         
     | 
| 
       1445 
1334 
     | 
    
         
             
                    error_msg1 = /SQL0803N  One or more values in the INSERT statement, UPDATE statement, or foreign key update caused by a DELETE statement are not valid because the primary key, unique constraint or unique index identified by .* constrains table .* from having duplicate values for the index key/
         
     | 
| 
       1446 
1335 
     | 
    
         
             
                    error_msg2 = /SQL0204N  .* is an undefined name/
         
     | 
| 
       1447 
1336 
     | 
    
         
             
                    error_msg3 = /SQL0413N  Overflow occurred during numeric data type conversion/
         
     | 
| 
         @@ -1471,8 +1360,13 @@ module ActiveRecord 
     | 
|
| 
       1471 
1360 
     | 
    
         
             
                    elsif exception.message.match?(/called on a closed database/i)
         
     | 
| 
       1472 
1361 
     | 
    
         
             
                      puts_log 'ConnectionNotEstablished exception'
         
     | 
| 
       1473 
1362 
     | 
    
         
             
                      ConnectionNotEstablished.new(exception, connection_pool: @pool)
         
     | 
| 
      
 1363 
     | 
    
         
            +
                    elsif message.strip.start_with?("FrozenError") or
         
     | 
| 
      
 1364 
     | 
    
         
            +
                          message.strip.start_with?("ActiveRecord::Encryption::Errors::Encoding:") or
         
     | 
| 
      
 1365 
     | 
    
         
            +
                          message.strip.start_with?("ActiveRecord::Encryption::Errors::Encryption") or
         
     | 
| 
      
 1366 
     | 
    
         
            +
                          message.strip.start_with?("ActiveRecord::ConnectionFailed")
         
     | 
| 
      
 1367 
     | 
    
         
            +
                      exception
         
     | 
| 
       1474 
1368 
     | 
    
         
             
                    else
         
     | 
| 
       1475 
     | 
    
         
            -
                      super
         
     | 
| 
      
 1369 
     | 
    
         
            +
                      super(message, message: exception, sql: sql, binds: binds)
         
     | 
| 
       1476 
1370 
     | 
    
         
             
                    end
         
     | 
| 
       1477 
1371 
     | 
    
         
             
                  end
         
     | 
| 
       1478 
1372 
     | 
    
         | 
| 
         @@ -1611,11 +1505,52 @@ module ActiveRecord 
     | 
|
| 
       1611 
1505 
     | 
    
         
             
                    " VALUES (#{val})"
         
     | 
| 
       1612 
1506 
     | 
    
         
             
                  end
         
     | 
| 
       1613 
1507 
     | 
    
         | 
| 
      
 1508 
     | 
    
         
            +
                  def getTableIdentityColumn(table_name)
         
     | 
| 
      
 1509 
     | 
    
         
            +
                    query = "SELECT COLNAME FROM SYSCAT.COLUMNS WHERE TABNAME = #{quote(table_name.upcase)} AND IDENTITY = 'Y'"
         
     | 
| 
      
 1510 
     | 
    
         
            +
                    puts_log "getTableIdentityColumn table_name = #{table_name}, query = #{query}"
         
     | 
| 
      
 1511 
     | 
    
         
            +
                    rows = execute_without_logging(query).rows
         
     | 
| 
      
 1512 
     | 
    
         
            +
                    puts_log "getTableIdentityColumn rows = #{rows}"
         
     | 
| 
      
 1513 
     | 
    
         
            +
                    if rows.any?
         
     | 
| 
      
 1514 
     | 
    
         
            +
                      return rows.first
         
     | 
| 
      
 1515 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1516 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1517 
     | 
    
         
            +
             
     | 
| 
      
 1518 
     | 
    
         
            +
                  def return_insert (stmt, sql, binds, pk, id_value = nil, returning: nil)
         
     | 
| 
      
 1519 
     | 
    
         
            +
                    puts_log "return_insert sql = #{sql}, pk = #{pk}, returning = #{returning}"
         
     | 
| 
      
 1520 
     | 
    
         
            +
                    @sql << sql
         
     | 
| 
      
 1521 
     | 
    
         
            +
             
     | 
| 
      
 1522 
     | 
    
         
            +
                    table_name = sql[/\AINSERT\s+INTO\s+([^\s\(]+)/i, 1]
         
     | 
| 
      
 1523 
     | 
    
         
            +
                    rowID = getTableIdentityColumn(table_name)
         
     | 
| 
      
 1524 
     | 
    
         
            +
                    #Identity column exist.
         
     | 
| 
      
 1525 
     | 
    
         
            +
                    if Array(rowID).any?
         
     | 
| 
      
 1526 
     | 
    
         
            +
                      val = @servertype.last_generated_id(stmt)
         
     | 
| 
      
 1527 
     | 
    
         
            +
                      #returning required is just an ID, or nothing is expected to return
         
     | 
| 
      
 1528 
     | 
    
         
            +
                      only_returning_id = Array(returning).empty? ||
         
     | 
| 
      
 1529 
     | 
    
         
            +
                                         (Array(returning).size == 1 && Array(rowID).first == Array(returning).first)
         
     | 
| 
      
 1530 
     | 
    
         
            +
                      unless only_returning_id
         
     | 
| 
      
 1531 
     | 
    
         
            +
                        cols = Array(returning).join(', ')
         
     | 
| 
      
 1532 
     | 
    
         
            +
                        query = "SELECT #{cols} FROM #{table_name} WHERE #{Array(rowID).first} = #{val}"
         
     | 
| 
      
 1533 
     | 
    
         
            +
                        puts_log "return_insert val = #{val}, cols = #{cols}, table_name = #{table_name}"
         
     | 
| 
      
 1534 
     | 
    
         
            +
                        puts_log "return_insert query = #{query}"
         
     | 
| 
      
 1535 
     | 
    
         
            +
                        rows = execute_without_logging(query).rows
         
     | 
| 
      
 1536 
     | 
    
         
            +
                        puts_log "return_insert rows = #{rows}"
         
     | 
| 
      
 1537 
     | 
    
         
            +
                        return rows.first
         
     | 
| 
      
 1538 
     | 
    
         
            +
                      end
         
     | 
| 
      
 1539 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1540 
     | 
    
         
            +
             
     | 
| 
      
 1541 
     | 
    
         
            +
                    puts_log "return_insert id_value = #{id_value}, val = #{val}"
         
     | 
| 
      
 1542 
     | 
    
         
            +
                    if !returning.nil?
         
     | 
| 
      
 1543 
     | 
    
         
            +
                      [id_value || val]
         
     | 
| 
      
 1544 
     | 
    
         
            +
                    else
         
     | 
| 
      
 1545 
     | 
    
         
            +
                      id_value || val
         
     | 
| 
      
 1546 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1547 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1548 
     | 
    
         
            +
             
     | 
| 
       1614 
1549 
     | 
    
         
             
                  # Perform an insert and returns the last ID generated.
         
     | 
| 
       1615 
1550 
     | 
    
         
             
                  # This can be the ID passed to the method or the one auto-generated by the database,
         
     | 
| 
       1616 
1551 
     | 
    
         
             
                  # and retrieved by the +last_generated_id+ method.
         
     | 
| 
       1617 
     | 
    
         
            -
                  def insert_direct(sql, name = nil, _pk = nil, id_value = nil,  
     | 
| 
       1618 
     | 
    
         
            -
                    puts_log  
     | 
| 
      
 1552 
     | 
    
         
            +
                  def insert_direct(sql, name = nil, _pk = nil, id_value = nil, returning: nil)
         
     | 
| 
      
 1553 
     | 
    
         
            +
                    puts_log "insert_direct sql = #{sql}, name = #{name}, _pk = #{_pk}, returning = #{returning}"
         
     | 
| 
       1619 
1554 
     | 
    
         
             
                    if @handle_lobs_triggered # Ensure the array of sql is cleared if they have been handled in the callback
         
     | 
| 
       1620 
1555 
     | 
    
         
             
                      @sql = []
         
     | 
| 
       1621 
1556 
     | 
    
         
             
                      @handle_lobs_triggered = false
         
     | 
| 
         @@ -1624,9 +1559,7 @@ module ActiveRecord 
     | 
|
| 
       1624 
1559 
     | 
    
         
             
                    return unless stmt = execute(sql, name)
         
     | 
| 
       1625 
1560 
     | 
    
         | 
| 
       1626 
1561 
     | 
    
         
             
                    begin
         
     | 
| 
       1627 
     | 
    
         
            -
                       
     | 
| 
       1628 
     | 
    
         
            -
                      return [@servertype.last_generated_id(stmt)] unless returning.nil?
         
     | 
| 
       1629 
     | 
    
         
            -
                      id_value || @servertype.last_generated_id(stmt)
         
     | 
| 
      
 1562 
     | 
    
         
            +
                      return_insert(stmt, sql, nil, _pk, id_value, returning: returning)
         
     | 
| 
       1630 
1563 
     | 
    
         
             
                      # Ensures to free the resources associated with the statement
         
     | 
| 
       1631 
1564 
     | 
    
         
             
                    ensure
         
     | 
| 
       1632 
1565 
     | 
    
         
             
                      IBM_DB.free_stmt(stmt) if stmt
         
     | 
| 
         @@ -1634,7 +1567,7 @@ module ActiveRecord 
     | 
|
| 
       1634 
1567 
     | 
    
         
             
                  end
         
     | 
| 
       1635 
1568 
     | 
    
         | 
| 
       1636 
1569 
     | 
    
         
             
                  def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [], returning: nil)
         
     | 
| 
       1637 
     | 
    
         
            -
                    puts_log "insert Binds P = #{binds}"
         
     | 
| 
      
 1570 
     | 
    
         
            +
                    puts_log "insert Binds P = #{binds}, name = #{name}, pk = #{pk}, id_value = #{id_value}, returning = #{returning}"
         
     | 
| 
       1638 
1571 
     | 
    
         
             
                    puts_log caller
         
     | 
| 
       1639 
1572 
     | 
    
         
             
                    if @arelVersion < 6
         
     | 
| 
       1640 
1573 
     | 
    
         
             
                      sql = to_sql(arel)
         
     | 
| 
         @@ -1646,27 +1579,30 @@ module ActiveRecord 
     | 
|
| 
       1646 
1579 
     | 
    
         
             
                    puts_log "insert Binds A = #{binds}"
         
     | 
| 
       1647 
1580 
     | 
    
         
             
                    puts_log "insert SQL = #{sql}"
         
     | 
| 
       1648 
1581 
     | 
    
         
             
                    # unless IBM_DBAdapter.respond_to?(:exec_insert)
         
     | 
| 
       1649 
     | 
    
         
            -
                    return insert_direct(sql, name, pk, id_value,  
     | 
| 
      
 1582 
     | 
    
         
            +
                    return insert_direct(sql, name, pk, id_value, returning: returning) if binds.nil? || binds.empty?
         
     | 
| 
       1650 
1583 
     | 
    
         | 
| 
       1651 
1584 
     | 
    
         
             
                    ActiveRecord::Base.clear_query_caches_for_current_thread
         
     | 
| 
       1652 
1585 
     | 
    
         | 
| 
       1653 
1586 
     | 
    
         
             
                    return unless stmt = exec_insert_db2(sql, name, binds, pk, sequence_name, returning)
         
     | 
| 
       1654 
1587 
     | 
    
         | 
| 
       1655 
1588 
     | 
    
         
             
                    begin
         
     | 
| 
       1656 
     | 
    
         
            -
                       
     | 
| 
       1657 
     | 
    
         
            -
                      return [@servertype.last_generated_id(stmt)] unless returning.nil?
         
     | 
| 
       1658 
     | 
    
         
            -
                      id_value || @servertype.last_generated_id(stmt)
         
     | 
| 
      
 1589 
     | 
    
         
            +
                      return_insert(stmt, sql, binds, pk, id_value, returning: returning)
         
     | 
| 
       1659 
1590 
     | 
    
         
             
                    ensure
         
     | 
| 
       1660 
1591 
     | 
    
         
             
                      IBM_DB.free_stmt(stmt) if stmt
         
     | 
| 
       1661 
1592 
     | 
    
         
             
                    end
         
     | 
| 
       1662 
1593 
     | 
    
         
             
                  end
         
     | 
| 
       1663 
1594 
     | 
    
         | 
| 
       1664 
1595 
     | 
    
         
             
                  def exec_insert_db2(sql, name = nil, binds = [], pk = nil, sequence_name = nil, returning = nil)
         
     | 
| 
       1665 
     | 
    
         
            -
                    puts_log  
     | 
| 
      
 1596 
     | 
    
         
            +
                    puts_log "exec_insert_db2 sql = #{sql}, name = #{name}, binds = #{binds}, pk = #{pk}, returning = #{returning}"
         
     | 
| 
       1666 
1597 
     | 
    
         
             
                    sql, binds = sql_for_insert(sql, pk, binds, returning)
         
     | 
| 
       1667 
1598 
     | 
    
         
             
                    exec_query_ret_stmt(sql, name, binds, prepare: false)
         
     | 
| 
       1668 
1599 
     | 
    
         
             
                  end
         
     | 
| 
       1669 
1600 
     | 
    
         | 
| 
      
 1601 
     | 
    
         
            +
                  def build_insert_sql(insert) # :nodoc:
         
     | 
| 
      
 1602 
     | 
    
         
            +
                    sql = +"INSERT #{insert.into} #{insert.values_list}"
         
     | 
| 
      
 1603 
     | 
    
         
            +
                    sql
         
     | 
| 
      
 1604 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1605 
     | 
    
         
            +
             
     | 
| 
       1670 
1606 
     | 
    
         
             
                  def last_inserted_id(result)
         
     | 
| 
       1671 
1607 
     | 
    
         
             
                    puts_log 'last_inserted_id'
         
     | 
| 
       1672 
1608 
     | 
    
         
             
                    result
         
     | 
| 
         @@ -1745,7 +1681,7 @@ module ActiveRecord 
     | 
|
| 
       1745 
1681 
     | 
    
         
             
                    !READ_QUERY.match?(sql.b)
         
     | 
| 
       1746 
1682 
     | 
    
         
             
                  end
         
     | 
| 
       1747 
1683 
     | 
    
         | 
| 
       1748 
     | 
    
         
            -
                  def explain(arel, binds = [])
         
     | 
| 
      
 1684 
     | 
    
         
            +
                  def explain(arel, binds = [], options = [])
         
     | 
| 
       1749 
1685 
     | 
    
         
             
                    sql = "EXPLAIN ALL SET QUERYNO = 1 FOR #{to_sql(arel, binds)}"
         
     | 
| 
       1750 
1686 
     | 
    
         
             
                    stmt = execute(sql, 'EXPLAIN')
         
     | 
| 
       1751 
1687 
     | 
    
         
             
                    result = select("select * from explain_statement where explain_level = 'P' and queryno = 1", 'EXPLAIN')
         
     | 
| 
         @@ -1755,15 +1691,55 @@ module ActiveRecord 
     | 
|
| 
       1755 
1691 
     | 
    
         
             
                    IBM_DB.free_stmt(stmt) if stmt
         
     | 
| 
       1756 
1692 
     | 
    
         
             
                  end
         
     | 
| 
       1757 
1693 
     | 
    
         | 
| 
      
 1694 
     | 
    
         
            +
                  def execute_without_logging(sql, name = nil, binds = [], prepare: true, async: false)
         
     | 
| 
      
 1695 
     | 
    
         
            +
                    puts_log "execute_without_logging sql = #{sql}, name = #{name}, binds = #{binds}"
         
     | 
| 
      
 1696 
     | 
    
         
            +
             
     | 
| 
      
 1697 
     | 
    
         
            +
                    sql = transform_query(sql)
         
     | 
| 
      
 1698 
     | 
    
         
            +
                    check_if_write_query(sql)
         
     | 
| 
      
 1699 
     | 
    
         
            +
                    mark_transaction_written_if_write(sql)
         
     | 
| 
      
 1700 
     | 
    
         
            +
                    cols = nil
         
     | 
| 
      
 1701 
     | 
    
         
            +
                    results = nil
         
     | 
| 
      
 1702 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 1703 
     | 
    
         
            +
                      param_array = type_casted_binds(binds)
         
     | 
| 
      
 1704 
     | 
    
         
            +
                      puts_log "execute_without_logging Param array = #{param_array}"
         
     | 
| 
      
 1705 
     | 
    
         
            +
                      puts_log "execute_without_logging #{caller}"
         
     | 
| 
      
 1706 
     | 
    
         
            +
             
     | 
| 
      
 1707 
     | 
    
         
            +
                      stmt = @servertype.prepare(sql, name)
         
     | 
| 
      
 1708 
     | 
    
         
            +
                      @statements[sql] = stmt if prepare
         
     | 
| 
      
 1709 
     | 
    
         
            +
             
     | 
| 
      
 1710 
     | 
    
         
            +
                      puts_log "execute_without_logging Statement = #{stmt}"
         
     | 
| 
      
 1711 
     | 
    
         
            +
             
     | 
| 
      
 1712 
     | 
    
         
            +
                      execute_prepared_stmt(stmt, param_array)
         
     | 
| 
      
 1713 
     | 
    
         
            +
             
     | 
| 
      
 1714 
     | 
    
         
            +
                      if stmt and sql.strip.upcase.start_with?("SELECT")
         
     | 
| 
      
 1715 
     | 
    
         
            +
                        cols = IBM_DB.resultCols(stmt)
         
     | 
| 
      
 1716 
     | 
    
         
            +
                        results = fetch_data(stmt) if stmt
         
     | 
| 
      
 1717 
     | 
    
         
            +
             
     | 
| 
      
 1718 
     | 
    
         
            +
                        puts_log "execute_without_logging columns = #{cols}"
         
     | 
| 
      
 1719 
     | 
    
         
            +
                        puts_log "execute_without_logging result = #{results}"
         
     | 
| 
      
 1720 
     | 
    
         
            +
                      end
         
     | 
| 
      
 1721 
     | 
    
         
            +
                    rescue => e
         
     | 
| 
      
 1722 
     | 
    
         
            +
                      raise translate_exception_class(e, sql, binds)
         
     | 
| 
      
 1723 
     | 
    
         
            +
                    ensure
         
     | 
| 
      
 1724 
     | 
    
         
            +
                      @offset = @limit = nil
         
     | 
| 
      
 1725 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1726 
     | 
    
         
            +
                    if @isAr3
         
     | 
| 
      
 1727 
     | 
    
         
            +
                      results
         
     | 
| 
      
 1728 
     | 
    
         
            +
                    elsif results.nil?
         
     | 
| 
      
 1729 
     | 
    
         
            +
                      ActiveRecord::Result.empty
         
     | 
| 
      
 1730 
     | 
    
         
            +
                    else
         
     | 
| 
      
 1731 
     | 
    
         
            +
                      ActiveRecord::Result.new(cols, results)
         
     | 
| 
      
 1732 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1733 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1734 
     | 
    
         
            +
             
     | 
| 
       1758 
1735 
     | 
    
         
             
                  # Executes +sql+ statement in the context of this connection using
         
     | 
| 
       1759 
1736 
     | 
    
         
             
                  # +binds+ as the bind substitutes.  +name+ is logged along with
         
     | 
| 
       1760 
1737 
     | 
    
         
             
                  # the executed +sql+ statement.
         
     | 
| 
       1761 
1738 
     | 
    
         
             
                  # Here prepare argument is not used, by default this method creates prepared statment and execute.
         
     | 
| 
       1762 
     | 
    
         
            -
                  def exec_query_ret_stmt(sql, name = 'SQL', binds = [], prepare: false, async: false)
         
     | 
| 
      
 1739 
     | 
    
         
            +
                  def exec_query_ret_stmt(sql, name = 'SQL', binds = [], prepare: false, async: false, allow_retry: false)
         
     | 
| 
       1763 
1740 
     | 
    
         
             
                    puts_log "exec_query_ret_stmt #{sql}"
         
     | 
| 
       1764 
1741 
     | 
    
         
             
                    sql = transform_query(sql)
         
     | 
| 
       1765 
1742 
     | 
    
         
             
                    check_if_write_query(sql)
         
     | 
| 
       1766 
     | 
    
         
            -
            #materialize_transactions
         
     | 
| 
       1767 
1743 
     | 
    
         
             
                    mark_transaction_written_if_write(sql)
         
     | 
| 
       1768 
1744 
     | 
    
         
             
                    begin
         
     | 
| 
       1769 
1745 
     | 
    
         
             
                      puts_log "SQL = #{sql}"
         
     | 
| 
         @@ -1778,7 +1754,7 @@ module ActiveRecord 
     | 
|
| 
       1778 
1754 
     | 
    
         | 
| 
       1779 
1755 
     | 
    
         
             
                      puts_log "Statement = #{stmt}"
         
     | 
| 
       1780 
1756 
     | 
    
         
             
                      log(sql, name, binds, param_array, async: async) do
         
     | 
| 
       1781 
     | 
    
         
            -
                        with_raw_connection do |conn|
         
     | 
| 
      
 1757 
     | 
    
         
            +
                        with_raw_connection(allow_retry: allow_retry) do |conn|
         
     | 
| 
       1782 
1758 
     | 
    
         
             
                          return false unless stmt
         
     | 
| 
       1783 
1759 
     | 
    
         
             
                          return stmt if execute_prepared_stmt(stmt, param_array)
         
     | 
| 
       1784 
1760 
     | 
    
         
             
                        end
         
     | 
| 
         @@ -1799,7 +1775,10 @@ module ActiveRecord 
     | 
|
| 
       1799 
1775 
     | 
    
         
             
                    puts_log "select_prepared sql before = #{sql}"
         
     | 
| 
       1800 
1776 
     | 
    
         
             
                    puts_log "select_prepared Binds = #{binds}"
         
     | 
| 
       1801 
1777 
     | 
    
         
             
                    stmt = exec_query_ret_stmt(sql, name, binds, prepare: prepare, async: async)
         
     | 
| 
       1802 
     | 
    
         
            -
                     
     | 
| 
      
 1778 
     | 
    
         
            +
                    cols = nil
         
     | 
| 
      
 1779 
     | 
    
         
            +
                    results = nil
         
     | 
| 
      
 1780 
     | 
    
         
            +
             
     | 
| 
      
 1781 
     | 
    
         
            +
                    if stmt and sql.strip.upcase.start_with?("SELECT")
         
     | 
| 
       1803 
1782 
     | 
    
         
             
                      cols = IBM_DB.resultCols(stmt)
         
     | 
| 
       1804 
1783 
     | 
    
         | 
| 
       1805 
1784 
     | 
    
         
             
                      results = fetch_data(stmt) if stmt
         
     | 
| 
         @@ -1807,12 +1786,11 @@ module ActiveRecord 
     | 
|
| 
       1807 
1786 
     | 
    
         
             
                      puts_log "select_prepared columns = #{cols}"
         
     | 
| 
       1808 
1787 
     | 
    
         
             
                      puts_log "select_prepared sql after = #{sql}"
         
     | 
| 
       1809 
1788 
     | 
    
         
             
                      puts_log "select_prepared result = #{results}"
         
     | 
| 
       1810 
     | 
    
         
            -
                    else
         
     | 
| 
       1811 
     | 
    
         
            -
                      cols = nil
         
     | 
| 
       1812 
     | 
    
         
            -
                      results = nil
         
     | 
| 
       1813 
1789 
     | 
    
         
             
                    end
         
     | 
| 
       1814 
1790 
     | 
    
         
             
                    if @isAr3
         
     | 
| 
       1815 
1791 
     | 
    
         
             
                      results
         
     | 
| 
      
 1792 
     | 
    
         
            +
                    elsif results.nil?
         
     | 
| 
      
 1793 
     | 
    
         
            +
                      ActiveRecord::Result.empty
         
     | 
| 
       1816 
1794 
     | 
    
         
             
                    else
         
     | 
| 
       1817 
1795 
     | 
    
         
             
                      ActiveRecord::Result.new(cols, results)
         
     | 
| 
       1818 
1796 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -1829,19 +1807,36 @@ module ActiveRecord 
     | 
|
| 
       1829 
1807 
     | 
    
         
             
                  def execute(sql, name = nil, allow_retry: false)
         
     | 
| 
       1830 
1808 
     | 
    
         
             
                    puts_log "execute #{sql}"
         
     | 
| 
       1831 
1809 
     | 
    
         
             
                    ActiveRecord::Base.clear_query_caches_for_current_thread
         
     | 
| 
       1832 
     | 
    
         
            -
                    internal_execute(sql, name, allow_retry: allow_retry)
         
     | 
| 
      
 1810 
     | 
    
         
            +
                    stmt = internal_execute(sql, name, allow_retry: allow_retry)
         
     | 
| 
      
 1811 
     | 
    
         
            +
                    cols = nil
         
     | 
| 
      
 1812 
     | 
    
         
            +
                    results = nil
         
     | 
| 
      
 1813 
     | 
    
         
            +
                    puts_log "raw_execute stmt = #{stmt}"
         
     | 
| 
      
 1814 
     | 
    
         
            +
                    if sql.strip.upcase.start_with?("SELECT") and stmt
         
     | 
| 
      
 1815 
     | 
    
         
            +
                      cols = IBM_DB.resultCols(stmt)
         
     | 
| 
      
 1816 
     | 
    
         
            +
                      results = fetch_data(stmt)
         
     | 
| 
      
 1817 
     | 
    
         
            +
             
     | 
| 
      
 1818 
     | 
    
         
            +
                      puts_log "execute columns = #{cols}"
         
     | 
| 
      
 1819 
     | 
    
         
            +
                      puts_log "execute result = #{results}"
         
     | 
| 
      
 1820 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1821 
     | 
    
         
            +
                    if results.nil? || results.empty?
         
     | 
| 
      
 1822 
     | 
    
         
            +
                      stmt
         
     | 
| 
      
 1823 
     | 
    
         
            +
                    else
         
     | 
| 
      
 1824 
     | 
    
         
            +
                      formatted = cols.each_with_index.map { |col, i| { col => results[i].first } }
         
     | 
| 
      
 1825 
     | 
    
         
            +
                      puts_log "raw_execute formatted = #{formatted}"
         
     | 
| 
      
 1826 
     | 
    
         
            +
                      formatted.to_s
         
     | 
| 
      
 1827 
     | 
    
         
            +
                    end
         
     | 
| 
       1833 
1828 
     | 
    
         
             
                  end
         
     | 
| 
       1834 
1829 
     | 
    
         | 
| 
       1835 
1830 
     | 
    
         
             
                  def raw_execute(sql, name, async: false, allow_retry: false, materialize_transactions: true)
         
     | 
| 
       1836 
1831 
     | 
    
         
             
                    # Logs and execute the sql instructions.
         
     | 
| 
       1837 
1832 
     | 
    
         
             
                    # The +log+ method is defined in the parent class +AbstractAdapter+
         
     | 
| 
       1838 
1833 
     | 
    
         
             
                    # sql='INSERT INTO ar_internal_metadata (key, value, created_at, updated_at) VALUES ('10', '10', '10', '10')
         
     | 
| 
       1839 
     | 
    
         
            -
                    puts_log "raw_execute #{sql} #{Thread.current}"
         
     | 
| 
      
 1834 
     | 
    
         
            +
                    puts_log "raw_execute sql = #{sql} #{Thread.current}"
         
     | 
| 
       1840 
1835 
     | 
    
         
             
                    log(sql, name, async: async) do
         
     | 
| 
       1841 
1836 
     | 
    
         
             
                      with_raw_connection(allow_retry: allow_retry, materialize_transactions: materialize_transactions) do |conn|
         
     | 
| 
       1842 
1837 
     | 
    
         
             
                        verify!
         
     | 
| 
       1843 
1838 
     | 
    
         
             
                        puts_log "raw_execute executes query #{Thread.current}"
         
     | 
| 
       1844 
     | 
    
         
            -
                        result 
     | 
| 
      
 1839 
     | 
    
         
            +
                        result= @servertype.execute(sql, name)
         
     | 
| 
       1845 
1840 
     | 
    
         
             
                        puts_log "raw_execute result = #{result} #{Thread.current}"
         
     | 
| 
       1846 
1841 
     | 
    
         
             
                        verified!
         
     | 
| 
       1847 
1842 
     | 
    
         
             
                        result
         
     | 
| 
         @@ -2009,7 +2004,8 @@ module ActiveRecord 
     | 
|
| 
       2009 
2004 
     | 
    
         
             
                  end
         
     | 
| 
       2010 
2005 
     | 
    
         | 
| 
       2011 
2006 
     | 
    
         
             
                  def default_sequence_name(table, column) # :nodoc:
         
     | 
| 
       2012 
     | 
    
         
            -
                    puts_log  
     | 
| 
      
 2007 
     | 
    
         
            +
                    puts_log "default_sequence_name table = #{table}, column = #{column}"
         
     | 
| 
      
 2008 
     | 
    
         
            +
                    return nil if column.is_a?(Array)
         
     | 
| 
       2013 
2009 
     | 
    
         
             
                    "#{table}_#{column}_seq"
         
     | 
| 
       2014 
2010 
     | 
    
         
             
                  end
         
     | 
| 
       2015 
2011 
     | 
    
         | 
| 
         @@ -2078,6 +2074,7 @@ module ActiveRecord 
     | 
|
| 
       2078 
2074 
     | 
    
         | 
| 
       2079 
2075 
     | 
    
         
             
                  def quote_table_name(name)
         
     | 
| 
       2080 
2076 
     | 
    
         
             
                    puts_log "quote_table_name #{name}"
         
     | 
| 
      
 2077 
     | 
    
         
            +
                    puts_log caller
         
     | 
| 
       2081 
2078 
     | 
    
         
             
                    if name.start_with? '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
         
     | 
| 
       2082 
2079 
     | 
    
         
             
                      name = "\"#{name}\""
         
     | 
| 
       2083 
2080 
     | 
    
         
             
                    else
         
     | 
| 
         @@ -2089,7 +2086,7 @@ module ActiveRecord 
     | 
|
| 
       2089 
2086 
     | 
    
         
             
                  end
         
     | 
| 
       2090 
2087 
     | 
    
         | 
| 
       2091 
2088 
     | 
    
         
             
                  def quote_column_name(name)
         
     | 
| 
       2092 
     | 
    
         
            -
                    puts_log  
     | 
| 
      
 2089 
     | 
    
         
            +
                    puts_log "quote_column_name #{name}"
         
     | 
| 
       2093 
2090 
     | 
    
         
             
                    @servertype.check_reserved_words(name).gsub('"', '').gsub("'", '')
         
     | 
| 
       2094 
2091 
     | 
    
         
             
                  end
         
     | 
| 
       2095 
2092 
     | 
    
         | 
| 
         @@ -2106,7 +2103,7 @@ module ActiveRecord 
     | 
|
| 
       2106 
2103 
     | 
    
         
             
                  def native_database_types
         
     | 
| 
       2107 
2104 
     | 
    
         
             
                    {
         
     | 
| 
       2108 
2105 
     | 
    
         
             
                      primary_key: { name: @servertype.primary_key_definition(@start_id) },
         
     | 
| 
       2109 
     | 
    
         
            -
                      string: { name: 'varchar', limit:  
     | 
| 
      
 2106 
     | 
    
         
            +
                      string: { name: 'varchar', limit: 400 },
         
     | 
| 
       2110 
2107 
     | 
    
         
             
                      text: { name: 'clob' },
         
     | 
| 
       2111 
2108 
     | 
    
         
             
                      integer: { name: 'integer' },
         
     | 
| 
       2112 
2109 
     | 
    
         
             
                      float: { name: 'float' },
         
     | 
| 
         @@ -2509,7 +2506,7 @@ module ActiveRecord 
     | 
|
| 
       2509 
2506 
     | 
    
         
             
                          next if is_composite
         
     | 
| 
       2510 
2507 
     | 
    
         | 
| 
       2511 
2508 
     | 
    
         
             
                          sql = "select remarks from syscat.indexes where tabname = #{quote(table_name.upcase)} and indname = #{quote(index_stats[5])}"
         
     | 
| 
       2512 
     | 
    
         
            -
                          comment = single_value_from_rows( 
     | 
| 
      
 2509 
     | 
    
         
            +
                          comment = single_value_from_rows(execute_without_logging(sql, "SCHEMA").rows)
         
     | 
| 
       2513 
2510 
     | 
    
         | 
| 
       2514 
2511 
     | 
    
         
             
                          indexes << IndexDefinition.new(table_name, index_name, index_unique, index_columns,
         
     | 
| 
       2515 
2512 
     | 
    
         
             
                                                         comment: comment)
         
     | 
| 
         @@ -2669,22 +2666,34 @@ module ActiveRecord 
     | 
|
| 
       2669 
2666 
     | 
    
         
             
                    #       sql = "select * from sysibm.sqlcolumns where table_name = #{quote(table_name.upcase)}"
         
     | 
| 
       2670 
2667 
     | 
    
         
             
                    if @debug == true
         
     | 
| 
       2671 
2668 
     | 
    
         
             
                      sql = "select * from syscat.columns  where tabname = #{quote(table_name.upcase)}"
         
     | 
| 
       2672 
     | 
    
         
            -
                      puts_log "SYSIBM.SQLCOLUMNS = #{ 
     | 
| 
      
 2669 
     | 
    
         
            +
                      puts_log "SYSIBM.SQLCOLUMNS = #{execute_without_logging(sql).rows}"
         
     | 
| 
       2673 
2670 
     | 
    
         
             
                    end
         
     | 
| 
       2674 
2671 
     | 
    
         | 
| 
      
 2672 
     | 
    
         
            +
                    pri_key = primary_key(table_name)
         
     | 
| 
      
 2673 
     | 
    
         
            +
             
     | 
| 
       2675 
2674 
     | 
    
         
             
                    if stmt
         
     | 
| 
       2676 
2675 
     | 
    
         
             
                      begin
         
     | 
| 
       2677 
2676 
     | 
    
         
             
                        # Fetches all the columns and assigns them to col.
         
     | 
| 
       2678 
2677 
     | 
    
         
             
                        # +col+ is an hash with keys/value pairs for a column
         
     | 
| 
       2679 
2678 
     | 
    
         
             
                        while col = IBM_DB.fetch_assoc(stmt)
         
     | 
| 
       2680 
     | 
    
         
            -
                           
     | 
| 
      
 2679 
     | 
    
         
            +
                          rowid = false
         
     | 
| 
      
 2680 
     | 
    
         
            +
                          puts_log "def columns fecthed = #{col}"
         
     | 
| 
       2681 
2681 
     | 
    
         
             
                          column_name = col['column_name'].downcase
         
     | 
| 
      
 2682 
     | 
    
         
            +
                          sql = "select 1 FROM syscat.columns where tabname = #{quote(table_name.upcase)} and generated = 'D' and colname = '#{col['column_name']}'"
         
     | 
| 
      
 2683 
     | 
    
         
            +
                          rows = execute_without_logging(sql).rows
         
     | 
| 
      
 2684 
     | 
    
         
            +
                          auto_increment = rows.dig(0, 0) == 1 ? true : nil
         
     | 
| 
      
 2685 
     | 
    
         
            +
                          puts_log "def columns auto_increment = #{rows}, #{auto_increment}"
         
     | 
| 
      
 2686 
     | 
    
         
            +
             
     | 
| 
       2682 
2687 
     | 
    
         
             
                          # Assigns the column default value.
         
     | 
| 
       2683 
2688 
     | 
    
         
             
                          column_default_value = col['column_def']
         
     | 
| 
       2684 
2689 
     | 
    
         
             
                          default_value = extract_value_from_default(column_default_value)
         
     | 
| 
       2685 
2690 
     | 
    
         
             
                          # Assigns the column type
         
     | 
| 
       2686 
2691 
     | 
    
         
             
                          column_type = col['type_name'].downcase
         
     | 
| 
       2687 
2692 
     | 
    
         | 
| 
      
 2693 
     | 
    
         
            +
                          if Array(pri_key).include?(column_name) and column_type =~ /integer|bigint/i
         
     | 
| 
      
 2694 
     | 
    
         
            +
                            rowid = true
         
     | 
| 
      
 2695 
     | 
    
         
            +
                            puts_log "def columns rowid = true"
         
     | 
| 
      
 2696 
     | 
    
         
            +
                          end
         
     | 
| 
       2688 
2697 
     | 
    
         
             
                          # Assigns the field length (size) for the column
         
     | 
| 
       2689 
2698 
     | 
    
         | 
| 
       2690 
2699 
     | 
    
         
             
                          column_length = if column_type =~ /integer|bigint/i
         
     | 
| 
         @@ -2743,7 +2752,9 @@ module ActiveRecord 
     | 
|
| 
       2743 
2752 
     | 
    
         | 
| 
       2744 
2753 
     | 
    
         
             
                          column_type = 'boolean' if ruby_type.to_s == 'boolean'
         
     | 
| 
       2745 
2754 
     | 
    
         | 
| 
      
 2755 
     | 
    
         
            +
                          puts_log "Inside def columns() - default_value = #{default_value}, column_default_value = #{column_default_value}"
         
     | 
| 
       2746 
2756 
     | 
    
         
             
                          default_function = extract_default_function(default_value, column_default_value)
         
     | 
| 
      
 2757 
     | 
    
         
            +
                          puts_log "Inside def columns() - default_function = #{default_function}"
         
     | 
| 
       2747 
2758 
     | 
    
         | 
| 
       2748 
2759 
     | 
    
         
             
                          sqltype_metadata = SqlTypeMetadata.new(
         
     | 
| 
       2749 
2760 
     | 
    
         
             
                            # sql_type: sql_type,
         
     | 
| 
         @@ -2755,7 +2766,7 @@ module ActiveRecord 
     | 
|
| 
       2755 
2766 
     | 
    
         
             
                          )
         
     | 
| 
       2756 
2767 
     | 
    
         | 
| 
       2757 
2768 
     | 
    
         
             
                          columns << Column.new(column_name, default_value, sqltype_metadata, column_nullable, default_function,
         
     | 
| 
       2758 
     | 
    
         
            -
                                                comment: col['remarks'])
         
     | 
| 
      
 2769 
     | 
    
         
            +
                                                comment: col['remarks'], auto_increment: auto_increment, rowid: rowid)
         
     | 
| 
       2759 
2770 
     | 
    
         
             
                        end
         
     | 
| 
       2760 
2771 
     | 
    
         
             
                      rescue StandardError => e # Handle driver fetch errors
         
     | 
| 
       2761 
2772 
     | 
    
         
             
                        error_msg = IBM_DB.getErrormsg(stmt, IBM_DB::DB_STMT)
         
     | 
| 
         @@ -2789,6 +2800,7 @@ module ActiveRecord 
     | 
|
| 
       2789 
2800 
     | 
    
         | 
| 
       2790 
2801 
     | 
    
         
             
                  def has_default_function?(default_value, default)
         
     | 
| 
       2791 
2802 
     | 
    
         
             
                    !default_value && /\w+\(.*\)|CURRENT_TIME|CURRENT_DATE|CURRENT_TIMESTAMP/.match?(default)
         
     | 
| 
      
 2803 
     | 
    
         
            +
                    !default_value && /(\w+\(.*\)|CURRENT(?:[_\s]TIME|[_\s]DATE|[_\s]TIMESTAMP))/i.match?(default)
         
     | 
| 
       2792 
2804 
     | 
    
         
             
                  end
         
     | 
| 
       2793 
2805 
     | 
    
         | 
| 
       2794 
2806 
     | 
    
         
             
                  def foreign_keys(table_name)
         
     | 
| 
         @@ -2932,9 +2944,10 @@ module ActiveRecord 
     | 
|
| 
       2932 
2944 
     | 
    
         | 
| 
       2933 
2945 
     | 
    
         
             
                  # Adds comment for given table or drops it if +comment+ is a +nil+
         
     | 
| 
       2934 
2946 
     | 
    
         
             
                  def change_table_comment(table_name, comment_or_changes) # :nodoc:
         
     | 
| 
       2935 
     | 
    
         
            -
                    puts_log  
     | 
| 
      
 2947 
     | 
    
         
            +
                    puts_log "change_table_comment table_name = #{table_name}, comment_or_changes = #{comment_or_changes}"
         
     | 
| 
       2936 
2948 
     | 
    
         
             
                    clear_cache!
         
     | 
| 
       2937 
2949 
     | 
    
         
             
                    comment = extract_new_comment_value(comment_or_changes)
         
     | 
| 
      
 2950 
     | 
    
         
            +
                    puts_log "change_table_comment new_comment = #{comment}"
         
     | 
| 
       2938 
2951 
     | 
    
         
             
                    if comment.nil?
         
     | 
| 
       2939 
2952 
     | 
    
         
             
                      execute "COMMENT ON TABLE #{quote_table_name(table_name)} IS ''"
         
     | 
| 
       2940 
2953 
     | 
    
         
             
                    else
         
     | 
| 
         @@ -2963,9 +2976,9 @@ module ActiveRecord 
     | 
|
| 
       2963 
2976 
     | 
    
         
             
                  end
         
     | 
| 
       2964 
2977 
     | 
    
         | 
| 
       2965 
2978 
     | 
    
         
             
                  def table_comment(table_name) # :nodoc:
         
     | 
| 
       2966 
     | 
    
         
            -
                    puts_log  
     | 
| 
      
 2979 
     | 
    
         
            +
                    puts_log "table_comment table_name = #{table_name}"
         
     | 
| 
       2967 
2980 
     | 
    
         
             
                    sql = "select remarks from syscat.tables where tabname = #{quote(table_name.upcase)}"
         
     | 
| 
       2968 
     | 
    
         
            -
                    single_value_from_rows( 
     | 
| 
      
 2981 
     | 
    
         
            +
                    single_value_from_rows(execute_without_logging(sql).rows)
         
     | 
| 
       2969 
2982 
     | 
    
         
             
                  end
         
     | 
| 
       2970 
2983 
     | 
    
         | 
| 
       2971 
2984 
     | 
    
         
             
                  def add_index(table_name, column_name, **options) # :nodoc:
         
     | 
| 
         @@ -3087,7 +3100,7 @@ module ActiveRecord 
     | 
|
| 
       3087 
3100 
     | 
    
         
             
                  # rename_table('octopuses', 'octopi')
         
     | 
| 
       3088 
3101 
     | 
    
         
             
                  # Overriden to satisfy IBM data servers syntax
         
     | 
| 
       3089 
3102 
     | 
    
         
             
                  def rename_table(name, new_name, **options)
         
     | 
| 
       3090 
     | 
    
         
            -
                    puts_log  
     | 
| 
      
 3103 
     | 
    
         
            +
                    puts_log "rename_table name = #{name}, new_name = #{new_name}"
         
     | 
| 
       3091 
3104 
     | 
    
         
             
                    validate_table_length!(new_name) unless options[:_uses_legacy_table_name]
         
     | 
| 
       3092 
3105 
     | 
    
         
             
                    clear_cache!
         
     | 
| 
       3093 
3106 
     | 
    
         
             
                    schema_cache.clear_data_source_cache!(name.to_s)
         
     | 
| 
         @@ -3108,19 +3121,20 @@ module ActiveRecord 
     | 
|
| 
       3108 
3121 
     | 
    
         
             
                  end
         
     | 
| 
       3109 
3122 
     | 
    
         | 
| 
       3110 
3123 
     | 
    
         
             
                  def add_reference(table_name, ref_name, **options) # :nodoc:
         
     | 
| 
      
 3124 
     | 
    
         
            +
                    puts_log "add_reference table_name = #{table_name}, ref_name = #{ref_name}"
         
     | 
| 
       3111 
3125 
     | 
    
         
             
                    super(table_name, ref_name, type: :integer, **options)
         
     | 
| 
       3112 
3126 
     | 
    
         
             
                  end
         
     | 
| 
       3113 
3127 
     | 
    
         
             
                  alias :add_belongs_to :add_reference
         
     | 
| 
       3114 
3128 
     | 
    
         | 
| 
       3115 
3129 
     | 
    
         
             
                  def drop_table_indexes(index_list)
         
     | 
| 
       3116 
     | 
    
         
            -
                    puts_log  
     | 
| 
      
 3130 
     | 
    
         
            +
                    puts_log "drop_table_indexes index_list = #{index_list}"
         
     | 
| 
       3117 
3131 
     | 
    
         
             
                    index_list.each do |indexs|
         
     | 
| 
       3118 
3132 
     | 
    
         
             
                      remove_index(indexs.table, name: indexs.name)
         
     | 
| 
       3119 
3133 
     | 
    
         
             
                    end
         
     | 
| 
       3120 
3134 
     | 
    
         
             
                  end
         
     | 
| 
       3121 
3135 
     | 
    
         | 
| 
       3122 
3136 
     | 
    
         
             
                  def create_table_indexes(index_list, new_table)
         
     | 
| 
       3123 
     | 
    
         
            -
                    puts_log  
     | 
| 
      
 3137 
     | 
    
         
            +
                    puts_log "create_table_indexes index_list = #{index_list}, new_table = #{new_table}"
         
     | 
| 
       3124 
3138 
     | 
    
         
             
                    index_list.each do |indexs|
         
     | 
| 
       3125 
3139 
     | 
    
         
             
                      generated_index_name = index_name(indexs.table, column: indexs.columns)
         
     | 
| 
       3126 
3140 
     | 
    
         
             
                      custom_index_name = indexs.name
         
     | 
| 
         @@ -3412,6 +3426,7 @@ module ActiveRecord 
     | 
|
| 
       3412 
3426 
     | 
    
         
             
                    puts_log "remove_unique_constraint table_name = #{table_name}, column_name = #{column_name}, options = #{options}"
         
     | 
| 
       3413 
3427 
     | 
    
         
             
                    unique_name_to_delete = unique_constraint_for!(table_name, column: column_name, **options).name
         
     | 
| 
       3414 
3428 
     | 
    
         | 
| 
      
 3429 
     | 
    
         
            +
                    puts_log "remove_unique_constraint unique_name_to_delete = #{unique_name_to_delete}"
         
     | 
| 
       3415 
3430 
     | 
    
         
             
                    at = create_alter_table(table_name)
         
     | 
| 
       3416 
3431 
     | 
    
         
             
                    at.drop_unique_constraint(unique_name_to_delete)
         
     | 
| 
       3417 
3432 
     | 
    
         | 
| 
         @@ -3419,7 +3434,7 @@ module ActiveRecord 
     | 
|
| 
       3419 
3434 
     | 
    
         
             
                  end
         
     | 
| 
       3420 
3435 
     | 
    
         | 
| 
       3421 
3436 
     | 
    
         
             
                  def unique_constraint_name(table_name, **options)
         
     | 
| 
       3422 
     | 
    
         
            -
                    puts_log "unique_constraint_name"
         
     | 
| 
      
 3437 
     | 
    
         
            +
                    puts_log "unique_constraint_name table_name = #{table_name}, options = #{options}"
         
     | 
| 
       3423 
3438 
     | 
    
         
             
                    options.fetch(:name) do
         
     | 
| 
       3424 
3439 
     | 
    
         
             
                      column_or_index = Array(options[:column] || options[:using_index]).map(&:to_s)
         
     | 
| 
       3425 
3440 
     | 
    
         
             
                      identifier = "#{table_name}_#{column_or_index * '_and_'}_unique"
         
     | 
| 
         @@ -3430,16 +3445,72 @@ module ActiveRecord 
     | 
|
| 
       3430 
3445 
     | 
    
         
             
                  end
         
     | 
| 
       3431 
3446 
     | 
    
         | 
| 
       3432 
3447 
     | 
    
         
             
                  def unique_constraint_for(table_name, **options)
         
     | 
| 
       3433 
     | 
    
         
            -
                     
     | 
| 
       3434 
     | 
    
         
            -
                     
     | 
| 
      
 3448 
     | 
    
         
            +
                    puts_log "unique_constraint_for table_name = #{table_name}, options = #{options}"
         
     | 
| 
      
 3449 
     | 
    
         
            +
                    name = unique_constraint_name(table_name, **options)
         
     | 
| 
      
 3450 
     | 
    
         
            +
                    puts_log "unique_constraint_for name = #{name}"
         
     | 
| 
      
 3451 
     | 
    
         
            +
                    uq = unique_constraints(table_name)
         
     | 
| 
      
 3452 
     | 
    
         
            +
                    puts_log "unique_constraint_for unique_constraints = #{uq}"
         
     | 
| 
      
 3453 
     | 
    
         
            +
                    uq.detect { |unique_constraint| unique_constraint.defined_for?(name: name) }
         
     | 
| 
       3435 
3454 
     | 
    
         
             
                  end
         
     | 
| 
       3436 
3455 
     | 
    
         | 
| 
       3437 
3456 
     | 
    
         
             
                  def unique_constraint_for!(table_name, column: nil, **options)
         
     | 
| 
       3438 
     | 
    
         
            -
                    puts_log "unique_constraint_for table_name = #{table_name}, column = #{column}, options = #{options}"
         
     | 
| 
      
 3457 
     | 
    
         
            +
                    puts_log "unique_constraint_for! table_name = #{table_name}, column = #{column}, options = #{options}"
         
     | 
| 
       3439 
3458 
     | 
    
         
             
                    unique_constraint_for(table_name, column: column, **options) ||
         
     | 
| 
       3440 
3459 
     | 
    
         
             
                    raise(ArgumentError, "Table '#{table_name}' has no unique constraint for #{column || options}")
         
     | 
| 
       3441 
3460 
     | 
    
         
             
                  end
         
     | 
| 
       3442 
3461 
     | 
    
         | 
| 
      
 3462 
     | 
    
         
            +
                  def foreign_key_name(table_name, options)
         
     | 
| 
      
 3463 
     | 
    
         
            +
                    puts_log "foreign_key_name table_name = #{table_name}, options = #{options}"
         
     | 
| 
      
 3464 
     | 
    
         
            +
                    options.fetch(:name) do
         
     | 
| 
      
 3465 
     | 
    
         
            +
                      columns = Array(options.fetch(:column)).map(&:to_s)
         
     | 
| 
      
 3466 
     | 
    
         
            +
                      identifier = "#{table_name}_#{columns * '_and_'}_fk"
         
     | 
| 
      
 3467 
     | 
    
         
            +
                      hashed_identifier = OpenSSL::Digest::SHA256.hexdigest(identifier).first(10)
         
     | 
| 
      
 3468 
     | 
    
         
            +
             
     | 
| 
      
 3469 
     | 
    
         
            +
                      "fk_rails_#{hashed_identifier}"
         
     | 
| 
      
 3470 
     | 
    
         
            +
                    end
         
     | 
| 
      
 3471 
     | 
    
         
            +
                  end
         
     | 
| 
      
 3472 
     | 
    
         
            +
             
     | 
| 
      
 3473 
     | 
    
         
            +
                  def foreign_key_for(from_table, **options)
         
     | 
| 
      
 3474 
     | 
    
         
            +
                    puts_log "foreign_key_for from_table = #{from_table}, options = #{options}"
         
     | 
| 
      
 3475 
     | 
    
         
            +
                    return unless use_foreign_keys?
         
     | 
| 
      
 3476 
     | 
    
         
            +
                    fks = foreign_keys(from_table)
         
     | 
| 
      
 3477 
     | 
    
         
            +
                    puts_log "foreign_key_for fks = #{fks}"
         
     | 
| 
      
 3478 
     | 
    
         
            +
                    if options.key?(:column) && options.key?(:to_table) && options[:to_table] != nil
         
     | 
| 
      
 3479 
     | 
    
         
            +
                      name = foreign_key_name(from_table, options)
         
     | 
| 
      
 3480 
     | 
    
         
            +
                      puts_log "foreign_key_for name = #{options}"
         
     | 
| 
      
 3481 
     | 
    
         
            +
                      fks.detect { |fk| fk.defined_for?(name: name) }
         
     | 
| 
      
 3482 
     | 
    
         
            +
                    else
         
     | 
| 
      
 3483 
     | 
    
         
            +
                      fks.detect { |fk| fk.defined_for?(**options) }
         
     | 
| 
      
 3484 
     | 
    
         
            +
                    end
         
     | 
| 
      
 3485 
     | 
    
         
            +
                  end
         
     | 
| 
      
 3486 
     | 
    
         
            +
             
     | 
| 
      
 3487 
     | 
    
         
            +
                  def foreign_key_for!(from_table, to_table: nil, **options)
         
     | 
| 
      
 3488 
     | 
    
         
            +
                    puts_log "foreign_key_for! from_table = #{from_table}, to_table = #{to_table}, options = #{options}"
         
     | 
| 
      
 3489 
     | 
    
         
            +
                    foreign_key_for(from_table, to_table: to_table, **options) ||
         
     | 
| 
      
 3490 
     | 
    
         
            +
                      raise(ArgumentError, "Table '#{from_table}' has no foreign key for #{to_table || options}")
         
     | 
| 
      
 3491 
     | 
    
         
            +
                  end
         
     | 
| 
      
 3492 
     | 
    
         
            +
             
     | 
| 
      
 3493 
     | 
    
         
            +
                  def foreign_key_exists?(from_table, to_table = nil, **options)
         
     | 
| 
      
 3494 
     | 
    
         
            +
                    puts_log "foreign_key_exists? from_table = #{from_table}, to_table = #{to_table}, options = #{options}"
         
     | 
| 
      
 3495 
     | 
    
         
            +
                    foreign_key_for(from_table, to_table: to_table, **options).present?
         
     | 
| 
      
 3496 
     | 
    
         
            +
                  end
         
     | 
| 
      
 3497 
     | 
    
         
            +
             
     | 
| 
      
 3498 
     | 
    
         
            +
                  def remove_foreign_key(from_table, to_table = nil, **options)
         
     | 
| 
      
 3499 
     | 
    
         
            +
                    puts_log "remove_foreign_key from_table = #{from_table}, to_table = #{to_table}, options = #{options}"
         
     | 
| 
      
 3500 
     | 
    
         
            +
                    #to_table ||= options[:to_table]
         
     | 
| 
      
 3501 
     | 
    
         
            +
                    return unless use_foreign_keys?
         
     | 
| 
      
 3502 
     | 
    
         
            +
                    #return if options.delete(:if_exists) == true && !foreign_key_exists?(from_table, to_table, **options.slice(:column))
         
     | 
| 
      
 3503 
     | 
    
         
            +
                    return if options.delete(:if_exists) == true && !foreign_key_exists?(from_table, to_table)
         
     | 
| 
      
 3504 
     | 
    
         
            +
             
     | 
| 
      
 3505 
     | 
    
         
            +
                    fk_name_to_delete = foreign_key_for!(from_table, to_table: to_table, **options).name
         
     | 
| 
      
 3506 
     | 
    
         
            +
                    puts_log "remove_foreign_key fk_name_to_delete = #{fk_name_to_delete}"
         
     | 
| 
      
 3507 
     | 
    
         
            +
             
     | 
| 
      
 3508 
     | 
    
         
            +
                    at = create_alter_table from_table
         
     | 
| 
      
 3509 
     | 
    
         
            +
                    at.drop_foreign_key fk_name_to_delete
         
     | 
| 
      
 3510 
     | 
    
         
            +
             
     | 
| 
      
 3511 
     | 
    
         
            +
                    execute schema_creation.accept(at)
         
     | 
| 
      
 3512 
     | 
    
         
            +
                  end
         
     | 
| 
      
 3513 
     | 
    
         
            +
             
     | 
| 
       3443 
3514 
     | 
    
         
             
                  def create_table_definition(name, **options)
         
     | 
| 
       3444 
3515 
     | 
    
         
             
                    puts_log "create_table_definition name = #{name}"
         
     | 
| 
       3445 
3516 
     | 
    
         
             
                    puts_log caller
         
     |