activerecord-jdbc-alt-adapter 72.0.0.alpha1-java → 72.0.0.rc1-java
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/README.md +2 -2
 - data/lib/arjdbc/abstract/core.rb +10 -1
 - data/lib/arjdbc/abstract/transaction_support.rb +3 -1
 - data/lib/arjdbc/jdbc/adapter.rb +0 -1
 - data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
 - data/lib/arjdbc/mssql/adapter.rb +12 -13
 - data/lib/arjdbc/mssql/column.rb +16 -7
 - data/lib/arjdbc/mssql/database_statements.rb +5 -0
 - data/lib/arjdbc/mssql/schema_creation.rb +16 -0
 - data/lib/arjdbc/mssql/schema_statements.rb +43 -1
 - data/lib/arjdbc/mysql/adapter.rb +1 -10
 - data/lib/arjdbc/mysql/adapter_hash_config.rb +12 -2
 - data/lib/arjdbc/postgresql/adapter.rb +14 -2
 - data/lib/arjdbc/sqlite3/adapter.rb +164 -66
 - data/lib/arjdbc/sqlite3/column.rb +17 -3
 - data/lib/arjdbc/sqlite3/pragmas.rb +105 -0
 - data/lib/arjdbc/version.rb +1 -1
 - data/lib/arjdbc.rb +9 -0
 - data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +5 -0
 - data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +12 -2
 - metadata +4 -4
 - data/lib/arjdbc/jdbc/base_ext.rb +0 -17
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 0f7f249466042cd80343c394b99718ff78c5754a2105f06eaf87672f25d2d54e
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: cc61ff60b8f74d3fa100156f59c4cdd198865e87d9be401bf833a2e0ed623291
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 25c0368cbbeecad8536caa0ffadff34c28aacb0ff4a66f2085016224322645add68206976dbcef42475bdc39c1ffd47da761eacd919292ae15e6711c44935317
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 9beed2af43699a9349a9284c252fd97db3c0110510892ac6937b5ace94df6be02269fb7360caa653fb864a4326d6582e958bea1afe4c69d8adaabec96af2a671
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -175,7 +175,7 @@ adapters are available: 
     | 
|
| 
       175 
175 
     | 
    
         | 
| 
       176 
176 
     | 
    
         
             
            ```yml
         
     | 
| 
       177 
177 
     | 
    
         
             
            development:
         
     | 
| 
       178 
     | 
    
         
            -
              adapter: mysql2 
     | 
| 
      
 178 
     | 
    
         
            +
              adapter: mysql2
         
     | 
| 
       179 
179 
     | 
    
         
             
              database: blog_development
         
     | 
| 
       180 
180 
     | 
    
         
             
              username: blog
         
     | 
| 
       181 
181 
     | 
    
         
             
              password: 1234
         
     | 
| 
         @@ -199,7 +199,7 @@ or preferably using the *properties:* syntax: 
     | 
|
| 
       199 
199 
     | 
    
         | 
| 
       200 
200 
     | 
    
         
             
            ```yml
         
     | 
| 
       201 
201 
     | 
    
         
             
            production:
         
     | 
| 
       202 
     | 
    
         
            -
              adapter:  
     | 
| 
      
 202 
     | 
    
         
            +
              adapter: mysql2
         
     | 
| 
       203 
203 
     | 
    
         
             
              username: blog
         
     | 
| 
       204 
204 
     | 
    
         
             
              password: blog
         
     | 
| 
       205 
205 
     | 
    
         
             
              url: "jdbc:mysql://localhost:3306/blog?profileSQL=true"
         
     | 
    
        data/lib/arjdbc/abstract/core.rb
    CHANGED
    
    | 
         @@ -60,7 +60,16 @@ module ArJdbc 
     | 
|
| 
       60 
60 
     | 
    
         
             
                  # this version of log() automatically fills type_casted_binds from binds if necessary
         
     | 
| 
       61 
61 
     | 
    
         
             
                  def log(sql, name = "SQL", binds = [], type_casted_binds = [], statement_name = nil, async: false)
         
     | 
| 
       62 
62 
     | 
    
         
             
                    if binds.any? && (type_casted_binds.nil? || type_casted_binds.empty?)
         
     | 
| 
       63 
     | 
    
         
            -
                      type_casted_binds =  
     | 
| 
      
 63 
     | 
    
         
            +
                      type_casted_binds = lambda {
         
     | 
| 
      
 64 
     | 
    
         
            +
                        # extract_raw_bind_values
         
     | 
| 
      
 65 
     | 
    
         
            +
                        binds.map do |bind|
         
     | 
| 
      
 66 
     | 
    
         
            +
                          if bind.respond_to?(:value_for_database)
         
     | 
| 
      
 67 
     | 
    
         
            +
                            bind.value_for_database
         
     | 
| 
      
 68 
     | 
    
         
            +
                          else
         
     | 
| 
      
 69 
     | 
    
         
            +
                            bind
         
     | 
| 
      
 70 
     | 
    
         
            +
                          end
         
     | 
| 
      
 71 
     | 
    
         
            +
                        end
         
     | 
| 
      
 72 
     | 
    
         
            +
                      }
         
     | 
| 
       64 
73 
     | 
    
         
             
                    end
         
     | 
| 
       65 
74 
     | 
    
         
             
                    super
         
     | 
| 
       66 
75 
     | 
    
         
             
                  end
         
     | 
    
        data/lib/arjdbc/jdbc/adapter.rb
    CHANGED
    
    
| 
         Binary file 
     | 
    
        data/lib/arjdbc/mssql/adapter.rb
    CHANGED
    
    | 
         @@ -54,6 +54,7 @@ module ActiveRecord 
     | 
|
| 
       54 
54 
     | 
    
         
             
                  include MSSQL::ExplainSupport
         
     | 
| 
       55 
55 
     | 
    
         
             
                  include MSSQL::DatabaseLimits
         
     | 
| 
       56 
56 
     | 
    
         | 
| 
      
 57 
     | 
    
         
            +
                  # Latin1-General, case-sensitive, accent-sensitive, kanatype-insensitive, width-sensitive
         
     | 
| 
       57 
58 
     | 
    
         
             
                  @cs_equality_operator = 'COLLATE Latin1_General_CS_AS_WS'
         
     | 
| 
       58 
59 
     | 
    
         | 
| 
       59 
60 
     | 
    
         
             
                  class << self
         
     | 
| 
         @@ -265,29 +266,25 @@ module ActiveRecord 
     | 
|
| 
       265 
266 
     | 
    
         | 
| 
       266 
267 
     | 
    
         
             
                  alias_method :current_schema=, :default_schema=
         
     | 
| 
       267 
268 
     | 
    
         | 
| 
       268 
     | 
    
         
            -
                  # FIXME: This needs to be fixed when we implement the collation per
         
     | 
| 
       269 
     | 
    
         
            -
                   
     | 
| 
       270 
     | 
    
         
            -
                  def default_uniqueness_comparison(attribute, value) # :nodoc:
         
     | 
| 
      
 269 
     | 
    
         
            +
                  # FIXME: This needs to be fixed when we implement the collation per column
         
     | 
| 
      
 270 
     | 
    
         
            +
                  def case_sensitive_comparison(attribute, value)
         
     | 
| 
       271 
271 
     | 
    
         
             
                    column = column_for_attribute(attribute)
         
     | 
| 
       272 
272 
     | 
    
         | 
| 
       273 
     | 
    
         
            -
                     
     | 
| 
       274 
     | 
    
         
            -
             
     | 
| 
       275 
     | 
    
         
            -
             
     | 
| 
      
 273 
     | 
    
         
            +
                    case_sensitive = collation && collation.match(/_CS/)
         
     | 
| 
      
 274 
     | 
    
         
            +
             
     | 
| 
      
 275 
     | 
    
         
            +
                    if %i[string text].include?(column.type) && !case_sensitive && !value.nil?
         
     | 
| 
       276 
276 
     | 
    
         
             
                      attribute.eq(Arel::Nodes::Bin.new(value))
         
     | 
| 
       277 
277 
     | 
    
         
             
                    else
         
     | 
| 
       278 
278 
     | 
    
         
             
                      super
         
     | 
| 
       279 
279 
     | 
    
         
             
                    end
         
     | 
| 
       280 
280 
     | 
    
         
             
                  end
         
     | 
| 
       281 
281 
     | 
    
         | 
| 
       282 
     | 
    
         
            -
                  def  
     | 
| 
       283 
     | 
    
         
            -
                     
     | 
| 
      
 282 
     | 
    
         
            +
                  def can_perform_case_insensitive_comparison_for?(column)
         
     | 
| 
      
 283 
     | 
    
         
            +
                    case_sensitive = collation && collation.match(/_CS/)
         
     | 
| 
       284 
284 
     | 
    
         | 
| 
       285 
     | 
    
         
            -
                     
     | 
| 
       286 
     | 
    
         
            -
                      attribute.eq(Arel::Nodes::Bin.new(value))
         
     | 
| 
       287 
     | 
    
         
            -
                    else
         
     | 
| 
       288 
     | 
    
         
            -
                      super
         
     | 
| 
       289 
     | 
    
         
            -
                    end
         
     | 
| 
      
 285 
     | 
    
         
            +
                    %i[string text].include?(column.type) && !case_sensitive
         
     | 
| 
       290 
286 
     | 
    
         
             
                  end
         
     | 
| 
      
 287 
     | 
    
         
            +
                  private :can_perform_case_insensitive_comparison_for?
         
     | 
| 
       291 
288 
     | 
    
         | 
| 
       292 
289 
     | 
    
         
             
                  def configure_connection
         
     | 
| 
       293 
290 
     | 
    
         
             
                    # Here goes initial settings per connection
         
     | 
| 
         @@ -485,6 +482,8 @@ module ActiveRecord 
     | 
|
| 
       485 
482 
     | 
    
         
             
                      ConnectionNotEstablished.new(exception)
         
     | 
| 
       486 
483 
     | 
    
         
             
                    when /(cannot insert duplicate key .* with unique index) | (violation of unique key constraint)/i
         
     | 
| 
       487 
484 
     | 
    
         
             
                      RecordNotUnique.new(message, sql: sql, binds: binds)
         
     | 
| 
      
 485 
     | 
    
         
            +
                    when /Violation of PRIMARY KEY constraint .* Cannot insert duplicate key in object .* The duplicate key value is/i
         
     | 
| 
      
 486 
     | 
    
         
            +
                      RecordNotUnique.new(message, sql: sql, binds: binds)
         
     | 
| 
       488 
487 
     | 
    
         
             
                    when /Lock request time out period exceeded/i
         
     | 
| 
       489 
488 
     | 
    
         
             
                      LockTimeout.new(message, sql: sql, binds: binds)
         
     | 
| 
       490 
489 
     | 
    
         
             
                    when /The .* statement conflicted with the FOREIGN KEY constraint/
         
     | 
    
        data/lib/arjdbc/mssql/column.rb
    CHANGED
    
    | 
         @@ -9,17 +9,26 @@ module ActiveRecord 
     | 
|
| 
       9 
9 
     | 
    
         
             
                  def initialize(name, raw_default, sql_type_metadata = nil, null = true, table_name = nil, default_function = nil, collation = nil, comment: nil)
         
     | 
| 
       10 
10 
     | 
    
         
             
                    @table_name = table_name
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
                     
     | 
