activerecord 3.0.0 → 4.0.0
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.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +7 -0
 - data/CHANGELOG.md +2102 -0
 - data/MIT-LICENSE +20 -0
 - data/README.rdoc +35 -44
 - data/examples/performance.rb +110 -100
 - data/lib/active_record/aggregations.rb +59 -75
 - data/lib/active_record/associations/alias_tracker.rb +76 -0
 - data/lib/active_record/associations/association.rb +248 -0
 - data/lib/active_record/associations/association_scope.rb +135 -0
 - data/lib/active_record/associations/belongs_to_association.rb +60 -59
 - data/lib/active_record/associations/belongs_to_polymorphic_association.rb +16 -59
 - data/lib/active_record/associations/builder/association.rb +108 -0
 - data/lib/active_record/associations/builder/belongs_to.rb +98 -0
 - data/lib/active_record/associations/builder/collection_association.rb +89 -0
 - data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +39 -0
 - data/lib/active_record/associations/builder/has_many.rb +15 -0
 - data/lib/active_record/associations/builder/has_one.rb +25 -0
 - data/lib/active_record/associations/builder/singular_association.rb +32 -0
 - data/lib/active_record/associations/collection_association.rb +608 -0
 - data/lib/active_record/associations/collection_proxy.rb +986 -0
 - data/lib/active_record/associations/has_and_belongs_to_many_association.rb +40 -112
 - data/lib/active_record/associations/has_many_association.rb +83 -76
 - data/lib/active_record/associations/has_many_through_association.rb +147 -66
 - data/lib/active_record/associations/has_one_association.rb +67 -108
 - data/lib/active_record/associations/has_one_through_association.rb +21 -25
 - data/lib/active_record/associations/join_dependency/join_association.rb +174 -0
 - data/lib/active_record/associations/join_dependency/join_base.rb +24 -0
 - data/lib/active_record/associations/join_dependency/join_part.rb +78 -0
 - data/lib/active_record/associations/join_dependency.rb +235 -0
 - data/lib/active_record/associations/join_helper.rb +45 -0
 - data/lib/active_record/associations/preloader/association.rb +121 -0
 - data/lib/active_record/associations/preloader/belongs_to.rb +17 -0
 - data/lib/active_record/associations/preloader/collection_association.rb +24 -0
 - data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +60 -0
 - data/lib/active_record/associations/preloader/has_many.rb +17 -0
 - data/lib/active_record/associations/preloader/has_many_through.rb +19 -0
 - data/lib/active_record/associations/preloader/has_one.rb +23 -0
 - data/lib/active_record/associations/preloader/has_one_through.rb +9 -0
 - data/lib/active_record/associations/preloader/singular_association.rb +21 -0
 - data/lib/active_record/associations/preloader/through_association.rb +63 -0
 - data/lib/active_record/associations/preloader.rb +178 -0
 - data/lib/active_record/associations/singular_association.rb +64 -0
 - data/lib/active_record/associations/through_association.rb +87 -0
 - data/lib/active_record/associations.rb +512 -1224
 - data/lib/active_record/attribute_assignment.rb +201 -0
 - data/lib/active_record/attribute_methods/before_type_cast.rb +49 -12
 - data/lib/active_record/attribute_methods/dirty.rb +51 -28
 - data/lib/active_record/attribute_methods/primary_key.rb +94 -22
 - data/lib/active_record/attribute_methods/query.rb +5 -4
 - data/lib/active_record/attribute_methods/read.rb +63 -72
 - data/lib/active_record/attribute_methods/serialization.rb +162 -0
 - data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -41
 - data/lib/active_record/attribute_methods/write.rb +39 -13
 - data/lib/active_record/attribute_methods.rb +362 -29
 - data/lib/active_record/autosave_association.rb +132 -75
 - data/lib/active_record/base.rb +83 -1627
 - data/lib/active_record/callbacks.rb +69 -47
 - data/lib/active_record/coders/yaml_column.rb +38 -0
 - data/lib/active_record/connection_adapters/abstract/connection_pool.rb +411 -138
 - data/lib/active_record/connection_adapters/abstract/database_limits.rb +21 -11
 - data/lib/active_record/connection_adapters/abstract/database_statements.rb +234 -173
 - data/lib/active_record/connection_adapters/abstract/query_cache.rb +36 -22
 - data/lib/active_record/connection_adapters/abstract/quoting.rb +82 -25
 - data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +176 -414
 - data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +70 -0
 - data/lib/active_record/connection_adapters/abstract/schema_statements.rb +562 -232
 - data/lib/active_record/connection_adapters/abstract/transaction.rb +203 -0
 - data/lib/active_record/connection_adapters/abstract_adapter.rb +281 -53
 - data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +782 -0
 - data/lib/active_record/connection_adapters/column.rb +318 -0
 - data/lib/active_record/connection_adapters/connection_specification.rb +96 -0
 - data/lib/active_record/connection_adapters/mysql2_adapter.rb +273 -0
 - data/lib/active_record/connection_adapters/mysql_adapter.rb +365 -450
 - data/lib/active_record/connection_adapters/postgresql/array_parser.rb +97 -0
 - data/lib/active_record/connection_adapters/postgresql/cast.rb +152 -0
 - data/lib/active_record/connection_adapters/postgresql/database_statements.rb +242 -0
 - data/lib/active_record/connection_adapters/postgresql/oid.rb +366 -0
 - data/lib/active_record/connection_adapters/postgresql/quoting.rb +171 -0
 - data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +30 -0
 - data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +489 -0
 - data/lib/active_record/connection_adapters/postgresql_adapter.rb +672 -752
 - data/lib/active_record/connection_adapters/schema_cache.rb +129 -0
 - data/lib/active_record/connection_adapters/sqlite3_adapter.rb +588 -17
 - data/lib/active_record/connection_adapters/statement_pool.rb +40 -0
 - data/lib/active_record/connection_handling.rb +98 -0
 - data/lib/active_record/core.rb +463 -0
 - data/lib/active_record/counter_cache.rb +108 -101
 - data/lib/active_record/dynamic_matchers.rb +131 -0
 - data/lib/active_record/errors.rb +54 -13
 - data/lib/active_record/explain.rb +38 -0
 - data/lib/active_record/explain_registry.rb +30 -0
 - data/lib/active_record/explain_subscriber.rb +29 -0
 - data/lib/active_record/fixture_set/file.rb +55 -0
 - data/lib/active_record/fixtures.rb +703 -785
 - data/lib/active_record/inheritance.rb +200 -0
 - data/lib/active_record/integration.rb +60 -0
 - data/lib/active_record/locale/en.yml +8 -1
 - data/lib/active_record/locking/optimistic.rb +69 -60
 - data/lib/active_record/locking/pessimistic.rb +34 -12
 - data/lib/active_record/log_subscriber.rb +40 -6
 - data/lib/active_record/migration/command_recorder.rb +164 -0
 - data/lib/active_record/migration/join_table.rb +15 -0
 - data/lib/active_record/migration.rb +614 -216
 - data/lib/active_record/model_schema.rb +345 -0
 - data/lib/active_record/nested_attributes.rb +248 -119
 - data/lib/active_record/null_relation.rb +65 -0
 - data/lib/active_record/persistence.rb +275 -57
 - data/lib/active_record/query_cache.rb +29 -9
 - data/lib/active_record/querying.rb +62 -0
 - data/lib/active_record/railtie.rb +135 -21
 - data/lib/active_record/railties/console_sandbox.rb +5 -0
 - data/lib/active_record/railties/controller_runtime.rb +17 -5
 - data/lib/active_record/railties/databases.rake +249 -359
 - data/lib/active_record/railties/jdbcmysql_error.rb +16 -0
 - data/lib/active_record/readonly_attributes.rb +30 -0
 - data/lib/active_record/reflection.rb +283 -103
 - data/lib/active_record/relation/batches.rb +38 -34
 - data/lib/active_record/relation/calculations.rb +252 -139
 - data/lib/active_record/relation/delegation.rb +125 -0
 - data/lib/active_record/relation/finder_methods.rb +182 -188
 - data/lib/active_record/relation/merger.rb +161 -0
 - data/lib/active_record/relation/predicate_builder.rb +86 -21
 - data/lib/active_record/relation/query_methods.rb +917 -134
 - data/lib/active_record/relation/spawn_methods.rb +53 -92
 - data/lib/active_record/relation.rb +405 -143
 - data/lib/active_record/result.rb +67 -0
 - data/lib/active_record/runtime_registry.rb +17 -0
 - data/lib/active_record/sanitization.rb +168 -0
 - data/lib/active_record/schema.rb +20 -14
 - data/lib/active_record/schema_dumper.rb +55 -46
 - data/lib/active_record/schema_migration.rb +39 -0
 - data/lib/active_record/scoping/default.rb +146 -0
 - data/lib/active_record/scoping/named.rb +175 -0
 - data/lib/active_record/scoping.rb +82 -0
 - data/lib/active_record/serialization.rb +8 -46
 - data/lib/active_record/serializers/xml_serializer.rb +21 -68
 - data/lib/active_record/statement_cache.rb +26 -0
 - data/lib/active_record/store.rb +156 -0
 - data/lib/active_record/tasks/database_tasks.rb +203 -0
 - data/lib/active_record/tasks/firebird_database_tasks.rb +56 -0
 - data/lib/active_record/tasks/mysql_database_tasks.rb +143 -0
 - data/lib/active_record/tasks/oracle_database_tasks.rb +45 -0
 - data/lib/active_record/tasks/postgresql_database_tasks.rb +90 -0
 - data/lib/active_record/tasks/sqlite_database_tasks.rb +51 -0
 - data/lib/active_record/tasks/sqlserver_database_tasks.rb +48 -0
 - data/lib/active_record/test_case.rb +57 -28
 - data/lib/active_record/timestamp.rb +49 -18
 - data/lib/active_record/transactions.rb +106 -63
 - data/lib/active_record/translation.rb +22 -0
 - data/lib/active_record/validations/associated.rb +25 -24
 - data/lib/active_record/validations/presence.rb +65 -0
 - data/lib/active_record/validations/uniqueness.rb +123 -83
 - data/lib/active_record/validations.rb +29 -29
 - data/lib/active_record/version.rb +7 -5
 - data/lib/active_record.rb +83 -34
 - data/lib/rails/generators/active_record/migration/migration_generator.rb +46 -9
 - data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +19 -0
 - data/lib/rails/generators/active_record/migration/templates/migration.rb +30 -8
 - data/lib/rails/generators/active_record/model/model_generator.rb +15 -5
 - data/lib/rails/generators/active_record/model/templates/model.rb +7 -2
 - data/lib/rails/generators/active_record/model/templates/module.rb +3 -1
 - data/lib/rails/generators/active_record.rb +4 -8
 - metadata +163 -121
 - data/CHANGELOG +0 -6023
 - data/examples/associations.png +0 -0
 - data/lib/active_record/association_preload.rb +0 -403
 - data/lib/active_record/associations/association_collection.rb +0 -562
 - data/lib/active_record/associations/association_proxy.rb +0 -295
 - data/lib/active_record/associations/through_association_scope.rb +0 -154
 - data/lib/active_record/connection_adapters/abstract/connection_specification.rb +0 -113
 - data/lib/active_record/connection_adapters/sqlite_adapter.rb +0 -401
 - data/lib/active_record/dynamic_finder_match.rb +0 -53
 - data/lib/active_record/dynamic_scope_match.rb +0 -32
 - data/lib/active_record/named_scope.rb +0 -138
 - data/lib/active_record/observer.rb +0 -140
 - data/lib/active_record/session_store.rb +0 -340
 - data/lib/rails/generators/active_record/model/templates/migration.rb +0 -16
 - data/lib/rails/generators/active_record/observer/observer_generator.rb +0 -15
 - data/lib/rails/generators/active_record/observer/templates/observer.rb +0 -2
 - data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +0 -24
 - data/lib/rails/generators/active_record/session_migration/templates/migration.rb +0 -16
 
