sequel 3.5.0 → 3.6.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 +108 -0
 - data/README.rdoc +25 -14
 - data/Rakefile +20 -1
 - data/doc/advanced_associations.rdoc +61 -64
 - data/doc/cheat_sheet.rdoc +16 -7
 - data/doc/opening_databases.rdoc +3 -3
 - data/doc/prepared_statements.rdoc +1 -1
 - data/doc/reflection.rdoc +2 -1
 - data/doc/release_notes/3.6.0.txt +366 -0
 - data/doc/schema.rdoc +19 -14
 - data/lib/sequel/adapters/amalgalite.rb +5 -27
 - data/lib/sequel/adapters/jdbc.rb +13 -3
 - data/lib/sequel/adapters/jdbc/h2.rb +17 -0
 - data/lib/sequel/adapters/jdbc/mysql.rb +20 -7
 - data/lib/sequel/adapters/mysql.rb +4 -3
 - data/lib/sequel/adapters/oracle.rb +1 -1
 - data/lib/sequel/adapters/postgres.rb +87 -28
 - data/lib/sequel/adapters/shared/mssql.rb +47 -6
 - data/lib/sequel/adapters/shared/mysql.rb +12 -31
 - data/lib/sequel/adapters/shared/postgres.rb +15 -12
 - data/lib/sequel/adapters/shared/sqlite.rb +18 -0
 - data/lib/sequel/adapters/sqlite.rb +1 -16
 - data/lib/sequel/connection_pool.rb +1 -1
 - data/lib/sequel/core.rb +1 -1
 - data/lib/sequel/database.rb +1 -1
 - data/lib/sequel/database/schema_generator.rb +2 -0
 - data/lib/sequel/database/schema_sql.rb +1 -1
 - data/lib/sequel/dataset.rb +5 -179
 - data/lib/sequel/dataset/actions.rb +123 -0
 - data/lib/sequel/dataset/convenience.rb +18 -10
 - data/lib/sequel/dataset/features.rb +65 -0
 - data/lib/sequel/dataset/prepared_statements.rb +29 -23
 - data/lib/sequel/dataset/query.rb +429 -0
 - data/lib/sequel/dataset/sql.rb +67 -435
 - data/lib/sequel/model/associations.rb +77 -13
 - data/lib/sequel/model/base.rb +30 -8
 - data/lib/sequel/model/errors.rb +4 -4
 - data/lib/sequel/plugins/caching.rb +38 -15
 - data/lib/sequel/plugins/force_encoding.rb +18 -7
 - data/lib/sequel/plugins/hook_class_methods.rb +4 -0
 - data/lib/sequel/plugins/many_through_many.rb +1 -1
 - data/lib/sequel/plugins/nested_attributes.rb +40 -11
 - data/lib/sequel/plugins/serialization.rb +17 -3
 - data/lib/sequel/plugins/validation_helpers.rb +65 -18
 - data/lib/sequel/sql.rb +23 -1
 - data/lib/sequel/version.rb +1 -1
 - data/spec/adapters/mssql_spec.rb +96 -10
 - data/spec/adapters/mysql_spec.rb +19 -0
 - data/spec/adapters/postgres_spec.rb +65 -2
 - data/spec/adapters/sqlite_spec.rb +10 -0
 - data/spec/core/core_sql_spec.rb +9 -0
 - data/spec/core/database_spec.rb +8 -4
 - data/spec/core/dataset_spec.rb +122 -29
 - data/spec/core/expression_filters_spec.rb +17 -0
 - data/spec/extensions/caching_spec.rb +43 -3
 - data/spec/extensions/force_encoding_spec.rb +43 -1
 - data/spec/extensions/nested_attributes_spec.rb +55 -2
 - data/spec/extensions/validation_helpers_spec.rb +71 -0
 - data/spec/integration/associations_test.rb +281 -0
 - data/spec/integration/dataset_test.rb +383 -9
 - data/spec/integration/eager_loader_test.rb +0 -65
 - data/spec/integration/model_test.rb +110 -0
 - data/spec/integration/plugin_test.rb +306 -0
 - data/spec/integration/prepared_statement_test.rb +32 -0
 - data/spec/integration/schema_test.rb +8 -3
 - data/spec/integration/spec_helper.rb +1 -25
 - data/spec/model/association_reflection_spec.rb +38 -0
 - data/spec/model/associations_spec.rb +184 -8
 - data/spec/model/eager_loading_spec.rb +23 -0
 - data/spec/model/model_spec.rb +8 -0
 - data/spec/model/record_spec.rb +84 -1
 - metadata +9 -2
 
    
        data/spec/adapters/mysql_spec.rb
    CHANGED
    
    | 
         @@ -787,6 +787,25 @@ context "MySQL::Dataset#replace" do 
     | 
|
| 
       787 
787 
     | 
    
         
             
                MYSQL_DB.drop_table(:items)
         
     | 
| 
       788 
788 
     | 
    
         
             
              end
         
     | 
| 
       789 
789 
     | 
    
         | 
| 
      
 790 
     | 
    
         
            +
              specify "should use default values if they exist" do
         
     | 
| 
      
 791 
     | 
    
         
            +
                MYSQL_DB.alter_table(:items){set_column_default :id, 1; set_column_default :value, 2}
         
     | 
| 
      
 792 
     | 
    
         
            +
                @d.replace
         
     | 
| 
      
 793 
     | 
    
         
            +
                @d.all.should == [{:id=>1, :value=>2}]
         
     | 
| 
      
 794 
     | 
    
         
            +
                @d.replace([])
         
     | 
| 
      
 795 
     | 
    
         
            +
                @d.all.should == [{:id=>1, :value=>2}]
         
     | 
| 
      
 796 
     | 
    
         
            +
                @d.replace({})
         
     | 
| 
      
 797 
     | 
    
         
            +
                @d.all.should == [{:id=>1, :value=>2}]
         
     | 
| 
      
 798 
     | 
    
         
            +
              end
         
     | 
| 
      
 799 
     | 
    
         
            +
              
         
     | 
| 
      
 800 
     | 
    
         
            +
              specify "should use support arrays, datasets, and multiple values" do
         
     | 
| 
      
 801 
     | 
    
         
            +
                @d.replace([1, 2])
         
     | 
| 
      
 802 
     | 
    
         
            +
                @d.all.should == [{:id=>1, :value=>2}]
         
     | 
| 
      
 803 
     | 
    
         
            +
                @d.replace(1, 2)
         
     | 
| 
      
 804 
     | 
    
         
            +
                @d.all.should == [{:id=>1, :value=>2}]
         
     | 
| 
      
 805 
     | 
    
         
            +
                @d.replace(@d)
         
     | 
| 
      
 806 
     | 
    
         
            +
                @d.all.should == [{:id=>1, :value=>2}]
         
     | 
| 
      
 807 
     | 
    
         
            +
              end
         
     | 
| 
      
 808 
     | 
    
         
            +
              
         
     | 
| 
       790 
809 
     | 
    
         
             
              specify "should create a record if the condition is not met" do
         
     | 
| 
       791 