| 
      
 12 
     | 
    
         
            +
                    default_val, default_fun = extract_default(raw_default)
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       14 
     | 
    
         
            -
                    super(name,  
     | 
| 
      
 14 
     | 
    
         
            +
                    super(name, default_val, sql_type_metadata, null, default_fun, collation: collation, comment: comment)
         
     | 
| 
       15 
15 
     | 
    
         
             
                  end
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
       17 
17 
     | 
    
         
             
                  def extract_default(value)
         
     | 
| 
       18 
     | 
    
         
            -
                     
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
                     
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
      
 18 
     | 
    
         
            +
                    return [nil, nil] unless value
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                    case value
         
     | 
| 
      
 21 
     | 
    
         
            +
                    when /\A\(N?'(.*)'\)\Z/m
         
     | 
| 
      
 22 
     | 
    
         
            +
                      [unquote_string(Regexp.last_match[1]), nil]
         
     | 
| 
      
 23 
     | 
    
         
            +
                    when /\A\(\((.*)\)\)\Z/
         
     | 
| 
      
 24 
     | 
    
         
            +
                      [unquote_string(Regexp.last_match[1]), nil]
         
     | 
| 
      
 25 
     | 
    
         
            +
                    when /\A\((\w+\(\))\)\Z/
         
     | 
| 
      
 26 
     | 
    
         
            +
                      [nil, unquote_string(Regexp.last_match[1])]
         
     | 
| 
      
 27 
     | 
    
         
            +
                    else
         
     | 
| 
      
 28 
     | 
    
         
            +
                      # return nil if default does not match the patterns to avoid
         
     | 
| 
      
 29 
     | 
    
         
            +
                      # any unexpected errors.
         
     | 
| 
      
 30 
     | 
    
         
            +
                      [nil, nil]
         
     | 
| 
      
 31 
     | 
    
         
            +
                    end
         
     | 
| 
       23 
32 
     | 
    
         
             
                  end
         
     | 
| 
       24 
33 
     | 
    
         | 
| 
       25 
34 
     | 
    
         
             
                  def unquote_string(string)
         
     | 
| 
         @@ -31,6 +31,8 @@ module ActiveRecord 
     | 
|
| 
       31 
31 
     | 
    
         | 
| 
       32 
32 
     | 
    
         
             
                    def write_query?(sql) # :nodoc:
         
     | 
| 
       33 
33 
     | 
    
         
             
                      !READ_QUERY.match?(sql)
         
     | 
| 
      
 34 
     | 
    
         
            +
                    rescue ArgumentError # Invalid encoding
         
     | 
| 
      
 35 
     | 
    
         
            +
                      !READ_QUERY.match?(sql.b)
         
     | 
| 
       34 
36 
     | 
    
         
             
                    end
         
     | 
| 
       35 
37 
     | 
    
         | 
| 
       36 
38 
     | 
    
         
             
                    # Internal method to test different isolation levels supported by this
         
     | 
| 
         @@ -176,6 +178,9 @@ module ActiveRecord 
     | 
|
| 
       176 
178 
     | 
    
         
             
                        log(sql, name, binds) do
         
     | 
| 
       177 
179 
     | 
    
         
             
                          with_raw_connection do |conn|
         
     | 
| 
       178 
180 
     | 
    
         
             
                            result = conditional_indentity_insert(sql) do
         
     | 
| 
      
 181 
     | 
    
         
            +
                              # DEPRECATION WARNING: to_time will always preserve the timezone offset of the receiver in Rails 8.0.
         
     | 
| 
      
 182 
     | 
    
         
            +
                              # To opt in to the new behavior, set `ActiveSupport.to_time_preserves_timezone = true`.
         
     | 
| 
      
 183 
     | 
    
         
            +
                              # (called from block in execute_insert_pk
         
     | 
| 
       179 
184 
     | 
    
         
             
                              conn.execute_insert_pk(sql, binds, pk)
         
     | 
| 
       180 
185 
     | 
    
         
             
                            end
         
     | 
| 
       181 
186 
     | 
    
         
             
                            verified!
         
     | 
| 
         @@ -38,6 +38,22 @@ module ActiveRecord 
     | 
|
| 
       38 
38 
     | 
    
         
             
                      end
         
     | 
| 
       39 
39 
     | 
    
         
             
                    end
         
     | 
| 
       40 
40 
     | 
    
         | 
| 
      
 41 
     | 
    
         
            +
                    def visit_CreateIndexDefinition(o)
         
     | 
| 
      
 42 
     | 
    
         
            +
                      index = o.index
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                      sql = []
         
     | 
| 
      
 45 
     | 
    
         
            +
                      sql << "IF NOT EXISTS (SELECT name FROM sysindexes WHERE name = '#{o.index.name}')" if o.if_not_exists
         
     | 
| 
      
 46 
     | 
    
         
            +
                      sql << "CREATE"
         
     | 
| 
      
 47 
     | 
    
         
            +
                      sql << "UNIQUE" if index.unique
         
     | 
| 
      
 48 
     | 
    
         
            +
                      sql << index.type.upcase if index.type
         
     | 
| 
      
 49 
     | 
    
         
            +
                      sql << "INDEX"
         
     | 
| 
      
 50 
     | 
    
         
            +
                      sql << "#{quote_column_name(index.name)} ON #{quote_table_name(index.table)}"
         
     | 
| 
      
 51 
     | 
    
         
            +
                      sql << "(#{quoted_columns(index)})"
         
     | 
| 
      
 52 
     | 
    
         
            +
                      sql << "WHERE #{index.where}" if index.where
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                      sql.join(" ")
         
     | 
| 
      
 55 
     | 
    
         
            +
                    end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
       41 
57 
     | 
    
         
             
                    def add_column_options!(sql, options)
         
     | 
| 
       42 
58 
     | 
    
         
             
                      sql << " DEFAULT #{quote_default_expression(options[:default], options[:column])}" if options_include_default?(options)
         
     | 
| 
       43 
59 
     | 
    
         | 
| 
         @@ -80,8 +80,50 @@ module ActiveRecord 
     | 
|
| 
       80 
80 
     | 
    
         
             
                      valid_raw_connection.primary_keys(table_name)
         
     | 
| 
       81 
81 
     | 
    
         
             
                    end
         
     | 
| 
       82 
82 
     | 
    
         | 
| 
      
 83 
     | 
    
         
            +
                    def build_change_column_definition(table_name, column_name, type, **options) # :nodoc:
         
     | 
| 
      
 84 
     | 
    
         
            +
                      td = create_table_definition(table_name)
         
     | 
| 
      
 85 
     | 
    
         
            +
                      cd = td.new_column_definition(column_name, type, **options)
         
     | 
| 
      
 86 
     | 
    
         
            +
                      ChangeColumnDefinition.new(cd, column_name)
         
     | 
| 
      
 87 
     | 
    
         
            +
                    end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                    def build_change_column_default_definition(table_name, column_name, default_or_changes) # :nodoc:
         
     | 
| 
      
 90 
     | 
    
         
            +
                      column = column_for(table_name, column_name)
         
     | 
| 
      
 91 
     | 
    
         
            +
                      return unless column
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
                      default = extract_new_default_value(default_or_changes)
         
     | 
| 
      
 94 
     | 
    
         
            +
                      ChangeColumnDefaultDefinition.new(column, default)
         
     | 
| 
      
 95 
     | 
    
         
            +
                    end
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
       83 
97 
     | 
    
         
             
                    def foreign_keys(table_name)
         
     | 
| 
       84 
     | 
    
         
            -
                      valid_raw_connection.foreign_keys(table_name)
         
     | 
| 
      
 98 
     | 
    
         
            +
                      # valid_raw_connection.foreign_keys(table_name)
         
     | 
| 
      
 99 
     | 
    
         
            +
                      fk_info = execute_procedure(:sp_fkeys, nil, nil, nil, table_name, nil)
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
                      grouped_fk = fk_info.group_by { |row| row["FK_NAME"] }.values.each { |group| group.sort_by! { |row| row["KEY_SEQ"] } }
         
     | 
| 
      
 102 
     | 
    
         
            +
                      grouped_fk.map do |group|
         
     | 
| 
      
 103 
     | 
    
         
            +
                        row = group.first
         
     | 
| 
      
 104 
     | 
    
         
            +
                        options = {
         
     | 
| 
      
 105 
     | 
    
         
            +
                          name: row["FK_NAME"],
         
     | 
| 
      
 106 
     | 
    
         
            +
                          on_update: extract_foreign_key_action("update", row["FK_NAME"]),
         
     | 
| 
      
 107 
     | 
    
         
            +
                          on_delete: extract_foreign_key_action("delete", row["FK_NAME"])
         
     | 
| 
      
 108 
     | 
    
         
            +
                        }
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
                        if group.one?
         
     | 
| 
      
 111 
     | 
    
         
            +
                          options[:column] = row["FKCOLUMN_NAME"]
         
     | 
| 
      
 112 
     | 
    
         
            +
                          options[:primary_key] = row["PKCOLUMN_NAME"]
         
     | 
| 
      
 113 
     | 
    
         
            +
                        else
         
     | 
| 
      
 114 
     | 
    
         
            +
                          options[:column] = group.map { |row| row["FKCOLUMN_NAME"] }
         
     | 
| 
      
 115 
     | 
    
         
            +
                          options[:primary_key] = group.map { |row| row["PKCOLUMN_NAME"] }
         
     | 
| 
      
 116 
     | 
    
         
            +
                        end
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
                        ForeignKeyDefinition.new(table_name, row["PKTABLE_NAME"], options)
         
     | 
| 
      
 119 
     | 
    
         
            +
                      end
         
     | 
| 
      
 120 
     | 
    
         
            +
                    end
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
                    def extract_foreign_key_action(action, fk_name)
         
     | 
| 
      
 123 
     | 
    
         
            +
                      case select_value("SELECT #{action}_referential_action_desc FROM sys.foreign_keys WHERE name = '#{fk_name}'")
         
     | 
| 
      
 124 
     | 
    
         
            +
                      when "CASCADE" then :cascade
         
     | 
| 
      
 125 
     | 
    
         
            +
                      when "SET_NULL" then :nullify
         
     | 
| 
      
 126 
     | 
    
         
            +
                      end
         
     | 
| 
       85 
127 
     | 
    
         
             
                    end
         
     | 
| 
       86 
128 
     | 
    
         | 
| 
       87 
129 
     | 
    
         
             
                    def charset
         
     | 
    
        data/lib/arjdbc/mysql/adapter.rb
    CHANGED
    
    | 
         @@ -84,15 +84,6 @@ module ActiveRecord 
     | 
|
| 
       84 
84 
     | 
    
         
             
                    @connection_parameters = conn_params
         
     | 
| 
       85 
85 
     | 
    
         
             
                  end
         
     | 
| 
       86 
86 
     | 
    
         | 
| 
       87 
     | 
    
         
            -
                  def self.database_exists?(config)
         
     | 
| 
       88 
     | 
    
         
            -
                    conn = ActiveRecord::Base.mysql2_connection(config)
         
     | 
| 
       89 
     | 
    
         
            -
                    conn && conn.really_valid?
         
     | 
| 
       90 
     | 
    
         
            -
                  rescue ActiveRecord::NoDatabaseError
         
     | 
| 
       91 
     | 
    
         
            -
                    false
         
     | 
| 
       92 
     | 
    
         
            -
                  ensure
         
     | 
| 
       93 
     | 
    
         
            -
                    conn.disconnect! if conn
         
     | 
| 
       94 
     | 
    
         
            -
                  end
         
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
       96 
87 
     | 
    
         
             
                  def supports_json?
         
     | 
| 
       97 
88 
     | 
    
         
             
                    !mariadb? && database_version >= '5.7.8'
         
     | 
| 
       98 
89 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -250,7 +241,7 @@ module ActiveRecord 
     | 
|
| 
       250 
241 
     | 
    
         | 
| 
       251 
242 
     | 
    
         
             
                  # e.g. "5.7.20-0ubuntu0.16.04.1"
         
     | 
| 
       252 
243 
     | 
    
         
             
                  def full_version
         
     | 
| 
       253 
     | 
    
         
            -
                     
     | 
| 
      
 244 
     | 
    
         
            +
                    database_version.full_version_string
         
     | 
| 
       254 
245 
     | 
    
         
             
                  end
         
     | 
| 
       255 
246 
     | 
    
         | 
| 
       256 
247 
     | 
    
         
             
                  def get_full_version
         
     | 
| 
         @@ -7,7 +7,9 @@ module ArJdbc 
     | 
|
| 
       7 
7 
     | 
    
         | 
| 
       8 
8 
     | 
    
         
             
                  load_jdbc_driver
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
                   
     | 
| 
      
 10 
     | 
    
         
            +
                  # don't set driver if it's explicitly set to false
         
     | 
| 
      
 11 
     | 
    
         
            +
                  # allow Java's service discovery mechanism (with connector/j 8.0)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  config[:driver] ||= database_driver_name if config[:driver] != false
         
     | 
| 
       11 
13 
     | 
    
         | 
| 
       12 
14 
     | 
    
         
             
                  host = (config[:host] ||= "localhost")
         
     | 
| 
       13 
15 
     | 
    
         
             
                  port = (config[:port] ||= 3306)
         
     | 
| 
         @@ -40,7 +42,7 @@ module ArJdbc 
     | 
|
| 
       40 
42 
     | 
    
         
             
                def build_properties(config)
         
     | 
| 
       41 
43 
     | 
    
         
             
                  properties = config[:properties] || {}
         
     | 
| 
       42 
44 
     | 
    
         | 
| 
       43 
     | 
    
         
            -
                  properties["zeroDateTimeBehavior"] ||=  
     | 
| 
      
 45 
     | 
    
         
            +
                  properties["zeroDateTimeBehavior"] ||= default_zero_date_time_behavior(config[:driver])
         
     | 
| 
       44 
46 
     | 
    
         | 
| 
       45 
47 
     | 
    
         
             
                  properties["jdbcCompliantTruncation"] ||= false
         
     | 
| 
       46 
48 
     | 
    
         | 
| 
         @@ -88,6 +90,14 @@ module ArJdbc 
     | 
|
| 
       88 
90 
     | 
    
         
             
                  properties
         
     | 
| 
       89 
91 
     | 
    
         
             
                end
         
     | 
| 
       90 
92 
     | 
    
         | 
| 
      
 93 
     | 
    
         
            +
                def default_zero_date_time_behavior(driver)
         
     | 
| 
      
 94 
     | 
    
         
            +
                  return "CONVERT_TO_NULL" if driver == false
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
                  return "CONVERT_TO_NULL" if driver.start_with?("com.mysql.cj.")
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
                  "convertToNull"
         
     | 
| 
      
 99 
     | 
    
         
            +
                end
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
       91 
101 
     | 
    
         
             
                # See https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-charsets.html
         
     | 
| 
       92 
102 
     | 
    
         
             
                # to charset-name (characterEncoding=...)
         
     | 
| 
       93 
103 
     | 
    
         
             
                def convert_mysql_encoding(config)
         
     | 
| 
         @@ -345,7 +345,7 @@ module ArJdbc 
     | 
|
| 
       345 
345 
     | 
    
         
             
                      type.typname AS name,
         
     | 
| 
       346 
346 
     | 
    
         
             
                      type.OID AS oid,
         
     | 
| 
       347 
347 
     | 
    
         
             
                      n.nspname AS schema,
         
     | 
| 
       348 
     | 
    
         
            -
                       
     | 
| 
      
 348 
     | 
    
         
            +
                      array_agg(enum.enumlabel ORDER BY enum.enumsortorder) AS value
         
     | 
| 
       349 
349 
     | 
    
         
             
                    FROM pg_enum AS enum
         
     | 
| 
       350 
350 
     | 
    
         
             
                    JOIN pg_type AS type ON (type.oid = enum.enumtypid)
         
     | 
| 
       351 
351 
     | 
    
         
             
                    JOIN pg_namespace n ON type.typnamespace = n.oid
         
     | 
| 
         @@ -842,6 +842,15 @@ module ActiveRecord::ConnectionAdapters 
     | 
|
| 
       842 
842 
     | 
    
         
             
                # setting, you should immediately run <tt>bin/rails db:migrate</tt> to update the types in your schema.rb.
         
     | 
| 
       843 
843 
     | 
    
         
             
                class_attribute :datetime_type, default: :timestamp
         
     | 
| 
       844 
844 
     | 
    
         | 
| 
      
 845 
     | 
    
         
            +
                ##
         
     | 
| 
      
 846 
     | 
    
         
            +
                # :singleton-method:
         
     | 
| 
      
 847 
     | 
    
         
            +
                # Toggles automatic decoding of date columns.
         
     | 
| 
      
 848 
     | 
    
         
            +
                #
         
     | 
| 
      
 849 
     | 
    
         
            +
                #   ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.select_value("select '2024-01-01'::date").class #=> String
         
     | 
| 
      
 850 
     | 
    
         
            +
                #   ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.decode_dates = true
         
     | 
| 
      
 851 
     | 
    
         
            +
                #   ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.select_value("select '2024-01-01'::date").class #=> Date
         
     | 
| 
      
 852 
     | 
    
         
            +
                class_attribute :decode_dates, default: false
         
     | 
| 
      
 853 
     | 
    
         
            +
             
     | 
| 
       845 
854 
     | 
    
         
             
                # Try to use as much of the built in postgres logic as possible
         
     | 
| 
       846 
855 
     | 
    
         
             
                # maybe someday we can extend the actual adapter
         
     | 
| 
       847 
856 
     | 
    
         
             
                include ActiveRecord::ConnectionAdapters::PostgreSQL::ReferentialIntegrity
         
     | 
| 
         @@ -855,9 +864,12 @@ module ActiveRecord::ConnectionAdapters 
     | 
|
| 
       855 
864 
     | 
    
         
             
                include ArJdbc::Abstract::DatabaseStatements
         
     | 
| 
       856 
865 
     | 
    
         
             
                include ArJdbc::Abstract::StatementCache
         
     | 
| 
       857 
866 
     | 
    
         
             
                include ArJdbc::Abstract::TransactionSupport
         
     | 
| 
       858 
     | 
    
         
            -
                include ArJdbc::PostgreSQL
         
     | 
| 
       859 
867 
     | 
    
         
             
                include ArJdbc::PostgreSQLConfig
         
     | 
| 
       860 
868 
     | 
    
         | 
| 
      
 869 
     | 
    
         
            +
                # NOTE: after AR refactor quote_column_name became class and instance method
         
     | 
| 
      
 870 
     | 
    
         
            +
                include ArJdbc::PostgreSQL
         
     | 
| 
      
 871 
     | 
    
         
            +
                extend ArJdbc::PostgreSQL
         
     | 
| 
      
 872 
     | 
    
         
            +
             
     | 
| 
       861 
873 
     | 
    
         
             
                require 'arjdbc/postgresql/oid_types'
         
     | 
| 
       862 
874 
     | 
    
         
             
                include ::ArJdbc::PostgreSQL::OIDTypes
         
     | 
| 
       863 
875 
     | 
    
         
             
                include ::ArJdbc::PostgreSQL::DatabaseStatements
         
     | 
| 
         @@ -18,6 +18,7 @@ require "active_record/connection_adapters/sqlite3/schema_statements" 
     | 
|
| 
       18 
18 
     | 
    
         
             
            require "active_support/core_ext/class/attribute"
         
     | 
| 
       19 
19 
     | 
    
         
             
            require "arjdbc/sqlite3/column"
         
     | 
| 
       20 
20 
     | 
    
         
             
            require "arjdbc/sqlite3/adapter_hash_config"
         
     | 
| 
      
 21 
     | 
    
         
            +
            require "arjdbc/sqlite3/pragmas"
         
     | 
| 
       21 
22 
     | 
    
         | 
| 
       22 
23 
     | 
    
         
             
            require "arjdbc/abstract/relation_query_attribute_monkey_patch"
         
     | 
| 
       23 
24 
     | 
    
         | 
| 
         @@ -59,6 +60,7 @@ module ArJdbc 
     | 
|
| 
       59 
60 
     | 
    
         
             
                # DIFFERENCE: Some common constant names to reduce differences in rest of this module from AR5 version
         
     | 
| 
       60 
61 
     | 
    
         
             
                ConnectionAdapters = ::ActiveRecord::ConnectionAdapters
         
     | 
| 
       61 
62 
     | 
    
         
             
                IndexDefinition = ::ActiveRecord::ConnectionAdapters::IndexDefinition
         
     | 
| 
      
 63 
     | 
    
         
            +
                ForeignKeyDefinition = ::ActiveRecord::ConnectionAdapters::ForeignKeyDefinition
         
     | 
| 
       62 
64 
     | 
    
         
             
                Quoting = ::ActiveRecord::ConnectionAdapters::SQLite3::Quoting
         
     | 
| 
       63 
65 
     | 
    
         
             
                RecordNotUnique = ::ActiveRecord::RecordNotUnique
         
     | 
| 
       64 
66 
     | 
    
         
             
                SchemaCreation = ConnectionAdapters::SQLite3::SchemaCreation
         
     | 
| 
         @@ -79,6 +81,15 @@ module ArJdbc 
     | 
|
| 
       79 
81 
     | 
    
         
             
                    json:         { name: "json" },
         
     | 
| 
       80 
82 
     | 
    
         
             
                }
         
     | 