| 
         @@ -0,0 +1,318 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'set'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module ActiveRecord
         
     | 
| 
      
 4 
     | 
    
         
            +
              # :stopdoc:
         
     | 
| 
      
 5 
     | 
    
         
            +
              module ConnectionAdapters
         
     | 
| 
      
 6 
     | 
    
         
            +
                # An abstract definition of a column in a table.
         
     | 
| 
      
 7 
     | 
    
         
            +
                class Column
         
     | 
| 
      
 8 
     | 
    
         
            +
                  TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE', 'on', 'ON'].to_set
         
     | 
| 
      
 9 
     | 
    
         
            +
                  FALSE_VALUES = [false, 0, '0', 'f', 'F', 'false', 'FALSE', 'off', 'OFF'].to_set
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  module Format
         
     | 
| 
      
 12 
     | 
    
         
            +
                    ISO_DATE = /\A(\d{4})-(\d\d)-(\d\d)\z/
         
     | 
| 
      
 13 
     | 
    
         
            +
                    ISO_DATETIME = /\A(\d{4})-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)(\.\d+)?\z/
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  attr_reader :name, :default, :type, :limit, :null, :sql_type, :precision, :scale
         
     | 
| 
      
 17 
     | 
    
         
            +
                  attr_accessor :primary, :coder
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  alias :encoded? :coder
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  # Instantiates a new column in the table.
         
     | 
| 
      
 22 
     | 
    
         
            +
                  #
         
     | 
| 
      
 23 
     | 
    
         
            +
                  # +name+ is the column's name, such as <tt>supplier_id</tt> in <tt>supplier_id int(11)</tt>.
         
     | 
| 
      
 24 
     | 
    
         
            +
                  # +default+ is the type-casted default value, such as +new+ in <tt>sales_stage varchar(20) default 'new'</tt>.
         
     | 
| 
      
 25 
     | 
    
         
            +
                  # +sql_type+ is used to extract the column's length, if necessary. For example +60+ in
         
     | 
| 
      
 26 
     | 
    
         
            +
                  # <tt>company_name varchar(60)</tt>.
         
     | 
| 
      
 27 
     | 
    
         
            +
                  # It will be mapped to one of the standard Rails SQL types in the <tt>type</tt> attribute.
         
     | 
| 
      
 28 
     | 
    
         
            +
                  # +null+ determines if this column allows +NULL+ values.
         
     | 
| 
      
 29 
     | 
    
         
            +
                  def initialize(name, default, sql_type = nil, null = true)
         
     | 
| 
      
 30 
     | 
    
         
            +
                    @name      = name
         
     | 
| 
      
 31 
     | 
    
         
            +
                    @sql_type  = sql_type
         
     | 
| 
      
 32 
     | 
    
         
            +
                    @null      = null
         
     | 
| 
      
 33 
     | 
    
         
            +
                    @limit     = extract_limit(sql_type)
         
     | 
| 
      
 34 
     | 
    
         
            +
                    @precision = extract_precision(sql_type)
         
     | 
| 
      
 35 
     | 
    
         
            +
                    @scale     = extract_scale(sql_type)
         
     | 
| 
      
 36 
     | 
    
         
            +
                    @type      = simplified_type(sql_type)
         
     | 
| 
      
 37 
     | 
    
         
            +
                    @default   = extract_default(default)
         
     | 
| 
      
 38 
     | 
    
         
            +
                    @primary   = nil
         
     | 
| 
      
 39 
     | 
    
         
            +
                    @coder     = nil
         
     | 
| 
      
 40 
     | 
    
         
            +
                  end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                  # Returns +true+ if the column is either of type string or text.
         
     | 
| 
      
 43 
     | 
    
         
            +
                  def text?
         
     | 
| 
      
 44 
     | 
    
         
            +
                    type == :string || type == :text
         
     | 
| 
      
 45 
     | 
    
         
            +
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                  # Returns +true+ if the column is either of type integer, float or decimal.
         
     | 
| 
      
 48 
     | 
    
         
            +
                  def number?
         
     | 
| 
      
 49 
     | 
    
         
            +
                    type == :integer || type == :float || type == :decimal
         
     | 
| 
      
 50 
     | 
    
         
            +
                  end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                  def has_default?
         
     | 
| 
      
 53 
     | 
    
         
            +
                    !default.nil?
         
     | 
| 
      
 54 
     | 
    
         
            +
                  end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                  # Returns the Ruby class that corresponds to the abstract data type.
         
     | 