810 
     | 
    
         
             
                @d.replace(:id => 111, :value => 333)
         
     | 
| 
       792 
811 
     | 
    
         
             
                @d.all.should == [{:id => 111, :value => 333}]
         
     | 
| 
         @@ -129,6 +129,24 @@ context "A PostgreSQL dataset" do 
     | 
|
| 
       129 
129 
     | 
    
         
             
                @d.filter(:name => /bc/).count.should == 2
         
     | 
| 
       130 
130 
     | 
    
         
             
                @d.filter(:name => /^bc/).count.should == 1
         
     | 
| 
       131 
131 
     | 
    
         
             
              end
         
     | 
| 
      
 132 
     | 
    
         
            +
              
         
     | 
| 
      
 133 
     | 
    
         
            +
              specify "should support for_share and for_update" do
         
     | 
| 
      
 134 
     | 
    
         
            +
                @d.for_share.all.should == []
         
     | 
| 
      
 135 
     | 
    
         
            +
                @d.for_update.all.should == []
         
     | 
| 
      
 136 
     | 
    
         
            +
              end
         
     | 
| 
      
 137 
     | 
    
         
            +
              
         
     | 
| 
      
 138 
     | 
    
         
            +
              specify "#lock should lock tables and yield if a block is given" do
         
     | 
| 
      
 139 
     | 
    
         
            +
                @d.lock('EXCLUSIVE'){@d.insert(:name=>'a')}
         
     | 
| 
      
 140 
     | 
    
         
            +
              end
         
     | 
| 
      
 141 
     | 
    
         
            +
              
         
     | 
| 
      
 142 
     | 
    
         
            +
              specify "#lock should lock table if inside a transaction" do
         
     | 
| 
      
 143 
     | 
    
         
            +
                POSTGRES_DB.transaction{@d.lock('EXCLUSIVE'); @d.insert(:name=>'a')}
         
     | 
| 
      
 144 
     | 
    
         
            +
              end
         
     | 
| 
      
 145 
     | 
    
         
            +
              
         
     | 
| 
      
 146 
     | 
    
         
            +
              specify "#lock should return nil" do
         
     | 
| 
      
 147 
     | 
    
         
            +
                @d.lock('EXCLUSIVE'){@d.insert(:name=>'a')}.should == nil
         
     | 
| 
      
 148 
     | 
    
         
            +
                POSTGRES_DB.transaction{@d.lock('EXCLUSIVE').should == nil; @d.insert(:name=>'a')}
         
     | 
| 
      
 149 
     | 
    
         
            +
              end
         
     | 
| 
       132 
150 
     | 
    
         
             
            end
         
     | 
| 
       133 
151 
     | 
    
         | 
| 
       134 
152 
     | 
    
         
             
            context "A PostgreSQL dataset with a timestamp field" do
         
     | 
| 
         @@ -189,6 +207,11 @@ context "A PostgreSQL database" do 
     | 
|
| 
       189 
207 
     | 
    
         | 
| 
       190 
208 
     | 
    
         
             
                @db[:test2].first[:xyz].should == 57
         
     | 
| 
       191 
209 
     | 
    
         
             
              end
         
     | 
| 
      
 210 
     | 
    
         
            +
              
         
     | 
| 
      
 211 
     | 
    
         
            +
              specify "#locks should be a dataset returning database locks " do
         
     | 
| 
      
 212 
     | 
    
         
            +
                @db.locks.should be_a_kind_of(Sequel::Dataset)
         
     | 
| 
      
 213 
     | 
    
         
            +
                @db.locks.all.should be_a_kind_of(Array)
         
     | 
| 
      
 214 
     | 
    
         
            +
              end
         
     | 
| 
       192 
215 
     | 
    
         
             
            end  
         
     | 
| 
       193 
216 
     | 
    
         | 
| 
       194 
217 
     | 
    
         
             
            context "A PostgreSQL database" do
         
     | 
| 
         @@ -217,7 +240,6 @@ context "A PostgreSQL database" do 
     | 
|
| 
       217 
240 
     | 
    
         
             
                @db.reset_primary_key_sequence(:posts).should == nil
         
     | 
| 
       218 
241 
     | 
    
         
             
              end
         
     | 
| 
       219 
242 
     | 
    
         | 
| 
       220 
     | 
    
         
            -
              
         
     | 
| 
       221 
243 
     | 
    
         
             
              specify "should support opclass specification" do
         
     | 
| 
       222 
244 
     | 
    
         
             
                @db.create_table(:posts){text :title; text :body; integer :user_id; index(:user_id, :opclass => :int4_ops, :type => :btree)}
         
     | 
| 
       223 
245 
     | 
    
         
             
                @db.sqls.should == [
         
     | 
| 
         @@ -287,6 +309,11 @@ context "A PostgreSQL database" do 
     | 
|
| 
       287 
309 
     | 
    
         
             
                  "CREATE INDEX posts_title_index ON posts (title) WHERE (title = '5')"
         
     | 
| 
       288 
310 
     | 
    
         
             
                ]
         
     | 
| 
       289 
311 
     | 
    
         
             
              end
         
     | 
| 
      
 312 
     | 
    
         
            +
              
         
     | 
| 
      
 313 
     | 
    
         
            +
              specify "should support renaming tables" do
         
     | 
| 
      
 314 
     | 
    
         
            +
                @db.create_table!(:posts1){primary_key :a}
         
     | 
| 
      
 315 
     | 
    
         
            +
                @db.rename_table(:posts1, :posts)
         
     | 
| 
      
 316 
     | 
    
         
            +
              end
         
     | 
| 
       290 
317 
     | 
    
         
             
            end
         
     | 
| 
       291 
318 
     | 
    
         | 
| 
       292 
319 
     | 
    
         
             
            context "Postgres::Dataset#import" do
         
     | 
| 
         @@ -393,7 +420,7 @@ context "Postgres::Dataset#insert" do 
     | 
|
| 
       393 
420 
     | 
    
         
             
                @ds.disable_insert_returning.insert_select(:value=>10).should == nil
         
     | 
| 
       394 
421 
     | 
    
         
             
              end
         
     | 
| 
       395 
422 
     | 
    
         | 
| 
       396 
     | 
    
         
            -
              specify "should have insert_select insert the record and return the inserted record if server_version  
     | 
| 
      
 423 
     | 
    
         
            +
              specify "should have insert_select insert the record and return the inserted record if server_version >= 80200" do
         
     | 
| 
       397 
424 
     | 
    
         
             
                @ds.meta_def(:server_version){80201}
         
     | 
| 
       398 
425 
     | 
    
         
             
                h = @ds.insert_select(:value=>10)
         
     | 
| 
       399 
426 
     | 
    
         
             
                h[:value].should == 10
         
     | 
| 
         @@ -635,3 +662,39 @@ context "Postgres::Database functions, languages, and triggers" do 
     | 
|
| 
       635 
662 
     | 
    
         
             
                @d.drop_trigger(:test, :identity, :if_exists=>true, :cascade=>true)
         
     | 
| 
       636 
663 
     | 
    
         
             
              end
         
     | 
| 
       637 
664 
     | 
    
         
             
            end
         
     | 