| 
       81 
83 
     | 
    
         | 
| 
      
 84 
     | 
    
         
            +
                DEFAULT_PRAGMAS = {
         
     | 
| 
      
 85 
     | 
    
         
            +
                  "foreign_keys"        => true,
         
     | 
| 
      
 86 
     | 
    
         
            +
                  "journal_mode"        => :wal,
         
     | 
| 
      
 87 
     | 
    
         
            +
                  "synchronous"         => :normal,
         
     | 
| 
      
 88 
     | 
    
         
            +
                  "mmap_size"           => 134217728, # 128 megabytes
         
     | 
| 
      
 89 
     | 
    
         
            +
                  "journal_size_limit"  => 67108864, # 64 megabytes
         
     | 
| 
      
 90 
     | 
    
         
            +
                  "cache_size"          => 2000
         
     | 
| 
      
 91 
     | 
    
         
            +
                }
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
       82 
93 
     | 
    
         
             
                class StatementPool < ConnectionAdapters::StatementPool # :nodoc:
         
     | 
| 
       83 
94 
     | 
    
         
             
                  private
         
     | 
| 
       84 
95 
     | 
    
         
             
                  def dealloc(stmt)
         
     | 
| 
         @@ -154,8 +165,23 @@ module ArJdbc 
     | 
|
| 
       154 
165 
     | 
    
         
             
                  !@memory_database
         
     | 
| 
       155 
166 
     | 
    
         
             
                end
         
     | 
| 
       156 
167 
     | 
    
         | 
| 
      
 168 
     | 
    
         
            +
                def supports_virtual_columns?
         
     | 