| 
      
 57 
     | 
    
         
            +
                  def klass
         
     | 
| 
      
 58 
     | 
    
         
            +
                    case type
         
     | 
| 
      
 59 
     | 
    
         
            +
                    when :integer                     then Fixnum
         
     | 
| 
      
 60 
     | 
    
         
            +
                    when :float                       then Float
         
     | 
| 
      
 61 
     | 
    
         
            +
                    when :decimal                     then BigDecimal
         
     | 
| 
      
 62 
     | 
    
         
            +
                    when :datetime, :timestamp, :time then Time
         
     | 
| 
      
 63 
     | 
    
         
            +
                    when :date                        then Date
         
     | 
| 
      
 64 
     | 
    
         
            +
                    when :text, :string, :binary      then String
         
     | 
| 
      
 65 
     | 
    
         
            +
                    when :boolean                     then Object
         
     | 
| 
      
 66 
     | 
    
         
            +
                    end
         
     | 
| 
      
 67 
     | 
    
         
            +
                  end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                  def binary?
         
     | 
| 
      
 70 
     | 
    
         
            +
                    type == :binary
         
     | 
| 
      
 71 
     | 
    
         
            +
                  end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                  # Casts a Ruby value to something appropriate for writing to the database.
         
     | 
| 
      
 74 
     | 
    
         
            +
                  def type_cast_for_write(value)
         
     | 
| 
      
 75 
     | 
    
         
            +
                    return value unless number?
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                    case value
         
     | 
| 
      
 78 
     | 
    
         
            +
                    when FalseClass
         
     | 
| 
      
 79 
     | 
    
         
            +
                      0
         
     | 
| 
      
 80 
     | 
    
         
            +
                    when TrueClass
         
     | 
| 
      
 81 
     | 
    
         
            +
                      1
         
     | 
| 
      
 82 
     | 
    
         
            +
                    when String
         
     | 
| 
      
 83 
     | 
    
         
            +
                      value.presence
         
     | 
| 
      
 84 
     | 
    
         
            +
                    else
         
     | 
| 
      
 85 
     | 
    
         
            +
                      value
         
     | 
| 
      
 86 
     | 
    
         
            +
                    end
         
     | 
| 
      
 87 
     | 
    
         
            +
                  end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                  # Casts value (which is a String) to an appropriate instance.
         
     | 
| 
      
 90 
     | 
    
         
            +
                  def type_cast(value)
         
     | 
| 
      
 91 
     | 
    
         
            +
                    return nil if value.nil?
         
     | 
| 
      
 92 
     | 
    
         
            +
                    return coder.load(value) if encoded?
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                    klass = self.class
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
                    case type
         
     | 
| 
      
 97 
     | 
    
         
            +
                    when :string, :text        then value
         
     | 
| 
      
 98 
     | 
    
         
            +
                    when :integer              then klass.value_to_integer(value)
         
     | 
| 
      
 99 
     | 
    
         
            +
                    when :float                then value.to_f
         
     | 
| 
      
 100 
     | 
    
         
            +
                    when :decimal              then klass.value_to_decimal(value)
         
     | 
| 
      
 101 
     | 
    
         
            +
                    when :datetime, :timestamp then klass.string_to_time(value)
         
     | 
| 
      
 102 
     | 
    
         
            +
                    when :time                 then klass.string_to_dummy_time(value)
         
     | 
| 
      
 103 
     | 
    
         
            +
                    when :date                 then klass.value_to_date(value)
         
     | 
| 
      
 104 
     | 
    
         
            +
                    when :binary               then klass.binary_to_string(value)
         
     | 
| 
      
 105 
     | 
    
         
            +
                    when :boolean              then klass.value_to_boolean(value)
         
     | 
| 
      
 106 
     | 
    
         
            +
                    else value
         
     | 
| 
      
 107 
     | 
    
         
            +
                    end
         
     | 
| 
      
 108 
     | 
    
         
            +
                  end
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
                  def type_cast_code(var_name)
         
     | 
| 
      
 111 
     | 
    
         
            +
                    message = "Column#type_cast_code is deprecated in favor of using Column#type_cast only, " \
         
     | 
| 
      
 112 
     | 
    
         
            +
                              "and it is going to be removed in future Rails versions."
         
     | 
| 
      
 113 
     | 
    
         
            +
                    ActiveSupport::Deprecation.warn message
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
                    klass = self.class.name
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
                    case type
         
     | 
| 
      
 118 
     | 
    
         
            +
                    when :string, :text        then var_name
         
     | 
| 
      
 119 
     | 
    
         
            +
                    when :integer              then "#{klass}.value_to_integer(#{var_name})"
         
     | 
| 
      
 120 
     | 
    
         
            +
                    when :float                then "#{var_name}.to_f"
         
     | 
| 
      
 121 
     | 
    
         
            +
                    when :decimal              then "#{klass}.value_to_decimal(#{var_name})"
         
     | 
| 
      
 122 
     | 
    
         
            +
                    when :datetime, :timestamp then "#{klass}.string_to_time(#{var_name})"
         
     | 
| 
      
 123 
     | 
    
         
            +
                    when :time                 then "#{klass}.string_to_dummy_time(#{var_name})"
         
     | 
| 
      
 124 
     | 
    
         
            +
                    when :date                 then "#{klass}.value_to_date(#{var_name})"
         
     | 
| 
      
 125 
     | 
    
         
            +
                    when :binary               then "#{klass}.binary_to_string(#{var_name})"
         
     | 
| 
      
 126 
     | 
    
         
            +
                    when :boolean              then "#{klass}.value_to_boolean(#{var_name})"
         
     | 
| 
      
 127 
     | 
    
         
            +
                    when :hstore               then "#{klass}.string_to_hstore(#{var_name})"
         
     | 
| 
      
 128 
     | 
    
         
            +
                    when :inet, :cidr          then "#{klass}.string_to_cidr(#{var_name})"
         
     | 
| 
      
 129 
     | 
    
         
            +
                    when :json                 then "#{klass}.string_to_json(#{var_name})"
         
     | 
| 
      
 130 
     | 
    
         
            +
                    else var_name
         
     | 
| 
      
 131 
     | 
    
         
            +
                    end
         
     | 
| 
      
 132 
     | 
    
         
            +
                  end
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
                  # Returns the human name of the column name.
         
     | 
| 
      
 135 
     | 
    
         
            +
                  #
         
     | 
| 
      
 136 
     | 
    
         
            +
                  # ===== Examples
         
     | 
| 
      
 137 
     | 
    
         
            +
                  #  Column.new('sales_stage', ...).human_name # => 'Sales stage'
         
     | 
| 
      
 138 
     | 
    
         
            +
                  def human_name
         
     | 
| 
      
 139 
     | 
    
         
            +
                    Base.human_attribute_name(@name)
         
     | 
| 
      
 140 
     | 
    
         
            +
                  end
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
                  def extract_default(default)
         
     | 
| 
      
 143 
     | 
    
         
            +
                    type_cast(default)
         
     | 
| 
      
 144 
     | 
    
         
            +
                  end
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
                  # Used to convert from Strings to BLOBs
         
     | 
| 
      
 147 
     | 
    
         
            +
                  def string_to_binary(value)
         
     | 
| 
      
 148 
     | 
    
         
            +
                    self.class.string_to_binary(value)
         
     | 
| 
      
 149 
     | 
    
         
            +
                  end
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
                  class << self
         
     | 
| 
      
 152 
     | 
    
         
            +
                    # Used to convert from Strings to BLOBs
         
     | 
| 
      
 153 
     | 
    
         
            +
                    def string_to_binary(value)
         
     | 
| 
      
 154 
     | 
    
         
            +
                      value
         
     | 
| 
      
 155 
     | 
    
         
            +
                    end
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
                    # Used to convert from BLOBs to Strings
         
     | 
| 
      
 158 
     | 
    
         
            +
                    def binary_to_string(value)
         
     | 
| 
      
 159 
     | 
    
         
            +
                      value
         
     | 
| 
      
 160 
     | 
    
         
            +
                    end
         
     | 
| 
      
 161 
     | 
    
         
            +
             
     | 
| 
      
 162 
     | 
    
         
            +
                    def value_to_date(value)
         
     | 