| 
      
 665 
     | 
    
         
            +
             
     | 
| 
      
 666 
     | 
    
         
            +
            if POSTGRES_DB.class.adapter_scheme == :postgres
         
     | 
| 
      
 667 
     | 
    
         
            +
            context "Postgres::Dataset #use_cursor" do
         
     | 
| 
      
 668 
     | 
    
         
            +
              before(:all) do
         
     | 
| 
      
 669 
     | 
    
         
            +
                @db = POSTGRES_DB
         
     | 
| 
      
 670 
     | 
    
         
            +
                @db.create_table!(:test_cursor){Integer :x}
         
     | 
| 
      
 671 
     | 
    
         
            +
                @db.sqls.clear
         
     | 
| 
      
 672 
     | 
    
         
            +
                @ds = @db[:test_cursor]
         
     | 
| 
      
 673 
     | 
    
         
            +
                @db.transaction{1001.times{|i| @ds.insert(i)}}
         
     | 
| 
      
 674 
     | 
    
         
            +
              end
         
     | 
| 
      
 675 
     | 
    
         
            +
              after(:all) do
         
     | 
| 
      
 676 
     | 
    
         
            +
                @db.drop_table(:test) rescue nil
         
     | 
| 
      
 677 
     | 
    
         
            +
              end
         
     | 
| 
      
 678 
     | 
    
         
            +
              
         
     | 
| 
      
 679 
     | 
    
         
            +
                specify "should return the same results as the non-cursor use" do
         
     | 
| 
      
 680 
     | 
    
         
            +
                  @ds.all.should == @ds.use_cursor.all
         
     | 
| 
      
 681 
     | 
    
         
            +
                end
         
     | 
| 
      
 682 
     | 
    
         
            +
                
         
     | 
| 
      
 683 
     | 
    
         
            +
                specify "should respect the :rows_per_fetch option" do
         
     | 
| 
      
 684 
     | 
    
         
            +
                  @db.sqls.clear
         
     | 
| 
      
 685 
     | 
    
         
            +
                  @ds.use_cursor.all
         
     | 
| 
      
 686 
     | 
    
         
            +
                  @db.sqls.length.should == 6
         
     | 
| 
      
 687 
     | 
    
         
            +
                  @db.sqls.clear
         
     | 
| 
      
 688 
     | 
    
         
            +
                  @ds.use_cursor(:rows_per_fetch=>100).all
         
     | 
| 
      
 689 
     | 
    
         
            +
                  @db.sqls.length.should == 15
         
     | 
| 
      
 690 
     | 
    
         
            +
                end
         
     | 
| 
      
 691 
     | 
    
         
            +
                
         
     | 
| 
      
 692 
     | 
    
         
            +
                specify "should handle returning inside block" do
         
     | 
| 
      
 693 
     | 
    
         
            +
                  def @ds.check_return
         
     | 
| 
      
 694 
     | 
    
         
            +
                    use_cursor.each{|r| return}
         
     | 
| 
      
 695 
     | 
    
         
            +
                  end
         
     | 
| 
      
 696 
     | 
    
         
            +
                  @ds.check_return
         
     | 
| 
      
 697 
     | 
    
         
            +
                  @ds.all.should == @ds.use_cursor.all
         
     | 
| 
      
 698 
     | 
    
         
            +
                end
         
     | 
| 
      
 699 
     | 
    
         
            +
            end
         
     | 
| 
      
 700 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -241,6 +241,16 @@ context "SQLite dataset" do 
     | 
|
| 
       241 
241 
     | 
    
         
             
                SQLITE_DB[:test].select(:name, :value).order(:value).to_a.should == \
         
     | 
| 
       242 
242 
     | 
    
         
             
                  @d.select(:name, :value).order(:value).to_a
         
     | 
| 
       243 
243 
     | 
    
         
             
              end
         
     | 
| 
      
 244 
     | 
    
         
            +
                
         
     | 
| 
      
 245 
     | 
    
         
            +
              specify "should support #explain" do
         
     | 
| 
      
 246 
     | 
    
         
            +
                SQLITE_DB[:test].explain.should be_a_kind_of(Array)
         
     | 
| 
      
 247 
     | 
    
         
            +
              end
         
     | 
| 
      
 248 
     | 
    
         
            +
              
         
     | 
| 
      
 249 
     | 
    
         
            +
              specify "should have #explain work when identifier_output_method is modified" do
         
     | 
| 
      
 250 
     | 
    
         
            +
                ds = SQLITE_DB[:test]
         
     | 
| 
      
 251 
     | 
    
         
            +
                ds.identifier_output_method = :upcase
         
     | 
| 
      
 252 
     | 
    
         
            +
                ds.explain.should be_a_kind_of(Array)
         
     | 
| 
      
 253 
     | 
    
         
            +
              end
         
     | 
| 
       244 
254 
     | 
    
         
             
            end
         
     | 
| 
       245 
255 
     | 
    
         | 
| 
       246 
256 
     | 
    
         
             
            context "A SQLite database" do
         
     | 
    
        data/spec/core/core_sql_spec.rb
    CHANGED
    
    | 
         @@ -82,6 +82,15 @@ context "String#lit" do 
     | 
|
| 
       82 
82 
     | 
    
         
             
                ds.quote_identifiers = true
         
     | 
| 
       83 
83 
     | 
    
         
             
                ds.literal(a).should == 'DISTINCT "a"'
         
     | 
| 
       84 
84 
     | 
    
         
             
              end
         
     | 
| 
      
 85 
     | 
    
         
            +
              
         
     | 
| 
      
 86 
     | 
    
         
            +
              specify "should handle named placeholders if given a single argument hash" do
         
     | 
| 
      
 87 
     | 
    
         
            +
                a = 'DISTINCT :b'.lit(:b=>:a)
         
     | 
| 
      
 88 
     | 
    
         
            +
                a.should be_a_kind_of(Sequel::SQL::PlaceholderLiteralString)
         
     | 
| 
      
 89 
     | 
    
         
            +
                ds = MockDatabase.new.dataset
         
     | 
| 
      
 90 
     | 
    
         
            +
                ds.literal(a).should == 'DISTINCT a'
         
     | 
| 
      
 91 
     | 
    
         
            +
                ds.quote_identifiers = true
         
     | 
| 
      
 92 
     | 
    
         
            +
                ds.literal(a).should == 'DISTINCT "a"'
         
     | 
| 
      
 93 
     | 
    
         
            +
              end
         
     | 
| 
       85 
94 
     | 
    
         
             
            end
         
     | 
| 
       86 
95 
     | 
    
         | 
| 
       87 
96 
     | 
    
         
             
            context "String#to_sequel_blob" do
         
     | 
    
        data/spec/core/database_spec.rb
    CHANGED
    
    | 
         @@ -1027,12 +1027,16 @@ context "Database#fetch" do 
     | 
|
| 
       1027 
1027 
     | 
    
         
             
                @db.fetch('select * from xyz where x = ? and y = ?', 15, 'abc') {|r| sql = r[:sql]}
         
     | 
| 
       1028 