| 
      
 169 
     | 
    
         
            +
                  database_version >= "3.31.0"
         
     | 
| 
      
 170 
     | 
    
         
            +
                end
         
     | 
| 
      
 171 
     | 
    
         
            +
             
     | 
| 
      
 172 
     | 
    
         
            +
                def connected?
         
     | 
| 
      
 173 
     | 
    
         
            +
                  !(@raw_connection.nil? || @raw_connection.closed?)
         
     | 
| 
      
 174 
     | 
    
         
            +
                end
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
       157 
176 
     | 
    
         
             
                def active?
         
     | 
| 
       158 
     | 
    
         
            -
                   
     | 
| 
      
 177 
     | 
    
         
            +
                  if connected?
         
     | 
| 
      
 178 
     | 
    
         
            +
                    @lock.synchronize do
         
     | 
| 
      
 179 
     | 
    
         
            +
                      if @raw_connection&.active?
         
     | 
| 
      
 180 
     | 
    
         
            +
                        verified!
         
     | 
| 
      
 181 
     | 
    
         
            +
                        true
         
     | 
| 
      
 182 
     | 
    
         
            +
                      end
         
     | 
| 
      
 183 
     | 
    
         
            +
                    end
         
     | 
| 
      
 184 
     | 
    
         
            +
                  end || false
         
     | 
| 
       159 
185 
     | 
    
         
             
                end
         
     | 
| 
       160 
186 
     | 
    
         | 
| 
       161 
187 
     | 
    
         
             
                def return_value_after_insert?(column) # :nodoc:
         
     | 
| 
         @@ -167,10 +193,11 @@ module ArJdbc 
     | 
|
| 
       167 
193 
     | 
    
         
             
                # Disconnects from the database if already connected. Otherwise, this
         
     | 
| 
       168 
194 
     | 
    
         
             
                # method does nothing.
         
     | 
| 
       169 
195 
     | 
    
         
             
                def disconnect!
         
     | 
| 
       170 
     | 
    
         
            -
                   
     | 
| 
       171 
     | 
    
         
            -
             
     | 
| 
       172 
     | 
    
         
            -
             
     | 
| 
       173 
     | 
    
         
            -
             
     | 
| 
      
 196 
     | 
    
         
            +
                  @lock.synchronize do
         
     | 
| 
      
 197 
     | 
    
         
            +
                    super
         
     | 
| 
      
 198 
     | 
    
         
            +
                    @raw_connection&.close rescue nil
         
     | 
| 
      
 199 
     | 
    
         
            +
                    @raw_connection = nil
         
     | 
| 
      
 200 
     | 
    
         
            +
                  end
         
     | 
| 
       174 
201 
     | 
    
         
             
                end
         
     | 
| 
       175 
202 
     | 
    
         | 
| 
       176 
203 
     | 
    
         
             
                def supports_index_sort_order?
         
     | 
| 
         @@ -235,7 +262,6 @@ module ArJdbc 
     | 
|
| 
       235 
262 
     | 
    
         
             
                  internal_exec_query "DROP INDEX #{quote_column_name(index_name)}"
         
     | 
| 
       236 
263 
     | 
    
         
             
                end
         
     | 
| 
       237 
264 
     | 
    
         | 
| 
       238 
     | 
    
         
            -
                
         
     | 
| 
       239 
265 
     | 
    
         
             
                # Renames a table.
         
     | 
| 
       240 
266 
     | 
    
         
             
                #
         
     | 
| 
       241 
267 
     | 
    
         
             
                # Example:
         
     | 
| 
         @@ -324,15 +350,31 @@ module ArJdbc 
     | 
|
| 
       324 
350 
     | 
    
         
             
                end
         
     | 
| 
       325 
351 
     | 
    
         
             
                alias :add_belongs_to :add_reference
         
     | 
| 
       326 
352 
     | 
    
         | 
| 
      
 353 
     | 
    
         
            +
                FK_REGEX = /.*FOREIGN KEY\s+\("([^"]+)"\)\s+REFERENCES\s+"(\w+)"\s+\("(\w+)"\)/
         
     | 
| 
      
 354 
     | 
    
         
            +
                DEFERRABLE_REGEX = /DEFERRABLE INITIALLY (\w+)/
         
     | 
| 
       327 
355 
     | 
    
         
             
                def foreign_keys(table_name)
         
     | 
| 
       328 
356 
     | 
    
         
             
                  # SQLite returns 1 row for each column of composite foreign keys.
         
     | 
| 
       329 
357 
     | 
    
         
             
                  fk_info = internal_exec_query("PRAGMA foreign_key_list(#{quote(table_name)})", "SCHEMA")
         
     | 
| 
      
 358 
     | 
    
         
            +
                  # Deferred or immediate foreign keys can only be seen in the CREATE TABLE sql
         
     | 
| 
      
 359 
     | 
    
         
            +
                  fk_defs = table_structure_sql(table_name)
         
     | 
| 
      
 360 
     | 
    
         
            +
                              .select do |column_string|
         
     | 
| 
      
 361 
     | 
    
         
            +
                                column_string.start_with?("CONSTRAINT") &&
         
     | 
| 
      
 362 
     | 
    
         
            +
                                column_string.include?("FOREIGN KEY")
         
     | 
| 
      
 363 
     | 
    
         
            +
                              end
         
     | 
| 
      
 364 
     | 
    
         
            +
                              .to_h do |fk_string|
         
     | 
| 
      
 365 
     | 
    
         
            +
                                _, from, table, to = fk_string.match(FK_REGEX).to_a
         
     | 
| 
      
 366 
     | 
    
         
            +
                                _, mode = fk_string.match(DEFERRABLE_REGEX).to_a
         
     | 
| 
      
 367 
     | 
    
         
            +
                                deferred = mode&.downcase&.to_sym || false
         
     | 
| 
      
 368 
     | 
    
         
            +
                                [[table, from, to], deferred]
         
     | 
| 
      
 369 
     | 
    
         
            +
                              end
         
     | 
| 
      
 370 
     | 
    
         
            +
             
     | 
| 
       330 
371 
     | 
    
         
             
                  grouped_fk = fk_info.group_by { |row| row["id"] }.values.each { |group| group.sort_by! { |row| row["seq"] } }
         
     | 
| 
       331 
372 
     | 
    
         
             
                  grouped_fk.map do |group|
         
     | 
| 
       332 
373 
     | 
    
         
             
                    row = group.first
         
     | 
| 
       333 
374 
     | 
    
         
             
                    options = {
         
     | 
| 
       334 
375 
     | 
    
         
             
                      on_delete: extract_foreign_key_action(row["on_delete"]),
         
     | 
| 
       335 
     | 
    
         
            -
                      on_update: extract_foreign_key_action(row["on_update"])
         
     | 
| 
      
 376 
     | 
    
         
            +
                      on_update: extract_foreign_key_action(row["on_update"]),
         
     | 
| 
      
 377 
     | 
    
         
            +
                      deferrable: fk_defs[[row["table"], row["from"], row["to"]]]
         
     | 
| 
       336 
378 
     | 
    
         
             
                    }
         
     | 
| 
       337 
379 
     | 
    
         | 
| 
       338 
380 
     | 
    
         
             
                    if group.one?
         
     | 
| 
         @@ -342,8 +384,7 @@ module ArJdbc 
     | 
|
| 
       342 
384 
     | 
    
         
             
                      options[:column] = group.map { |row| row["from"] }
         
     | 
| 
       343 
385 
     | 
    
         
             
                      options[:primary_key] = group.map { |row| row["to"] }
         
     | 
| 
       344 
386 
     | 
    
         
             
                    end
         
     | 
| 
       345 
     | 
    
         
            -
                     
     | 
| 
       346 
     | 
    
         
            -
                    ::ActiveRecord::ConnectionAdapters::ForeignKeyDefinition.new(table_name, row["table"], options)
         
     | 
| 
      
 387 
     | 
    
         
            +
                    ForeignKeyDefinition.new(table_name, row["table"], options)
         
     | 
| 
       347 
388 
     | 
    
         
             
                  end
         
     | 
| 
       348 
389 
     | 
    
         
             
                end
         
     | 
| 
       349 
390 
     | 
    
         | 
| 
         @@ -390,7 +431,14 @@ module ArJdbc 
     | 
|
| 
       390 
431 
     | 
    
         | 
| 
       391 
432 
     | 
    
         
             
                  type_metadata = fetch_type_metadata(field["type"])
         
     | 
| 
       392 
433 
     | 
    
         
             
                  default_value = extract_value_from_default(default)
         
     | 
| 
       393 
     | 
    
         
            -
                   
     | 
| 
      
 434 
     | 
    
         
            +
                  generated_type = extract_generated_type(field)
         
     | 
| 
      
 435 
     | 
    
         
            +
             
     | 
| 
      
 436 
     | 
    
         
            +
                  if generated_type.present?
         
     | 
| 
      
 437 
     | 
    
         
            +
                    default_function = default
         
     | 
| 
      
 438 
     | 
    
         
            +
                  else
         
     | 
| 
      
 439 
     | 
    
         
            +
                    default_function = extract_default_function(default_value, default)
         
     | 
| 
      
 440 
     | 
    
         
            +
                  end
         
     | 
| 
      
 441 
     | 
    
         
            +
             
     | 
| 
       394 
442 
     | 
    
         
             
                  rowid = is_column_the_rowid?(field, definitions)
         
     | 
| 
       395 
443 
     | 
    
         | 
| 
       396 
444 
     | 
    
         
             
                  ActiveRecord::ConnectionAdapters::SQLite3Column.new(
         
     | 
| 
         @@ -401,7 +449,8 @@ module ArJdbc 
     | 
|
| 
       401 
449 
     | 
    
         
             
                    default_function,
         
     | 
| 
       402 
450 
     | 
    
         
             
                    collation: field["collation"],
         
     | 
| 
       403 
451 
     | 
    
         
             
                    auto_increment: field["auto_increment"],
         
     | 
| 
       404 
     | 
    
         
            -
                    rowid: rowid
         
     | 
| 
      
 452 
     | 
    
         
            +
                    rowid: rowid,
         
     | 
| 
      
 453 
     | 
    
         
            +
                    generated_type: generated_type
         
     | 
| 
       405 
454 
     | 
    
         
             
                  )
         
     | 
| 
       406 
455 
     | 
    
         
             
                end
         
     | 
| 
       407 
456 
     | 
    
         | 
| 
         @@ -413,7 +462,12 @@ module ArJdbc 
     | 
|
| 
       413 
462 
     | 
    
         
             
                end
         
     | 
| 
       414 
463 
     | 
    
         | 
| 
       415 
464 
     | 
    
         
             
                def table_structure(table_name)
         
     | 
| 
       416 
     | 
    
         
            -
                  structure =  
     | 
| 
      
 465 
     | 
    
         
            +
                  structure = if supports_virtual_columns?
         
     | 
| 
      
 466 
     | 
    
         
            +
                    internal_exec_query("PRAGMA table_xinfo(#{quote_table_name(table_name)})", "SCHEMA")
         
     | 
| 
      
 467 
     | 
    
         
            +
                  else
         
     | 
| 
      
 468 
     | 
    
         
            +
                    internal_exec_query("PRAGMA table_info(#{quote_table_name(table_name)})", "SCHEMA")
         
     | 
| 
      
 469 
     | 
    
         
            +
                  end
         
     | 
| 
      
 470 
     | 
    
         
            +
             
     | 
| 
       417 