| 
      
 163 
     | 
    
         
            +
                      if value.is_a?(String)
         
     | 
| 
      
 164 
     | 
    
         
            +
                        return nil if value.empty?
         
     | 
| 
      
 165 
     | 
    
         
            +
                        fast_string_to_date(value) || fallback_string_to_date(value)
         
     | 
| 
      
 166 
     | 
    
         
            +
                      elsif value.respond_to?(:to_date)
         
     | 
| 
      
 167 
     | 
    
         
            +
                        value.to_date
         
     | 
| 
      
 168 
     | 
    
         
            +
                      else
         
     | 
| 
      
 169 
     | 
    
         
            +
                        value
         
     | 
| 
      
 170 
     | 
    
         
            +
                      end
         
     | 
| 
      
 171 
     | 
    
         
            +
                    end
         
     | 
| 
      
 172 
     | 
    
         
            +
             
     | 
| 
      
 173 
     | 
    
         
            +
                    def string_to_time(string)
         
     | 
| 
      
 174 
     | 
    
         
            +
                      return string unless string.is_a?(String)
         
     | 
| 
      
 175 
     | 
    
         
            +
                      return nil if string.empty?
         
     | 
| 
      
 176 
     | 
    
         
            +
             
     | 
| 
      
 177 
     | 
    
         
            +
                      fast_string_to_time(string) || fallback_string_to_time(string)
         
     | 
| 
      
 178 
     | 
    
         
            +
                    end
         
     | 
| 
      
 179 
     | 
    
         
            +
             
     | 
| 
      
 180 
     | 
    
         
            +
                    def string_to_dummy_time(string)
         
     | 
| 
      
 181 
     | 
    
         
            +
                      return string unless string.is_a?(String)
         
     | 
| 
      
 182 
     | 
    
         
            +
                      return nil if string.empty?
         
     | 
| 
      
 183 
     | 
    
         
            +
             
     | 
| 
      
 184 
     | 
    
         
            +
                      dummy_time_string = "2000-01-01 #{string}"
         
     | 
| 
      
 185 
     | 
    
         
            +
             
     | 
| 
      
 186 
     | 
    
         
            +
                      fast_string_to_time(dummy_time_string) || begin
         
     | 
| 
      
 187 
     | 
    
         
            +
                        time_hash = Date._parse(dummy_time_string)
         
     | 
| 
      
 188 
     | 
    
         
            +
                        return nil if time_hash[:hour].nil?
         
     | 
| 
      
 189 
     | 
    
         
            +
                        new_time(*time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction))
         
     | 
| 
      
 190 
     | 
    
         
            +
                      end
         
     | 
| 
      
 191 
     | 
    
         
            +
                    end
         
     | 
| 
      
 192 
     | 
    
         
            +
             
     | 
| 
      
 193 
     | 
    
         
            +
                    # convert something to a boolean
         
     | 
| 
      
 194 
     | 
    
         
            +
                    def value_to_boolean(value)
         
     | 
| 
      
 195 
     | 
    
         
            +
                      if value.is_a?(String) && value.empty?
         
     | 
| 
      
 196 
     | 
    
         
            +
                        nil
         
     | 
| 
      
 197 
     | 
    
         
            +
                      else
         
     | 
| 
      
 198 
     | 
    
         
            +
                        TRUE_VALUES.include?(value)
         
     | 
| 
      
 199 
     | 
    
         
            +
                      end
         
     | 
| 
      
 200 
     | 
    
         
            +
                    end
         
     | 
| 
      
 201 
     | 
    
         
            +
             
     | 
| 
      
 202 
     | 
    
         
            +
                    # Used to convert values to integer.
         
     | 
| 
      
 203 
     | 
    
         
            +
                    # handle the case when an integer column is used to store boolean values
         
     | 
| 
      
 204 
     | 
    
         
            +
                    def value_to_integer(value)
         
     | 
| 
      
 205 
     | 
    
         
            +
                      case value
         
     | 
| 
      
 206 
     | 
    
         
            +
                      when TrueClass, FalseClass
         
     | 
| 
      
 207 
     | 
    
         
            +
                        value ? 1 : 0
         
     | 
| 
      
 208 
     | 
    
         
            +
                      else
         
     | 
| 
      
 209 
     | 
    
         
            +
                        value.to_i rescue nil
         
     | 
| 
      
 210 
     | 
    
         
            +
                      end
         
     | 
| 
      
 211 
     | 
    
         
            +
                    end
         
     | 
| 
      
 212 
     | 
    
         
            +
             
     | 
| 
      
 213 
     | 
    
         
            +
                    # convert something to a BigDecimal
         
     | 
| 
      
 214 
     | 
    
         
            +
                    def value_to_decimal(value)
         
     | 
| 
      
 215 
     | 
    
         
            +
                      # Using .class is faster than .is_a? and
         
     | 
| 
      
 216 
     | 
    
         
            +
                      # subclasses of BigDecimal will be handled
         
     | 
| 
      
 217 
     | 
    
         
            +
                      # in the else clause
         
     | 
| 
      
 218 
     | 
    
         
            +
                      if value.class == BigDecimal
         
     | 
| 
      
 219 
     | 
    
         
            +
                        value
         
     | 
| 
      
 220 
     | 
    
         
            +
                      elsif value.respond_to?(:to_d)
         
     | 
| 
      
 221 
     | 
    
         
            +
                        value.to_d
         
     | 
| 
      
 222 
     | 
    
         
            +
                      else
         
     | 
| 
      
 223 
     | 
    
         
            +
                        value.to_s.to_d
         
     | 
| 
      
 224 
     | 
    
         
            +
                      end
         
     | 
| 
      
 225 
     | 
    
         
            +
                    end
         
     | 
| 
      
 226 
     | 
    
         
            +
             
     | 
| 
      
 227 
     | 
    
         
            +
                    protected
         
     | 
| 
      
 228 
     | 
    
         
            +
                      # '0.123456' -> 123456
         
     | 
| 
      
 229 
     | 
    
         
            +
                      # '1.123456' -> 123456
         
     | 
| 
      
 230 
     | 
    
         
            +
                      def microseconds(time)
         
     | 
| 
      
 231 
     | 
    
         
            +
                        time[:sec_fraction] ? (time[:sec_fraction] * 1_000_000).to_i : 0
         
     | 
| 
      
 232 
     | 
    
         
            +
                      end
         
     | 
| 
      
 233 
     | 
    
         
            +
             
     | 
| 
      
 234 
     | 
    
         
            +
                      def new_date(year, mon, mday)
         
     | 
| 
      
 235 
     | 
    
         
            +
                        if year && year != 0
         
     | 
| 
      
 236 
     | 
    
         
            +
                          Date.new(year, mon, mday) rescue nil
         
     | 
| 
      
 237 
     | 
    
         
            +
                        end
         
     | 
| 
      
 238 
     | 
    
         
            +
                      end
         
     | 
| 
      
 239 
     | 
    
         
            +
             
     | 
| 
      
 240 
     | 
    
         
            +
                      def new_time(year, mon, mday, hour, min, sec, microsec)
         
     | 
| 
      
 241 
     | 
    
         
            +
                        # Treat 0000-00-00 00:00:00 as nil.
         
     | 
| 
      
 242 
     | 
    
         
            +
                        return nil if year.nil? || (year == 0 && mon == 0 && mday == 0)
         
     | 
| 
      
 243 
     | 
    
         
            +
             
     | 
| 
      
 244 
     | 
    
         
            +
                        Time.send(Base.default_timezone, year, mon, mday, hour, min, sec, microsec) rescue nil
         
     | 
| 
      
 245 
     | 
    
         
            +
                      end
         
     | 
| 
      
 246 
     | 
    
         
            +
             
     | 
| 
      
 247 
     | 
    
         
            +
                      def fast_string_to_date(string)
         
     | 
| 
      
 248 
     | 
    
         
            +
                        if string =~ Format::ISO_DATE
         
     | 
| 
      
 249 
     | 
    
         
            +
                          new_date $1.to_i, $2.to_i, $3.to_i
         
     | 
| 
      
 250 
     | 
    
         
            +
                        end
         
     | 
| 
      
 251 
     | 
    
         
            +
                      end
         
     | 
| 
      
 252 
     | 
    
         
            +
             
     | 