1028 
     | 
    
         
             
                sql.should == "select * from xyz where x = 15 and y = 'abc'"
         
     | 
| 
       1029 
1029 
     | 
    
         | 
| 
       1030 
     | 
    
         
            -
                 
     | 
| 
       1031 
     | 
    
         
            -
                @db.fetch('select name from table where name = ? or id in ?',
         
     | 
| 
       1032 
     | 
    
         
            -
                'aman', [3,4,7]) {|r| sql = r[:sql]}
         
     | 
| 
      
 1030 
     | 
    
         
            +
                @db.fetch('select name from table where name = ? or id in ?', 'aman', [3,4,7]) {|r| sql = r[:sql]}
         
     | 
| 
       1033 
1031 
     | 
    
         
             
                sql.should == "select name from table where name = 'aman' or id in (3, 4, 7)"
         
     | 
| 
       1034 
1032 
     | 
    
         
             
              end
         
     | 
| 
       1035 
1033 
     | 
    
         | 
| 
      
 1034 
     | 
    
         
            +
              specify "should format the given sql with named arguments" do
         
     | 
| 
      
 1035 
     | 
    
         
            +
                sql = nil
         
     | 
| 
      
 1036 
     | 
    
         
            +
                @db.fetch('select * from xyz where x = :x and y = :y', :x=>15, :y=>'abc') {|r| sql = r[:sql]}
         
     | 
| 
      
 1037 
     | 
    
         
            +
                sql.should == "select * from xyz where x = 15 and y = 'abc'"
         
     | 
| 
      
 1038 
     | 
    
         
            +
              end
         
     | 
| 
      
 1039 
     | 
    
         
            +
              
         
     | 
| 
       1036 
1040 
     | 
    
         
             
              specify "should return the dataset if no block is given" do
         
     | 
| 
       1037 
1041 
     | 
    
         
             
                @db.fetch('select * from xyz').should be_a_kind_of(Sequel::Dataset)
         
     | 
| 
       1038 
1042 
     | 
    
         | 
| 
         @@ -1065,7 +1069,7 @@ context "Database#[]" do 
     | 
|
| 
       1065 
1069 
     | 
    
         
             
                ds.opts[:from].should == [:items]
         
     | 
| 
       1066 
1070 
     | 
    
         
             
              end
         
     | 
| 
       1067 
1071 
     | 
    
         | 
| 
       1068 
     | 
    
         
            -
              specify "should return  
     | 
| 
      
 1072 
     | 
    
         
            +
              specify "should return a dataset when a string is given" do
         
     | 
| 
       1069 
1073 
     | 
    
         
             
                c = Class.new(Sequel::Dataset) do
         
     | 
| 
       1070 
1074 
     | 
    
         
             
                  def fetch_rows(sql); yield({:sql => sql}); end
         
     | 
| 
       1071 
1075 
     | 
    
         
             
                end
         
     | 
    
        data/spec/core/dataset_spec.rb
    CHANGED
    
    | 
         @@ -300,15 +300,44 @@ context "Dataset#where" do 
     | 
|
| 
       300 
300 
     | 
    
         
             
                  should match(/WHERE \(\(name = 'xyz'\) AND \(price = 342\)\)|WHERE \(\(price = 342\) AND \(name = 'xyz'\)\)/)
         
     | 
| 
       301 
301 
     | 
    
         
             
              end
         
     | 
| 
       302 
302 
     | 
    
         | 
| 
       303 
     | 
    
         
            -
              specify "should work with  
     | 
| 
      
 303 
     | 
    
         
            +
              specify "should work with a string with placeholders and arguments for those placeholders" do
         
     | 
| 
       304 
304 
     | 
    
         
             
                @dataset.where('price < ? AND id in ?', 100, [1, 2, 3]).select_sql.should ==
         
     | 
| 
       305 
305 
     | 
    
         
             
                  "SELECT * FROM test WHERE (price < 100 AND id in (1, 2, 3))"
         
     | 
| 
       306 
306 
     | 
    
         
             
              end
         
     | 
| 
       307 
307 
     | 
    
         | 
| 
      
 308 
     | 
    
         
            +
              specify "should not modify passed array with placeholders" do
         
     | 
| 
      
 309 
     | 
    
         
            +
                a = ['price < ? AND id in ?', 100, 1, 2, 3]
         
     | 
| 
      
 310 
     | 
    
         
            +
                b = a.dup
         
     | 
| 
      
 311 
     | 
    
         
            +
                @dataset.where(a)
         
     | 
| 
      
 312 
     | 
    
         
            +
                b.should == a
         
     | 
| 
      
 313 
     | 
    
         
            +
              end
         
     | 
| 
      
 314 
     | 
    
         
            +
             
     | 
| 
       308 
315 
     | 
    
         
             
              specify "should work with strings (custom SQL expressions)" do
         
     | 
| 
       309 
316 
     | 
    
         
             
                @dataset.where('(a = 1 AND b = 2)').select_sql.should ==
         
     | 
| 
       310 
317 
     | 
    
         
             
                  "SELECT * FROM test WHERE ((a = 1 AND b = 2))"
         
     | 
| 
       311 
318 
     | 
    
         
             
              end
         
     | 
| 
      
 319 
     | 
    
         
            +
                
         
     | 
| 
      
 320 
     | 
    
         
            +
              specify "should work with a string with named placeholders and a hash of placeholder value arguments" do
         
     | 
| 
      
 321 
     | 
    
         
            +
                @dataset.where('price < :price AND id in :ids', :price=>100, :ids=>[1, 2, 3]).select_sql.should ==
         
     | 
| 
      
 322 
     | 
    
         
            +
                  "SELECT * FROM test WHERE (price < 100 AND id in (1, 2, 3))"
         
     | 
| 
      
 323 
     | 
    
         
            +
              end
         
     | 
| 
      
 324 
     | 
    
         
            +
                
         
     | 
| 
      
 325 
     | 
    
         
            +
              specify "should not modify passed array with named placeholders" do
         
     | 
| 
      
 326 
     | 
    
         
            +
                a = ['price < :price AND id in :ids', {:price=>100}]
         
     | 
| 
      
 327 
     | 
    
         
            +
                b = a.dup
         
     | 
| 
      
 328 
     | 
    
         
            +
                @dataset.where(a)
         
     | 
| 
      
 329 
     | 
    
         
            +
                b.should == a
         
     | 
| 
      
 330 
     | 
    
         
            +
              end
         
     | 
| 
      
 331 
     | 
    
         
            +
             
     | 
| 
      
 332 
     | 
    
         
            +
              specify "should not replace named placeholders that don't existin in the hash" do
         
     | 
| 
      
 333 
     | 
    
         
            +
                @dataset.where('price < :price AND id in :ids', :price=>100).select_sql.should ==
         
     | 
| 
      
 334 
     | 
    
         
            +
                  "SELECT * FROM test WHERE (price < 100 AND id in :ids)"
         
     | 
| 
      
 335 
     | 
    
         
            +
              end
         
     | 
| 
      
 336 
     | 
    
         
            +
                
         
     | 
| 
      
 337 
     | 
    
         
            +
              specify "should handle partial names" do
         
     | 