471 
     | 
    
         
             
                  raise(ActiveRecord::StatementInvalid, "Could not find table '#{table_name}'") if structure.empty?
         
     | 
| 
       418 
472 
     | 
    
         
             
                  table_structure_with_collation(table_name, structure)
         
     | 
| 
       419 
473 
     | 
    
         
             
                end
         
     | 
| 
         @@ -453,8 +507,9 @@ module ArJdbc 
     | 
|
| 
       453 
507 
     | 
    
         
             
                # See: https://www.sqlite.org/lang_altertable.html
         
     | 
| 
       454 
508 
     | 
    
         
             
                # SQLite has an additional restriction on the ALTER TABLE statement
         
     | 
| 
       455 
509 
     | 
    
         
             
                def invalid_alter_table_type?(type, options)
         
     | 
| 
       456 
     | 
    
         
            -
                  type 
     | 
| 
       457 
     | 
    
         
            -
                    options[:null] == false && options[:default].nil?
         
     | 
| 
      
 510 
     | 
    
         
            +
                  type == :primary_key || options[:primary_key] ||
         
     | 
| 
      
 511 
     | 
    
         
            +
                    options[:null] == false && options[:default].nil? ||
         
     | 
| 
      
 512 
     | 
    
         
            +
                    (type == :virtual && options[:stored])
         
     | 
| 
       458 
513 
     | 
    
         
             
                end
         
     | 
| 
       459 
514 
     | 
    
         | 
| 
       460 
515 
     | 
    
         
             
                def alter_table(
         
     | 
| 
         @@ -510,12 +565,6 @@ module ArJdbc 
     | 
|
| 
       510 
565 
     | 
    
         
             
                         options[:rename][column.name.to_sym] ||
         
     | 
| 
       511 
566 
     | 
    
         
             
                         column.name) : column.name
         
     | 
| 
       512 
567 
     | 
    
         | 
| 
       513 
     | 
    
         
            -
                      if column.has_default?
         
     | 
| 
       514 
     | 
    
         
            -
                        type = lookup_cast_type_from_column(column)
         
     | 
| 
       515 
     | 
    
         
            -
                        default = type.deserialize(column.default)
         
     | 
| 
       516 
     | 
    
         
            -
                        default = -> { column.default_function } if default.nil?
         
     | 
| 
       517 
     | 
    
         
            -
                      end
         
     | 
| 
       518 
     | 
    
         
            -
             
     | 
| 
       519 
568 
     | 
    
         
             
                      column_options = {
         
     | 
| 
       520 
569 
     | 
    
         
             
                        limit: column.limit,
         
     | 
| 
       521 
570 
     | 
    
         
             
                        precision: column.precision,
         
     | 
| 
         @@ -525,19 +574,31 @@ module ArJdbc 
     | 
|
| 
       525 
574 
     | 
    
         
             
                        primary_key: column_name == from_primary_key
         
     | 
| 
       526 
575 
     | 
    
         
             
                      }
         
     | 
| 
       527 
576 
     | 
    
         | 
| 
       528 
     | 
    
         
            -
                       
     | 