| 
      
 253 
     | 
    
         
            +
                      # Doesn't handle time zones.
         
     | 
| 
      
 254 
     | 
    
         
            +
                      def fast_string_to_time(string)
         
     | 
| 
      
 255 
     | 
    
         
            +
                        if string =~ Format::ISO_DATETIME
         
     | 
| 
      
 256 
     | 
    
         
            +
                          microsec = ($7.to_r * 1_000_000).to_i
         
     | 
| 
      
 257 
     | 
    
         
            +
                          new_time $1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i, microsec
         
     | 
| 
      
 258 
     | 
    
         
            +
                        end
         
     | 
| 
      
 259 
     | 
    
         
            +
                      end
         
     | 
| 
      
 260 
     | 
    
         
            +
             
     | 
| 
      
 261 
     | 
    
         
            +
                      def fallback_string_to_date(string)
         
     | 
| 
      
 262 
     | 
    
         
            +
                        new_date(*::Date._parse(string, false).values_at(:year, :mon, :mday))
         
     | 
| 
      
 263 
     | 
    
         
            +
                      end
         
     | 
| 
      
 264 
     | 
    
         
            +
             
     | 
| 
      
 265 
     | 
    
         
            +
                      def fallback_string_to_time(string)
         
     | 
| 
      
 266 
     | 
    
         
            +
                        time_hash = Date._parse(string)
         
     | 
| 
      
 267 
     | 
    
         
            +
                        time_hash[:sec_fraction] = microseconds(time_hash)
         
     | 
| 
      
 268 
     | 
    
         
            +
             
     | 
| 
      
 269 
     | 
    
         
            +
                        new_time(*time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction))
         
     | 
| 
      
 270 
     | 
    
         
            +
                      end
         
     | 
| 
      
 271 
     | 
    
         
            +
                  end
         
     | 
| 
      
 272 
     | 
    
         
            +
             
     | 
| 
      
 273 
     | 
    
         
            +
                  private
         
     | 
| 
      
 274 
     | 
    
         
            +
                    def extract_limit(sql_type)
         
     | 
| 
      
 275 
     | 
    
         
            +
                      $1.to_i if sql_type =~ /\((.*)\)/
         
     | 
| 
      
 276 
     | 
    
         
            +
                    end
         
     | 
| 
      
 277 
     | 
    
         
            +
             
     | 
| 
      
 278 
     | 
    
         
            +
                    def extract_precision(sql_type)
         
     | 
| 
      
 279 
     | 
    
         
            +
                      $2.to_i if sql_type =~ /^(numeric|decimal|number)\((\d+)(,\d+)?\)/i
         
     | 
| 
      
 280 
     | 
    
         
            +
                    end
         
     | 
| 
      
 281 
     | 
    
         
            +
             
     | 
| 
      
 282 
     | 
    
         
            +
                    def extract_scale(sql_type)
         
     | 
| 
      
 283 
     | 
    
         
            +
                      case sql_type
         
     | 
| 
      
 284 
     | 
    
         
            +
                        when /^(numeric|decimal|number)\((\d+)\)/i then 0
         
     | 
| 
      
 285 
     | 
    
         
            +
                        when /^(numeric|decimal|number)\((\d+)(,(\d+))\)/i then $4.to_i
         
     | 
| 
      
 286 
     | 
    
         
            +
                      end
         
     | 
| 
      
 287 
     | 
    
         
            +
                    end
         
     | 
| 
      
 288 
     | 
    
         
            +
             
     | 
| 
      
 289 
     | 
    
         
            +
                    def simplified_type(field_type)
         
     | 
| 
      
 290 
     | 
    
         
            +
                      case field_type
         
     | 
| 
      
 291 
     | 
    
         
            +
                      when /int/i
         
     | 
| 
      
 292 
     | 
    
         
            +
                        :integer
         
     | 
| 
      
 293 
     | 
    
         
            +
                      when /float|double/i
         
     | 
| 
      
 294 
     | 
    
         
            +
                        :float
         
     | 
| 
      
 295 
     | 
    
         
            +
                      when /decimal|numeric|number/i
         
     | 
| 
      
 296 
     | 
    
         
            +
                        extract_scale(field_type) == 0 ? :integer : :decimal
         
     | 
| 
      
 297 
     | 
    
         
            +
                      when /datetime/i
         
     | 
| 
      
 298 
     | 
    
         
            +
                        :datetime
         
     | 
| 
      
 299 
     | 
    
         
            +
                      when /timestamp/i
         
     | 
| 
      
 300 
     | 
    
         
            +
                        :timestamp
         
     | 
| 
      
 301 
     | 
    
         
            +
                      when /time/i
         
     | 
| 
      
 302 
     | 
    
         
            +
                        :time
         
     | 
| 
      
 303 
     | 
    
         
            +
                      when /date/i
         
     | 
| 
      
 304 
     | 
    
         
            +
                        :date
         
     | 
| 
      
 305 
     | 
    
         
            +
                      when /clob/i, /text/i
         
     | 
| 
      
 306 
     | 
    
         
            +
                        :text
         
     | 
| 
      
 307 
     | 
    
         
            +
                      when /blob/i, /binary/i
         
     | 
| 
      
 308 
     | 
    
         
            +
                        :binary
         
     | 
| 
      
 309 
     | 
    
         
            +
                      when /char/i, /string/i
         
     | 
| 
      
 310 
     | 
    
         
            +
                        :string
         
     | 
| 
      
 311 
     | 
    
         
            +
                      when /boolean/i
         
     | 
| 
      
 312 
     | 
    
         
            +
                        :boolean
         
     | 
| 
      
 313 
     | 
    
         
            +
                      end
         
     | 
| 
      
 314 
     | 
    
         
            +
                    end
         
     | 
| 
      
 315 
     | 
    
         
            +
                end
         
     | 
| 
      
 316 
     | 
    
         
            +
              end
         
     | 
| 
      
 317 
     | 
    
         
            +
              # :startdoc:
         
     | 
| 
      
 318 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,96 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'uri'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module ActiveRecord
         
     | 
| 
      
 4 
     | 
    
         
            +
              module ConnectionAdapters
         
     | 
| 
      
 5 
     | 
    
         
            +
                class ConnectionSpecification #:nodoc:
         
     | 
| 
      
 6 
     | 
    
         
            +
                  attr_reader :config, :adapter_method
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                  def initialize(config, adapter_method)
         
     | 
| 
      
 9 
     | 
    
         
            +
                    @config, @adapter_method = config, adapter_method
         
     | 
| 
      
 10 
     | 
    
         
            +
                  end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  def initialize_dup(original)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    @config = original.config.dup
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  ##
         
     | 
| 
      
 17 
     | 
    
         
            +
                  # Builds a ConnectionSpecification from user input
         
     | 
| 
      
 18 
     | 
    
         
            +
                  class Resolver # :nodoc:
         
     | 
| 
      
 19 
     | 
    
         
            +
                    attr_reader :config, :klass, :configurations
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                    def initialize(config, configurations)
         
     | 
| 
      
 22 
     | 
    
         
            +
                      @config         = config
         
     | 
| 
      
 23 
     | 
    
         
            +
                      @configurations = configurations
         
     | 
| 
      
 24 
     | 
    
         
            +
                    end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                    def spec
         
     | 
| 
      
 27 
     | 
    
         
            +
                      case config
         
     | 
| 
      
 28 
     | 
    
         
            +
                      when nil
         
     | 
| 
      
 29 
     | 
    
         
            +
                        raise AdapterNotSpecified unless defined?(Rails.env)
         
     | 
| 
      
 30 
     | 
    
         
            +
                        resolve_string_connection Rails.env
         
     | 
| 
      
 31 
     | 
    
         
            +
                      when Symbol, String
         
     | 
| 
      
 32 
     | 
    
         
            +
                        resolve_string_connection config.to_s
         
     | 
| 
      
 33 
     | 
    
         
            +
                      when Hash
         
     | 
| 
      
 34 
     | 
    
         
            +
                        resolve_hash_connection config
         
     | 
| 
      
 35 
     | 
    
         
            +
                      end
         
     | 
| 
      
 36 
     | 
    
         
            +
                    end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                    private
         
     | 
