sequel 3.18.0 → 3.19.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.
- data/CHANGELOG +18 -0
 - data/{COPYING → MIT-LICENSE} +0 -0
 - data/Rakefile +2 -2
 - data/doc/release_notes/3.19.0.txt +67 -0
 - data/doc/sharding.rdoc +25 -0
 - data/lib/sequel/adapters/amalgalite.rb +1 -1
 - data/lib/sequel/adapters/dbi.rb +1 -1
 - data/lib/sequel/adapters/firebird.rb +1 -1
 - data/lib/sequel/adapters/informix.rb +1 -1
 - data/lib/sequel/adapters/jdbc.rb +27 -12
 - data/lib/sequel/adapters/mysql.rb +42 -17
 - data/lib/sequel/adapters/odbc.rb +1 -1
 - data/lib/sequel/adapters/oracle.rb +1 -1
 - data/lib/sequel/adapters/postgres.rb +30 -17
 - data/lib/sequel/adapters/shared/mssql.rb +2 -2
 - data/lib/sequel/adapters/shared/sqlite.rb +1 -1
 - data/lib/sequel/adapters/sqlite.rb +39 -16
 - data/lib/sequel/adapters/swift/postgres.rb +1 -1
 - data/lib/sequel/dataset/actions.rb +2 -2
 - data/lib/sequel/dataset/query.rb +3 -3
 - data/lib/sequel/model/associations.rb +2 -0
 - data/lib/sequel/model/base.rb +2 -2
 - data/lib/sequel/plugins/class_table_inheritance.rb +2 -2
 - data/lib/sequel/plugins/schema.rb +1 -1
 - data/lib/sequel/plugins/subclasses.rb +1 -1
 - data/lib/sequel/plugins/typecast_on_load.rb +1 -1
 - data/lib/sequel/plugins/validation_class_methods.rb +32 -3
 - data/lib/sequel/version.rb +1 -1
 - data/spec/extensions/validation_class_methods_spec.rb +20 -1
 - data/spec/integration/associations_test.rb +20 -0
 - data/spec/integration/database_test.rb +6 -0
 - data/spec/integration/prepared_statement_test.rb +58 -1
 - data/spec/integration/schema_test.rb +1 -1
 - data/spec/integration/type_test.rb +1 -1
 - data/spec/model/associations_spec.rb +46 -2
 - data/spec/model/model_spec.rb +11 -0
 - metadata +8 -6
 
    
        data/CHANGELOG
    CHANGED
    
    | 
         @@ -1,3 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            === 3.19.0 (2011-01-03)
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            * Handle Date and DateTime types in prepared statements when using the jdbc adapter (jeremyevans)
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            * Handle Date, DateTime, Time, SQL::Blob, true, and false in prepared statements when using the SQLite adapter (jeremyevans)
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            * Use varbinary(max) instead of image for the generic blob type on MSSQL (jeremyevans)
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            * Close prepared statements when disconnecting when using SQLite (jeremyevans)
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            * Allow reflecting on validations in the validation_class_methods plugin (jeremyevans)
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            * Allow passing a primary key value to the add_* association method (gucki)
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            * When typecasting model column values, check the classes of the new and existing values (jeremyevans)
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            * Improve type translation performance in the postgres, mysql, and sqlite adapters by using methods instead of procs (jeremyevans)
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
       1 
19 
     | 
    
         
             
            === 3.18.0 (2010-12-01)
         
     | 
| 
       2 
20 
     | 
    
         | 
| 
       3 
21 
     | 
    
         
             
            * Allow the user to control how the connection pool deals with attempts to access shards that aren't configured (jeremyevans)
         
     | 
    
        data/{COPYING → MIT-LICENSE}
    RENAMED
    
    | 
         
            File without changes
         
     | 
    
        data/Rakefile
    CHANGED
    
    | 
         @@ -43,7 +43,7 @@ end 
     | 
|
| 
       43 
43 
     | 
    
         
             
            Rake::RDocTask.new do |rdoc|
         
     | 
| 
       44 
44 
     | 
    
         
             
              rdoc.rdoc_dir = "rdoc"
         
     | 
| 
       45 
45 
     | 
    
         
             
              rdoc.options += RDOC_OPTS
         
     | 
| 
       46 
     | 
    
         
            -
              rdoc.rdoc_files.add %w"README.rdoc CHANGELOG  
     | 
| 
      
 46 
     | 
    
         
            +
              rdoc.rdoc_files.add %w"README.rdoc CHANGELOG MIT-LICENSE lib/**/*.rb doc/*.rdoc doc/release_notes/*.txt"
         
     | 
| 
       47 
47 
     | 
    
         
             
            end
         
     | 
| 
       48 
48 
     | 
    
         | 
| 
       49 
49 
     | 
    
         
             
            ### Website
         
     | 
| 
         @@ -59,7 +59,7 @@ task :website_rdoc=>[:website_rdoc_main, :website_rdoc_adapters, :website_rdoc_p 
     | 
|
| 
       59 
59 
     | 
    
         
             
            Rake::RDocTask.new(:website_rdoc_main) do |rdoc|
         
     | 
| 
       60 
60 
     | 
    
         
             
              rdoc.rdoc_dir = "www/public/rdoc"
         
     | 
| 
       61 
61 
     | 
    
         
             
              rdoc.options += RDOC_OPTS
         
     | 
| 
       62 
     | 
    
         
            -
              rdoc.rdoc_files.add %w"README.rdoc CHANGELOG  
     | 
| 
      
 62 
     | 
    
         
            +
              rdoc.rdoc_files.add %w"README.rdoc CHANGELOG MIT-LICENSE lib/*.rb lib/sequel/*.rb lib/sequel/{connection_pool,dataset,database,model}/*.rb doc/*.rdoc doc/release_notes/*.txt lib/sequel/extensions/migration.rb"
         
     | 
| 
       63 
63 
     | 
    
         
             
            end
         
     | 
| 
       64 
64 
     | 
    
         | 
| 
       65 
65 
     | 
    
         
             
            Rake::RDocTask.new(:website_rdoc_adapters) do |rdoc|
         
     | 
| 
         @@ -0,0 +1,67 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            = New Features
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            * The add_* association methods now accept a primary key, and
         
     | 
| 
      
 4 
     | 
    
         
            +
              associates the receiver to the associated model object with that
         
     | 
| 
      
 5 
     | 
    
         
            +
              primary key:
         
     | 
| 
      
 6 
     | 
    
         
            +
              
         
     | 
| 
      
 7 
     | 
    
         
            +
                artist.add_album(42)
         
     | 
| 
      
 8 
     | 
    
         
            +
                # equivalent to: artist.add_album(Album[42])
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            * The validation_class_methods plugin now has the ability to
         
     | 
| 
      
 11 
     | 
    
         
            +
              reflect on validations:
         
     | 
| 
      
 12 
     | 
    
         
            +
              
         
     | 
| 
      
 13 
     | 
    
         
            +
                Album.plugin :validation_class_methods
         
     | 
| 
      
 14 
     | 
    
         
            +
                Album.validates_acceptance_of(:a)
         
     | 
| 
      
 15 
     | 
    
         
            +
                Album.validation_reflections
         
     | 
| 
      
 16 
     | 
    
         
            +
                # => {:a=>[[:acceptance, {:tag=>:acceptance, :allow_nil=>true,
         
     | 
| 
      
 17 
     | 
    
         
            +
                            :message=>"is not accepted", :accept=>"1"}]]}
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            = Other Improvements
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            * In the postgres, mysql, and sqlite adapters, typecasting now uses
         
     | 
| 
      
 22 
     | 
    
         
            +
              methods instead of procs.  Since methods aren't closures (while
         
     | 
| 
      
 23 
     | 
    
         
            +
              procs are), this makes typecasting faster (up to 15%).
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            * When typecasting model column values, the classes of the new and
         
     | 
| 
      
 26 
     | 
    
         
            +
              existing values are checked in addition to the values themselves.
         
     | 
| 
      
 27 
     | 
    
         
            +
              Previously, if the new and existing values were equal (i.e. 1.0
         
     | 
| 
      
 28 
     | 
    
         
            +
              and 1), it wouldn't update the value.  Now, if the classes are
         
     | 
| 
      
 29 
     | 
    
         
            +
              different, it always updates the value.
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            * Date and DateTime objects are now handled correctly when using
         
     | 
| 
      
 32 
     | 
    
         
            +
              prepared statements/bound variables in the jdbc adapter.
         
     | 
| 
      
 33 
     | 
    
         
            +
              
         
     | 
| 
      
 34 
     | 
    
         
            +
            * Date, DateTime, Time, true, false, and SQL::Blob objects are now
         
     | 
| 
      
 35 
     | 
    
         
            +
              handled correctly when using prepared statements/bound variables
         
     | 
| 
      
 36 
     | 
    
         
            +
              in the sqlite adapter.
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            * Sequel now uses varbinary(max) instead of image for the generic
         
     | 
| 
      
 39 
     | 
    
         
            +
              File (blob) type on Microsoft SQL Server.  This makes it possible
         
     | 
| 
      
 40 
     | 
    
         
            +
              to use an SQL::Blob object as a prepared statement argument.
         
     | 
| 
      
 41 
     | 
    
         
            +
              
         
     | 
| 
      
 42 
     | 
    
         
            +
            * Sequel now handles blobs better in the Amalgalite adapter.
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
            * When disconnecting a connection using the sqlite adapter, all
         
     | 
| 
      
 45 
     | 
    
         
            +
              open prepared statements are now closed first.  Previously,
         
     | 
| 
      
 46 
     | 
    
         
            +
              attempting to disconnect a connection with open prepared statements
         
     | 
| 
      
 47 
     | 
    
         
            +
              resulted in an error.
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
            * The license file has been renamed from COPYING to MIT-LICENSE, to
         
     | 
| 
      
 50 
     | 
    
         
            +
              make it easier to determine at a glance which license is used.
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
            = Backwards Compatibility
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
            * Because Sequel switched the generic File type from image to
         
     | 
| 
      
 55 
     | 
    
         
            +
              varbinary(max) on Microsoft SQL Server, any migrations/schema
         
     | 
| 
      
 56 
     | 
    
         
            +
              modification methods that used the File type will now result in a
         
     | 
| 
      
 57 
     | 
    
         
            +
              different column type than before.
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            * The MYSQL_TYPE_PROCS, PG_TYPE_PROCS, and SQLITE_TYPE_PROCS
         
     | 
| 
      
 60 
     | 
    
         
            +
              constants have been removed from the mysql, postgres, and sqlite
         
     | 
| 
      
 61 
     | 
    
         
            +
              adapters, respectively.  The UNIX_EPOCH_TIME_FORMAT and
         
     | 
| 
      
 62 
     | 
    
         
            +
              FALSE_VALUES constants have also been removed from the sqlite
         
     | 
| 
      
 63 
     | 
    
         
            +
              adapter.
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
            * Typecasting in the sqlite adapters now uses to_i and to_f instead
         
     | 
| 
      
 66 
     | 
    
         
            +
              of Integer() and Float() with rescues.  If you put non-numeric
         
     | 
| 
      
 67 
     | 
    
         
            +
              data in numeric columns on SQLite, this could cause problems.
         
     | 
    
        data/doc/sharding.rdoc
    CHANGED
    
    | 
         @@ -112,6 +112,31 @@ the shard to use.  This is fairly easy using a Sequel::Model: 
     | 
|
| 
       112 
112 
     | 
    
         | 
| 
       113 
113 
     | 
    
         
             
              Rainbow.plaintext_for_hash("e580726d31f6e1ad216ffd87279e536d1f74e606")
         
     | 
| 
       114 
114 
     | 
    
         | 
| 
      
 115 
     | 
    
         
            +
            The connection pool can be further controlled to change how it handles attempts
         
     | 
| 
      
 116 
     | 
    
         
            +
            to access shards that haven't been configured.  The default is
         
     | 
| 
      
 117 
     | 
    
         
            +
            to assume the :default shard.  However, you can specify a
         
     | 
| 
      
 118 
     | 
    
         
            +
            different shard using the :servers_hash option when connecting
         
     | 
| 
      
 119 
     | 
    
         
            +
            to the database:
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
              DB = Sequel.connect(..., :servers_hash=>Hash.new(:some_shard))
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
            You can also use this feature to raise an exception if an
         
     | 
| 
      
 124 
     | 
    
         
            +
            unconfigured shard is used:
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
              DB = Sequel.connect(..., :servers_hash=>Hash.new{raise ...})
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
            If you specify a :servers_hash option to raise an exception for non configured
         
     | 
| 
      
 129 
     | 
    
         
            +
            shards you should also explicitly specify a :read_only entry in your :servers option
         
     | 
| 
      
 130 
     | 
    
         
            +
            for the case where a shard is not specified. In most cases it is sufficient
         
     | 
| 
      
 131 
     | 
    
         
            +
            to make the :read_only entry the same as the :default shard:
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
              servers = {:read_only => {}}
         
     | 
| 
      
 134 
     | 
    
         
            +
              (('0'..'9').to_a + ('a'..'f').to_a).each do |hex|
         
     | 
| 
      
 135 
     | 
    
         
            +
                servers[hex.to_sym] = {:host=>"hash_host_#{hex}"}
         
     | 