| 
      
 338 
     | 
    
         
            +
                @dataset.where('price < :price AND id = :p', :p=>2, :price=>100).select_sql.should ==
         
     | 
| 
      
 339 
     | 
    
         
            +
                  "SELECT * FROM test WHERE (price < 100 AND id = 2)"
         
     | 
| 
      
 340 
     | 
    
         
            +
              end
         
     | 
| 
       312 
341 
     | 
    
         | 
| 
       313 
342 
     | 
    
         
             
              specify "should affect select, delete and update statements" do
         
     | 
| 
       314 
343 
     | 
    
         
             
                @d1.select_sql.should == "SELECT * FROM test WHERE (region = 'Asia')"
         
     | 
| 
         @@ -626,10 +655,6 @@ context "Dataset#having" do 
     | 
|
| 
       626 
655 
     | 
    
         
             
                @columns = "region, sum(population), avg(gdp)"
         
     | 
| 
       627 
656 
     | 
    
         
             
              end
         
     | 
| 
       628 
657 
     | 
    
         | 
| 
       629 
     | 
    
         
            -
              specify "should raise if the dataset is not grouped" do
         
     | 
| 
       630 
     | 
    
         
            -
                proc {@dataset.having('avg(gdp) > 10')}.should raise_error(Sequel::InvalidOperation)
         
     | 
| 
       631 
     | 
    
         
            -
              end
         
     | 
| 
       632 
     | 
    
         
            -
             
     | 
| 
       633 
658 
     | 
    
         
             
              specify "should affect select statements" do
         
     | 
| 
       634 
659 
     | 
    
         
             
                @d1.select_sql.should ==
         
     | 
| 
       635 
660 
     | 
    
         
             
                  "SELECT #{@columns} FROM test GROUP BY region HAVING (sum(population) > 10)"
         
     | 
| 
         @@ -768,8 +793,20 @@ context "Dataset#literal" do 
     | 
|
| 
       768 
793 
     | 
    
         
             
                @dataset.literal(:items__name).should == "items.name"
         
     | 
| 
       769 
794 
     | 
    
         
             
              end
         
     | 
| 
       770 
795 
     | 
    
         | 
| 
       771 
     | 
    
         
            -
              specify "should  
     | 
| 
       772 
     | 
    
         
            -
                 
     | 
| 
      
 796 
     | 
    
         
            +
              specify "should call sql_literal with dataset on type if not natively supported and the object responds to it" do
         
     | 
| 
      
 797 
     | 
    
         
            +
                @a = Class.new do
         
     | 
| 
      
 798 
     | 
    
         
            +
                  def sql_literal(ds)
         
     | 
| 
      
 799 
     | 
    
         
            +
                    "called #{ds.blah}"
         
     | 
| 
      
 800 
     | 
    
         
            +
                  end
         
     | 
| 
      
 801 
     | 
    
         
            +
                end
         
     | 
| 
      
 802 
     | 
    
         
            +
                def @dataset.blah
         
     | 
| 
      
 803 
     | 
    
         
            +
                  "ds"
         
     | 
| 
      
 804 
     | 
    
         
            +
                end
         
     | 
| 
      
 805 
     | 
    
         
            +
                @dataset.literal(@a.new).should == "called ds"
         
     | 
| 
      
 806 
     | 
    
         
            +
              end
         
     | 
| 
      
 807 
     | 
    
         
            +
              
         
     | 
| 
      
 808 
     | 
    
         
            +
              specify "should raise an error for unsupported types with no sql_literal method" do
         
     | 
| 
      
 809 
     | 
    
         
            +
                proc {@dataset.literal(Object.new)}.should raise_error
         
     | 
| 
       773 
810 
     | 
    
         
             
              end
         
     | 
| 
       774 
811 
     | 
    
         | 
| 
       775 
812 
     | 
    
         
             
              specify "should literalize datasets as subqueries" do
         
     | 
| 
         @@ -1106,10 +1143,18 @@ context "Dataset#with_sql" do 
     | 
|
| 
       1106 
1143 
     | 
    
         
             
                @dataset = Sequel::Dataset.new(nil).from(:test)
         
     | 
| 
       1107 
1144 
     | 
    
         
             
              end
         
     | 
| 
       1108 
1145 
     | 
    
         | 
| 
       1109 
     | 
    
         
            -
              specify "should  
     | 
| 
      
 1146 
     | 
    
         
            +
              specify "should use static sql" do
         
     | 
| 
       1110 
1147 
     | 
    
         
             
                @dataset.with_sql('SELECT 1 FROM test').sql.should == 'SELECT 1 FROM test'
         
     | 
| 
       1111 
1148 
     | 
    
         
             
              end
         
     | 
| 
       1112 
1149 
     | 
    
         | 
| 
      
 1150 
     | 
    
         
            +
              specify "should work with placeholders" do
         
     | 
| 
      
 1151 
     | 
    
         
            +
                @dataset.with_sql('SELECT ? FROM test', 1).sql.should == 'SELECT 1 FROM test'
         
     | 
| 
      
 1152 
     | 
    
         
            +
              end
         
     | 
| 
      
 1153 
     | 
    
         
            +
             
     | 
| 
      
 1154 
     | 
    
         
            +
              specify "should work with named placeholders" do
         
     | 
| 
      
 1155 
     | 
    
         
            +
                @dataset.with_sql('SELECT :x FROM test', :x=>1).sql.should == 'SELECT 1 FROM test'
         
     | 
| 
      
 1156 
     | 
    
         
            +
              end
         
     | 
| 
      
 1157 
     | 
    
         
            +
             
     | 
| 
       1113 
1158 
     | 
    
         
             
              specify "should keep row_proc" do
         
     | 
| 
       1114 
1159 
     | 
    
         
             
                @dataset.with_sql('SELECT 1 FROM test').row_proc.should == @dataset.row_proc
         
     | 
| 
       1115 
1160 
     | 
    
         
             
              end
         
     | 
| 
         @@ -1440,6 +1485,11 @@ context "Dataset#group_and_count" do 
     | 
|
| 
       1440 
1485 
     | 
    
         
             
                @ds.group_and_count(:a, :b).sql.should == 
         
     | 
| 
       1441 
1486 
     | 
    
         
             
                  "SELECT a, b, count(*) AS count FROM test GROUP BY a, b ORDER BY count"
         
     | 
| 
       1442 
1487 
     | 
    
         
             
              end
         
     | 
| 
      
 1488 
     | 
    
         
            +
             
     | 
| 
      
 1489 
     | 
    
         
            +
              specify "should format column aliases in the select clause but not in the group clause" do
         
     | 
| 
      
 1490 
     | 
    
         
            +
                @ds.group_and_count(:name___n).sql.should ==
         
     | 
| 
      
 1491 
     | 
    
         
            +
                  "SELECT name AS n, count(*) AS count FROM test GROUP BY name ORDER BY count"
         
     | 
| 
      
 1492 
     | 
    
         
            +
              end
         
     | 
| 
       1443 
1493 
     | 
    
         
             
            end
         
     | 
| 
       1444 
1494 
     | 
    
         | 