| 
      
 39 
     | 
    
         
            +
                    def resolve_string_connection(spec) # :nodoc:
         
     | 
| 
      
 40 
     | 
    
         
            +
                      hash = configurations.fetch(spec) do |k|
         
     | 
| 
      
 41 
     | 
    
         
            +
                        connection_url_to_hash(k)
         
     | 
| 
      
 42 
     | 
    
         
            +
                      end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                      raise(AdapterNotSpecified, "#{spec} database is not configured") unless hash
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                      resolve_hash_connection hash
         
     | 
| 
      
 47 
     | 
    
         
            +
                    end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                    def resolve_hash_connection(spec) # :nodoc:
         
     | 
| 
      
 50 
     | 
    
         
            +
                      spec = spec.symbolize_keys
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                      raise(AdapterNotSpecified, "database configuration does not specify adapter") unless spec.key?(:adapter)
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                      path_to_adapter = "active_record/connection_adapters/#{spec[:adapter]}_adapter"
         
     | 
| 
      
 55 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 56 
     | 
    
         
            +
                        require path_to_adapter
         
     | 
| 
      
 57 
     | 
    
         
            +
                      rescue Gem::LoadError => e
         
     | 
| 
      
 58 
     | 
    
         
            +
                        raise Gem::LoadError, "Specified '#{spec[:adapter]}' for database adapter, but the gem is not loaded. Add `gem '#{e.name}'` to your Gemfile."
         
     | 
| 
      
 59 
     | 
    
         
            +
                      rescue LoadError => e
         
     | 
| 
      
 60 
     | 
    
         
            +
                        raise LoadError, "Could not load '#{path_to_adapter}'. Make sure that the adapter in config/database.yml is valid. If you use an adapter other than 'mysql', 'mysql2', 'postgresql' or 'sqlite3' add the necessary adapter gem to the Gemfile.", e.backtrace
         
     | 
| 
      
 61 
     | 
    
         
            +
                      end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                      adapter_method = "#{spec[:adapter]}_connection"
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                      ConnectionSpecification.new(spec, adapter_method)
         
     | 
| 
      
 66 
     | 
    
         
            +
                    end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                    def connection_url_to_hash(url) # :nodoc:
         
     | 
| 
      
 69 
     | 
    
         
            +
                      config = URI.parse url
         
     | 
| 
      
 70 
     | 
    
         
            +
                      adapter = config.scheme
         
     | 
| 
      
 71 
     | 
    
         
            +
                      adapter = "postgresql" if adapter == "postgres"
         
     | 
| 
      
 72 
     | 
    
         
            +
                      spec = { :adapter  => adapter,
         
     | 
| 
      
 73 
     | 
    
         
            +
                               :username => config.user,
         
     | 
| 
      
 74 
     | 
    
         
            +
                               :password => config.password,
         
     | 
| 
      
 75 
     | 
    
         
            +
                               :port     => config.port,
         
     | 
| 
      
 76 
     | 
    
         
            +
                               :database => config.path.sub(%r{^/},""),
         
     | 
| 
      
 77 
     | 
    
         
            +
                               :host     => config.host }
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                      spec.reject!{ |_,value| value.blank? }
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                      uri_parser = URI::Parser.new
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                      spec.map { |key,value| spec[key] = uri_parser.unescape(value) if value.is_a?(String) }
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                      if config.query
         
     | 
| 
      
 86 
     | 
    
         
            +
                        options = Hash[config.query.split("&").map{ |pair| pair.split("=") }].symbolize_keys
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                        spec.merge!(options)
         
     | 
| 
      
 89 
     | 
    
         
            +
                      end
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
                      spec
         
     | 
| 
      
 92 
     | 
    
         
            +
                    end
         
     | 
| 
      
 93 
     | 
    
         
            +
                  end
         
     | 
| 
      
 94 
     | 
    
         
            +
                end
         
     | 
| 
      
 95 
     | 
    
         
            +
              end
         
     | 
| 
      
 96 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,273 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'active_record/connection_adapters/abstract_mysql_adapter'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            gem 'mysql2', '~> 0.3.10'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'mysql2'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            module ActiveRecord
         
     | 
| 
      
 7 
     | 
    
         
            +
              module ConnectionHandling # :nodoc:
         
     | 
| 
      
 8 
     | 
    
         
            +
                # Establishes a connection to the database that's used by all Active Record objects.
         
     | 
| 
      
 9 
     | 
    
         
            +
                def mysql2_connection(config)
         
     | 
| 
      
 10 
     | 
    
         
            +
                  config = config.symbolize_keys
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  config[:username] = 'root' if config[:username].nil?
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  if Mysql2::Client.const_defined? :FOUND_ROWS
         
     | 
| 
      
 15 
     | 
    
         
            +
                    config[:flags] = Mysql2::Client::FOUND_ROWS
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  client = Mysql2::Client.new(config)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  options = [config[:host], config[:username], config[:password], config[:database], config[:port], config[:socket], 0]
         
     | 
| 
      
 20 
     | 
    
         
            +
                  ConnectionAdapters::Mysql2Adapter.new(client, logger, options, config)
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
              module ConnectionAdapters
         
     | 
| 
      
 25 
     | 
    
         
            +
                class Mysql2Adapter < AbstractMysqlAdapter
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                  class Column < AbstractMysqlAdapter::Column # :nodoc:
         
     | 
| 
      
 28 
     | 
    
         
            +
                    def adapter
         
     | 
| 
      
 29 
     | 
    
         
            +
                      Mysql2Adapter
         
     | 
| 
      
 30 
     | 
    
         
            +
                    end
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                  ADAPTER_NAME = 'Mysql2'
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                  def initialize(connection, logger, connection_options, config)
         
     | 
| 
      
 36 
     | 
    
         
            +
                    super
         
     | 
| 
      
 37 
     | 
    
         
            +
                    @visitor = BindSubstitution.new self
         
     | 
| 
      
 38 
     | 
    
         
            +
                    configure_connection
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                  MAX_INDEX_LENGTH_FOR_UTF8MB4 = 191
         
     | 
| 
      
 42 
     | 
    
         
            +
                  def initialize_schema_migrations_table
         
     | 
| 
      
 43 
     | 
    
         
            +
                    if @config[:encoding] == 'utf8mb4'
         
     | 
| 
      
 44 
     | 
    
         
            +
                      ActiveRecord::SchemaMigration.create_table(MAX_INDEX_LENGTH_FOR_UTF8MB4)
         
     | 
| 
      
 45 
     | 
    
         
            +
                    else
         
     | 
| 
      
 46 
     | 
    
         
            +
                      ActiveRecord::SchemaMigration.create_table
         
     | 
| 
      
 47 
     | 
    
         
            +
                    end
         
     | 
| 
      
 48 
     | 
    
         
            +
                  end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                  def supports_explain?
         
     | 
| 
      
 51 
     | 
    
         
            +
                    true
         
     | 
| 
      
 52 
     | 
    
         
            +
                  end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                  # HELPER METHODS ===========================================
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                  def each_hash(result) # :nodoc:
         
     | 
| 
      
 57 
     | 
    
         
            +
                    if block_given?
         
     | 
| 
      
 58 
     | 
    
         
            +
                      result.each(:as => :hash, :symbolize_keys => true) do |row|
         
     | 
| 
      
 59 
     | 
    
         
            +
                        yield row
         
     | 
| 
      
 60 
     | 
    
         
            +
                      end
         
     | 
| 
      
 61 
     | 
    
         
            +
                    else
         
     | 
| 
      
 62 
     | 
    
         
            +
                      to_enum(:each_hash, result)
         
     | 
| 
      
 63 
     | 
    
         
            +
                    end
         
     | 
| 
      
 64 
     | 
    
         
            +
                  end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                  def new_column(field, default, type, null, collation, extra = "") # :nodoc:
         
     | 
| 
      
 67 
     | 
    
         
            +
                    Column.new(field, default, type, null, collation, strict_mode?, extra)
         
     | 
| 
      
 68 
     | 
    
         
            +
                  end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                  def error_number(exception)
         
     | 
| 
      
 71 
     | 
    
         
            +
                    exception.error_number if exception.respond_to?(:error_number)
         
     | 
| 
      
 72 
     | 
    
         
            +
                  end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                  # QUOTING ==================================================
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                  def quote_string(string)
         
     | 