| 
       529 
     | 
    
         
            -
                        column_options[: 
     | 
| 
      
 577 
     | 
    
         
            +
                      if column.virtual?
         
     | 
| 
      
 578 
     | 
    
         
            +
                        column_options[:as] = column.default_function
         
     | 
| 
      
 579 
     | 
    
         
            +
                        column_options[:stored] = column.virtual_stored?
         
     | 
| 
      
 580 
     | 
    
         
            +
                        column_options[:type] = column.type
         
     | 
| 
      
 581 
     | 
    
         
            +
                      elsif column.has_default?
         
     | 
| 
      
 582 
     | 
    
         
            +
                        type = lookup_cast_type_from_column(column)
         
     | 
| 
      
 583 
     | 
    
         
            +
                        default = type.deserialize(column.default)
         
     | 
| 
      
 584 
     | 
    
         
            +
                        default = -> { column.default_function } if default.nil?
         
     | 
| 
      
 585 
     | 
    
         
            +
             
     | 
| 
      
 586 
     | 
    
         
            +
                        unless column.auto_increment?
         
     | 
| 
      
 587 
     | 
    
         
            +
                          column_options[:default] = default
         
     | 
| 
      
 588 
     | 
    
         
            +
                        end
         
     | 
| 
       530 
589 
     | 
    
         
             
                      end
         
     | 
| 
       531 
590 
     | 
    
         | 
| 
       532 
     | 
    
         
            -
                      column_type = column.bigint? ? :bigint : column.type
         
     | 
| 
      
 591 
     | 
    
         
            +
                      column_type = column.virtual? ? :virtual : (column.bigint? ? :bigint : column.type)
         
     | 
| 
       533 
592 
     | 
    
         
             
                      @definition.column(column_name, column_type, **column_options)
         
     | 
| 
       534 
593 
     | 
    
         
             
                    end
         
     | 
| 
       535 
594 
     | 
    
         | 
| 
       536 
595 
     | 
    
         
             
                    yield @definition if block_given?
         
     | 
| 
       537 
596 
     | 
    
         
             
                  end
         
     | 
| 
       538 
597 
     | 
    
         
             
                  copy_table_indexes(from, to, options[:rename] || {})
         
     | 
| 
      
 598 
     | 
    
         
            +
             
     | 
| 
      
 599 
     | 
    
         
            +
                  columns_to_copy = @definition.columns.reject { |col| col.options.key?(:as) }.map(&:name)
         
     | 
| 
       539 
600 
     | 
    
         
             
                  copy_table_contents(from, to,
         
     | 
| 
       540 
     | 
    
         
            -
                     
     | 
| 
      
 601 
     | 
    
         
            +
                    columns_to_copy,
         
     | 
| 
       541 
602 
     | 
    
         
             
                    options[:rename] || {})
         
     | 
| 
       542 
603 
     | 
    
         
             
                end
         
     | 
| 
       543 
604 
     | 
    
         | 
| 
         @@ -611,32 +672,22 @@ module ArJdbc 
     | 
|
| 
       611 
672 
     | 
    
         | 
| 
       612 
673 
     | 
    
         
             
                COLLATE_REGEX = /.*\"(\w+)\".*collate\s+\"(\w+)\".*/i.freeze
         
     | 
| 
       613 
674 
     | 
    
         
             
                PRIMARY_KEY_AUTOINCREMENT_REGEX = /.*\"(\w+)\".+PRIMARY KEY AUTOINCREMENT/i
         
     | 
| 
      
 675 
     | 
    
         
            +
                GENERATED_ALWAYS_AS_REGEX = /.*"(\w+)".+GENERATED ALWAYS AS \((.+)\) (?:STORED|VIRTUAL)/i
         
     | 
| 
       614 
676 
     | 
    
         | 
| 
       615 
677 
     | 
    
         
             
                def table_structure_with_collation(table_name, basic_structure)
         
     | 
| 
       616 
678 
     | 
    
         
             
                  collation_hash = {}
         
     | 
| 
       617 
679 
     | 
    
         
             
                  auto_increments = {}
         
     | 
| 
       618 
     | 
    
         
            -
                   
     | 
| 
       619 
     | 
    
         
            -
                    SELECT sql FROM
         
     | 
| 
       620 
     | 
    
         
            -
                      (SELECT * FROM sqlite_master UNION ALL
         
     | 
| 
       621 
     | 
    
         
            -
                       SELECT * FROM sqlite_temp_master)
         
     | 
| 
       622 
     | 
    
         
            -
                    WHERE type = 'table' AND name = #{quote(table_name)}
         
     | 
| 
       623 
     | 
    
         
            -
                  SQL
         
     | 
| 
       624 
     | 
    
         
            -
             
     | 
| 
       625 
     | 
    
         
            -
                  # Result will have following sample string
         
     | 
| 
       626 
     | 
    
         
            -
                  # CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
         
     | 
| 
       627 
     | 
    
         
            -
                  #                       "password_digest" varchar COLLATE "NOCASE");
         
     | 
| 
       628 
     | 
    
         
            -
                  result = query_value(sql, "SCHEMA")
         
     | 
| 
      
 680 
     | 
    
         
            +
                  generated_columns = {}
         
     | 
| 
       629 
681 
     | 
    
         | 
| 
       630 
     | 
    
         
            -
                   
     | 
| 
       631 
     | 
    
         
            -
                    # Splitting with left parentheses and discarding the first part will return all
         
     | 
| 
       632 
     | 
    
         
            -
                    # columns separated with comma(,).
         
     | 
| 
       633 
     | 
    
         
            -
                    columns_string = result.split("(", 2).last
         
     | 
| 
      
 682 
     | 
    
         
            +
                  column_strings = table_structure_sql(table_name, basic_structure.map { |column| column["name"] })
         
     | 
| 
       634 
683 
     | 
    
         | 
| 
       635 
     | 
    
         
            -
             
     | 
| 
      
 684 
     | 
    
         
            +
                  if column_strings.any?
         
     | 
| 
      
 685 
     | 
    
         
            +
                    column_strings.each do |column_string|
         
     | 
| 
       636 
686 
     | 
    
         
             
                      # This regex will match the column name and collation type and will save
         
     | 
| 
       637 
687 
     | 
    
         
             
                      # the value in $1 and $2 respectively.
         
     | 
| 
       638 
688 
     | 
    
         
             
                      collation_hash[$1] = $2 if COLLATE_REGEX =~ column_string
         
     | 
| 
       639 
689 
     | 
    
         
             
                      auto_increments[$1] = true if PRIMARY_KEY_AUTOINCREMENT_REGEX =~ column_string
         
     | 
| 
      
 690 
     | 
    
         
            +
                      generated_columns[$1] = $2 if GENERATED_ALWAYS_AS_REGEX =~ column_string
         
     | 
| 
       640 
691 
     | 
    
         
             
                    end
         
     | 
| 
       641 
692 
     | 
    
         | 
| 
       642 
693 
     | 
    
         
             
                    basic_structure.map do |column|
         
     | 
| 
         @@ -650,6 +701,10 @@ module ArJdbc 
     | 
|
| 
       650 
701 
     | 
    
         
             
                        column["auto_increment"] = true
         
     | 
| 
       651 
702 
     | 
    
         
             
                      end
         
     | 
| 
       652 
703 
     | 
    
         | 
| 
      
 704 
     | 
    
         
            +
                      if generated_columns.has_key?(column_name)
         
     | 
| 
      
 705 
     | 
    
         
            +
                        column["dflt_value"] = generated_columns[column_name]
         
     | 
| 
      
 706 
     | 
    
         
            +
                      end
         
     | 
| 
      
 707 
     | 
    
         
            +
             
     | 
| 
       653 
708 
     | 
    
         
             
                      column
         
     | 
| 
       654 
709 
     | 
    
         
             
                    end
         
     | 
| 
       655 
710 
     | 
    
         
             
                  else
         
     | 
| 
         @@ -657,6 +712,50 @@ module ArJdbc 
     | 
|
| 
       657 
712 
     | 
    
         
             
                  end
         
     | 
| 
       658 
713 
     | 
    
         
             
                end
         
     | 
| 
       659 
714 
     | 
    
         | 
| 
      
 715 
     | 
    
         
            +
                UNQUOTED_OPEN_PARENS_REGEX = /\((?![^'"]*['"][^'"]*$)/
         
     | 
| 
      
 716 
     | 
    
         
            +
                FINAL_CLOSE_PARENS_REGEX = /\);*\z/
         
     | 
| 
      
 717 
     | 
    
         
            +
             
     | 
| 
      
 718 
     | 
    
         
            +
                def table_structure_sql(table_name, column_names = nil)
         
     | 
| 
      
 719 
     | 
    
         
            +
                  unless column_names
         
     | 
| 
      
 720 
     | 
    
         
            +
                    column_info = table_info(table_name)
         
     | 
| 
      
 721 
     | 
    
         
            +
                    column_names = column_info.map { |column| column["name"] }
         
     | 
| 
      
 722 
     | 
    
         
            +
                  end
         
     | 
| 
      
 723 
     | 
    
         
            +
             
     | 
| 
      
 724 
     | 
    
         
            +
                  sql = <<~SQL
         
     | 
| 
      
 725 
     | 
    
         
            +
                    SELECT sql FROM
         
     | 
| 
      
 726 
     | 
    
         
            +
                      (SELECT * FROM sqlite_master UNION ALL
         
     | 
| 
      
 727 
     | 
    
         
            +
                       SELECT * FROM sqlite_temp_master)
         
     | 
| 
      
 728 
     | 
    
         
            +
                    WHERE type = 'table' AND name = #{quote(table_name)}
         
     | 
| 
      
 729 
     | 
    
         
            +
                  SQL
         
     | 
| 
      
 730 
     | 
    
         
            +
             
     | 
| 
      
 731 
     | 
    
         
            +
                  # Result will have following sample string
         
     | 
| 
      
 732 
     | 
    
         
            +
                  # CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
         
     | 
| 
      
 733 
     | 
    
         
            +
                  #                       "password_digest" varchar COLLATE "NOCASE",
         
     | 
| 
      
 734 
     | 
    
         
            +
                  #                       "o_id" integer,
         
     | 
| 
      
 735 
     | 
    
         
            +
                  #                       CONSTRAINT "fk_rails_78146ddd2e" FOREIGN KEY ("o_id") REFERENCES "os" ("id"));
         
     | 
| 
      
 736 
     | 
    
         
            +
                  result = query_value(sql, "SCHEMA")
         
     | 
| 
      
 737 
     | 
    
         
            +
             
     | 
| 
      
 738 
     | 
    
         
            +
                  return [] unless result
         
     | 
| 
      
 739 
     | 
    
         
            +
             
     | 
| 
      
 740 
     | 
    
         
            +
                  # Splitting with left parentheses and discarding the first part will return all
         
     | 
| 
      
 741 
     | 
    
         
            +
                  # columns separated with comma(,).
         
     | 
| 
      
 742 
     | 
    
         
            +
                  result.partition(UNQUOTED_OPEN_PARENS_REGEX)
         
     | 
| 
      
 743 
     | 
    
         
            +
                        .last
         
     | 
| 
      
 744 
     | 
    
         
            +
                        .sub(FINAL_CLOSE_PARENS_REGEX, "")
         
     | 
| 
      
 745 
     | 
    
         
            +
                        # column definitions can have a comma in them, so split on commas followed
         
     | 
| 
      
 746 
     | 
    
         
            +
                        # by a space and a column name in quotes or followed by the keyword CONSTRAINT
         
     | 
| 
      
 747 
     | 
    
         
            +
                        .split(/,(?=\s(?:CONSTRAINT|"(?:#{Regexp.union(column_names).source})"))/i)
         
     | 
| 
      
 748 
     | 
    
         
            +
                        .map(&:strip)
         
     | 
| 
      
 749 
     | 
    
         
            +
                end
         
     | 
| 
      
 750 
     | 
    
         
            +
             
     | 
| 
      
 751 
     | 
    
         
            +
                def table_info(table_name)
         
     | 
| 
      
 752 
     | 
    
         
            +
                  if supports_virtual_columns?
         
     | 
| 
      
 753 
     | 
    
         
            +
                    internal_exec_query("PRAGMA table_xinfo(#{quote_table_name(table_name)})", "SCHEMA")
         
     | 
| 
      
 754 
     | 
    
         
            +
                  else
         
     | 
| 
      
 755 
     | 
    
         
            +
                    internal_exec_query("PRAGMA table_info(#{quote_table_name(table_name)})", "SCHEMA")
         
     | 
| 
      
 756 
     | 
    
         
            +
                  end
         
     | 
| 
      
 757 
     | 
    
         
            +
                end
         
     | 
| 
      
 758 
     | 
    
         
            +
             
     | 
| 
       660 
759 
     | 
    
         
             
                def arel_visitor
         
     | 
| 
       661 
760 
     | 
    
         
             
                  Arel::Visitors::SQLite.new(self)
         
     | 
| 
       662 
761 
     | 
    
         
             
                end
         
     | 
| 
         @@ -686,29 +785,17 @@ module ArJdbc 
     | 
|
| 
       686 
785 
     | 
    
         
             
                    end
         
     | 
| 
       687 
786 
     | 
    
         
             
                  end
         
     | 
| 
       688 
787 
     | 
    
         | 
| 
       689 
     | 
    
         
            -
                   
     | 
| 
       690 
     | 
    
         
            -
             
     | 
| 
       691 
     | 
    
         
            -
                   
     | 
| 
       692 
     | 
    
         
            -
                   
     | 
| 
       693 
     | 
    
         
            -
             
     | 
| 
       694 
     | 
    
         
            -
             
     | 
| 
       695 
     | 
    
         
            -
             
     | 
| 
       696 
     | 
    
         
            -
                     
     | 
| 
       697 
     | 
    
         
            -
             
     | 
| 
       698 
     | 
    
         
            -
                     
     | 
| 
       699 
     | 
    
         
            -
             
     | 
| 
       700 
     | 
    
         
            -
                    raw_execute("PRAGMA synchronous = NORMAL", "SCHEMA")
         
     | 
| 
       701 
     | 
    
         
            -
                    # Set the global memory map so all processes can share some data
         
     | 
| 
       702 
     | 
    
         
            -
                    # https://www.sqlite.org/pragma.html#pragma_mmap_size
         
     | 
| 
       703 
     | 
    
         
            -
                    # https://www.sqlite.org/mmap.html
         
     | 
| 
       704 
     | 
    
         
            -
                    raw_execute("PRAGMA mmap_size = #{128.megabytes}", "SCHEMA")
         
     | 
| 
       705 
     | 
    
         
            -
                  end
         
     | 
| 
       706 
     | 
    
         
            -
                  # Impose a limit on the WAL file to prevent unlimited growth
         
     | 
| 
       707 
     | 
    
         
            -
                  # https://www.sqlite.org/pragma.html#pragma_journal_size_limit
         
     | 
| 
       708 
     | 
    
         
            -
                  raw_execute("PRAGMA journal_size_limit = #{64.megabytes}", "SCHEMA")
         
     | 
| 
       709 
     | 
    
         
            -
                  # Set the local connection cache to 2000 pages
         
     | 
| 
       710 
     | 
    
         
            -
                  # https://www.sqlite.org/pragma.html#pragma_cache_size
         
     | 
| 
       711 
     | 
    
         
            -
                  raw_execute("PRAGMA cache_size = 2000", "SCHEMA")
         
     | 
| 
      
 788 
     | 
    
         
            +
                  super
         
     | 
| 
      
 789 
     | 
    
         
            +
             
     | 
| 
      
 790 
     | 
    
         
            +
                  pragmas = @config.fetch(:pragmas, {}).stringify_keys
         
     | 
| 
      
 791 
     | 
    
         
            +
                  DEFAULT_PRAGMAS.merge(pragmas).each do |pragma, value|
         
     | 
| 
      
 792 
     | 
    
         
            +
                    if ::SQLite3::Pragmas.respond_to?(pragma)
         
     | 
| 
      
 793 
     | 
    
         
            +
                      stmt = ::SQLite3::Pragmas.public_send(pragma, value)
         
     | 
| 
      
 794 
     | 
    
         
            +
                      raw_execute(stmt, "SCHEMA")
         
     | 
| 
      
 795 
     | 
    
         
            +
                    else
         
     | 
| 
      
 796 
     | 
    
         
            +
                      warn "Unknown SQLite pragma: #{pragma}"
         
     | 
| 
      
 797 
     | 
    
         
            +
                    end
         
     | 
| 
      
 798 
     | 
    
         
            +
                  end
         
     | 
| 
       712 
799 
     | 
    
         
             
                end
         
     | 
| 
       713 
800 
     | 
    
         
             
              end
         
     | 
| 
       714 
801 
     | 
    
         
             
              # DIFFERENCE: A registration here is moved down to concrete class so we are not registering part of an adapter.
         
     | 
| 
         @@ -745,6 +832,12 @@ module ActiveRecord::ConnectionAdapters 
     | 
|
| 
       745 
832 
     | 
    
         
             
                  end
         
     | 
| 
       746 
833 
     | 
    
         
             
                end
         
     | 
| 
       747 
834 
     | 
    
         | 
| 
      
 835 
     | 
    
         
            +
                # NOTE: include these modules before all then override some methods with the
         
     | 
| 
      
 836 
     | 
    
         
            +
                # ones defined in ArJdbc::SQLite3 java part and ArJdbc::Abstract
         
     | 
| 
      
 837 
     | 
    
         
            +
                include ::ActiveRecord::ConnectionAdapters::SQLite3::Quoting
         
     | 
| 
      
 838 
     | 
    
         
            +
                include ::ActiveRecord::ConnectionAdapters::SQLite3::SchemaStatements
         
     | 
| 
      
 839 
     | 
    
         
            +
                include ::ActiveRecord::ConnectionAdapters::SQLite3::DatabaseStatements
         
     | 
| 
      
 840 
     | 
    
         
            +
             
     | 
| 
       748 
841 
     | 
    
         
             
                include ArJdbc::Abstract::Core
         
     | 
| 
       749 
842 
     | 
    
         
             
                include ArJdbc::SQLite3
         
     | 
| 
       750 
843 
     | 
    
         
             
                include ArJdbc::SQLite3Config
         
     | 
| 
         @@ -754,9 +847,6 @@ module ActiveRecord::ConnectionAdapters 
     | 
|
| 
       754 
847 
     | 
    
         
             
                include ArJdbc::Abstract::StatementCache
         
     | 
| 
       755 
848 
     | 
    
         
             
                include ArJdbc::Abstract::TransactionSupport
         
     | 
| 
       756 
849 
     | 
    
         | 
| 
       757 
     | 
    
         
            -
                include ::ActiveRecord::ConnectionAdapters::SQLite3::Quoting
         
     | 
| 
       758 
     | 
    
         
            -
                include ::ActiveRecord::ConnectionAdapters::SQLite3::SchemaStatements
         
     | 
| 
       759 
     | 
    
         
            -
                include ::ActiveRecord::ConnectionAdapters::SQLite3::DatabaseStatements
         
     | 
| 
       760 
850 
     | 
    
         | 
| 
       761 
851 
     | 
    
         
             
                ##
         
     | 
| 
       762 
852 
     | 
    
         
             
                # :singleton-method:
         
     | 
| 
         @@ -771,6 +861,14 @@ module ActiveRecord::ConnectionAdapters 
     | 
|
| 
       771 
861 
     | 
    
         
             
                def initialize(...)
         
     | 
| 
       772 
862 
     | 
    
         
             
                  super
         
     | 
| 
       773 
863 
     | 
    
         | 
| 
      
 864 
     | 
    
         
            +
                  @memory_database = false
         
     | 
| 
      
 865 
     | 
    
         
            +
                  case @config[:database].to_s
         
     | 
| 
      
 866 
     | 
    
         
            +
                  when ""
         
     | 
| 
      
 867 
     | 
    
         
            +
                    raise ArgumentError, "No database file specified. Missing argument: database"
         
     | 
| 
      
 868 
     | 
    
         
            +
                  when ":memory:"
         
     | 
| 
      
 869 
     | 
    
         
            +
                    @memory_database = true
         
     | 
| 
      
 870 
     | 
    
         
            +
                  end
         
     | 
| 
      
 871 
     | 
    
         
            +
             
     | 
| 
       774 
872 
     | 
    
         
             
                  # assign arjdbc extra connection params
         
     | 
| 
       775 
873 
     | 
    
         
             
                  conn_params = build_connection_config(@config.compact)
         
     | 
| 
       776 
874 
     | 
    
         | 
| 
         @@ -4,12 +4,14 @@ module ActiveRecord::ConnectionAdapters 
     | 
|
| 
       4 
4 
     | 
    
         
             
              class SQLite3Column < JdbcColumn
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
       6 
6 
     | 
    
         
             
                attr_reader :rowid
         
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
                def initialize( 
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                def initialize(*, auto_increment: nil, rowid: false, generated_type: nil, **)
         
     | 
| 
       9 
9 
     | 
    
         
             
                  super
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
       10 
11 
     | 
    
         
             
                  @auto_increment = auto_increment
         
     | 
| 
       11 
12 
     | 
    
         
             
                  @default = nil if default =~ /NULL/
         
     | 
| 
       12 
13 
     | 
    
         
             
                  @rowid = rowid
         
     | 
| 
      
 14 
     | 
    
         
            +
                  @generated_type = generated_type
         
     | 
| 
       13 
15 
     | 
    
         
             
                end
         
     | 
| 
       14 
16 
     | 
    
         | 
| 
       15 
17 
     | 
    
         
             
                def self.string_to_binary(value)
         
     | 
| 
         @@ -39,6 +41,18 @@ module ActiveRecord::ConnectionAdapters 
     | 
|
| 
       39 
41 
     | 
    
         
             
                  auto_increment? || rowid
         
     | 
| 
       40 
42 
     | 
    
         
             
                end
         
     | 
| 
       41 
43 
     | 
    
         | 
| 
      
 44 
     | 
    
         
            +
                def virtual?
         
     | 
| 
      
 45 
     | 
    
         
            +
                  !@generated_type.nil?
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                def virtual_stored?
         
     | 
| 
      
 49 
     | 
    
         
            +
                  virtual? && @generated_type == :stored
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                def has_default?
         
     | 
| 
      
 53 
     | 
    
         
            +
                  super && !virtual?
         
     | 
| 
      
 54 
     | 
    
         
            +
                end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
       42 
56 
     | 
    
         
             
                def init_with(coder)
         
     | 
| 
       43 
57 
     | 
    
         
             
                  @auto_increment = coder["auto_increment"]
         
     | 
| 
       44 
58 
     | 
    
         
             
                  super
         
     | 
| 
         @@ -100,4 +114,4 @@ module ActiveRecord::ConnectionAdapters 
     | 
|
| 
       100 
114 
     | 
    
         
             
                  end
         
     | 
| 
       101 
115 
     | 
    
         
             
                end
         
     | 
| 
       102 
116 
     | 
    
         
             
              end
         
     | 
| 
       103 
     | 
    
         
            -
            end
         
     | 
| 
      
 117 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,105 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module SQLite3
         
     | 
| 
      
 4 
     | 
    
         
            +
              # defines methods to de generate pragma statements
         
     | 
| 
      
 5 
     | 
    
         
            +
              module Pragmas
         
     | 
| 
      
 6 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 7 
     | 
    
         
            +
                  # The enumeration of valid synchronous modes.
         
     | 
| 
      
 8 
     | 
    
         
            +
                  SYNCHRONOUS_MODES = [["full", 2], ["normal", 1], ["off", 0]].freeze
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  # The enumeration of valid temp store modes.
         
     | 
| 
      
 11 
     | 
    
         
            +
                  TEMP_STORE_MODES = [["default", 0], ["file", 1], ["memory", 2]].freeze
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                  # The enumeration of valid auto vacuum modes.
         
     | 
| 
      
 14 
     | 
    
         
            +
                  AUTO_VACUUM_MODES = [["none", 0], ["full", 1], ["incremental", 2]].freeze
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  # The list of valid journaling modes.
         
     | 
| 
      
 17 
     | 
    
         
            +
                  JOURNAL_MODES = [["delete"], ["truncate"], ["persist"], ["memory"], ["wal"], ["off"]].freeze
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  # The list of valid locking modes.
         
     | 
| 
      
 20 
     | 
    
         
            +
                  LOCKING_MODES = [["normal"], ["exclusive"]].freeze
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                  # The list of valid encodings.
         
     | 
| 
      
 23 
     | 
    
         
            +
                  ENCODINGS = [["utf-8"], ["utf-16"], ["utf-16le"], ["utf-16be"]].freeze
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                  # The list of valid WAL checkpoints.
         
     | 
| 
      
 26 
     | 
    
         
            +
                  WAL_CHECKPOINTS = [["passive"], ["full"], ["restart"], ["truncate"]].freeze
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                  # Enforce foreign key constraints
         
     | 
| 
      
 29 
     | 
    
         
            +
                  # https://www.sqlite.org/pragma.html#pragma_foreign_keys
         
     | 
| 
      
 30 
     | 
    
         
            +
                  # https://www.sqlite.org/foreignkeys.html
         
     | 
| 
      
 31 
     | 
    
         
            +
                  def foreign_keys(value)
         
     | 
| 
      
 32 
     | 
    
         
            +
                    gen_boolean_pragma(:foreign_keys, value)
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                  # Journal mode WAL allows for greater concurrency (many readers + one writer)
         
     | 
| 
      
 36 
     | 
    
         
            +
                  # https://www.sqlite.org/pragma.html#pragma_journal_mode
         
     | 
| 
      
 37 
     | 
    
         
            +
                  def journal_mode(value)
         
     | 
| 
      
 38 
     | 
    
         
            +
                    gen_enum_pragma(:journal_mode, value, JOURNAL_MODES)
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                  # Set more relaxed level of database durability
         
     | 
| 
      
 42 
     | 
    
         
            +
                  # 2 = "FULL" (sync on every write), 1 = "NORMAL" (sync every 1000 written pages) and 0 = "NONE"
         
     | 
| 
      
 43 
     | 
    
         
            +
                  # https://www.sqlite.org/pragma.html#pragma_synchronous
         
     | 
| 
      
 44 
     | 
    
         
            +
                  def synchronous(value)
         
     | 
| 
      
 45 
     | 
    
         
            +
                    gen_enum_pragma(:synchronous, value, SYNCHRONOUS_MODES)
         
     | 
| 
      
 46 
     | 
    
         
            +
                  end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                  def temp_store(value)
         
     | 
| 
      
 49 
     | 
    
         
            +
                    gen_enum_pragma(:temp_store, value, TEMP_STORE_MODES)
         
     | 
| 
      
 50 
     | 
    
         
            +
                  end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                  # Set the global memory map so all processes can share some data
         
     | 
| 
      
 53 
     | 
    
         
            +
                  # https://www.sqlite.org/pragma.html#pragma_mmap_size
         
     | 
| 
      
 54 
     | 
    
         
            +
                  # https://www.sqlite.org/mmap.html
         
     | 
| 
      
 55 
     | 
    
         
            +
                  def mmap_size(value)
         
     | 
| 
      
 56 
     | 
    
         
            +
                    "PRAGMA mmap_size = #{value.to_i}"
         
     | 
| 
      
 57 
     | 
    
         
            +
                  end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                  # Impose a limit on the WAL file to prevent unlimited growth
         
     | 
| 
      
 60 
     | 
    
         
            +
                  # https://www.sqlite.org/pragma.html#pragma_journal_size_limit
         
     | 
| 
      
 61 
     | 
    
         
            +
                  def journal_size_limit(value)
         
     | 
| 
      
 62 
     | 
    
         
            +
                    "PRAGMA journal_size_limit = #{value.to_i}"
         
     | 
| 
      
 63 
     | 
    
         
            +
                  end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                  # Set the local connection cache to 2000 pages
         
     | 
| 
      
 66 
     | 
    
         
            +
                  # https://www.sqlite.org/pragma.html#pragma_cache_size
         
     | 
| 
      
 67 
     | 
    
         
            +
                  def cache_size(value)
         
     | 
| 
      
 68 
     | 
    
         
            +
                    "PRAGMA cache_size = #{value.to_i}"
         
     | 
| 
      
 69 
     | 
    
         
            +
                  end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                  private
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                  def gen_boolean_pragma(name, mode)
         
     | 
| 
      
 74 
     | 
    
         
            +
                    case mode
         
     | 
| 
      
 75 
     | 
    
         
            +
                    when String
         
     | 
| 
      
 76 
     | 
    
         
            +
                      case mode.downcase
         
     | 
| 
      
 77 
     | 
    
         
            +
                      when "on", "yes", "true", "y", "t" then mode = "'ON'"
         
     | 
| 
      
 78 
     | 
    
         
            +
                      when "off", "no", "false", "n", "f" then mode = "'OFF'"
         
     | 
| 
      
 79 
     | 
    
         
            +
                      else
         
     | 
| 
      
 80 
     | 
    
         
            +
                        raise ActiveRecord::JDBCError, "unrecognized pragma parameter #{mode.inspect}"
         
     | 
| 
      
 81 
     | 
    
         
            +
                      end
         
     | 
| 
      
 82 
     | 
    
         
            +
                    when true, 1
         
     | 
| 
      
 83 
     | 
    
         
            +
                      mode = "ON"
         
     | 
| 
      
 84 
     | 
    
         
            +
                    when false, 0, nil
         
     | 
| 
      
 85 
     | 
    
         
            +
                      mode = "OFF"
         
     | 
| 
      
 86 
     | 
    
         
            +
                    else
         
     | 
| 
      
 87 
     | 
    
         
            +
                      raise ActiveRecord::JDBCError, "unrecognized pragma parameter #{mode.inspect}"
         
     | 
| 
      
 88 
     | 
    
         
            +
                    end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                    "PRAGMA #{name} = #{mode}"
         
     | 
| 
      
 91 
     | 
    
         
            +
                  end
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
                  def gen_enum_pragma(name, mode, enums)
         
     | 
| 
      
 94 
     | 
    
         
            +
                    match = enums.find { |p| p.find { |i| i.to_s.downcase == mode.to_s.downcase } }
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
                    unless match
         
     | 
| 
      
 97 
     | 
    
         
            +
                      # Unknown pragma value
         
     | 
| 
      
 98 
     | 
    
         
            +
                      raise ActiveRecord::JDBCError, "unrecognized #{name} #{mode.inspect}"
         
     | 
| 
      
 99 
     | 
    
         
            +
                    end
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
                    "PRAGMA #{name} = '#{match.first.upcase}'"
         
     | 
| 
      
 102 
     | 
    
         
            +
                  end
         
     | 
| 
      
 103 
     | 
    
         
            +
                end
         
     | 
| 
      
 104 
     | 
    
         
            +
              end
         
     | 
| 
      
 105 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/arjdbc/version.rb
    CHANGED
    
    
    
        data/lib/arjdbc.rb
    CHANGED
    
    | 
         @@ -17,6 +17,15 @@ if defined?(JRUBY_VERSION) 
     | 
|
| 
       17 
17 
     | 
    
         
             
                ActiveRecord::ConnectionAdapters.register(
         
     | 
| 
       18 
18 
     | 
    
         
             
                  "sqlserver", "ActiveRecord::ConnectionAdapters::MSSQLAdapter", "active_record/connection_adapters/mssql_adapter"
         
     | 
| 
       19 
19 
     | 
    
         
             
                )
         
     | 
| 
      
 20 
     | 
    
         
            +
                ActiveRecord::ConnectionAdapters.register(
         
     | 
| 
      
 21 
     | 
    
         
            +
                  "sqlite3", "ActiveRecord::ConnectionAdapters::SQLite3Adapter", "arjdbc/sqlite3/adapter"
         
     | 
| 
      
 22 
     | 
    
         
            +
                )
         
     | 
| 
      
 23 
     | 
    
         
            +
                ActiveRecord::ConnectionAdapters.register(
         
     | 
| 
      
 24 
     | 
    
         
            +
                  "postgresql", "ActiveRecord::ConnectionAdapters::PostgreSQLAdapter", "arjdbc/postgresql/adapter"
         
     | 
| 
      
 25 
     | 
    
         
            +
                )
         
     | 
| 
      
 26 
     | 
    
         
            +
                ActiveRecord::ConnectionAdapters.register(
         
     | 
| 
      
 27 
     | 
    
         
            +
                  "mysql2", "ActiveRecord::ConnectionAdapters::Mysql2Adapter", "arjdbc/mysql/adapter"
         
     | 
| 
      
 28 
     | 
    
         
            +
                )
         
     | 
| 
       20 
29 
     | 
    
         
             
              end
         
     | 
| 
       21 
30 
     | 
    
         
             
            else
         
     | 
| 
       22 
31 
     | 
    
         
             
              warn "activerecord-jdbc-adapter is for use with JRuby only"
         
     | 
| 
         @@ -126,6 +126,7 @@ public class RubyJdbcConnection extends RubyObject { 
     | 
|
| 
       126 
126 
     | 
    
         
             
                private IRubyObject adapter; // the AbstractAdapter instance we belong to
         
     | 
| 
       127 
127 
     | 
    
         
             
                private volatile boolean connected = true;
         
     | 
| 
       128 
128 
     | 
    
         
             
                private RubyClass attributeClass;
         
     | 
| 
      
 129 
     | 
    
         
            +
                private RubyClass timeZoneClass;
         
     | 
| 
       129 
130 
     | 
    
         | 
| 
       130 
131 
     | 
    
         
             
                private boolean lazy = false; // final once set on initialize
         
     | 
| 
       131 
132 
     | 
    
         
             
                private boolean jndi; // final once set on initialize
         
     | 
| 
         @@ -135,6 +136,7 @@ public class RubyJdbcConnection extends RubyObject { 
     | 
|
| 
       135 
136 
     | 
    
         
             
                protected RubyJdbcConnection(Ruby runtime, RubyClass metaClass) {
         
     | 
| 
       136 
137 
     | 
    
         
             
                    super(runtime, metaClass);
         
     | 
| 
       137 
138 
     | 
    
         
             
                    attributeClass = runtime.getModule("ActiveModel").getClass("Attribute");
         
     | 
| 
      
 139 
     | 
    
         
            +
                    timeZoneClass = runtime.getModule("ActiveSupport").getClass("TimeWithZone");
         
     | 
| 
       138 
140 
     | 
    
         
             
                }
         
     | 
| 
       139 
141 
     | 
    
         | 
| 
       140 
142 
     | 
    
         
             
                private static final ObjectAllocator ALLOCATOR = new ObjectAllocator() {
         
     | 
| 
         @@ -2441,6 +2443,9 @@ public class RubyJdbcConnection extends RubyObject { 
     | 
|
| 
       2441 
2443 
     | 
    
         
             
                    if (attributeClass.isInstance(attribute)) {
         
     | 
| 
       2442 
2444 
     | 
    
         
             
                        type = jdbcTypeForAttribute(context, attribute);
         
     | 
| 
       2443 
2445 
     | 
    
         
             
                        value = valueForDatabase(context, attribute);
         
     | 
| 
      
 2446 
     | 
    
         
            +
                    } else if (timeZoneClass.isInstance(attribute)) {
         
     | 
| 
      
 2447 
     | 
    
         
            +
                        type = jdbcTypeFor("timestamp");
         
     | 
| 
      
 2448 
     | 
    
         
            +
                        value = attribute;
         
     | 
| 
       2444 
2449 
     | 
    
         
             
                    } else {
         
     | 
| 
       2445 
2450 
     | 
    
         
             
                        type = jdbcTypeForPrimitiveAttribute(context, attribute);
         
     | 
| 
       2446 
2451 
     | 
    
         
             
                        value = attribute;
         
     | 
| 
         @@ -473,7 +473,10 @@ public class SQLite3RubyJdbcConnection extends RubyJdbcConnection { 
     | 
|
| 
       473 
473 
     | 
    
         
             
                    // Assume we will only call this with an array.
         
     | 
| 
       474 
474 
     | 
    
         
             
                    final RubyArray statements = (RubyArray) statementsArg;
         
     | 
| 
       475 
475 
     | 
    
         
             
                    return withConnection(context, connection -> {
         
     | 
| 
      
 476 
     | 
    
         
            +
                        final Ruby runtime = context.runtime;
         
     | 
| 
      
 477 
     | 
    
         
            +
             
     | 
| 
       476 
478 
     | 
    
         
             
                        Statement statement = null;
         
     | 
| 
      
 479 
     | 
    
         
            +
             
     | 
| 
       477 
480 
     | 
    
         
             
                        try {
         
     | 
| 
       478 
481 
     | 
    
         
             
                            statement = createStatement(context, connection);
         
     | 
| 
       479 
482 
     | 
    
         | 
| 
         @@ -481,8 +484,15 @@ public class SQLite3RubyJdbcConnection extends RubyJdbcConnection { 
     | 
|
| 
       481 
484 
     | 
    
         
             
                            for (int i = 0; i < length; i++) {
         
     | 
| 
       482 
485 
     | 
    
         
             
                                statement.addBatch(sqlString(statements.eltOk(i)));
         
     | 
| 
       483 
486 
     | 
    
         
             
                            }
         
     | 
| 
       484 
     | 
    
         
            -
             
     | 
| 
       485 
     | 
    
         
            -
                             
     | 
| 
      
 487 
     | 
    
         
            +
             
     | 
| 
      
 488 
     | 
    
         
            +
                            int[] rows = statement.executeBatch();
         
     | 
| 
      
 489 
     | 
    
         
            +
             
     | 
| 
      
 490 
     | 
    
         
            +
                            RubyArray rowsAffected = runtime.newArray();
         
     | 
| 
      
 491 
     | 
    
         
            +
             
     | 
| 
      
 492 
     | 
    
         
            +
                            for (int i = 0; i < rows.length; i++) {
         
     | 
| 
      
 493 
     | 
    
         
            +
                                rowsAffected.append(runtime.newFixnum(rows[i]));
         
     | 
| 
      
 494 
     | 
    
         
            +
                            }
         
     | 
| 
      
 495 
     | 
    
         
            +
                            return rowsAffected;
         
     | 
| 
       486 
496 
     | 
    
         
             
                        } catch (final SQLException e) {
         
     | 
| 
       487 
497 
     | 
    
         
             
                            // Generate list semicolon list of statements which should match AR error formatting more.
         
     | 
| 
       488 
498 
     | 
    
         
             
                            debugErrorSQL(context, sqlString(statements.join(context, context.runtime.newString(";\n"))));
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,22 +1,22 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: activerecord-jdbc-alt-adapter
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 72.0.0. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 72.0.0.rc1
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: java
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Nick Sieger, Ola Bini, Karol Bucek, Jesse Chavez, and JRuby contributors
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire:
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2025- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2025-02-09 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 14 
     | 
    
         
            +
              name: activerecord
         
     | 
| 
       14 
15 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
       15 
16 
     | 
    
         
             
                requirements:
         
     | 
| 
       16 
17 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       17 
18 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       18 
19 
     | 
    
         
             
                    version: 7.2.2
         
     | 
| 
       19 
     | 
    
         
            -
              name: activerecord
         
     | 
| 
       20 
20 
     | 
    
         
             
              type: :runtime
         
     | 
| 
       21 
21 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       22 
22 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
         @@ -95,7 +95,6 @@ files: 
     | 
|
| 
       95 
95 
     | 
    
         
             
            - lib/arjdbc/jdbc/adapter.rb
         
     | 
| 
       96 
96 
     | 
    
         
             
            - lib/arjdbc/jdbc/adapter_java.jar
         
     | 
| 
       97 
97 
     | 
    
         
             
            - lib/arjdbc/jdbc/adapter_require.rb
         
     | 
| 
       98 
     | 
    
         
            -
            - lib/arjdbc/jdbc/base_ext.rb
         
     | 
| 
       99 
98 
     | 
    
         
             
            - lib/arjdbc/jdbc/callbacks.rb
         
     | 
| 
       100 
99 
     | 
    
         
             
            - lib/arjdbc/jdbc/column.rb
         
     | 
| 
       101 
100 
     | 
    
         
             
            - lib/arjdbc/jdbc/connection.rb
         
     | 
| 
         @@ -157,6 +156,7 @@ files: 
     | 
|
| 
       157 
156 
     | 
    
         
             
            - lib/arjdbc/sqlite3/adapter_hash_config.rb
         
     | 
| 
       158 
157 
     | 
    
         
             
            - lib/arjdbc/sqlite3/column.rb
         
     | 
| 
       159 
158 
     | 
    
         
             
            - lib/arjdbc/sqlite3/connection_methods.rb
         
     | 
| 
      
 159 
     | 
    
         
            +
            - lib/arjdbc/sqlite3/pragmas.rb
         
     | 
| 
       160 
160 
     | 
    
         
             
            - lib/arjdbc/tasks.rb
         
     | 
| 
       161 
161 
     | 
    
         
             
            - lib/arjdbc/tasks/database_tasks.rb
         
     | 
| 
       162 
162 
     | 
    
         
             
            - lib/arjdbc/tasks/databases.rake
         
     | 
    
        data/lib/arjdbc/jdbc/base_ext.rb
    DELETED
    
    | 
         @@ -1,17 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # frozen_string_literal: true
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            module ActiveRecord
         
     | 
| 
       4 
     | 
    
         
            -
              class << Base
         
     | 
| 
       5 
     | 
    
         
            -
                m = Module.new do
         
     | 
| 
       6 
     | 
    
         
            -
                  # Allow adapters to provide their own {#reset_column_information} method.
         
     | 
| 
       7 
     | 
    
         
            -
                  # @note This only affects the current thread's connection.
         
     | 
| 
       8 
     | 
    
         
            -
                  def reset_column_information # :nodoc:
         
     | 
| 
       9 
     | 
    
         
            -
                    # invoke the adapter-specific reset_column_information method
         
     | 
| 
       10 
     | 
    
         
            -
                    connection.reset_column_information if connection.respond_to?(:reset_column_information)
         
     | 
| 
       11 
     | 
    
         
            -
                    super
         
     | 
| 
       12 
     | 
    
         
            -
                  end
         
     | 
| 
       13 
     | 
    
         
            -
                end
         
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
                self.prepend(m)
         
     | 
| 
       16 
     | 
    
         
            -
              end
         
     | 
| 
       17 
     | 
    
         
            -
            end
         
     |