| 
      
 136 
     | 
    
         
            +
              end
         
     | 
| 
      
 137 
     | 
    
         
            +
              DB=Sequel.connect('postgres://hash_host/hashes', :servers=>servers, 
         
     | 
| 
      
 138 
     | 
    
         
            +
                :servers_hash=>Hash.new{raise Exception.new("Invalid Server")}) 
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
       115 
140 
     | 
    
         
             
            === Sharding Plugin
         
     | 
| 
       116 
141 
     | 
    
         | 
| 
       117 
142 
     | 
    
         
             
            Sequel comes with a sharding plugin that makes it easy to use sharding with model objects.
         
     | 
| 
         @@ -36,7 +36,7 @@ module Sequel 
     | 
|
| 
       36 
36 
     | 
    
         
             
                  # type doesn't match a known type, just return the value.
         
     | 
| 
       37 
37 
     | 
    
         
             
                  def result_value_of(declared_type, value)
         
     | 
| 
       38 
38 
     | 
    
         
             
                    if value.is_a?(::Amalgalite::Blob)
         
     | 
| 
       39 
     | 
    
         
            -
                      SQL::Blob.new(value. 
     | 
| 
      
 39 
     | 
    
         
            +
                      SQL::Blob.new(value.to_s)
         
     | 
| 
       40 
40 
     | 
    
         
             
                    elsif value.is_a?(String) && declared_type
         
     | 
| 
       41 
41 
     | 
    
         
             
                      (meth = self.class.sql_to_method(declared_type.downcase)) ? send(meth, value) : value
         
     | 
| 
       42 
42 
     | 
    
         
             
                    else
         
     | 
    
        data/lib/sequel/adapters/dbi.rb
    CHANGED
    
    
| 
         @@ -201,7 +201,7 @@ module Sequel 
     | 
|
| 
       201 
201 
     | 
    
         | 
| 
       202 
202 
     | 
    
         
             
                  # Yield all rows returned by executing the given SQL and converting
         
     | 
| 
       203 
203 
     | 
    
         
             
                  # the types.
         
     | 
| 
       204 
     | 
    
         
            -
                  def fetch_rows(sql 
     | 
| 
      
 204 
     | 
    
         
            +
                  def fetch_rows(sql)
         
     | 
| 
       205 
205 
     | 
    
         
             
                    execute(sql) do |s|
         
     | 
| 
       206 
206 
     | 
    
         
             
                      begin
         
     | 
| 
       207 
207 
     | 
    
         
             
                        @columns = s.fields.map{|c| output_identifier(c.name)}
         
     | 
| 
         @@ -37,7 +37,7 @@ module Sequel 
     | 
|
| 
       37 
37 
     | 
    
         
             
                class Dataset < Sequel::Dataset
         
     | 
| 
       38 
38 
     | 
    
         
             
                  SELECT_CLAUSE_METHODS = clause_methods(:select, %w'limit distinct columns from join where having group compounds order')
         
     | 
| 
       39 
39 
     | 
    
         | 
| 
       40 
     | 
    
         
            -
                  def fetch_rows(sql 
     | 
| 
      
 40 
     | 
    
         
            +
                  def fetch_rows(sql)
         
     | 
| 
       41 
41 
     | 
    
         
             
                    execute(sql) do |cursor|
         
     | 
| 
       42 
42 
     | 
    
         
             
                      begin
         
     | 
| 
       43 
43 
     | 
    
         
             
                        col_map = nil
         
     | 
    
        data/lib/sequel/adapters/jdbc.rb
    CHANGED
    
    | 
         @@ -191,7 +191,7 @@ module Sequel 
     | 
|
| 
       191 
191 
     | 
    
         
             
                    return execute_prepared_statement(sql, opts, &block) if [Symbol, Dataset].any?{|c| sql.is_a?(c)}
         
     | 
| 
       192 
192 
     | 
    
         
             
                    synchronize(opts[:server]) do |conn|
         
     | 
| 
       193 
193 
     | 
    
         
             
                      statement(conn) do |stmt|
         
     | 
| 
       194 
     | 
    
         
            -
                        if  
     | 
| 
      
 194 
     | 
    
         
            +
                        if block
         
     | 
| 
       195 
195 
     | 
    
         
             
                          yield log_yield(sql){stmt.executeQuery(sql)}
         
     | 
| 
       196 
196 
     | 
    
         
             
                        else
         
     | 
| 
       197 
197 
     | 
    
         
             
                          case opts[:type]
         
     | 
| 
         @@ -338,14 +338,25 @@ module Sequel 
     | 
|
| 
       338 
338 
     | 
    
         
             
                    JavaxNaming::InitialContext.new.lookup(jndi_name).connection
         
     | 
| 
       339 
339 
     | 
    
         
             
                  end
         
     | 
| 
       340 
340 
     | 
    
         | 
| 
       341 
     | 
    
         
            -
                  # Support  
     | 
| 
       342 
     | 
    
         
            -
                  def  
     | 
| 
       343 
     | 
    
         
            -
                     
     | 
| 
       344 
     | 
    
         
            -
             
     | 
| 
       345 
     | 
    
         
            -
             
     | 
| 
      
 341 
     | 
    
         
            +
                  # Support Date objects used in bound variables
         
     | 
| 
      
 342 
     | 
    
         
            +
                  def java_sql_date(date)
         
     | 
| 
      
 343 
     | 
    
         
            +
                    java.sql.Date.new(Time.local(date.year, date.month, date.day).to_i * 1000)
         
     | 
| 
      
 344 
     | 
    
         
            +
                  end
         
     | 
| 
      
 345 
     | 
    
         
            +
             
     | 
| 
      
 346 
     | 
    
         
            +
                  # Support DateTime objects used in bound variables
         
     | 
| 
      
 347 
     | 
    
         
            +
                  def java_sql_datetime(datetime)
         
     | 
| 
      
 348 
     | 
    
         
            +
                    ts = java.sql.Timestamp.new(Time.local(datetime.year, datetime.month, datetime.day, datetime.hour, datetime.min, datetime.sec).to_i * 1000)
         
     | 
| 
      
 349 
     | 
    
         
            +
                    ts.setNanos((datetime.sec_fraction * (RUBY_VERSION >= '1.9.0' ?  1000000000 : 86400000000000)).to_i)
         
     | 
| 
       346 
350 
     | 
    
         
             
                    ts
         
     | 
| 
       347 
351 
     | 
    
         
             
                  end
         
     | 
| 
       348 
352 
     | 
    
         | 
| 
      
 353 
     | 
    
         
            +
                  # Support fractional seconds for Time objects used in bound variables
         
     | 
| 
      
 354 
     | 
    
         
            +
                  def java_sql_timestamp(time)
         
     | 
| 
      
 355 
     | 
    
         
            +
                    ts = java.sql.Timestamp.new(time.to_i * 1000)
         
     | 
| 
      
 356 
     | 
    
         
            +
                    ts.setNanos(RUBY_VERSION >= '1.9.0' ? time.nsec : time.usec * 1000)
         
     | 
| 
      
 357 
     | 
    
         
            +
                    ts
         
     | 
| 
      
 358 
     | 
    
         
            +
                  end 
         
     | 
| 
      
 359 
     | 
    
         
            +
                  
         
     | 
| 
       349 
360 
     | 
    
         
             
                  # Log the given SQL and then execute it on the connection, used by
         
     | 
| 
       350 
361 
     | 
    
         
             
                  # the transaction code.
         
     | 
| 
       351 
362 
     | 
    
         
             
                  def log_connection_execute(conn, sql)
         
     | 
| 
         @@ -389,18 +400,22 @@ module Sequel 
     | 
|
| 
       389 
400 
     | 
    
         
             
                      cps.setBytes(i, arg.to_java_bytes)
         
     | 
| 
       390 
401 
     | 
    
         
             
                    when String
         
     | 
| 
       391 
402 
     | 
    
         
             
                      cps.setString(i, arg)
         
     | 
| 
       392 
     | 
    
         
            -
                    when Date, Java::JavaSql::Date
         
     | 
| 
       393 
     | 
    
         
            -
                      cps.setDate(i, arg)
         
     | 
| 
       394 
     | 
    
         
            -
                    when DateTime, Java::JavaSql::Timestamp
         
     | 
| 
       395 
     | 
    
         
            -
                      cps.setTimestamp(i, arg)
         
     | 
| 
       396 
     | 
    
         
            -
                    when Time
         
     | 
| 
       397 
     | 
    
         
            -
                      cps.setTimestamp(i, java_sql_timestamp(arg))
         
     | 
| 
       398 
403 
     | 
    
         
             
                    when Float
         
     | 
| 
       399 
404 
     | 
    
         
             
                      cps.setDouble(i, arg)
         
     | 
| 
       400 
405 
     | 
    
         
             
                    when TrueClass, FalseClass
         
     | 
| 
       401 
406 
     | 
    
         
             
                      cps.setBoolean(i, arg)
         
     | 
| 
       402 
407 
     | 
    
         
             
                    when nil
         
     | 
| 
       403 
408 
     | 
    
         
             
                      cps.setNull(i, JavaSQL::Types::NULL)
         
     | 
| 
      
 409 
     | 
    
         
            +
                    when DateTime
         
     | 
| 
      
 410 
     | 
    
         
            +
                      cps.setTimestamp(i, java_sql_datetime(arg))
         
     | 
| 
      
 411 
     | 
    
         
            +
                    when Date
         
     | 
| 
      
 412 
     | 
    
         
            +
                      cps.setDate(i, java_sql_date(arg))
         
     | 
| 
      
 413 
     | 
    
         
            +
                    when Time
         
     | 
| 
      
 414 
     | 
    
         
            +
                      cps.setTimestamp(i, java_sql_timestamp(arg))
         
     | 
| 
      
 415 
     | 
    
         
            +
                    when Java::JavaSql::Timestamp
         
     | 
| 
      
 416 
     | 
    
         
            +
                      cps.setTimestamp(i, arg)
         
     | 
| 
      
 417 
     | 
    
         
            +
                    when Java::JavaSql::Date
         
     | 
| 
      
 418 
     | 
    
         
            +
                      cps.setDate(i, arg)
         
     | 
| 
       404 
419 
     | 
    
         
             
                    else
         
     | 
| 
       405 
420 
     | 
    
         
             
                      cps.setObject(i, arg)
         
     | 
| 
       406 
421 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -10,33 +10,58 @@ Sequel.require %w'shared/mysql utils/stored_procedures', 'adapters' 
     | 
|
| 
       10 
10 
     | 
    
         
             
            module Sequel
         
     | 
| 
       11 
11 
     | 
    
         
             
              # Module for holding all MySQL-related classes and modules for Sequel.
         
     | 
| 
       12 
12 
     | 
    
         
             
              module MySQL
         
     | 
| 
       13 
     | 
    
         
            -
                 
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
      
 13 
     | 
    
         
            +
                TYPE_TRANSLATOR = tt = Class.new do
         
     | 
| 
      
 14 
     | 
    
         
            +
                  def boolean(s) s.to_i != 0 end
         
     | 
| 
      
 15 
     | 
    
         
            +
                  def blob(s) ::Sequel::SQL::Blob.new(s) end
         
     | 
| 
      
 16 
     | 
    
         
            +
                  def integer(s) s.to_i end
         
     | 
| 
      
 17 
     | 
    
         
            +
                  def float(s) s.to_f end
         
     | 
| 
      
 18 
     | 
    
         
            +
                  def decimal(s) ::BigDecimal.new(s) end
         
     | 
| 
      
 19 
     | 
    
         
            +
                  def date(s) ::Sequel.string_to_date(s) end
         
     | 
| 
      
 20 
     | 
    
         
            +
                  def time(s) ::Sequel.string_to_time(s) end
         
     | 
| 
      
 21 
     | 
    
         
            +
                  def timestamp(s) ::Sequel.database_to_application_timestamp(s) end
         
     | 
| 
      
 22 
     | 
    
         
            +
                  def date_conv(s) ::Sequel::MySQL.convert_date_time(:string_to_date, s) end
         
     | 
| 
      
 23 
     | 
    
         
            +
                  def time_conv(s) ::Sequel::MySQL.convert_date_time(:string_to_time, s) end
         
     | 
| 
      
 24 
     | 
    
         
            +
                  def timestamp_conv(s) ::Sequel::MySQL.convert_date_time(:database_to_application_timestamp, s) end
         
     | 
| 
      
 25 
     | 
    
         
            +
                end.new
         
     | 
| 
       15 
26 
     | 
    
         | 
| 
       16 
     | 
    
         
            -
                #  
     | 
| 
       17 
     | 
    
         
            -
                 
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
                  [ 
     | 
| 
       20 
     | 
    
         
            -
                  [2, 3, 8, 9, 13, 247, 248]  =>  
     | 
| 
       21 
     | 
    
         
            -
                  [4, 5]  =>  
     | 
| 
       22 
     | 
    
         
            -
                  [ 
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
                  [11]  => lambda{|v| convert_date_time(:string_to_time, v)},         # time
         
     | 
| 
       25 
     | 
    
         
            -
                  [249, 250, 251, 252]  => lambda{|v| Sequel::SQL::Blob.new(v)}       # blob
         
     | 
| 
       26 
     | 
    
         
            -
                }
         
     | 
| 
       27 
     | 
    
         
            -
                MYSQL_TYPE_PROCS.each do |k,v|
         
     | 
| 
      
 27 
     | 
    
         
            +
                # Hash with integer keys and callable values for converting MySQL types.
         
     | 
| 
      
 28 
     | 
    
         
            +
                MYSQL_TYPES = {}
         
     | 
| 
      
 29 
     | 
    
         
            +
                {
         
     | 
| 
      
 30 
     | 
    
         
            +
                  [0, 246]  => tt.method(:decimal),
         
     | 
| 
      
 31 
     | 
    
         
            +
                  [2, 3, 8, 9, 13, 247, 248]  => tt.method(:integer),
         
     | 
| 
      
 32 
     | 
    
         
            +
                  [4, 5]  => tt.method(:float),
         
     | 
| 
      
 33 
     | 
    
         
            +
                  [249, 250, 251, 252]  => tt.method(:blob)
         
     | 
| 
      
 34 
     | 
    
         
            +
                }.each do |k,v|
         
     | 
| 
       28 
35 
     | 
    
         
             
                  k.each{|n| MYSQL_TYPES[n] = v}
         
     | 
| 
       29 
36 
     | 
    
         
             
                end
         
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
                 
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                # Modify the type translator used for the tinyint type based
         
     | 
| 
      
 39 
     | 
    
         
            +
                # on the value given.
         
     | 
| 
      
 40 
     | 
    
         
            +
                def self.convert_tinyint_to_bool=(v)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  MYSQL_TYPES[1] = TYPE_TRANSLATOR.method(v ? :boolean : :integer)
         
     | 
| 
      
 42 
     | 
    
         
            +
                  @convert_tinyint_to_bool = v
         
     | 
| 
      
 43 
     | 
    
         
            +
                end
         
     | 
| 
      
 44 
     | 
    
         
            +
                self.convert_tinyint_to_bool = convert_tinyint_to_bool
         
     | 
| 
       32 
45 
     | 
    
         | 
| 
       33 
46 
     | 
    
         
             
                class << self
         
     | 
| 
       34 
47 
     | 
    
         
             
                  # By default, Sequel raises an exception if in invalid date or time is used.
         
     | 
| 
       35 
48 
     | 
    
         
             
                  # However, if this is set to nil or :nil, the adapter treats dates
         
     | 
| 
       36 
49 
     | 
    
         
             
                  # like 0000-00-00 and times like 838:00:00 as nil values.  If set to :string,
         
     | 
| 
       37 
50 
     | 
    
         
             
                  # it returns the strings as is.  
         
     | 
| 
       38 
     | 
    
         
            -
                   
     | 
| 
      
 51 
     | 
    
         
            +
                  attr_reader :convert_invalid_date_time
         
     | 
| 
      
 52 
     | 
    
         
            +
                end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                # Modify the type translators for the date, time, and timestamp types
         
     | 
| 
      
 55 
     | 
    
         
            +
                # depending on the value given.
         
     | 
| 
      
 56 
     | 
    
         
            +
                def self.convert_invalid_date_time=(v)
         
     | 
| 
      
 57 
     | 
    
         
            +
                  MYSQL_TYPES[11] = TYPE_TRANSLATOR.method(v == false ? :time : :time_conv)
         
     | 
| 
      
 58 
     | 
    
         
            +
                  m = TYPE_TRANSLATOR.method(v == false ? :date : :date_conv)
         
     | 
| 
      
 59 
     | 
    
         
            +
                  [10, 14].each{|i| MYSQL_TYPES[i] = m}
         
     | 
| 
      
 60 
     | 
    
         
            +
                  m = TYPE_TRANSLATOR.method(v == false ? :timestamp : :timestamp_conv)
         
     | 
| 
      
 61 
     | 
    
         
            +
                  [7, 12].each{|i| MYSQL_TYPES[i] = m}
         
     | 
| 
      
 62 
     | 
    
         
            +
                  @convert_invalid_date_time = v
         
     | 
| 
       39 
63 
     | 
    
         
             
                end
         
     | 
| 
      
 64 
     | 
    
         
            +
                self.convert_invalid_date_time = false
         
     | 
| 
       40 
65 
     | 
    
         | 
| 
       41 
66 
     | 
    
         
             
                # If convert_invalid_date_time is nil, :nil, or :string and
         
     | 
| 
       42 
67 
     | 
    
         
             
                # the conversion raises an InvalidValue exception, return v
         
     | 
    
        data/lib/sequel/adapters/odbc.rb
    CHANGED
    
    | 
         @@ -87,7 +87,7 @@ module Sequel 
     | 
|
| 
       87 
87 
     | 
    
         
             
                  ODBC_DATE_FORMAT = "{d '%Y-%m-%d'}".freeze
         
     | 
| 
       88 
88 
     | 
    
         
             
                  TIMESTAMP_FORMAT="{ts '%Y-%m-%d %H:%M:%S'}".freeze
         
     | 
| 
       89 
89 
     | 
    
         | 
| 
       90 
     | 
    
         
            -
                  def fetch_rows(sql 
     | 
| 
      
 90 
     | 
    
         
            +
                  def fetch_rows(sql)
         
     | 
| 
       91 
91 
     | 
    
         
             
                    execute(sql) do |s|
         
     | 
| 
       92 
92 
     | 
    
         
             
                      i = -1
         
     | 
| 
       93 
93 
     | 
    
         
             
                      cols = s.columns(true).map{|c| [output_identifier(c.name), i+=1]}
         
     | 
| 
         @@ -88,32 +88,45 @@ module Sequel 
     | 
|
| 
       88 
88 
     | 
    
         
             
              module Postgres
         
     | 
| 
       89 
89 
     | 
    
         
             
                CONVERTED_EXCEPTIONS << PGError
         
     | 
| 
       90 
90 
     | 
    
         | 
| 
       91 
     | 
    
         
            -
                 
     | 
| 
       92 
     | 
    
         
            -
             
     | 
| 
      
 91 
     | 
    
         
            +
                TYPE_TRANSLATOR = tt = Class.new do
         
     | 
| 
      
 92 
     | 
    
         
            +
                  def boolean(s) s == 't' end
         
     | 
| 
      
 93 
     | 
    
         
            +
                  def bytea(s) ::Sequel::SQL::Blob.new(Adapter.unescape_bytea(s)) end
         
     | 
| 
      
 94 
     | 
    
         
            +
                  def integer(s) s.to_i end
         
     | 
| 
      
 95 
     | 
    
         
            +
                  def float(s) s.to_f end
         
     | 
| 
      
 96 
     | 
    
         
            +
                  def numeric(s) ::BigDecimal.new(s) end
         
     | 
| 
      
 97 
     | 
    
         
            +
                  def date(s) ::Sequel.string_to_date(s) end
         
     | 
| 
      
 98 
     | 
    
         
            +
                  def date_iso(s) ::Date.new(*s.split("-").map{|x| x.to_i}) end
         
     | 
| 
      
 99 
     | 
    
         
            +
                  def time(s) ::Sequel.string_to_time(s) end
         
     | 
| 
      
 100 
     | 
    
         
            +
                  def timestamp(s) ::Sequel.database_to_application_timestamp(s) end
         
     | 
| 
      
 101 
     | 
    
         
            +
                end.new
         
     | 
| 
       93 
102 
     | 
    
         | 
| 
       94 
     | 
    
         
            -
                #  
     | 
| 
       95 
     | 
    
         
            -
                 
     | 
| 
       96 
     | 
    
         
            -
             
     | 
| 
       97 
     | 
    
         
            -
                  [ 
     | 
| 
       98 
     | 
    
         
            -
                  [ 
     | 
| 
       99 
     | 
    
         
            -
                  [ 
     | 
| 
       100 
     | 
    
         
            -
                  [ 
     | 
| 
       101 
     | 
    
         
            -
                  [ 
     | 
| 
       102 
     | 
    
         
            -
                  [1083, 1266] =>  
     | 
| 
       103 
     | 
    
         
            -
                  [1114, 1184] =>  
     | 
| 
       104 
     | 
    
         
            -
                }
         
     | 
| 
       105 
     | 
    
         
            -
                PG_TYPE_PROCS.each do |k,v|
         
     | 
| 
      
 103 
     | 
    
         
            +
                # Hash with integer keys and callable values for converting PostgreSQL types.
         
     | 
| 
      
 104 
     | 
    
         
            +
                PG_TYPES = {}
         
     | 
| 
      
 105 
     | 
    
         
            +
                {
         
     | 
| 
      
 106 
     | 
    
         
            +
                  [16] => tt.method(:boolean),
         
     | 
| 
      
 107 
     | 
    
         
            +
                  [17] => tt.method(:bytea),
         
     | 
| 
      
 108 
     | 
    
         
            +
                  [20, 21, 22, 23, 26] => tt.method(:integer),
         
     | 
| 
      
 109 
     | 
    
         
            +
                  [700, 701] => tt.method(:float),
         
     | 
| 
      
 110 
     | 
    
         
            +
                  [790, 1700] => tt.method(:numeric),
         
     | 
| 
      
 111 
     | 
    
         
            +
                  [1083, 1266] => tt.method(:time),
         
     | 
| 
      
 112 
     | 
    
         
            +
                  [1114, 1184] => tt.method(:timestamp)
         
     | 
| 
      
 113 
     | 
    
         
            +
                }.each do |k,v|
         
     | 
| 
       106 
114 
     | 
    
         
             
                  k.each{|n| PG_TYPES[n] = v}
         
     | 
| 
       107 
115 
     | 
    
         
             
                end
         
     | 
| 
       108 
116 
     | 
    
         | 
| 
       109 
     | 
    
         
            -
                @use_iso_date_format = true
         
     | 
| 
       110 
     | 
    
         
            -
             
     | 
| 
       111 
117 
     | 
    
         
             
                class << self
         
     | 
| 
       112 
118 
     | 
    
         
             
                  # As an optimization, Sequel sets the date style to ISO, so that PostgreSQL provides
         
     | 
| 
       113 
119 
     | 
    
         
             
                  # the date in a known format that Sequel can parse faster.  This can be turned off
         
     | 
| 
       114 
120 
     | 
    
         
             
                  # if you require a date style other than ISO.
         
     | 
| 
       115 
     | 
    
         
            -
                   
     | 
| 
      
 121 
     | 
    
         
            +
                  attr_reader :use_iso_date_format
         
     | 
| 
      
 122 
     | 
    
         
            +
                end
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
                # Modify the type translator for the date type depending on the value given.
         
     | 
| 
      
 125 
     | 
    
         
            +
                def self.use_iso_date_format=(v)
         
     | 
| 
      
 126 
     | 
    
         
            +
                  PG_TYPES[1082] = TYPE_TRANSLATOR.method(v ? :date_iso : :date)
         
     | 
| 
      
 127 
     | 
    
         
            +
                  @use_iso_date_format = v
         
     | 
| 
       116 
128 
     | 
    
         
             
                end
         
     | 
| 
      
 129 
     | 
    
         
            +
                self.use_iso_date_format = true
         
     | 
| 
       117 
130 
     | 
    
         | 
| 
       118 
131 
     | 
    
         
             
                # PGconn subclass for connection specific methods used with the
         
     | 
| 
       119 
132 
     | 
    
         
             
                # pg, postgres, or postgres-pr driver.
         
     | 
| 
         @@ -181,9 +181,9 @@ module Sequel 
     | 
|
| 
       181 
181 
     | 
    
         
             
                    :bit
         
     | 
| 
       182 
182 
     | 
    
         
             
                  end
         
     | 
| 
       183 
183 
     | 
    
         | 
| 
       184 
     | 
    
         
            -
                  # MSSQL uses  
     | 
| 
      
 184 
     | 
    
         
            +
                  # MSSQL uses varbinary(max) type for blobs
         
     | 
| 
       185 
185 
     | 
    
         
             
                  def type_literal_generic_file(column)
         
     | 
| 
       186 
     | 
    
         
            -
                    : 
     | 
| 
      
 186 
     | 
    
         
            +
                    :'varbinary(max)'
         
     | 
| 
       187 
187 
     | 
    
         
             
                  end
         
     | 
| 
       188 
188 
     | 
    
         | 
| 
       189 
189 
     | 
    
         
             
                  # support for clustered index type
         
     | 
| 
         @@ -10,27 +10,36 @@ module Sequel 
     | 
|
| 
       10 
10 
     | 
    
         
             
              # Top level module for holding all SQLite-related modules and classes
         
     | 
| 
       11 
11 
     | 
    
         
             
              # for Sequel.
         
     | 
| 
       12 
12 
     | 
    
         
             
              module SQLite
         
     | 
| 
       13 
     | 
    
         
            -
                 
     | 
| 
      
 13 
     | 
    
         
            +
                TYPE_TRANSLATOR = tt = Class.new do
         
     | 
| 
      
 14 
     | 
    
         
            +
                  FALSE_VALUES = %w'0 false f no n'.freeze
         
     | 
| 
      
 15 
     | 
    
         
            +
                  def boolean(s) !FALSE_VALUES.include?(s.downcase) end
         
     | 
| 
      
 16 
     | 
    
         
            +
                  def blob(s) ::Sequel::SQL::Blob.new(s) end
         
     | 
| 
      
 17 
     | 
    
         
            +
                  def integer(s) s.to_i end
         
     | 
| 
      
 18 
     | 
    
         
            +
                  def float(s) s.to_f end
         
     | 
| 
      
 19 
     | 
    
         
            +
                  def numeric(s) ::BigDecimal.new(s) rescue s end
         
     | 
| 
      
 20 
     | 
    
         
            +
                  def date(s) ::Sequel.string_to_date(s) end
         
     | 
| 
      
 21 
     | 
    
         
            +
                  def time(s) ::Sequel.string_to_time(s) end
         
     | 
| 
      
 22 
     | 
    
         
            +
                  def timestamp(s) ::Sequel.database_to_application_timestamp(s) end
         
     | 
| 
      
 23 
     | 
    
         
            +
                end.new
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                # Hash with string keys and callable values for converting SQLite types.
         
     | 
| 
       14 
26 
     | 
    
         
             
                SQLITE_TYPES = {}
         
     | 
| 
       15 
     | 
    
         
            -
                 
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
                  %w' 
     | 
| 
       18 
     | 
    
         
            -
                  %w' 
     | 
| 
       19 
     | 
    
         
            -
                  %w' 
     | 
| 
       20 
     | 
    
         
            -
                  %w' 
     | 
| 
       21 
     | 
    
         
            -
                  %w' 
     | 
| 
       22 
     | 
    
         
            -
                  %w' 
     | 
| 
       23 
     | 
    
         
            -
                  %w' 
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
                }
         
     | 
| 
       26 
     | 
    
         
            -
                SQLITE_TYPE_PROCS.each do |k,v|
         
     | 
| 
      
 27 
     | 
    
         
            +
                {
         
     | 
| 
      
 28 
     | 
    
         
            +
                  %w'timestamp datetime' => tt.method(:timestamp),
         
     | 
| 
      
 29 
     | 
    
         
            +
                  %w'date' => tt.method(:date),
         
     | 
| 
      
 30 
     | 
    
         
            +
                  %w'time' => tt.method(:time),
         
     | 
| 
      
 31 
     | 
    
         
            +
                  %w'bit bool boolean' => tt.method(:boolean),
         
     | 
| 
      
 32 
     | 
    
         
            +
                  %w'integer smallint mediumint int bigint' => tt.method(:integer),
         
     | 
| 
      
 33 
     | 
    
         
            +
                  %w'numeric decimal money' => tt.method(:numeric),
         
     | 
| 
      
 34 
     | 
    
         
            +
                  %w'float double real dec fixed' + ['double precision'] => tt.method(:float),
         
     | 
| 
      
 35 
     | 
    
         
            +
                  %w'blob' => tt.method(:blob)
         
     | 
| 
      
 36 
     | 
    
         
            +
                }.each do |k,v|
         
     | 
| 
       27 
37 
     | 
    
         
             
                  k.each{|n| SQLITE_TYPES[n] = v}
         
     | 
| 
       28 
38 
     | 
    
         
             
                end
         
     | 
| 
       29 
39 
     | 
    
         | 
| 
       30 
40 
     | 
    
         
             
                # Database class for SQLite databases used with Sequel and the
         
     | 
| 
       31 
41 
     | 
    
         
             
                # ruby-sqlite3 driver.
         
     | 
| 
       32 
42 
     | 
    
         
             
                class Database < Sequel::Database
         
     | 
| 
       33 
     | 
    
         
            -
                  UNIX_EPOCH_TIME_FORMAT = /\A\d+\z/.freeze
         
     | 
| 
       34 
43 
     | 
    
         
             
                  include ::Sequel::SQLite::DatabaseMethods
         
     | 
| 
       35 
44 
     | 
    
         | 
| 
       36 
45 
     | 
    
         
             
                  set_adapter_scheme :sqlite
         
     | 
| 
         @@ -138,11 +147,24 @@ module Sequel 
     | 
|
| 
       138 
147 
     | 
    
         
             
                    o
         
     | 
| 
       139 
148 
     | 
    
         
             
                  end
         
     | 
| 
       140 
149 
     | 
    
         | 
| 
      
 150 
     | 
    
         
            +
                  def prepared_statement_argument(arg)
         
     | 
| 
      
 151 
     | 
    
         
            +
                    case arg
         
     | 
| 
      
 152 
     | 
    
         
            +
                    when Date, DateTime, Time, TrueClass, FalseClass
         
     | 
| 
      
 153 
     | 
    
         
            +
                      literal(arg)[1...-1]
         
     | 
| 
      
 154 
     | 
    
         
            +
                    when SQL::Blob
         
     | 
| 
      
 155 
     | 
    
         
            +
                      arg.to_blob
         
     | 
| 
      
 156 
     | 
    
         
            +
                    else
         
     | 
| 
      
 157 
     | 
    
         
            +
                      arg
         
     | 
| 
      
 158 
     | 
    
         
            +
                    end
         
     | 
| 
      
 159 
     | 
    
         
            +
                  end
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
       141 
161 
     | 
    
         
             
                  # Execute a prepared statement on the database using the given name.
         
     | 
| 
       142 
162 
     | 
    
         
             
                  def execute_prepared_statement(conn, type, name, opts, &block)
         
     | 
| 
       143 
163 
     | 
    
         
             
                    ps = prepared_statements[name]
         
     | 
| 
       144 
164 
     | 
    
         
             
                    sql = ps.prepared_sql
         
     | 
| 
       145 
165 
     | 
    
         
             
                    args = opts[:arguments]
         
     | 
| 
      
 166 
     | 
    
         
            +
                    ps_args = {}
         
     | 
| 
      
 167 
     | 
    
         
            +
                    args.each{|k, v| ps_args[k] = prepared_statement_argument(v)}
         
     | 
| 
       146 
168 
     | 
    
         
             
                    if cpsa = conn.prepared_statements[name]
         
     | 
| 
       147 
169 
     | 
    
         
             
                      cps, cps_sql = cpsa
         
     | 
| 
       148 
170 
     | 
    
         
             
                      if cps_sql != sql
         
     | 
| 
         @@ -155,9 +177,9 @@ module Sequel 
     | 
|
| 
       155 
177 
     | 
    
         
             
                      conn.prepared_statements[name] = [cps, sql]
         
     | 
| 
       156 
178 
     | 
    
         
             
                    end
         
     | 
| 
       157 
179 
     | 
    
         
             
                    if block
         
     | 
| 
       158 
     | 
    
         
            -
                      log_yield("Executing prepared statement #{name}", args){cps.execute( 
     | 
| 
      
 180 
     | 
    
         
            +
                      log_yield("Executing prepared statement #{name}", args){cps.execute(ps_args, &block)}
         
     | 
| 
       159 
181 
     | 
    
         
             
                    else
         
     | 
| 
       160 
     | 
    
         
            -
                      log_yield("Executing prepared statement #{name}", args){cps.execute!( 
     | 
| 
      
 182 
     | 
    
         
            +
                      log_yield("Executing prepared statement #{name}", args){cps.execute!(ps_args){|r|}}
         
     | 
| 
       161 
183 
     | 
    
         
             
                      case type
         
     | 
| 
       162 
184 
     | 
    
         
             
                      when :insert
         
     | 
| 
       163 
185 
     | 
    
         
             
                        conn.last_insert_row_id
         
     | 
| 
         @@ -174,6 +196,7 @@ module Sequel 
     | 
|
| 
       174 
196 
     | 
    
         | 
| 
       175 
197 
     | 
    
         
             
                  # Disconnect given connections from the database.
         
     | 
| 
       176 
198 
     | 
    
         
             
                  def disconnect_connection(c)
         
     | 
| 
      
 199 
     | 
    
         
            +
                    c.prepared_statements.each_value{|v| v.first.close}
         
     | 
| 
       177 
200 
     | 
    
         
             
                    c.close
         
     | 
| 
       178 
201 
     | 
    
         
             
                  end
         
     | 
| 
       179 
202 
     | 
    
         
             
                end
         
     | 
| 
         @@ -133,11 +133,11 @@ module Sequel 
     | 
|
| 
       133 
133 
     | 
    
         
             
                  get(1).nil?
         
     | 
| 
       134 
134 
     | 
    
         
             
                end
         
     | 
| 
       135 
135 
     | 
    
         | 
| 
       136 
     | 
    
         
            -
                # Executes a select query and fetches records,  
     | 
| 
      
 136 
     | 
    
         
            +
                # Executes a select query and fetches records, yielding each record to the
         
     | 
| 
       137 
137 
     | 
    
         
             
                # supplied block.  The yielded records should be hashes with symbol keys.
         
     | 
| 
       138 
138 
     | 
    
         
             
                # This method should probably should not be called by user code, use +each+
         
     | 
| 
       139 
139 
     | 
    
         
             
                # instead.
         
     | 
| 
       140 
     | 
    
         
            -
                def fetch_rows(sql 
     | 
| 
      
 140 
     | 
    
         
            +
                def fetch_rows(sql)
         
     | 
| 
       141 
141 
     | 
    
         
             
                  raise NotImplemented, NOTIMPL_MSG
         
     | 
| 
       142 
142 
     | 
    
         
             
                end
         
     | 
| 
       143 
143 
     | 
    
         | 
    
        data/lib/sequel/dataset/query.rb
    CHANGED
    
    | 
         @@ -418,10 +418,10 @@ module Sequel 
     | 
|
| 
       418 
418 
     | 
    
         
             
                    table_name = table_alias || table
         
     | 
| 
       419 
419 
     | 
    
         
             
                  end
         
     | 
| 
       420 
420 
     | 
    
         | 
| 
       421 
     | 
    
         
            -
                  join = if expr.nil? and ! 
     | 
| 
      
 421 
     | 
    
         
            +
                  join = if expr.nil? and !block
         
     | 
| 
       422 
422 
     | 
    
         
             
                    SQL::JoinClause.new(type, table, table_alias)
         
     | 
| 
       423 
423 
     | 
    
         
             
                  elsif using_join
         
     | 
| 
       424 
     | 
    
         
            -
                    raise(Sequel::Error, "can't use a block if providing an array of symbols as expr") if  
     | 
| 
      
 424 
     | 
    
         
            +
                    raise(Sequel::Error, "can't use a block if providing an array of symbols as expr") if block
         
     | 
| 
       425 
425 
     | 
    
         
             
                    SQL::JoinUsingClause.new(expr, type, table, table_alias)
         
     | 
| 
       426 
426 
     | 
    
         
             
                  else
         
     | 
| 
       427 
427 
     | 
    
         
             
                    last_alias ||= @opts[:last_joined_table] || first_source_alias
         
     | 
| 
         @@ -432,7 +432,7 @@ module Sequel 
     | 
|
| 
       432 
432 
     | 
    
         
             
                        [k,v]
         
     | 
| 
       433 
433 
     | 
    
         
             
                      end
         
     | 
| 
       434 
434 
     | 
    
         
             
                    end
         
     | 
| 
       435 
     | 
    
         
            -
                    if  
     | 
| 
      
 435 
     | 
    
         
            +
                    if block
         
     | 
| 
       436 
436 
     | 
    
         
             
                      expr2 = yield(table_name, last_alias, @opts[:join] || [])
         
     | 
| 
       437 
437 
     | 
    
         
             
                      expr = expr ? SQL::BooleanExpression.new(:AND, expr, expr2) : expr2
         
     | 
| 
       438 
438 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -1067,6 +1067,8 @@ module Sequel 
     | 
|
| 
       1067 
1067 
     | 
    
         
             
                      klass = opts.associated_class
         
     | 
| 
       1068 
1068 
     | 
    
         
             
                      if o.is_a?(Hash)
         
     | 
| 
       1069 
1069 
     | 
    
         
             
                        o = klass.new(o)
         
     | 
| 
      
 1070 
     | 
    
         
            +
                      elsif o.is_a?(Integer) || o.is_a?(String) || o.is_a?(Array)
         
     | 
| 
      
 1071 
     | 
    
         
            +
                        o = klass[o]
         
     | 
| 
       1070 
1072 
     | 
    
         
             
                      elsif !o.is_a?(klass)
         
     | 
| 
       1071 
1073 
     | 
    
         
             
                        raise(Sequel::Error, "associated object #{o.inspect} not of correct type #{klass}")
         
     | 
| 
       1072 
1074 
     | 
    
         
             
                      end
         
     | 
    
        data/lib/sequel/model/base.rb
    CHANGED
    
    | 
         @@ -205,7 +205,7 @@ module Sequel 
     | 
|
| 
       205 
205 
     | 
    
         
             
                  #   Artist.server!(:server1)
         
     | 
| 
       206 
206 
     | 
    
         
             
                  def def_dataset_method(*args, &block)
         
     | 
| 
       207 
207 
     | 
    
         
             
                    raise(Error, "No arguments given") if args.empty?
         
     | 
| 
       208 
     | 
    
         
            -
                    if  
     | 
| 
      
 208 
     | 
    
         
            +
                    if block
         
     | 
| 
       209 
209 
     | 
    
         
             
                      raise(Error, "Defining a dataset method using a block requires only one argument") if args.length > 1
         
     | 
| 
       210 
210 
     | 
    
         
             
                      meth = args.first
         
     | 
| 
       211 
211 
     | 
    
         
             
                      @dataset_methods[meth] = block
         
     | 
| 
         @@ -729,7 +729,7 @@ module Sequel 
     | 
|
| 
       729 
729 
     | 
    
         
             
                    # If the column isn't in @values, we can't assume it is
         
     | 
| 
       730 
730 
     | 
    
         
             
                    # NULL in the database, so assume it has changed.
         
     | 
| 
       731 
731 
     | 
    
         
             
                    v = typecast_value(column, value)
         
     | 
| 
       732 
     | 
    
         
            -
                    if new? || !@values.include?(column) || v != @values[column]
         
     | 
| 
      
 732 
     | 
    
         
            +
                    if new? || !@values.include?(column) || v != (c = @values[column]) || v.class != c.class
         
     | 
| 
       733 
733 
     | 
    
         
             
                      changed_columns << column unless changed_columns.include?(column)
         
     | 
| 
       734 
734 
     | 
    
         
             
                      @values[column] = v
         
     | 
| 
       735 
735 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -68,7 +68,7 @@ module Sequel 
     | 
|
| 
       68 
68 
     | 
    
         
             
                  # The class_table_inheritance plugin requires the lazy_attributes plugin
         
     | 
| 
       69 
69 
     | 
    
         
             
                  # to handle lazily-loaded attributes for subclass instances returned
         
     | 
| 
       70 
70 
     | 
    
         
             
                  # by superclass methods.
         
     | 
| 
       71 
     | 
    
         
            -
                  def self.apply(model, opts={} 
     | 
| 
      
 71 
     | 
    
         
            +
                  def self.apply(model, opts={})
         
     | 
| 
       72 
72 
     | 
    
         
             
                    model.plugin :lazy_attributes
         
     | 
| 
       73 
73 
     | 
    
         
             
                  end
         
     | 
| 
       74 
74 
     | 
    
         | 
| 
         @@ -81,7 +81,7 @@ module Sequel 
     | 
|
| 
       81 
81 
     | 
    
         
             
                  # * :table_map - Hash with class name symbol keys and table name symbol
         
     | 
| 
       82 
82 
     | 
    
         
             
                  #   values.  Necessary if the implicit table name for the model class
         
     | 
| 
       83 
83 
     | 
    
         
             
                  #   does not match the database table name
         
     | 
| 
       84 
     | 
    
         
            -
                  def self.configure(model, opts={} 
     | 
| 
      
 84 
     | 
    
         
            +
                  def self.configure(model, opts={})
         
     | 
| 
       85 
85 
     | 
    
         
             
                    model.instance_eval do
         
     | 
| 
       86 
86 
     | 
    
         
             
                      m = method(:constantize)
         
     | 
| 
       87 
87 
     | 
    
         
             
                      @cti_base_model = self
         
     | 
| 
         @@ -20,7 +20,7 @@ module Sequel 
     | 
|
| 
       20 
20 
     | 
    
         
             
                  module ClassMethods
         
     | 
| 
       21 
21 
     | 
    
         
             
                    # Creates table, using the column information from set_schema.
         
     | 
| 
       22 
22 
     | 
    
         
             
                    def create_table(*args, &block)
         
     | 
| 
       23 
     | 
    
         
            -
                      set_schema(*args, &block) if  
     | 
| 
      
 23 
     | 
    
         
            +
                      set_schema(*args, &block) if block
         
     | 
| 
       24 
24 
     | 
    
         
             
                      db.create_table(table_name, :generator=>@schema)
         
     | 
| 
       25 
25 
     | 
    
         
             
                      @db_schema = get_db_schema(true)
         
     | 
| 
       26 
26 
     | 
    
         
             
                      columns
         
     | 
| 
         @@ -20,7 +20,7 @@ module Sequel 
     | 
|
| 
       20 
20 
     | 
    
         
             
                # the model object, you'll get Date objects instead of strings.
         
     | 
| 
       21 
21 
     | 
    
         
             
                module TypecastOnLoad
         
     | 
| 
       22 
22 
     | 
    
         
             
                  # Call add_typecast_on_load_columns on the passed column arguments.
         
     | 
| 
       23 
     | 
    
         
            -
                  def self.configure(model, *columns 
     | 
| 
      
 23 
     | 
    
         
            +
                  def self.configure(model, *columns)
         
     | 
| 
       24 
24 
     | 
    
         
             
                    model.instance_eval do
         
     | 
| 
       25 
25 
     | 
    
         
             
                      @typecast_on_load_columns ||= []
         
     | 
| 
       26 
26 
     | 
    
         
             
                      add_typecast_on_load_columns(*columns)
         
     | 
| 
         @@ -6,7 +6,9 @@ module Sequel 
     | 
|
| 
       6 
6 
     | 
    
         
             
                # for the legacy class-level validation methods (e.g. validates_presence_of :column).
         
     | 
| 
       7 
7 
     | 
    
         
             
                #
         
     | 
| 
       8 
8 
     | 
    
         
             
                # It is recommended to use the validation_helpers plugin instead of this one,
         
     | 
| 
       9 
     | 
    
         
            -
                # as it is less complex and more flexible.
         
     | 
| 
      
 9 
     | 
    
         
            +
                # as it is less complex and more flexible.  However, this plugin provides reflection
         
     | 
| 
      
 10 
     | 
    
         
            +
                # support, since it is class-level, while the instance-level validation_helpers
         
     | 
| 
      
 11 
     | 
    
         
            +
                # plugin does not.
         
     | 
| 
       10 
12 
     | 
    
         
             
                # 
         
     | 
| 
       11 
13 
     | 
    
         
             
                # Usage:
         
     | 
| 
       12 
14 
     | 
    
         
             
                #
         
     | 
| 
         @@ -21,14 +23,21 @@ module Sequel 
     | 
|
| 
       21 
23 
     | 
    
         
             
                    model.class_eval do
         
     | 
| 
       22 
24 
     | 
    
         
             
                      @validation_mutex = Mutex.new
         
     | 
| 
       23 
25 
     | 
    
         
             
                      @validations = {}
         
     | 
| 
      
 26 
     | 
    
         
            +
                      @validation_reflections = {}
         
     | 
| 
       24 
27 
     | 
    
         
             
                    end
         
     | 
| 
       25 
28 
     | 
    
         
             
                  end
         
     | 
| 
       26 
29 
     | 
    
         | 
| 
       27 
30 
     | 
    
         
             
                  module ClassMethods
         
     | 
| 
       28 
     | 
    
         
            -
                    # A hash of  
     | 
| 
      
 31 
     | 
    
         
            +
                    # A hash of validations for this model class.  Keys are column symbols,
         
     | 
| 
       29 
32 
     | 
    
         
             
                    # values are arrays of validation procs.
         
     | 
| 
       30 
33 
     | 
    
         
             
                    attr_reader :validations
         
     | 
| 
       31 
34 
     | 
    
         | 
| 
      
 35 
     | 
    
         
            +
                    # A hash of validation reflections for this model class.  Keys are column
         
     | 
| 
      
 36 
     | 
    
         
            +
                    # symbols, values are an array of two element arrays, with the first element
         
     | 
| 
      
 37 
     | 
    
         
            +
                    # being the validation type symbol and the second being a hash of validation
         
     | 
| 
      
 38 
     | 
    
         
            +
                    # options.
         
     | 
| 
      
 39 
     | 
    
         
            +
                    attr_reader :validation_reflections
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
       32 
41 
     | 
    
         
             
                    # The Generator class is used to generate validation definitions using 
         
     | 
| 
       33 
42 
     | 
    
         
             
                    # the validates {} idiom.
         
     | 
| 
       34 
43 
     | 
    
         
             
                    class Generator
         
     | 
| 
         @@ -49,12 +58,16 @@ module Sequel 
     | 
|
| 
       49 
58 
     | 
    
         
             
                      !validations.empty?
         
     | 
| 
       50 
59 
     | 
    
         
             
                    end
         
     | 
| 
       51 
60 
     | 
    
         | 
| 
       52 
     | 
    
         
            -
                    # Setup the validations hash in the subclass
         
     | 
| 
      
 61 
     | 
    
         
            +
                    # Setup the validations and validation_reflections hash in the subclass.
         
     | 
| 
       53 
62 
     | 
    
         
             
                    def inherited(subclass)
         
     | 
| 
       54 
63 
     | 
    
         
             
                      super
         
     | 
| 
      
 64 
     | 
    
         
            +
                      vr = @validation_reflections
         
     | 
| 
       55 
65 
     | 
    
         
             
                      subclass.class_eval do
         
     | 
| 
       56 
66 
     | 
    
         
             
                        @validation_mutex = Mutex.new
         
     | 
| 
       57 
67 
     | 
    
         
             
                        @validations = {}
         
     | 
| 
      
 68 
     | 
    
         
            +
                        h = {}
         
     | 
| 
      
 69 
     | 
    
         
            +
                        vr.each{|k,v| h[k] = v.dup}
         
     | 
| 
      
 70 
     | 
    
         
            +
                        @validation_reflections = h
         
     | 
| 
       58 
71 
     | 
    
         
             
                      end
         
     | 
| 
       59 
72 
     | 
    
         
             
                    end
         
     | 
| 
       60 
73 
     | 
    
         | 
| 
         @@ -115,6 +128,7 @@ module Sequel 
     | 
|
| 
       115 
128 
     | 
    
         
             
                        :accept => '1',
         
     | 
| 
       116 
129 
     | 
    
         
             
                        :tag => :acceptance,
         
     | 
| 
       117 
130 
     | 
    
         
             
                      }.merge!(extract_options!(atts))
         
     | 
| 
      
 131 
     | 
    
         
            +
                      reflect_validation(:acceptance, opts, atts)
         
     | 
| 
       118 
132 
     | 
    
         
             
                      atts << opts
         
     | 
| 
       119 
133 
     | 
    
         
             
                      validates_each(*atts) do |o, a, v|
         
     | 
| 
       120 
134 
     | 
    
         
             
                        o.errors.add(a, opts[:message]) unless v == opts[:accept]
         
     | 
| 
         @@ -136,6 +150,7 @@ module Sequel 
     | 
|
| 
       136 
150 
     | 
    
         
             
                        :message => 'is not confirmed',
         
     | 
| 
       137 
151 
     | 
    
         
             
                        :tag => :confirmation,
         
     | 
| 
       138 
152 
     | 
    
         
             
                      }.merge!(extract_options!(atts))
         
     | 
| 
      
 153 
     | 
    
         
            +
                      reflect_validation(:confirmation, opts, atts)
         
     | 
| 
       139 
154 
     | 
    
         
             
                      atts << opts
         
     | 
| 
       140 
155 
     | 
    
         
             
                      validates_each(*atts) do |o, a, v|
         
     | 
| 
       141 
156 
     | 
    
         
             
                        o.errors.add(a, opts[:message]) unless v == o.send(:"#{a}_confirmation")
         
     | 
| 
         @@ -205,6 +220,7 @@ module Sequel 
     | 
|
| 
       205 
220 
     | 
    
         
             
                        raise ArgumentError, "A regular expression must be supplied as the :with option of the options hash"
         
     | 
| 
       206 
221 
     | 
    
         
             
                      end
         
     | 
| 
       207 
222 
     | 
    
         | 
| 
      
 223 
     | 
    
         
            +
                      reflect_validation(:format, opts, atts)
         
     | 
| 
       208 
224 
     | 
    
         
             
                      atts << opts
         
     | 
| 
       209 
225 
     | 
    
         
             
                      validates_each(*atts) do |o, a, v|
         
     | 
| 
       210 
226 
     | 
    
         
             
                        o.errors.add(a, opts[:message]) unless v.to_s =~ opts[:with]
         
     | 
| 
         @@ -231,6 +247,7 @@ module Sequel 
     | 
|
| 
       231 
247 
     | 
    
         
             
                      }.merge!(extract_options!(atts))
         
     | 
| 
       232 
248 
     | 
    
         | 
| 
       233 
249 
     | 
    
         
             
                      opts[:tag] ||= ([:length] + [:maximum, :minimum, :is, :within].reject{|x| !opts.include?(x)}).join('-').to_sym
         
     | 
| 
      
 250 
     | 
    
         
            +
                      reflect_validation(:length, opts, atts)
         
     | 
| 
       234 
251 
     | 
    
         
             
                      atts << opts
         
     | 
| 
       235 
252 
     | 
    
         
             
                      validates_each(*atts) do |o, a, v|
         
     | 
| 
       236 
253 
     | 
    
         
             
                        if m = opts[:maximum]
         
     | 
| 
         @@ -261,6 +278,7 @@ module Sequel 
     | 
|
| 
       261 
278 
     | 
    
         
             
                      opts = {
         
     | 
| 
       262 
279 
     | 
    
         
             
                        :tag => :not_string,
         
     | 
| 
       263 
280 
     | 
    
         
             
                      }.merge!(extract_options!(atts))
         
     | 
| 
      
 281 
     | 
    
         
            +
                      reflect_validation(:not_string, opts, atts)
         
     | 
| 
       264 
282 
     | 
    
         
             
                      atts << opts
         
     | 
| 
       265 
283 
     | 
    
         
             
                      validates_each(*atts) do |o, a, v|
         
     | 
| 
       266 
284 
     | 
    
         
             
                        if v.is_a?(String)
         
     | 
| 
         @@ -286,6 +304,7 @@ module Sequel 
     | 
|
| 
       286 
304 
     | 
    
         
             
                        :message => 'is not a number',
         
     | 
| 
       287 
305 
     | 
    
         
             
                        :tag => :numericality,
         
     | 
| 
       288 
306 
     | 
    
         
             
                      }.merge!(extract_options!(atts))
         
     | 
| 
      
 307 
     | 
    
         
            +
                      reflect_validation(:numericality, opts, atts)
         
     | 
| 
       289 
308 
     | 
    
         
             
                      atts << opts
         
     | 
| 
       290 
309 
     | 
    
         
             
                      validates_each(*atts) do |o, a, v|
         
     | 
| 
       291 
310 
     | 
    
         
             
                        begin
         
     | 
| 
         @@ -310,6 +329,7 @@ module Sequel 
     | 
|
| 
       310 
329 
     | 
    
         
             
                        :message => 'is not present',
         
     | 
| 
       311 
330 
     | 
    
         
             
                        :tag => :presence,
         
     | 
| 
       312 
331 
     | 
    
         
             
                      }.merge!(extract_options!(atts))
         
     | 
| 
      
 332 
     | 
    
         
            +
                      reflect_validation(:presence, opts, atts)
         
     | 
| 
       313 
333 
     | 
    
         
             
                      atts << opts
         
     | 
| 
       314 
334 
     | 
    
         
             
                      validates_each(*atts) do |o, a, v|
         
     | 
| 
       315 
335 
     | 
    
         
             
                        o.errors.add(a, opts[:message]) if v.blank? && v != false
         
     | 
| 
         @@ -327,6 +347,7 @@ module Sequel 
     | 
|
| 
       327 
347 
     | 
    
         
             
                        raise ArgumentError, "The :in parameter is required, and respond to include?"
         
     | 
| 
       328 
348 
     | 
    
         
             
                      end
         
     | 
| 
       329 
349 
     | 
    
         
             
                      opts[:message] ||= "is not in range or set: #{opts[:in].inspect}"
         
     | 
| 
      
 350 
     | 
    
         
            +
                      reflect_validation(:inclusion, opts, atts)
         
     | 
| 
       330 
351 
     | 
    
         
             
                      atts << opts
         
     | 
| 
       331 
352 
     | 
    
         
             
                      validates_each(*atts) do |o, a, v|
         
     | 
| 
       332 
353 
     | 
    
         
             
                        o.errors.add(a, opts[:message]) unless opts[:in].include?(v)
         
     | 
| 
         @@ -355,6 +376,7 @@ module Sequel 
     | 
|
| 
       355 
376 
     | 
    
         
             
                        :tag => :uniqueness,
         
     | 
| 
       356 
377 
     | 
    
         
             
                      }.merge!(extract_options!(atts))
         
     | 
| 
       357 
378 
     | 
    
         | 
| 
      
 379 
     | 
    
         
            +
                      reflect_validation(:uniqueness, opts, atts)
         
     | 
| 
       358 
380 
     | 
    
         
             
                      atts << opts
         
     | 
| 
       359 
381 
     | 
    
         
             
                      validates_each(*atts) do |o, a, v|
         
     | 
| 
       360 
382 
     | 
    
         
             
                        error_field = a
         
     | 
| 
         @@ -391,6 +413,13 @@ module Sequel 
     | 
|
| 
       391 
413 
     | 
    
         
             
                      array.last.is_a?(Hash) ? array.pop : {}
         
     | 
| 
       392 
414 
     | 
    
         
             
                    end
         
     | 
| 
       393 
415 
     | 
    
         | 
| 
      
 416 
     | 
    
         
            +
                    # Add the validation reflection to the class's validations.
         
     | 
| 
      
 417 
     | 
    
         
            +
                    def reflect_validation(type, opts, atts)
         
     | 
| 
      
 418 
     | 
    
         
            +
                      atts.each do |att|
         
     | 
| 
      
 419 
     | 
    
         
            +
                        (validation_reflections[att] ||= []) << [type, opts]
         
     | 
| 
      
 420 
     | 
    
         
            +
                      end
         
     | 
| 
      
 421 
     | 
    
         
            +
                    end
         
     | 
| 
      
 422 
     | 
    
         
            +
             
     | 
| 
       394 
423 
     | 
    
         
             
                    # Handle the :if option for validations
         
     | 
| 
       395 
424 
     | 
    
         
             
                    def validation_if_proc(o, i)
         
     | 
| 
       396 
425 
     | 
    
         
             
                      case i
         
     | 
    
        data/lib/sequel/version.rb
    CHANGED
    
    | 
         @@ -3,7 +3,7 @@ module Sequel 
     | 
|
| 
       3 
3 
     | 
    
         
             
              MAJOR = 3
         
     | 
| 
       4 
4 
     | 
    
         
             
              # The minor version of Sequel.  Bumped for every non-patch level
         
     | 
| 
       5 
5 
     | 
    
         
             
              # release, generally around once a month.
         
     | 
| 
       6 
     | 
    
         
            -
              MINOR =  
     | 
| 
      
 6 
     | 
    
         
            +
              MINOR = 19
         
     | 
| 
       7 
7 
     | 
    
         
             
              # The tiny version of Sequel.  Usually 0, only bumped for bugfix
         
     | 
| 
       8 
8 
     | 
    
         
             
              # releases that fix regressions from previous versions.
         
     | 
| 
       9 
9 
     | 
    
         
             
              TINY  = 0
         
     | 
| 
         @@ -9,11 +9,30 @@ describe Sequel::Model do 
     | 
|
| 
       9 
9 
     | 
    
         
             
                end
         
     | 
| 
       10 
10 
     | 
    
         
             
              end
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
              specify "should respond to  
     | 
| 
      
 12 
     | 
    
         
            +
              specify "should respond to validations, has_validations?, and validation_reflections" do
         
     | 
| 
       13 
13 
     | 
    
         
             
                @c.should respond_to(:validations)
         
     | 
| 
       14 
14 
     | 
    
         
             
                @c.should respond_to(:has_validations?)
         
     | 
| 
      
 15 
     | 
    
         
            +
                @c.should respond_to(:validation_reflections)
         
     | 
| 
       15 
16 
     | 
    
         
             
              end
         
     | 
| 
       16 
17 
     | 
    
         | 
| 
      
 18 
     | 
    
         
            +
              specify "should be able to reflect on validations" do
         
     | 
| 
      
 19 
     | 
    
         
            +
                @c.validation_reflections.should == {}
         
     | 
| 
      
 20 
     | 
    
         
            +
                @c.validates_acceptance_of(:a)
         
     | 
| 
      
 21 
     | 
    
         
            +
                @c.validation_reflections.should == {:a=>[[:acceptance, {:tag=>:acceptance, :message=>"is not accepted", :allow_nil=>true, :accept=>"1"}]]}
         
     | 
| 
      
 22 
     | 
    
         
            +
                @c.validates_presence_of(:a)
         
     | 
| 
      
 23 
     | 
    
         
            +
                @c.validation_reflections[:a].length.should == 2
         
     | 
| 
      
 24 
     | 
    
         
            +
                @c.validation_reflections[:a].last.should == [:presence, {:tag=>:presence, :message=>"is not present"}]
         
     | 
| 
      
 25 
     | 
    
         
            +
              end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
              specify "should handle validation reflections correctly when subclassing" do
         
     | 
| 
      
 28 
     | 
    
         
            +
                @c.validates_acceptance_of(:a)
         
     | 
| 
      
 29 
     | 
    
         
            +
                c = Class.new(@c)
         
     | 
| 
      
 30 
     | 
    
         
            +
                c.validation_reflections.map{|k,v| k}.should == [:a]
         
     | 
| 
      
 31 
     | 
    
         
            +
                c.validates_presence_of(:a)
         
     | 
| 
      
 32 
     | 
    
         
            +
                @c.validation_reflections.should == {:a=>[[:acceptance, {:tag=>:acceptance, :message=>"is not accepted", :allow_nil=>true, :accept=>"1"}]]}
         
     | 
| 
      
 33 
     | 
    
         
            +
                c.validation_reflections[:a].last.should == [:presence, {:tag=>:presence, :message=>"is not present"}]
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
       17 
36 
     | 
    
         
             
              specify "should acccept validation definitions using validates_each" do
         
     | 
| 
       18 
37 
     | 
    
         
             
                @c.validates_each(:xx, :yy) {|o, a, v| o.errors[a] << 'too low' if v < 50}
         
     | 
| 
       19 
38 
     | 
    
         
             
                o = @c.new
         
     | 
| 
         @@ -196,6 +196,16 @@ describe "Sequel::Model Simple Associations" do 
     | 
|
| 
       196 
196 
     | 
    
         
             
                @album.tags_dataset.first[:name].should == 'T2'
         
     | 
| 
       197 
197 
     | 
    
         
             
              end
         
     | 
| 
       198 
198 
     | 
    
         | 
| 
      
 199 
     | 
    
         
            +
              specify "should have add method accept primary key and add related records" do
         
     | 
| 
      
 200 
     | 
    
         
            +
                @artist.remove_all_albums
         
     | 
| 
      
 201 
     | 
    
         
            +
                @artist.add_album(@album.id)
         
     | 
| 
      
 202 
     | 
    
         
            +
                @artist.albums_dataset.first[:id].should == @album.id
         
     | 
| 
      
 203 
     | 
    
         
            +
             
     | 
| 
      
 204 
     | 
    
         
            +
                @album.remove_all_tags
         
     | 
| 
      
 205 
     | 
    
         
            +
                @album.add_tag(@tag.id)
         
     | 
| 
      
 206 
     | 
    
         
            +
                @album.tags_dataset.first[:id].should == @tag.id
         
     | 
| 
      
 207 
     | 
    
         
            +
              end
         
     | 
| 
      
 208 
     | 
    
         
            +
              
         
     | 
| 
       199 
209 
     | 
    
         
             
              specify "should have remove method accept primary key and remove related album" do
         
     | 
| 
       200 
210 
     | 
    
         
             
                @artist.add_album(@album)
         
     | 
| 
       201 
211 
     | 
    
         
             
                @artist.reload.remove_album(@album.id)
         
     | 
| 
         @@ -287,6 +297,16 @@ describe "Sequel::Model Composite Key Associations" do 
     | 
|
| 
       287 
297 
     | 
    
         
             
                @album.tags_dataset.first[:name].should == 'T2'
         
     | 
| 
       288 
298 
     | 
    
         
             
              end
         
     | 
| 
       289 
299 
     | 
    
         | 
| 
      
 300 
     | 
    
         
            +
              specify "should have add method accept primary key and add related records" do
         
     | 
| 
      
 301 
     | 
    
         
            +
                @artist.remove_all_albums
         
     | 
| 
      
 302 
     | 
    
         
            +
                @artist.add_album([@album.id1, @album.id2])
         
     | 
| 
      
 303 
     | 
    
         
            +
                @artist.albums_dataset.first.pk.should == [@album.id1, @album.id2]
         
     | 
| 
      
 304 
     | 
    
         
            +
                
         
     | 
| 
      
 305 
     | 
    
         
            +
                @album.remove_all_tags
         
     | 
| 
      
 306 
     | 
    
         
            +
                @album.add_tag([@tag.id1, @tag.id2])
         
     | 
| 
      
 307 
     | 
    
         
            +
                @album.tags_dataset.first.pk.should == [@tag.id1, @tag.id2]
         
     | 
| 
      
 308 
     | 
    
         
            +
              end
         
     | 
| 
      
 309 
     | 
    
         
            +
              
         
     | 
| 
       290 
310 
     | 
    
         
             
              specify "should have remove method accept primary key and remove related album" do
         
     | 
| 
       291 
311 
     | 
    
         
             
                @artist.add_album(@album)
         
     | 
| 
       292 
312 
     | 
    
         
             
                @artist.reload.remove_album([@album.id1, @album.id2])
         
     | 
| 
         @@ -8,6 +8,12 @@ describe Sequel::Database do 
     | 
|
| 
       8 
8 
     | 
    
         
             
                INTEGRATION_DB.pool.size.should == 0
         
     | 
| 
       9 
9 
     | 
    
         
             
              end
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
      
 11 
     | 
    
         
            +
              specify "should provide disconnect functionality after preparing a connection" do
         
     | 
| 
      
 12 
     | 
    
         
            +
                INTEGRATION_DB['SELECT 1'].prepare(:first, :a).call
         
     | 
| 
      
 13 
     | 
    
         
            +
                INTEGRATION_DB.disconnect
         
     | 
| 
      
 14 
     | 
    
         
            +
                INTEGRATION_DB.pool.size.should == 0
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
       11 
17 
     | 
    
         
             
              specify "should raise Sequel::DatabaseError on invalid SQL" do
         
     | 
| 
       12 
18 
     | 
    
         
             
                proc{INTEGRATION_DB << "SELECT"}.should raise_error(Sequel::DatabaseError)
         
     | 
| 
       13 
19 
     | 
    
         
             
              end
         
     | 
| 
         @@ -12,7 +12,6 @@ describe "Prepared Statements and Bound Arguments" do 
     | 
|
| 
       12 
12 
     | 
    
         
             
                @ds.meta_def(:ba) do |sym|
         
     | 
| 
       13 
13 
     | 
    
         
             
                  prepared_arg_placeholder == '$' ? :"#{sym}__int" : sym
         
     | 
| 
       14 
14 
     | 
    
         
             
                end
         
     | 
| 
       15 
     | 
    
         
            -
                clear_sqls
         
     | 
| 
       16 
15 
     | 
    
         
             
              end
         
     | 
| 
       17 
16 
     | 
    
         
             
              after do
         
     | 
| 
       18 
17 
     | 
    
         
             
                INTEGRATION_DB.drop_table(:items)
         
     | 
| 
         @@ -211,3 +210,61 @@ describe "Prepared Statements and Bound Arguments" do 
     | 
|
| 
       211 
210 
     | 
    
         
             
                end
         
     | 
| 
       212 
211 
     | 
    
         
             
              end
         
     | 
| 
       213 
212 
     | 
    
         
             
            end
         
     | 
| 
      
 213 
     | 
    
         
            +
             
     | 
| 
      
 214 
     | 
    
         
            +
            describe "Bound Argument Types" do
         
     | 
| 
      
 215 
     | 
    
         
            +
              before do
         
     | 
| 
      
 216 
     | 
    
         
            +
                INTEGRATION_DB.create_table!(:items) do
         
     | 
| 
      
 217 
     | 
    
         
            +
                  primary_key :id
         
     | 
| 
      
 218 
     | 
    
         
            +
                  Date :d
         
     | 
| 
      
 219 
     | 
    
         
            +
                  DateTime :dt
         
     | 
| 
      
 220 
     | 
    
         
            +
                  File :file
         
     | 
| 
      
 221 
     | 
    
         
            +
                  String :s
         
     | 
| 
      
 222 
     | 
    
         
            +
                  Time :t
         
     | 
| 
      
 223 
     | 
    
         
            +
                  Float :f
         
     | 
| 
      
 224 
     | 
    
         
            +
                  TrueClass :b
         
     | 
| 
      
 225 
     | 
    
         
            +
                end
         
     | 
| 
      
 226 
     | 
    
         
            +
                @ds = INTEGRATION_DB[:items]
         
     | 
| 
      
 227 
     | 
    
         
            +
                @vs = {:d=>Date.civil(2010, 10, 11), :dt=>DateTime.civil(2010, 10, 12, 13, 14, 15), :f=>1.0, :s=>'str', :t=>Time.at(20101010), :file=>Sequel::SQL::Blob.new('blob'), :b=>true}
         
     | 
| 
      
 228 
     | 
    
         
            +
                @ds.insert(@vs)
         
     | 
| 
      
 229 
     | 
    
         
            +
                @ds.meta_def(:ba) do |sym, type|
         
     | 
| 
      
 230 
     | 
    
         
            +
                  prepared_arg_placeholder == '$' ? :"#{sym}__#{type}" : sym
         
     | 
| 
      
 231 
     | 
    
         
            +
                end
         
     | 
| 
      
 232 
     | 
    
         
            +
              end
         
     | 
| 
      
 233 
     | 
    
         
            +
              after do
         
     | 
| 
      
 234 
     | 
    
         
            +
                Sequel.datetime_class = Time
         
     | 
| 
      
 235 
     | 
    
         
            +
                if INTEGRATION_DB.adapter_scheme == :jdbc && INTEGRATION_DB.database_type == :sqlite
         
     | 
| 
      
 236 
     | 
    
         
            +
                  INTEGRATION_DB.synchronize{|c| c.prepared_statements.each{|k, ps| ps[1].close}.clear}
         
     | 
| 
      
 237 
     | 
    
         
            +
                end
         
     | 
| 
      
 238 
     | 
    
         
            +
                INTEGRATION_DB.drop_table(:items)
         
     | 
| 
      
 239 
     | 
    
         
            +
              end
         
     | 
| 
      
 240 
     | 
    
         
            +
             
     | 
| 
      
 241 
     | 
    
         
            +
              cspecify "should handle date type", [:do, :sqlite], :mssql, [:jdbc, :sqlite] do 
         
     | 
| 
      
 242 
     | 
    
         
            +
                @ds.filter(:d=>@ds.ba(:$x, :date)).prepare(:first, :ps_date).call(:x=>@vs[:d])[:d].should == @vs[:d]
         
     | 
| 
      
 243 
     | 
    
         
            +
              end
         
     | 
| 
      
 244 
     | 
    
         
            +
             
     | 
| 
      
 245 
     | 
    
         
            +
              cspecify "should handle datetime type", [:do], [:mysql2], [:swift], [:jdbc, :sqlite] do
         
     | 
| 
      
 246 
     | 
    
         
            +
                Sequel.datetime_class = DateTime
         
     | 
| 
      
 247 
     | 
    
         
            +
                @ds.filter(:dt=>@ds.ba(:$x, :timestamp)).prepare(:first, :ps_datetime).call(:x=>@vs[:dt])[:dt].should == @vs[:dt]
         
     | 
| 
      
 248 
     | 
    
         
            +
              end
         
     | 
| 
      
 249 
     | 
    
         
            +
             
     | 
| 
      
 250 
     | 
    
         
            +
              cspecify "should handle time type", [:do], [:jdbc, :sqlite] do
         
     | 
| 
      
 251 
     | 
    
         
            +
                @ds.filter(:t=>@ds.ba(:$x, :timestamp)).prepare(:first, :ps_time).call(:x=>@vs[:t])[:t].should == @vs[:t]
         
     | 
| 
      
 252 
     | 
    
         
            +
              end
         
     | 
| 
      
 253 
     | 
    
         
            +
             
     | 
| 
      
 254 
     | 
    
         
            +
              cspecify "should handle blob type", [:swift], [:jdbc, :postgres] do
         
     | 
| 
      
 255 
     | 
    
         
            +
                @ds.filter(:file=>@ds.ba(:$x, :bytea)).prepare(:first, :ps_blob).call(:x=>@vs[:file])[:file].should == @vs[:file]
         
     | 
| 
      
 256 
     | 
    
         
            +
              end
         
     | 
| 
      
 257 
     | 
    
         
            +
             
     | 
| 
      
 258 
     | 
    
         
            +
              specify "should handle float type" do
         
     | 
| 
      
 259 
     | 
    
         
            +
                @ds.filter(:f=>@ds.ba(:$x, :"double precision")).prepare(:first, :ps_float).call(:x=>@vs[:f])[:f].should == @vs[:f]
         
     | 
| 
      
 260 
     | 
    
         
            +
              end
         
     | 
| 
      
 261 
     | 
    
         
            +
             
     | 
| 
      
 262 
     | 
    
         
            +
              specify "should handle string type" do
         
     | 
| 
      
 263 
     | 
    
         
            +
                @ds.filter(:s=>@ds.ba(:$x, :text)).prepare(:first, :ps_string).call(:x=>@vs[:s])[:s].should == @vs[:s]
         
     | 
| 
      
 264 
     | 
    
         
            +
              end
         
     | 
| 
      
 265 
     | 
    
         
            +
             
     | 
| 
      
 266 
     | 
    
         
            +
              cspecify "should handle boolean type", [:do, :sqlite], [:odbc, :mssql], [:jdbc, :sqlite]  do
         
     | 
| 
      
 267 
     | 
    
         
            +
                @ds.filter(:b=>@ds.ba(:$x, :boolean)).prepare(:first, :ps_string).call(:x=>@vs[:b])[:b].should == @vs[:b]
         
     | 
| 
      
 268 
     | 
    
         
            +
              end
         
     | 
| 
      
 269 
     | 
    
         
            +
            end unless INTEGRATION_DB.adapter_scheme == :swift && INTEGRATION_DB.database_type == :postgres
         
     | 
| 
      
 270 
     | 
    
         
            +
             
     | 
| 
         @@ -9,10 +9,10 @@ describe "Database schema parser" do 
     | 
|
| 
       9 
9 
     | 
    
         
             
                clear_sqls
         
     | 
| 
       10 
10 
     | 
    
         
             
              end
         
     | 
| 
       11 
11 
     | 
    
         
             
              after do
         
     | 
| 
       12 
     | 
    
         
            -
                INTEGRATION_DB.drop_table(:items) if INTEGRATION_DB.table_exists?(:items)
         
     | 
| 
       13 
12 
     | 
    
         
             
                INTEGRATION_DB.identifier_output_method = @iom
         
     | 
| 
       14 
13 
     | 
    
         
             
                INTEGRATION_DB.identifier_input_method = @iim
         
     | 
| 
       15 
14 
     | 
    
         
             
                INTEGRATION_DB.default_schema = @defsch
         
     | 
| 
      
 15 
     | 
    
         
            +
                INTEGRATION_DB.drop_table(:items) if INTEGRATION_DB.table_exists?(:items)
         
     | 
| 
       16 
16 
     | 
    
         
             
              end
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
       18 
18 
     | 
    
         
             
              specify "should handle a database with a identifier_output_method" do
         
     | 
| 
         @@ -79,7 +79,7 @@ describe "Supported types" do 
     | 
|
| 
       79 
79 
     | 
    
         
             
                ds.first[:tim].strftime('%Y%m%d%H%M%S').should == t.strftime('%Y%m%d%H%M%S')
         
     | 
| 
       80 
80 
     | 
    
         
             
              end
         
     | 
| 
       81 
81 
     | 
    
         | 
| 
       82 
     | 
    
         
            -
              cspecify "should support generic file type", [:do], [:odbc, :mssql], [:mysql2], [:swift] do
         
     | 
| 
      
 82 
     | 
    
         
            +
              cspecify "should support generic file type", [:do], [:odbc, :mssql], [:mysql2], [:swift], [:jdbc, :postgres] do
         
     | 
| 
       83 
83 
     | 
    
         
             
                ds = create_items_table_with_column(:name, File)
         
     | 
| 
       84 
84 
     | 
    
         
             
                ds.insert(:name => ("a\0"*300).to_sequel_blob)
         
     | 
| 
       85 
85 
     | 
    
         
             
                ds.all.should == [{:name=>("a\0"*300).to_sequel_blob}]
         
     | 
| 
         @@ -1077,7 +1077,11 @@ describe Sequel::Model, "one_to_many" do 
     | 
|
| 
       1077 
1077 
     | 
    
         
             
                @c1 = Class.new(Sequel::Model(:attributes)) do
         
     | 
| 
       1078 
1078 
     | 
    
         
             
                  def _refresh(ds); end
         
     | 
| 
       1079 
1079 
     | 
    
         
             
                  unrestrict_primary_key
         
     | 
| 
       1080 
     | 
    
         
            -
                  columns :id, :node_id, :y
         
     | 
| 
      
 1080 
     | 
    
         
            +
                  columns :id, :node_id, :y, :z
         
     | 
| 
      
 1081 
     | 
    
         
            +
             
     | 
| 
      
 1082 
     | 
    
         
            +
                  def self.[](id)
         
     | 
| 
      
 1083 
     | 
    
         
            +
                    load(id.is_a?(Array) ? {:id => id[0], :z => id[1]} : {:id => id})
         
     | 
| 
      
 1084 
     | 
    
         
            +
                  end
         
     | 
| 
       1081 
1085 
     | 
    
         
             
                end
         
     | 
| 
       1082 
1086 
     | 
    
         | 
| 
       1083 
1087 
     | 
    
         
             
                @c2 = Class.new(Sequel::Model(:nodes)) do
         
     | 
| 
         @@ -1228,6 +1232,14 @@ describe Sequel::Model, "one_to_many" do 
     | 
|
| 
       1228 
1232 
     | 
    
         
             
                MODEL_DB.sqls.first.should =~ /INSERT INTO attributes \((node_)?id, (node_)?id\) VALUES \(1?234, 1?234\)/
         
     | 
| 
       1229 
1233 
     | 
    
         
             
              end
         
     | 
| 
       1230 
1234 
     | 
    
         | 
| 
      
 1235 
     | 
    
         
            +
              it "should accept a primary key for the add_ method" do
         
     | 
| 
      
 1236 
     | 
    
         
            +
                @c2.one_to_many :attributes, :class => @c1
         
     | 
| 
      
 1237 
     | 
    
         
            +
                n = @c2.new(:id => 1234)
         
     | 
| 
      
 1238 
     | 
    
         
            +
                MODEL_DB.reset
         
     | 
| 
      
 1239 
     | 
    
         
            +
                @c1.load(:node_id => 1234, :id => 234).should == n.add_attribute(234)
         
     | 
| 
      
 1240 
     | 
    
         
            +
                MODEL_DB.sqls.first.should == "UPDATE attributes SET node_id = 1234 WHERE (id = 234)"
         
     | 
| 
      
 1241 
     | 
    
         
            +
              end
         
     | 
| 
      
 1242 
     | 
    
         
            +
             
     | 
| 
       1231 
1243 
     | 
    
         
             
              it "should raise an error in the add_ method if the passed associated object is not of the correct type" do
         
     | 
| 
       1232 
1244 
     | 
    
         
             
                @c2.one_to_many :attributes, :class => @c1
         
     | 
| 
       1233 
1245 
     | 
    
         
             
                proc{@c2.new(:id => 1234).add_attribute(@c2.new)}.should raise_error(Sequel::Error)
         
     | 
| 
         @@ -1286,6 +1298,16 @@ describe Sequel::Model, "one_to_many" do 
     | 
|
| 
       1286 
1298 
     | 
    
         
             
                a.should == n.add_attribute(a)
         
     | 
| 
       1287 
1299 
     | 
    
         
             
                MODEL_DB.sqls.first.should =~ /UPDATE attributes SET (node_id = 1234|y = 5), (node_id = 1234|y = 5) WHERE \(id = 2345\)/
         
     | 
| 
       1288 
1300 
     | 
    
         
             
              end
         
     | 
| 
      
 1301 
     | 
    
         
            +
             
     | 
| 
      
 1302 
     | 
    
         
            +
              it "should have add_ method accept a composite key" do
         
     | 
| 
      
 1303 
     | 
    
         
            +
                @c1.set_primary_key :id, :z
         
     | 
| 
      
 1304 
     | 
    
         
            +
                @c2.one_to_many :attributes, :class => @c1, :key =>[:node_id, :y], :primary_key=>[:id, :x]
         
     | 
| 
      
 1305 
     | 
    
         
            +
                
         
     | 
| 
      
 1306 
     | 
    
         
            +
                n = @c2.load(:id => 1234, :x=>5)
         
     | 
| 
      
 1307 
     | 
    
         
            +
                a = @c1.load(:id => 2345, :z => 8, :node_id => 1234, :y=>5)
         
     | 
| 
      
 1308 
     | 
    
         
            +
                a.should == n.add_attribute([2345, 8])
         
     | 
| 
      
 1309 
     | 
    
         
            +
                MODEL_DB.sqls.first.should =~ /UPDATE attributes SET (node_id|y) = (1234|5), (node_id|y) = (1234|5) WHERE \(\((id|z) = (2345|8)\) AND \((id|z) = (2345|8)\)\)/
         
     | 
| 
      
 1310 
     | 
    
         
            +
              end
         
     | 
| 
       1289 
1311 
     | 
    
         | 
| 
       1290 
1312 
     | 
    
         
             
              it "should have remove_ method respect composite keys" do
         
     | 
| 
       1291 
1313 
     | 
    
         
             
                @c2.one_to_many :attributes, :class => @c1, :key =>[:node_id, :y], :primary_key=>[:id, :x]
         
     | 
| 
         @@ -1834,9 +1856,12 @@ describe Sequel::Model, "many_to_many" do 
     | 
|
| 
       1834 
1856 
     | 
    
         
             
                  def self.to_s; 'Attribute'; end
         
     | 
| 
       1835 
1857 
     | 
    
         
             
                  columns :id, :y
         
     | 
| 
       1836 
1858 
     | 
    
         
             
                  def _refresh(ds)
         
     | 
| 
       1837 
     | 
    
         
            -
                    self.id = 1
         
     | 
| 
       1838 
1859 
     | 
    
         
             
                    self
         
     | 
| 
       1839 
1860 
     | 
    
         
             
                  end
         
     | 
| 
      
 1861 
     | 
    
         
            +
                  
         
     | 
| 
      
 1862 
     | 
    
         
            +
                  def self.[](id)
         
     | 
| 
      
 1863 
     | 
    
         
            +
                    load(id.is_a?(Array) ? {:id => id[0], :y => id[1]} : {:id => id})
         
     | 
| 
      
 1864 
     | 
    
         
            +
                  end
         
     | 
| 
       1840 
1865 
     | 
    
         
             
                end
         
     | 
| 
       1841 
1866 
     | 
    
         | 
| 
       1842 
1867 
     | 
    
         
             
                @c2 = Class.new(Sequel::Model(:nodes)) do
         
     | 
| 
         @@ -2063,6 +2088,17 @@ describe Sequel::Model, "many_to_many" do 
     | 
|
| 
       2063 
2088 
     | 
    
         
             
                ].should(include(MODEL_DB.sqls.first))
         
     | 
| 
       2064 
2089 
     | 
    
         
             
              end
         
     | 
| 
       2065 
2090 
     | 
    
         | 
| 
      
 2091 
     | 
    
         
            +
              it "should define an add_ method that works with a primary key" do
         
     | 
| 
      
 2092 
     | 
    
         
            +
                @c2.many_to_many :attributes, :class => @c1
         
     | 
| 
      
 2093 
     | 
    
         
            +
                
         
     | 
| 
      
 2094 
     | 
    
         
            +
                n = @c2.load(:id => 1234)
         
     | 
| 
      
 2095 
     | 
    
         
            +
                a = @c1.load(:id => 2345)
         
     | 
| 
      
 2096 
     | 
    
         
            +
                a.should == n.add_attribute(2345)
         
     | 
| 
      
 2097 
     | 
    
         
            +
                ['INSERT INTO attributes_nodes (node_id, attribute_id) VALUES (1234, 2345)',
         
     | 
| 
      
 2098 
     | 
    
         
            +
                 'INSERT INTO attributes_nodes (attribute_id, node_id) VALUES (2345, 1234)'
         
     | 
| 
      
 2099 
     | 
    
         
            +
                ].should(include(MODEL_DB.sqls.first))
         
     | 
| 
      
 2100 
     | 
    
         
            +
              end
         
     | 
| 
      
 2101 
     | 
    
         
            +
             
     | 
| 
       2066 
2102 
     | 
    
         
             
              it "should allow passing a hash to the add_ method which creates a new record" do
         
     | 
| 
       2067 
2103 
     | 
    
         
             
                @c2.many_to_many :attributes, :class => @c1
         
     | 
| 
       2068 
2104 
     | 
    
         | 
| 
         @@ -2148,6 +2184,14 @@ describe Sequel::Model, "many_to_many" do 
     | 
|
| 
       2148 
2184 
     | 
    
         
             
                  v.should == true
         
     | 
| 
       2149 
2185 
     | 
    
         
             
                end
         
     | 
| 
       2150 
2186 
     | 
    
         
             
              end
         
     | 
| 
      
 2187 
     | 
    
         
            +
              
         
     | 
| 
      
 2188 
     | 
    
         
            +
              it "should have the add_ method respect composite keys" do
         
     | 
| 
      
 2189 
     | 
    
         
            +
                @c2.many_to_many :attributes, :class => @c1, :left_key=>[:l1, :l2], :right_key=>[:r1, :r2], :left_primary_key=>[:id, :x], :right_primary_key=>[:id, :y]
         
     | 
| 
      
 2190 
     | 
    
         
            +
                n = @c2.load(:id => 1234, :x=>5)
         
     | 
| 
      
 2191 
     | 
    
         
            +
                a = @c1.load(:id => 2345, :y=>8)
         
     | 
| 
      
 2192 
     | 
    
         
            +
                a.should == n.add_attribute([2345, 8])
         
     | 
| 
      
 2193 
     | 
    
         
            +
                MODEL_DB.sqls.first.should =~ /INSERT INTO attributes_nodes \([lr][12], [lr][12], [lr][12], [lr][12]\) VALUES \((1234|5|2345|8), (1234|5|2345|8), (1234|5|2345|8), (1234|5|2345|8)\)/
         
     | 
| 
      
 2194 
     | 
    
         
            +
              end
         
     | 
| 
       2151 
2195 
     | 
    
         | 
| 
       2152 
2196 
     | 
    
         
             
              it "should have the remove_ method respect the :left_primary_key and :right_primary_key options" do
         
     | 
| 
       2153 
2197 
     | 
    
         
             
                @c2.many_to_many :attributes, :class => @c1, :left_primary_key=>:xxx, :right_primary_key=>:yyy
         
     | 
    
        data/spec/model/model_spec.rb
    CHANGED
    
    | 
         @@ -452,6 +452,17 @@ describe Sequel::Model, "attribute accessors" do 
     | 
|
| 
       452 
452 
     | 
    
         
             
                o.x = '34'
         
     | 
| 
       453 
453 
     | 
    
         
             
                o.x.should == 34
         
     | 
| 
       454 
454 
     | 
    
         
             
              end
         
     | 
| 
      
 455 
     | 
    
         
            +
             
     | 
| 
      
 456 
     | 
    
         
            +
              it "should typecast if the new value is the same as the existing but has a different class" do
         
     | 
| 
      
 457 
     | 
    
         
            +
                @c.set_dataset(@dataset.select(:y))
         
     | 
| 
      
 458 
     | 
    
         
            +
                o = @c.new
         
     | 
| 
      
 459 
     | 
    
         
            +
             
     | 
| 
      
 460 
     | 
    
         
            +
                o.x = 34
         
     | 
| 
      
 461 
     | 
    
         
            +
                o.x = 34.0
         
     | 
| 
      
 462 
     | 
    
         
            +
                o.x.should == 34.0
         
     | 
| 
      
 463 
     | 
    
         
            +
                o.x = 34
         
     | 
| 
      
 464 
     | 
    
         
            +
                o.x.should == 34
         
     | 
| 
      
 465 
     | 
    
         
            +
              end
         
     | 
| 
       455 
466 
     | 
    
         
             
            end
         
     | 
| 
       456 
467 
     | 
    
         | 
| 
       457 
468 
     | 
    
         
             
            describe Sequel::Model, ".[]" do
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,13 +1,13 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification 
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: sequel
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version 
         
     | 
| 
       4 
     | 
    
         
            -
              hash:  
     | 
| 
      
 4 
     | 
    
         
            +
              hash: 75
         
     | 
| 
       5 
5 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       6 
6 
     | 
    
         
             
              segments: 
         
     | 
| 
       7 
7 
     | 
    
         
             
              - 3
         
     | 
| 
       8 
     | 
    
         
            -
              -  
     | 
| 
      
 8 
     | 
    
         
            +
              - 19
         
     | 
| 
       9 
9 
     | 
    
         
             
              - 0
         
     | 
| 
       10 
     | 
    
         
            -
              version: 3. 
     | 
| 
      
 10 
     | 
    
         
            +
              version: 3.19.0
         
     | 
| 
       11 
11 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       12 
12 
     | 
    
         
             
            authors: 
         
     | 
| 
       13 
13 
     | 
    
         
             
            - Jeremy Evans
         
     | 
| 
         @@ -15,7 +15,7 @@ autorequire: 
     | 
|
| 
       15 
15 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       16 
16 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
       18 
     | 
    
         
            -
            date:  
     | 
| 
      
 18 
     | 
    
         
            +
            date: 2011-01-03 00:00:00 -08:00
         
     | 
| 
       19 
19 
     | 
    
         
             
            default_executable: 
         
     | 
| 
       20 
20 
     | 
    
         
             
            dependencies: []
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
         @@ -28,7 +28,7 @@ extensions: [] 
     | 
|
| 
       28 
28 
     | 
    
         
             
            extra_rdoc_files: 
         
     | 
| 
       29 
29 
     | 
    
         
             
            - README.rdoc
         
     | 
| 
       30 
30 
     | 
    
         
             
            - CHANGELOG
         
     | 
| 
       31 
     | 
    
         
            -
            -  
     | 
| 
      
 31 
     | 
    
         
            +
            - MIT-LICENSE
         
     | 
| 
       32 
32 
     | 
    
         
             
            - doc/advanced_associations.rdoc
         
     | 
| 
       33 
33 
     | 
    
         
             
            - doc/cheat_sheet.rdoc
         
     | 
| 
       34 
34 
     | 
    
         
             
            - doc/dataset_filtering.rdoc
         
     | 
| 
         @@ -82,8 +82,9 @@ extra_rdoc_files: 
     | 
|
| 
       82 
82 
     | 
    
         
             
            - doc/release_notes/3.16.0.txt
         
     | 
| 
       83 
83 
     | 
    
         
             
            - doc/release_notes/3.17.0.txt
         
     | 
| 
       84 
84 
     | 
    
         
             
            - doc/release_notes/3.18.0.txt
         
     | 
| 
      
 85 
     | 
    
         
            +
            - doc/release_notes/3.19.0.txt
         
     | 
| 
       85 
86 
     | 
    
         
             
            files: 
         
     | 
| 
       86 
     | 
    
         
            -
            -  
     | 
| 
      
 87 
     | 
    
         
            +
            - MIT-LICENSE
         
     | 
| 
       87 
88 
     | 
    
         
             
            - CHANGELOG
         
     | 
| 
       88 
89 
     | 
    
         
             
            - README.rdoc
         
     | 
| 
       89 
90 
     | 
    
         
             
            - Rakefile
         
     | 
| 
         @@ -131,6 +132,7 @@ files: 
     | 
|
| 
       131 
132 
     | 
    
         
             
            - doc/release_notes/3.16.0.txt
         
     | 
| 
       132 
133 
     | 
    
         
             
            - doc/release_notes/3.17.0.txt
         
     | 
| 
       133 
134 
     | 
    
         
             
            - doc/release_notes/3.18.0.txt
         
     | 
| 
      
 135 
     | 
    
         
            +
            - doc/release_notes/3.19.0.txt
         
     | 
| 
       134 
136 
     | 
    
         
             
            - doc/sharding.rdoc
         
     | 
| 
       135 
137 
     | 
    
         
             
            - doc/sql.rdoc
         
     | 
| 
       136 
138 
     | 
    
         
             
            - doc/virtual_rows.rdoc
         
     |