| 
      
 77 
     | 
    
         
            +
                    @connection.escape(string)
         
     | 
| 
      
 78 
     | 
    
         
            +
                  end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                  # CONNECTION MANAGEMENT ====================================
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                  def active?
         
     | 
| 
      
 83 
     | 
    
         
            +
                    return false unless @connection
         
     | 
| 
      
 84 
     | 
    
         
            +
                    @connection.ping
         
     | 
| 
      
 85 
     | 
    
         
            +
                  end
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                  def reconnect!
         
     | 
| 
      
 88 
     | 
    
         
            +
                    super
         
     | 
| 
      
 89 
     | 
    
         
            +
                    disconnect!
         
     | 
| 
      
 90 
     | 
    
         
            +
                    connect
         
     | 
| 
      
 91 
     | 
    
         
            +
                  end
         
     | 
| 
      
 92 
     | 
    
         
            +
                  alias :reset! :reconnect!
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                  # Disconnects from the database if already connected.
         
     | 
| 
      
 95 
     | 
    
         
            +
                  # Otherwise, this method does nothing.
         
     | 
| 
      
 96 
     | 
    
         
            +
                  def disconnect!
         
     | 
| 
      
 97 
     | 
    
         
            +
                    super
         
     | 
| 
      
 98 
     | 
    
         
            +
                    unless @connection.nil?
         
     | 
| 
      
 99 
     | 
    
         
            +
                      @connection.close
         
     | 
| 
      
 100 
     | 
    
         
            +
                      @connection = nil
         
     | 
| 
      
 101 
     | 
    
         
            +
                    end
         
     | 
| 
      
 102 
     | 
    
         
            +
                  end
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
                  # DATABASE STATEMENTS ======================================
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
                  def explain(arel, binds = [])
         
     | 
| 
      
 107 
     | 
    
         
            +
                    sql     = "EXPLAIN #{to_sql(arel, binds.dup)}"
         
     | 
| 
      
 108 
     | 
    
         
            +
                    start   = Time.now
         
     | 
| 
      
 109 
     | 
    
         
            +
                    result  = exec_query(sql, 'EXPLAIN', binds)
         
     | 
| 
      
 110 
     | 
    
         
            +
                    elapsed = Time.now - start
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
                    ExplainPrettyPrinter.new.pp(result, elapsed)
         
     | 
| 
      
 113 
     | 
    
         
            +
                  end
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
                  class ExplainPrettyPrinter # :nodoc:
         
     | 
| 
      
 116 
     | 
    
         
            +
                    # Pretty prints the result of a EXPLAIN in a way that resembles the output of the
         
     | 
| 
      
 117 
     | 
    
         
            +
                    # MySQL shell:
         
     | 
| 
      
 118 
     | 
    
         
            +
                    #
         
     | 
| 
      
 119 
     | 
    
         
            +
                    #   +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
         
     | 
| 
      
 120 
     | 
    
         
            +
                    #   | id | select_type | table | type  | possible_keys | key     | key_len | ref   | rows | Extra       |
         
     | 
| 
      
 121 
     | 
    
         
            +
                    #   +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
         
     | 
| 
      
 122 
     | 
    
         
            +
                    #   |  1 | SIMPLE      | users | const | PRIMARY       | PRIMARY | 4       | const |    1 |             |
         
     | 
| 
      
 123 
     | 
    
         
            +
                    #   |  1 | SIMPLE      | posts | ALL   | NULL          | NULL    | NULL    | NULL  |    1 | Using where |
         
     | 
| 
      
 124 
     | 
    
         
            +
                    #   +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
         
     | 
| 
      
 125 
     | 
    
         
            +
                    #   2 rows in set (0.00 sec)
         
     | 
| 
      
 126 
     | 
    
         
            +
                    #
         
     | 
| 
      
 127 
     | 
    
         
            +
                    # This is an exercise in Ruby hyperrealism :).
         
     | 
| 
      
 128 
     | 
    
         
            +
                    def pp(result, elapsed)
         
     | 
| 
      
 129 
     | 
    
         
            +
                      widths    = compute_column_widths(result)
         
     | 
| 
      
 130 
     | 
    
         
            +
                      separator = build_separator(widths)
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
                      pp = []
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
                      pp << separator
         
     | 
| 
      
 135 
     | 
    
         
            +
                      pp << build_cells(result.columns, widths)
         
     | 
| 
      
 136 
     | 
    
         
            +
                      pp << separator
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
                      result.rows.each do |row|
         
     | 
| 
      
 139 
     | 
    
         
            +
                        pp << build_cells(row, widths)
         
     | 
| 
      
 140 
     | 
    
         
            +
                      end
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
                      pp << separator
         
     | 
| 
      
 143 
     | 
    
         
            +
                      pp << build_footer(result.rows.length, elapsed)
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
                      pp.join("\n") + "\n"
         
     | 
| 
      
 146 
     | 
    
         
            +
                    end
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
                    private
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
                    def compute_column_widths(result)
         
     | 
| 
      
 151 
     | 
    
         
            +
                      [].tap do |widths|
         
     | 
| 
      
 152 
     | 
    
         
            +
                        result.columns.each_with_index do |column, i|
         
     | 
| 
      
 153 
     | 
    
         
            +
                          cells_in_column = [column] + result.rows.map {|r| r[i].nil? ? 'NULL' : r[i].to_s}
         
     | 
| 
      
 154 
     | 
    
         
            +
                          widths << cells_in_column.map(&:length).max
         
     | 
| 
      
 155 
     | 
    
         
            +
                        end
         
     | 
| 
      
 156 
     | 
    
         
            +
                      end
         
     | 
| 
      
 157 
     | 
    
         
            +
                    end
         
     | 
| 
      
 158 
     | 
    
         
            +
             
     | 
| 
      
 159 
     | 
    
         
            +
                    def build_separator(widths)
         
     | 
| 
      
 160 
     | 
    
         
            +
                      padding = 1
         
     | 
| 
      
 161 
     | 
    
         
            +
                      '+' + widths.map {|w| '-' * (w + (padding*2))}.join('+') + '+'
         
     | 
| 
      
 162 
     | 
    
         
            +
                    end
         
     | 
| 
      
 163 
     | 
    
         
            +
             
     | 
| 
      
 164 
     | 
    
         
            +
                    def build_cells(items, widths)
         
     | 
| 
      
 165 
     | 
    
         
            +
                      cells = []
         
     | 
| 
      
 166 
     | 
    
         
            +
                      items.each_with_index do |item, i|
         
     | 
| 
      
 167 
     | 
    
         
            +
                        item = 'NULL' if item.nil?
         
     | 
| 
      
 168 
     | 
    
         
            +
                        justifier = item.is_a?(Numeric) ? 'rjust' : 'ljust'
         
     | 
| 
      
 169 
     | 
    
         
            +
                        cells << item.to_s.send(justifier, widths[i])
         
     | 
| 
      
 170 
     | 
    
         
            +
                      end
         
     | 
| 
      
 171 
     | 
    
         
            +
                      '| ' + cells.join(' | ') + ' |'
         
     | 
| 
      
 172 
     | 
    
         
            +
                    end
         
     | 
| 
      
 173 
     | 
    
         
            +
             
     | 
| 
      
 174 
     | 
    
         
            +
                    def build_footer(nrows, elapsed)
         
     | 
| 
      
 175 
     | 
    
         
            +
                      rows_label = nrows == 1 ? 'row' : 'rows'
         
     | 
| 
      
 176 
     | 
    
         
            +
                      "#{nrows} #{rows_label} in set (%.2f sec)" % elapsed
         
     | 
| 
      
 177 
     | 
    
         
            +
                    end
         
     | 
| 
      
 178 
     | 
    
         
            +
                  end
         
     | 
| 
      
 179 
     | 
    
         
            +
             
     | 
| 
      
 180 
     | 
    
         
            +
                  # FIXME: re-enable the following once a "better" query_cache solution is in core
         
     | 
| 
      
 181 
     | 
    
         
            +
                  #
         
     | 
| 
      
 182 
     | 
    
         
            +
                  # The overrides below perform much better than the originals in AbstractAdapter
         
     | 
| 
      
 183 
     | 
    
         
            +
                  # because we're able to take advantage of mysql2's lazy-loading capabilities
         
     | 