| 
       1445 
1495 
     | 
    
         
             
            context "Dataset#empty?" do
         
     | 
| 
         @@ -1511,38 +1561,54 @@ context "Dataset#join_table" do 
     | 
|
| 
       1511 
1561 
     | 
    
         
             
                  'SELECT * FROM "items" INNER JOIN "b" ON ("b"."items_id" = "items"."id") LEFT OUTER JOIN "c" ON ("c"."b_id" = "b"."id")'
         
     | 
| 
       1512 
1562 
     | 
    
         
             
              end
         
     | 
| 
       1513 
1563 
     | 
    
         | 
| 
       1514 
     | 
    
         
            -
              specify "should support  
     | 
| 
       1515 
     | 
    
         
            -
                @d.join_table(: 
     | 
| 
       1516 
     | 
    
         
            -
                  'SELECT * FROM "items"  
     | 
| 
      
 1564 
     | 
    
         
            +
              specify "should support arbitrary join types" do
         
     | 
| 
      
 1565 
     | 
    
         
            +
                @d.join_table(:magic, :categories, :category_id=>:id).sql.should ==
         
     | 
| 
      
 1566 
     | 
    
         
            +
                  'SELECT * FROM "items" MAGIC JOIN "categories" ON ("categories"."category_id" = "items"."id")'
         
     | 
| 
      
 1567 
     | 
    
         
            +
              end
         
     | 
| 
       1517 
1568 
     | 
    
         | 
| 
      
 1569 
     | 
    
         
            +
              specify "should support many join methods" do
         
     | 
| 
       1518 
1570 
     | 
    
         
             
                @d.left_outer_join(:categories, :category_id=>:id).sql.should ==
         
     | 
| 
       1519 
1571 
     | 
    
         
             
                  'SELECT * FROM "items" LEFT OUTER JOIN "categories" ON ("categories"."category_id" = "items"."id")'
         
     | 
| 
       1520 
     | 
    
         
            -
              end
         
     | 
| 
       1521 
     | 
    
         
            -
             
     | 
| 
       1522 
     | 
    
         
            -
              specify "should support right outer joins" do
         
     | 
| 
       1523 
     | 
    
         
            -
                @d.join_table(:right_outer, :categories, :category_id=>:id).sql.should ==
         
     | 
| 
       1524 
     | 
    
         
            -
                  'SELECT * FROM "items" RIGHT OUTER JOIN "categories" ON ("categories"."category_id" = "items"."id")'
         
     | 
| 
       1525 
     | 
    
         
            -
             
     | 
| 
       1526 
1572 
     | 
    
         
             
                @d.right_outer_join(:categories, :category_id=>:id).sql.should ==
         
     | 
| 
       1527 
1573 
     | 
    
         
             
                  'SELECT * FROM "items" RIGHT OUTER JOIN "categories" ON ("categories"."category_id" = "items"."id")'
         
     | 
| 
       1528 
     | 
    
         
            -
              end
         
     | 
| 
       1529 
     | 
    
         
            -
             
     | 
| 
       1530 
     | 
    
         
            -
              specify "should support full outer joins" do
         
     | 
| 
       1531 
     | 
    
         
            -
                @d.join_table(:full_outer, :categories, :category_id=>:id).sql.should ==
         
     | 
| 
       1532 
     | 
    
         
            -
                  'SELECT * FROM "items" FULL OUTER JOIN "categories" ON ("categories"."category_id" = "items"."id")'
         
     | 
| 
       1533 
     | 
    
         
            -
             
     | 
| 
       1534 
1574 
     | 
    
         
             
                @d.full_outer_join(:categories, :category_id=>:id).sql.should ==
         
     | 
| 
       1535 
1575 
     | 
    
         
             
                  'SELECT * FROM "items" FULL OUTER JOIN "categories" ON ("categories"."category_id" = "items"."id")'
         
     | 
| 
       1536 
     | 
    
         
            -
              end
         
     | 
| 
       1537 
     | 
    
         
            -
             
     | 
| 
       1538 
     | 
    
         
            -
              specify "should support inner joins" do
         
     | 
| 
       1539 
     | 
    
         
            -
                @d.join_table(:inner, :categories, :category_id=>:id).sql.should ==
         
     | 
| 
       1540 
     | 
    
         
            -
                  'SELECT * FROM "items" INNER JOIN "categories" ON ("categories"."category_id" = "items"."id")'
         
     | 
| 
       1541 
     | 
    
         
            -
             
     | 
| 
       1542 
1576 
     | 
    
         
             
                @d.inner_join(:categories, :category_id=>:id).sql.should ==
         
     | 
| 
       1543 
1577 
     | 
    
         
             
                  'SELECT * FROM "items" INNER JOIN "categories" ON ("categories"."category_id" = "items"."id")'
         
     | 
| 
      
 1578 
     | 
    
         
            +
                @d.left_join(:categories, :category_id=>:id).sql.should ==
         
     | 
| 
      
 1579 
     | 
    
         
            +
                  'SELECT * FROM "items" LEFT JOIN "categories" ON ("categories"."category_id" = "items"."id")'
         
     | 
| 
      
 1580 
     | 
    
         
            +
                @d.right_join(:categories, :category_id=>:id).sql.should ==
         
     | 
| 
      
 1581 
     | 
    
         
            +
                  'SELECT * FROM "items" RIGHT JOIN "categories" ON ("categories"."category_id" = "items"."id")'
         
     | 
| 
      
 1582 
     | 
    
         
            +
                @d.full_join(:categories, :category_id=>:id).sql.should ==
         
     | 
| 
      
 1583 
     | 
    
         
            +
                  'SELECT * FROM "items" FULL JOIN "categories" ON ("categories"."category_id" = "items"."id")'
         
     | 
| 
      
 1584 
     | 
    
         
            +
                @d.natural_join(:categories).sql.should ==
         
     | 
| 
      
 1585 
     | 
    
         
            +
                  'SELECT * FROM "items" NATURAL JOIN "categories"'
         
     | 
| 
      
 1586 
     | 
    
         
            +
                @d.natural_left_join(:categories).sql.should ==
         
     | 
| 
      
 1587 
     | 
    
         
            +
                  'SELECT * FROM "items" NATURAL LEFT JOIN "categories"'
         
     | 
| 
      
 1588 
     | 
    
         
            +
                @d.natural_right_join(:categories).sql.should ==
         
     | 
| 
      
 1589 
     | 
    
         
            +
                  'SELECT * FROM "items" NATURAL RIGHT JOIN "categories"'
         
     | 
| 
      
 1590 
     | 
    
         
            +
                @d.natural_full_join(:categories).sql.should ==
         
     | 
| 
      
 1591 
     | 
    
         
            +
                  'SELECT * FROM "items" NATURAL FULL JOIN "categories"'
         
     | 
| 
      
 1592 
     | 
    
         
            +
                @d.cross_join(:categories).sql.should ==
         
     | 
| 
      
 1593 
     | 
    
         
            +
                  'SELECT * FROM "items" CROSS JOIN "categories"'
         
     | 
| 
       1544 
1594 
     | 
    
         
             
              end
         
     | 
| 
       1545 
1595 
     | 
    
         | 
| 
      
 1596 
     | 
    
         
            +
              specify "should raise an error if additional arguments are provided to join methods that don't take conditions" do
         
     | 
| 
      
 1597 
     | 
    
         
            +
                proc{@d.natural_join(:categories, :id=>:id)}.should raise_error(ArgumentError)
         
     | 
| 
      
 1598 
     | 
    
         
            +
                proc{@d.natural_left_join(:categories, :id=>:id)}.should raise_error(ArgumentError)
         
     | 
| 
      
 1599 
     | 
    
         
            +
                proc{@d.natural_right_join(:categories, :id=>:id)}.should raise_error(ArgumentError)
         
     | 
| 
      
 1600 
     | 
    
         
            +
                proc{@d.natural_full_join(:categories, :id=>:id)}.should raise_error(ArgumentError)
         
     | 
| 
      
 1601 
     | 
    
         
            +
                proc{@d.cross_join(:categories, :id=>:id)}.should raise_error(ArgumentError)
         
     | 
| 
      
 1602 
     | 
    
         
            +
              end
         
     | 
| 
      
 1603 
     | 
    
         
            +
             
     | 
| 
      
 1604 
     | 
    
         
            +
              specify "should raise an error if blocks are provided to join methods that don't pass them" do
         
     | 
| 
      
 1605 
     | 
    
         
            +
                proc{@d.natural_join(:categories){}}.should raise_error(Sequel::Error)
         
     | 
| 
      
 1606 
     | 
    
         
            +
                proc{@d.natural_left_join(:categories){}}.should raise_error(Sequel::Error)
         
     | 
| 
      
 1607 
     | 
    
         
            +
                proc{@d.natural_right_join(:categories){}}.should raise_error(Sequel::Error)
         
     | 
| 
      
 1608 
     | 
    
         
            +
                proc{@d.natural_full_join(:categories){}}.should raise_error(Sequel::Error)
         
     | 
| 
      
 1609 
     | 
    
         
            +
                proc{@d.cross_join(:categories){}}.should raise_error(Sequel::Error)
         
     | 
| 
      
 1610 
     | 
    
         
            +
              end
         
     | 
| 
      
 1611 
     | 
    
         
            +
             
     | 
| 
       1546 
1612 
     | 
    
         
             
              specify "should default to a plain join if nil is used for the type" do
         
     | 
| 
       1547 
1613 
     | 
    
         
             
                @d.join_table(nil, :categories, :category_id=>:id).sql.should ==
         
     | 
| 
       1548 
1614 
     | 
    
         
             
                  'SELECT * FROM "items"  JOIN "categories" ON ("categories"."category_id" = "items"."id")'
         
     | 
| 
         @@ -1680,6 +1746,11 @@ context "Dataset#join_table" do 
     | 
|
| 
       1680 
1746 
     | 
    
         
             
                  'SELECT * FROM "items" INNER JOIN "categories" USING ("id1", "id2")'
         
     | 
| 
       1681 
1747 
     | 
    
         
             
              end
         
     | 
| 
       1682 
1748 
     | 
    
         | 
| 
      
 1749 
     | 
    
         
            +
              specify "should emulate JOIN USING (poorly) if the dataset doesn't support it" do
         
     | 
| 
      
 1750 
     | 
    
         
            +
                @d.meta_def(:supports_join_using?){false}
         
     | 
| 
      
 1751 
     | 
    
         
            +
                @d.join(:categories, [:id]).sql.should == 'SELECT * FROM "items" INNER JOIN "categories" ON ("categories"."id" = "items"."id")'
         
     | 
| 
      
 1752 
     | 
    
         
            +
              end
         
     | 
| 
      
 1753 
     | 
    
         
            +
             
     | 
| 
       1683 
1754 
     | 
    
         
             
              specify "should raise an error if using an array of symbols with a block" do
         
     | 
| 
       1684 
1755 
     | 
    
         
             
                proc{@d.join(:categories, [:id]){|j,lj,js|}}.should raise_error(Sequel::Error)
         
     | 
| 
       1685 
1756 
     | 
    
         
             
              end
         
     | 
| 
         @@ -1852,6 +1923,14 @@ context "Dataset aggregate methods" do 
     | 
|
| 
       1852 
1923 
     | 
    
         
             
              specify "should accept qualified columns" do
         
     | 
| 
       1853 
1924 
     | 
    
         
             
                @d.avg(:test__bc).should == 'SELECT avg(test.bc) FROM test LIMIT 1'
         
     | 
| 
       1854 
1925 
     | 
    
         
             
              end
         
     | 
| 
      
 1926 
     | 
    
         
            +
              
         
     | 
| 
      
 1927 
     | 
    
         
            +
              specify "should use a subselect for the same conditions as count" do
         
     | 
| 
      
 1928 
     | 
    
         
            +
                d = @d.order(:a).limit(5)
         
     | 
| 
      
 1929 
     | 
    
         
            +
                d.avg(:a).should == 'SELECT avg(a) FROM (SELECT * FROM test ORDER BY a LIMIT 5) AS t1 LIMIT 1'
         
     | 
| 
      
 1930 
     | 
    
         
            +
                d.sum(:a).should == 'SELECT sum(a) FROM (SELECT * FROM test ORDER BY a LIMIT 5) AS t1 LIMIT 1'
         
     | 
| 
      
 1931 
     | 
    
         
            +
                d.min(:a).should == 'SELECT min(a) FROM (SELECT * FROM test ORDER BY a LIMIT 5) AS t1 LIMIT 1'
         
     | 
| 
      
 1932 
     | 
    
         
            +
                d.max(:a).should == 'SELECT max(a) FROM (SELECT * FROM test ORDER BY a LIMIT 5) AS t1 LIMIT 1'
         
     | 
| 
      
 1933 
     | 
    
         
            +
              end
         
     | 
| 
       1855 
1934 
     | 
    
         
             
            end
         
     | 
| 
       1856 
1935 
     | 
    
         | 
| 
       1857 
1936 
     | 
    
         
             
            context "Dataset#range" do
         
     | 
| 
         @@ -1880,6 +1959,11 @@ context "Dataset#range" do 
     | 
|
| 
       1880 
1959 
     | 
    
         
             
              specify "should return a range object" do
         
     | 
| 
       1881 
1960 
     | 
    
         
             
                @d.range(:tryme).should == (1..10)
         
     | 
| 
       1882 
1961 
     | 
    
         
             
              end
         
     | 
| 
      
 1962 
     | 
    
         
            +
              
         
     | 
| 
      
 1963 
     | 
    
         
            +
              specify "should use a subselect for the same conditions as count" do
         
     | 
| 
      
 1964 
     | 
    
         
            +
                @d.order(:stamp).limit(5).range(:stamp).should == (1..10)
         
     | 
| 
      
 1965 
     | 
    
         
            +
                @d.last_sql.should == 'SELECT min(stamp) AS v1, max(stamp) AS v2 FROM (SELECT * FROM test ORDER BY stamp LIMIT 5) AS t1 LIMIT 1'
         
     | 
| 
      
 1966 
     | 
    
         
            +
              end
         
     | 
| 
       1883 
1967 
     | 
    
         
             
            end
         
     | 
| 
       1884 
1968 
     | 
    
         | 
| 
       1885 
1969 
     | 
    
         
             
            context "Dataset#interval" do
         
     | 
| 
         @@ -1908,6 +1992,11 @@ context "Dataset#interval" do 
     | 
|
| 
       1908 
1992 
     | 
    
         
             
              specify "should return an integer" do
         
     | 
| 
       1909 
1993 
     | 
    
         
             
                @d.interval(:tryme).should == 1234
         
     | 
| 
       1910 
1994 
     | 
    
         
             
              end
         
     | 
| 
      
 1995 
     | 
    
         
            +
              
         
     | 
| 
      
 1996 
     | 
    
         
            +
              specify "should use a subselect for the same conditions as count" do
         
     | 
| 
      
 1997 
     | 
    
         
            +
                @d.order(:stamp).limit(5).interval(:stamp).should == 1234
         
     | 
| 
      
 1998 
     | 
    
         
            +
                @d.last_sql.should == 'SELECT (max(stamp) - min(stamp)) FROM (SELECT * FROM test ORDER BY stamp LIMIT 5) AS t1 LIMIT 1'
         
     | 
| 
      
 1999 
     | 
    
         
            +
              end
         
     | 
| 
       1911 
2000 
     | 
    
         
             
            end
         
     | 
| 
       1912 
2001 
     | 
    
         | 
| 
       1913 
2002 
     | 
    
         
             
            context "Dataset #first and #last" do
         
     | 
| 
         @@ -3080,6 +3169,10 @@ context "Sequel::Dataset#qualify_to_first_source" do 
     | 
|
| 
       3080 
3169 
     | 
    
         
             
                @ds.filter('? > ?', :a, 1).qualify_to_first_source.sql.should == 'SELECT t.* FROM t WHERE (t.a > 1)'
         
     | 
| 
       3081 
3170 
     | 
    
         
             
              end
         
     | 
| 
       3082 
3171 
     | 
    
         | 
| 
      
 3172 
     | 
    
         
            +
              specify "should handle SQL::PlaceholderLiteralStrings with named placeholders" do
         
     | 
| 
      
 3173 
     | 
    
         
            +
                @ds.filter(':a > :b', :a=>:c, :b=>1).qualify_to_first_source.sql.should == 'SELECT t.* FROM t WHERE (t.c > 1)'
         
     | 
| 
      
 3174 
     | 
    
         
            +
              end
         
     | 
| 
      
 3175 
     | 
    
         
            +
             
     | 
| 
       3083 
3176 
     | 
    
         
             
              specify "should handle SQL::WindowFunctions" do
         
     | 
| 
       3084 
3177 
     | 
    
         
             
                @ds.meta_def(:supports_window_functions?){true}
         
     | 
| 
       3085 
3178 
     | 
    
         
             
                @ds.select{sum(:over, :args=>:a, :partition=>:b, :order=>:c){}}.qualify_to_first_source.sql.should == 'SELECT sum(t.a) OVER (PARTITION BY t.b ORDER BY t.c) FROM t'
         
     | 
| 
         @@ -327,6 +327,17 @@ context "Blockless Ruby Filters" do 
     | 
|
| 
       327 
327 
     | 
    
         
             
                @d.l([[:x, nil], [:y, [1,2,3]]].sql_or).should == '((x IS NULL) OR (y IN (1, 2, 3)))'
         
     | 
| 
       328 
328 
     | 
    
         
             
              end
         
     | 
| 
       329 
329 
     | 
    
         | 
| 
      
 330 
     | 
    
         
            +
              it "should emulate columns for array values" do
         
     | 
| 
      
 331 
     | 
    
         
            +
                @d.l([:x, :y]=>[[1,2], [3,4]].sql_array).should == '((x, y) IN ((1, 2), (3, 4)))'
         
     | 
| 
      
 332 
     | 
    
         
            +
                @d.l([:x, :y, :z]=>[[1,2,5], [3,4,6]]).should == '((x, y, z) IN ((1, 2, 5), (3, 4, 6)))'
         
     | 
| 
      
 333 
     | 
    
         
            +
              end
         
     | 
| 
      
 334 
     | 
    
         
            +
              
         
     | 
| 
      
 335 
     | 
    
         
            +
              it "should emulate multiple column in if not supported" do
         
     | 
| 
      
 336 
     | 
    
         
            +
                @d.meta_def(:supports_multiple_column_in?){false}
         
     | 
| 
      
 337 
     | 
    
         
            +
                @d.l([:x, :y]=>[[1,2], [3,4]].sql_array).should == '(((x = 1) AND (y = 2)) OR ((x = 3) AND (y = 4)))'
         
     | 
| 
      
 338 
     | 
    
         
            +
                @d.l([:x, :y, :z]=>[[1,2,5], [3,4,6]]).should == '(((x = 1) AND (y = 2) AND (z = 5)) OR ((x = 3) AND (y = 4) AND (z = 6)))'
         
     | 
| 
      
 339 
     | 
    
         
            +
              end
         
     | 
| 
      
 340 
     | 
    
         
            +
              
         
     | 
| 
       330 
341 
     | 
    
         
             
              it "should support Array#sql_string_join for concatenation of SQL strings" do
         
     | 
| 
       331 
342 
     | 
    
         
             
                @d.lit([:x].sql_string_join).should == '(x)'
         
     | 
| 
       332 
343 
     | 
    
         
             
                @d.lit([:x].sql_string_join(', ')).should == '(x)'
         
     | 
| 
         @@ -533,4 +544,10 @@ context Sequel::SQL::VirtualRow do 
     | 
|
| 
       533 
544 
     | 
    
         
             
                proc{@d.l{count(:over, :* =>true, :partition=>a, :order=>b, :window=>:win, :frame=>:rows){}}}.should raise_error(Sequel::Error)
         
     | 
| 
       534 
545 
     | 
    
         
             
                proc{Sequel::Dataset.new(nil).filter{count(:over, :* =>true, :partition=>a, :order=>b, :window=>:win, :frame=>:rows){}}.sql}.should raise_error(Sequel::Error)
         
     | 
| 
       535 
546 
     | 
    
         
             
              end
         
     | 
| 
      
 547 
     | 
    
         
            +
              
         
     | 
| 
      
 548 
     | 
    
         
            +
              it "should deal with classes without requiring :: prefix" do
         
     | 
| 
      
 549 
     | 
    
         
            +
                @d.l{date < Date.today}.should == "(\"date\" < '#{Date.today}')"
         
     | 
| 
      
 550 
     | 
    
         
            +
                @d.l{date < Sequel::CURRENT_DATE}.should == "(\"date\" < CURRENT_DATE)"
         
     | 
| 
      
 551 
     | 
    
         
            +
                @d.l{num < Math::PI.to_i}.should == "(\"num\" < 3)"
         
     | 
| 
      
 552 
     | 
    
         
            +
              end
         
     | 
| 
       536 
553 
     | 
    
         
             
            end
         
     |