| 
      
 184 
     | 
    
         
            +
                  #
         
     | 
| 
      
 185 
     | 
    
         
            +
                  # # Returns a record hash with the column names as keys and column values
         
     | 
| 
      
 186 
     | 
    
         
            +
                  # # as values.
         
     | 
| 
      
 187 
     | 
    
         
            +
                  # def select_one(sql, name = nil)
         
     | 
| 
      
 188 
     | 
    
         
            +
                  #   result = execute(sql, name)
         
     | 
| 
      
 189 
     | 
    
         
            +
                  #   result.each(as: :hash) do |r|
         
     | 
| 
      
 190 
     | 
    
         
            +
                  #     return r
         
     | 
| 
      
 191 
     | 
    
         
            +
                  #   end
         
     | 
| 
      
 192 
     | 
    
         
            +
                  # end
         
     | 
| 
      
 193 
     | 
    
         
            +
                  #
         
     | 
| 
      
 194 
     | 
    
         
            +
                  # # Returns a single value from a record
         
     | 
| 
      
 195 
     | 
    
         
            +
                  # def select_value(sql, name = nil)
         
     | 
| 
      
 196 
     | 
    
         
            +
                  #   result = execute(sql, name)
         
     | 
| 
      
 197 
     | 
    
         
            +
                  #   if first = result.first
         
     | 
| 
      
 198 
     | 
    
         
            +
                  #     first.first
         
     | 
| 
      
 199 
     | 
    
         
            +
                  #   end
         
     | 
| 
      
 200 
     | 
    
         
            +
                  # end
         
     | 
| 
      
 201 
     | 
    
         
            +
                  #
         
     | 
| 
      
 202 
     | 
    
         
            +
                  # # Returns an array of the values of the first column in a select:
         
     | 
| 
      
 203 
     | 
    
         
            +
                  # #   select_values("SELECT id FROM companies LIMIT 3") => [1,2,3]
         
     | 
| 
      
 204 
     | 
    
         
            +
                  # def select_values(sql, name = nil)
         
     | 
| 
      
 205 
     | 
    
         
            +
                  #   execute(sql, name).map { |row| row.first }
         
     | 
| 
      
 206 
     | 
    
         
            +
                  # end
         
     | 
| 
      
 207 
     | 
    
         
            +
             
     | 
| 
      
 208 
     | 
    
         
            +
                  # Returns an array of arrays containing the field values.
         
     | 
| 
      
 209 
     | 
    
         
            +
                  # Order is the same as that returned by +columns+.
         
     | 
| 
      
 210 
     | 
    
         
            +
                  def select_rows(sql, name = nil)
         
     | 
| 
      
 211 
     | 
    
         
            +
                    execute(sql, name).to_a
         
     | 
| 
      
 212 
     | 
    
         
            +
                  end
         
     | 
| 
      
 213 
     | 
    
         
            +
             
     | 
| 
      
 214 
     | 
    
         
            +
                  # Executes the SQL statement in the context of this connection.
         
     | 
| 
      
 215 
     | 
    
         
            +
                  def execute(sql, name = nil)
         
     | 
| 
      
 216 
     | 
    
         
            +
                    # make sure we carry over any changes to ActiveRecord::Base.default_timezone that have been
         
     | 
| 
      
 217 
     | 
    
         
            +
                    # made since we established the connection
         
     | 
| 
      
 218 
     | 
    
         
            +
                    @connection.query_options[:database_timezone] = ActiveRecord::Base.default_timezone
         
     | 
| 
      
 219 
     | 
    
         
            +
             
     | 
| 
      
 220 
     | 
    
         
            +
                    super
         
     | 
| 
      
 221 
     | 
    
         
            +
                  end
         
     | 
| 
      
 222 
     | 
    
         
            +
             
     | 
| 
      
 223 
     | 
    
         
            +
                  def exec_query(sql, name = 'SQL', binds = [])
         
     | 
| 
      
 224 
     | 
    
         
            +
                    result = execute(sql, name)
         
     | 
| 
      
 225 
     | 
    
         
            +
                    ActiveRecord::Result.new(result.fields, result.to_a)
         
     | 
| 
      
 226 
     | 
    
         
            +
                  end
         
     | 
| 
      
 227 
     | 
    
         
            +
             
     | 
| 
      
 228 
     | 
    
         
            +
                  alias exec_without_stmt exec_query
         
     | 
| 
      
 229 
     | 
    
         
            +
             
     | 
| 
      
 230 
     | 
    
         
            +
                  # Returns an array of record hashes with the column names as keys and
         
     | 
| 
      
 231 
     | 
    
         
            +
                  # column values as values.
         
     | 
| 
      
 232 
     | 
    
         
            +
                  def select(sql, name = nil, binds = [])
         
     | 
| 
      
 233 
     | 
    
         
            +
                    exec_query(sql, name)
         
     | 
| 
      
 234 
     | 
    
         
            +
                  end
         
     | 
| 
      
 235 
     | 
    
         
            +
             
     | 
| 
      
 236 
     | 
    
         
            +
                  def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
         
     | 
| 
      
 237 
     | 
    
         
            +
                    super
         
     | 
| 
      
 238 
     | 
    
         
            +
                    id_value || @connection.last_id
         
     | 
| 
      
 239 
     | 
    
         
            +
                  end
         
     | 
| 
      
 240 
     | 
    
         
            +
                  alias :create :insert_sql
         
     | 
| 
      
 241 
     | 
    
         
            +
             
     | 
| 
      
 242 
     | 
    
         
            +
                  def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
         
     | 
| 
      
 243 
     | 
    
         
            +
                    execute to_sql(sql, binds), name
         
     | 
| 
      
 244 
     | 
    
         
            +
                  end
         
     | 
| 
      
 245 
     | 
    
         
            +
             
     | 
| 
      
 246 
     | 
    
         
            +
                  def exec_delete(sql, name, binds)
         
     | 
| 
      
 247 
     | 
    
         
            +
                    execute to_sql(sql, binds), name
         
     | 
| 
      
 248 
     | 
    
         
            +
                    @connection.affected_rows
         
     | 
| 
      
 249 
     | 
    
         
            +
                  end
         
     | 
| 
      
 250 
     | 
    
         
            +
                  alias :exec_update :exec_delete
         
     | 
| 
      
 251 
     | 
    
         
            +
             
     | 
| 
      
 252 
     | 
    
         
            +
                  def last_inserted_id(result)
         
     | 
| 
      
 253 
     | 
    
         
            +
                    @connection.last_id
         
     | 
| 
      
 254 
     | 
    
         
            +
                  end
         
     | 
| 
      
 255 
     | 
    
         
            +
             
     | 
| 
      
 256 
     | 
    
         
            +
                  private
         
     | 
| 
      
 257 
     | 
    
         
            +
             
     | 
| 
      
 258 
     | 
    
         
            +
                  def connect
         
     | 
| 
      
 259 
     | 
    
         
            +
                    @connection = Mysql2::Client.new(@config)
         
     | 
| 
      
 260 
     | 
    
         
            +
                    configure_connection
         
     | 
| 
      
 261 
     | 
    
         
            +
                  end
         
     | 
| 
      
 262 
     | 
    
         
            +
             
     | 
| 
      
 263 
     | 
    
         
            +
                  def configure_connection
         
     | 
| 
      
 264 
     | 
    
         
            +
                    @connection.query_options.merge!(:as => :array)
         
     | 
| 
      
 265 
     | 
    
         
            +
                    super
         
     | 
| 
      
 266 
     | 
    
         
            +
                  end
         
     | 
| 
      
 267 
     | 
    
         
            +
             
     | 
| 
      
 268 
     | 
    
         
            +
                  def version
         
     | 
| 
      
 269 
     | 
    
         
            +
                    @version ||= @connection.info[:version].scan(/^(\d+)\.(\d+)\.(\d+)/).flatten.map { |v| v.to_i }
         
     | 
| 
      
 270 
     | 
    
         
            +
                  end
         
     | 
| 
      
 271 
     | 
    
         
            +
                end
         
     | 
| 
      
 272 
     | 
    
         
            +
              end
         
     | 
| 
      
 273 
     | 
    
         
            +
            end
         
     |