sequel 3.2.0 → 3.3.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 +40 -0
- data/Rakefile +1 -1
- data/doc/opening_databases.rdoc +7 -0
- data/doc/release_notes/3.3.0.txt +192 -0
- data/lib/sequel/adapters/ado.rb +34 -39
- data/lib/sequel/adapters/ado/mssql.rb +30 -0
- data/lib/sequel/adapters/jdbc.rb +27 -4
- data/lib/sequel/adapters/jdbc/h2.rb +14 -3
- data/lib/sequel/adapters/jdbc/mssql.rb +51 -0
- data/lib/sequel/adapters/mysql.rb +28 -12
- data/lib/sequel/adapters/odbc.rb +36 -30
- data/lib/sequel/adapters/odbc/mssql.rb +44 -0
- data/lib/sequel/adapters/shared/mssql.rb +185 -10
- data/lib/sequel/adapters/shared/mysql.rb +9 -9
- data/lib/sequel/adapters/shared/sqlite.rb +45 -47
- data/lib/sequel/connection_pool.rb +8 -5
- data/lib/sequel/core.rb +2 -8
- data/lib/sequel/database.rb +9 -10
- data/lib/sequel/database/schema_sql.rb +3 -2
- data/lib/sequel/dataset.rb +1 -0
- data/lib/sequel/dataset/sql.rb +15 -6
- data/lib/sequel/extensions/schema_dumper.rb +7 -7
- data/lib/sequel/model/associations.rb +16 -14
- data/lib/sequel/model/base.rb +25 -7
- data/lib/sequel/plugins/association_proxies.rb +41 -0
- data/lib/sequel/plugins/many_through_many.rb +0 -1
- data/lib/sequel/sql.rb +8 -11
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mysql_spec.rb +42 -38
- data/spec/adapters/sqlite_spec.rb +0 -4
- data/spec/core/database_spec.rb +22 -1
- data/spec/core/dataset_spec.rb +37 -12
- data/spec/core/expression_filters_spec.rb +5 -0
- data/spec/core/schema_spec.rb +15 -8
- data/spec/extensions/association_proxies_spec.rb +47 -0
- data/spec/extensions/caching_spec.rb +2 -2
- data/spec/extensions/hook_class_methods_spec.rb +6 -6
- data/spec/extensions/many_through_many_spec.rb +13 -0
- data/spec/extensions/schema_dumper_spec.rb +12 -4
- data/spec/extensions/validation_class_methods_spec.rb +3 -3
- data/spec/integration/dataset_test.rb +47 -17
- data/spec/integration/prepared_statement_test.rb +5 -5
- data/spec/integration/schema_test.rb +111 -34
- data/spec/model/associations_spec.rb +128 -11
- data/spec/model/hooks_spec.rb +7 -6
- data/spec/model/model_spec.rb +54 -4
- data/spec/model/record_spec.rb +2 -3
- data/spec/model/validations_spec.rb +4 -4
- metadata +109 -101
- data/spec/adapters/ado_spec.rb +0 -93
data/lib/sequel/model/base.rb
CHANGED
@@ -288,7 +288,13 @@ module Sequel
|
|
288
288
|
@dataset_methods.each{|meth, block| @dataset.meta_def(meth, &block)} if @dataset_methods
|
289
289
|
end
|
290
290
|
@dataset.model = self if @dataset.respond_to?(:model=)
|
291
|
-
|
291
|
+
begin
|
292
|
+
@db_schema = (inherited ? superclass.db_schema : get_db_schema)
|
293
|
+
rescue Sequel::DatabaseConnectionError
|
294
|
+
raise
|
295
|
+
rescue
|
296
|
+
nil
|
297
|
+
end
|
292
298
|
self
|
293
299
|
end
|
294
300
|
alias dataset= set_dataset
|
@@ -390,7 +396,15 @@ module Sequel
|
|
390
396
|
ds_opts = dataset.opts
|
391
397
|
single_table = ds_opts[:from] && (ds_opts[:from].length == 1) \
|
392
398
|
&& !ds_opts.include?(:join) && !ds_opts.include?(:sql)
|
393
|
-
get_columns = proc
|
399
|
+
get_columns = proc do
|
400
|
+
begin
|
401
|
+
columns
|
402
|
+
rescue Sequel::DatabaseConnectionError
|
403
|
+
raise
|
404
|
+
rescue
|
405
|
+
[]
|
406
|
+
end
|
407
|
+
end
|
394
408
|
if single_table && (schema_array = (db.schema(table_name, :reload=>reload) rescue nil))
|
395
409
|
schema_array.each{|k,v| schema_hash[k] = v}
|
396
410
|
if ds_opts.include?(:select)
|
@@ -405,9 +419,12 @@ module Sequel
|
|
405
419
|
# returned by the schema.
|
406
420
|
cols = schema_array.collect{|k,v| k}
|
407
421
|
set_columns(cols)
|
408
|
-
# Set the primary key(s) based on the schema information
|
409
|
-
|
410
|
-
|
422
|
+
# Set the primary key(s) based on the schema information,
|
423
|
+
# if the schema information includes primary key information
|
424
|
+
if schema_array.all?{|k,v| v.has_key?(:primary_key)}
|
425
|
+
pks = schema_array.collect{|k,v| k if v[:primary_key]}.compact
|
426
|
+
pks.length > 0 ? set_primary_key(*pks) : no_primary_key
|
427
|
+
end
|
411
428
|
# Also set the columns for the dataset, so the dataset
|
412
429
|
# doesn't have to do a query to get them.
|
413
430
|
dataset.instance_variable_set(:@columns, cols)
|
@@ -819,13 +836,14 @@ module Sequel
|
|
819
836
|
else
|
820
837
|
return save_failure(:update) if before_update == false
|
821
838
|
if columns.empty?
|
822
|
-
@columns_updated = opts[:changed] ? @values.reject{|k,v| !changed_columns.include?(k)} : @values
|
839
|
+
@columns_updated = opts[:changed] ? @values.reject{|k,v| !changed_columns.include?(k)} : @values.dup
|
823
840
|
changed_columns.clear
|
824
841
|
else # update only the specified columns
|
825
842
|
@columns_updated = @values.reject{|k, v| !columns.include?(k)}
|
826
843
|
changed_columns.reject!{|c| columns.include?(c)}
|
827
844
|
end
|
828
|
-
|
845
|
+
Array(primary_key).each{|x| @columns_updated.delete(x)}
|
846
|
+
this.update(@columns_updated) unless @columns_updated.empty?
|
829
847
|
after_update
|
830
848
|
after_save
|
831
849
|
@columns_updated = nil
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Sequel
|
2
|
+
module Plugins
|
3
|
+
# Sequel by default does not use proxies for associations. The association
|
4
|
+
# method for *_to_many associations returns an array, and the association_dataset
|
5
|
+
# method returns a dataset. This plugin makes the association method return a proxy
|
6
|
+
# that will load the association and call a method on the association array if sent
|
7
|
+
# an array method, and otherwise send the method to the association's dataset.
|
8
|
+
module AssociationProxies
|
9
|
+
# A proxy for the association. Calling an array method will load the
|
10
|
+
# associated objects and call the method on the associated object array.
|
11
|
+
# Calling any other method will call that method on the association's dataset.
|
12
|
+
class AssociationProxy < BasicObject
|
13
|
+
# Empty array used to check if an array responds to the given method.
|
14
|
+
ARRAY = []
|
15
|
+
|
16
|
+
# Set the association reflection to use, and whether the association should be
|
17
|
+
# reloaded if an array method is called.
|
18
|
+
def initialize(instance, reflection, reload=nil)
|
19
|
+
@instance = instance
|
20
|
+
@reflection = reflection
|
21
|
+
@reload = reload
|
22
|
+
end
|
23
|
+
|
24
|
+
# Call the method given on the array of associated objects if the method
|
25
|
+
# is an array method, otherwise call the method on the association's dataset.
|
26
|
+
def method_missing(meth, *args, &block)
|
27
|
+
(ARRAY.respond_to?(meth) ? @instance.send(:load_associated_objects, @reflection, @reload) : @instance.send(@reflection.dataset_method)).
|
28
|
+
send(meth, *args, &block)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
module ClassMethods
|
33
|
+
# Changes the association method to return a proxy instead of the associated objects
|
34
|
+
# directly.
|
35
|
+
def def_association_method(opts)
|
36
|
+
opts.returns_array? ? association_module_def(opts.association_method){|*r| AssociationProxy.new(self, opts, r[0])} : super
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -125,7 +125,6 @@ module Sequel
|
|
125
125
|
name = opts[:name]
|
126
126
|
model = self
|
127
127
|
opts[:read_only] = true
|
128
|
-
opts[:class_name] ||= camelize(singularize(name))
|
129
128
|
opts[:after_load].unshift(:array_uniq!) if opts[:uniq]
|
130
129
|
opts[:cartesian_product_number] ||= 2
|
131
130
|
opts[:through] = opts[:through].map do |e|
|
data/lib/sequel/sql.rb
CHANGED
@@ -1,4 +1,10 @@
|
|
1
1
|
module Sequel
|
2
|
+
if RUBY_VERSION < '1.9.0'
|
3
|
+
class BasicObject
|
4
|
+
(instance_methods - %w"__id__ __send__ instance_eval == equal?").each{|m| undef_method(m)}
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
2
8
|
class LiteralString < ::String
|
3
9
|
end
|
4
10
|
|
@@ -776,15 +782,6 @@ module Sequel
|
|
776
782
|
to_s_method :subscript_sql
|
777
783
|
end
|
778
784
|
|
779
|
-
if RUBY_VERSION >= '1.9.0'
|
780
|
-
class VirtualRow < BasicObject
|
781
|
-
end
|
782
|
-
else
|
783
|
-
class VirtualRow
|
784
|
-
(instance_methods - %w"__id__ __send__ instance_eval == equal?").each{|m| undef_method(m)}
|
785
|
-
end
|
786
|
-
end
|
787
|
-
|
788
785
|
# The purpose of this class is to allow the easy creation of SQL identifiers and functions
|
789
786
|
# without relying on methods defined on Symbol. This is useful if another library defines
|
790
787
|
# the methods defined by Sequel, or if you are running on ruby 1.9.
|
@@ -830,7 +827,7 @@ module Sequel
|
|
830
827
|
# ds.select{rank(:over){}} # SELECT rank() OVER () FROM t
|
831
828
|
# ds.select{count(:over, :*=>true){}} # SELECT count(*) OVER () FROM t
|
832
829
|
# ds.select{sum(:over, :args=>col1, :partition=>col2, :order=>col3){}} # SELECT sum(col1) OVER (PARTITION BY col2 ORDER BY col3) FROM t
|
833
|
-
class VirtualRow
|
830
|
+
class VirtualRow < BasicObject
|
834
831
|
WILDCARD = LiteralString.new('*').freeze
|
835
832
|
QUESTION_MARK = LiteralString.new('?').freeze
|
836
833
|
COMMA_SEPARATOR = LiteralString.new(', ').freeze
|
@@ -888,7 +885,7 @@ module Sequel
|
|
888
885
|
end
|
889
886
|
|
890
887
|
# A WindowFunction is a grouping of a function with a window over which it operates.
|
891
|
-
class WindowFunction <
|
888
|
+
class WindowFunction < GenericExpression
|
892
889
|
# The function to use, should be an SQL::Function.
|
893
890
|
attr_reader :function
|
894
891
|
|
data/lib/sequel/version.rb
CHANGED
data/spec/adapters/mysql_spec.rb
CHANGED
@@ -65,48 +65,52 @@ context "MySQL", '#create_table' do
|
|
65
65
|
end
|
66
66
|
|
67
67
|
context "A MySQL database" do
|
68
|
-
before do
|
69
|
-
@db = MYSQL_DB
|
70
|
-
@db.create_table(:booltest){TrueClass :value}
|
71
|
-
end
|
72
|
-
after do
|
73
|
-
Sequel.convert_tinyint_to_bool = true
|
74
|
-
@db.drop_table(:booltest)
|
75
|
-
end
|
76
|
-
|
77
68
|
specify "should provide the server version" do
|
78
|
-
|
69
|
+
MYSQL_DB.server_version.should >= 40000
|
79
70
|
end
|
71
|
+
end
|
80
72
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
MYSQL_DB[:booltest].delete
|
93
|
-
MYSQL_DB[:booltest] << {:value=>false}
|
94
|
-
MYSQL_DB[:booltest].all.should == [{:value=>false}]
|
73
|
+
if MYSQL_DB.class.adapter_scheme == :mysql
|
74
|
+
context "Sequel::MySQL.convert_tinyint_to_bool" do
|
75
|
+
before do
|
76
|
+
@db = MYSQL_DB
|
77
|
+
@db.create_table(:booltest){column :b, 'tinyint(1)'; column :i, 'tinyint(4)'}
|
78
|
+
@ds = @db[:booltest]
|
79
|
+
end
|
80
|
+
after do
|
81
|
+
Sequel::MySQL.convert_tinyint_to_bool = true
|
82
|
+
@db.drop_table(:booltest)
|
83
|
+
end
|
95
84
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
MYSQL_DB[:booltest] << {:value=>false}
|
102
|
-
MYSQL_DB[:booltest].all.should == [{:value=>0}]
|
85
|
+
specify "should consider tinyint(1) datatypes as boolean if set, but not larger tinyints" do
|
86
|
+
@db.schema(:booltest, :reload=>true).should == [[:b, {:type=>:boolean, :allow_null=>true, :primary_key=>false, :default=>nil, :ruby_default=>nil, :db_type=>"tinyint(1)"}, ], [:i, {:type=>:integer, :allow_null=>true, :primary_key=>false, :default=>nil, :ruby_default=>nil, :db_type=>"tinyint(4)"}, ]]
|
87
|
+
Sequel::MySQL.convert_tinyint_to_bool = false
|
88
|
+
@db.schema(:booltest, :reload=>true).should == [[:b, {:type=>:integer, :allow_null=>true, :primary_key=>false, :default=>nil, :ruby_default=>nil, :db_type=>"tinyint(1)"}, ], [:i, {:type=>:integer, :allow_null=>true, :primary_key=>false, :default=>nil, :ruby_default=>nil, :db_type=>"tinyint(4)"}, ]]
|
89
|
+
end
|
103
90
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
91
|
+
specify "should return tinyints as bools when set" do
|
92
|
+
@ds.delete
|
93
|
+
@ds << {:b=>true, :i=>10}
|
94
|
+
@ds.all.should == [{:b=>true, :i=>true}]
|
95
|
+
@ds.delete
|
96
|
+
@ds << {:b=>false, :i=>0}
|
97
|
+
@ds.all.should == [{:b=>false, :i=>false}]
|
98
|
+
|
99
|
+
Sequel::MySQL.convert_tinyint_to_bool = false
|
100
|
+
@ds.delete
|
101
|
+
@ds << {:b=>true, :i=>10}
|
102
|
+
@ds.all.should == [{:b=>1, :i=>10}]
|
103
|
+
@ds.delete
|
104
|
+
@ds << {:b=>false, :i=>0}
|
105
|
+
@ds.all.should == [{:b=>0, :i=>0}]
|
106
|
+
|
107
|
+
@ds.delete
|
108
|
+
@ds << {:b=>1, :i=>10}
|
109
|
+
@ds.all.should == [{:b=>1, :i=>10}]
|
110
|
+
@ds.delete
|
111
|
+
@ds << {:b=>0, :i=>0}
|
112
|
+
@ds.all.should == [{:b=>0, :i=>0}]
|
113
|
+
end
|
110
114
|
end
|
111
115
|
end
|
112
116
|
|
@@ -411,7 +415,7 @@ context "A MySQL database" do
|
|
411
415
|
|
412
416
|
specify "should support defaults for boolean columns" do
|
413
417
|
@db.create_table(:items){TrueClass :active1, :default=>true; FalseClass :active2, :default => false}
|
414
|
-
@db.sqls.should == ["CREATE TABLE items (active1 tinyint DEFAULT 1, active2 tinyint DEFAULT 0)"]
|
418
|
+
@db.sqls.should == ["CREATE TABLE items (active1 tinyint(1) DEFAULT 1, active2 tinyint(1) DEFAULT 0)"]
|
415
419
|
end
|
416
420
|
|
417
421
|
specify "should correctly format CREATE TABLE statements with foreign keys" do
|
@@ -377,10 +377,6 @@ context "A SQLite database" do
|
|
377
377
|
@db[:test3_backup2].columns.should == [:l]
|
378
378
|
end
|
379
379
|
|
380
|
-
specify "should not support set_column_type operations" do
|
381
|
-
proc {@db.set_column_type :test2, :value, :integer}.should raise_error(Sequel::Error)
|
382
|
-
end
|
383
|
-
|
384
380
|
specify "should support add_index" do
|
385
381
|
@db.add_index :test2, :value, :unique => true
|
386
382
|
@db.add_index :test2, [:name, :value]
|
data/spec/core/database_spec.rb
CHANGED
@@ -839,13 +839,34 @@ context "A Database adapter with a scheme" do
|
|
839
839
|
end
|
840
840
|
|
841
841
|
specify "should be accessible through Sequel.connect with URL parameters" do
|
842
|
-
c = Sequel.connect 'ccc
|
842
|
+
c = Sequel.connect 'ccc:///db?host=/tmp&user=test'
|
843
843
|
c.should be_a_kind_of(CCC)
|
844
844
|
c.opts[:host].should == '/tmp'
|
845
845
|
c.opts[:database].should == 'db'
|
846
846
|
c.opts[:user].should == 'test'
|
847
847
|
end
|
848
|
+
|
849
|
+
specify "should have URL parameters take precedence over fixed URL parts" do
|
850
|
+
c = Sequel.connect 'ccc://localhost/db?host=a&database=b'
|
851
|
+
c.should be_a_kind_of(CCC)
|
852
|
+
c.opts[:host].should == 'a'
|
853
|
+
c.opts[:database].should == 'b'
|
854
|
+
end
|
855
|
+
|
856
|
+
specify "should have hash options take predence over URL parameters or parts" do
|
857
|
+
c = Sequel.connect 'ccc://localhost/db?host=/tmp', :host=>'a', :database=>'b', :user=>'c'
|
858
|
+
c.should be_a_kind_of(CCC)
|
859
|
+
c.opts[:host].should == 'a'
|
860
|
+
c.opts[:database].should == 'b'
|
861
|
+
c.opts[:user].should == 'c'
|
862
|
+
end
|
848
863
|
|
864
|
+
specify "should unescape values of URL parameters and parts" do
|
865
|
+
c = Sequel.connect 'ccc:///d%5bb%5d?host=domain%5cinstance'
|
866
|
+
c.should be_a_kind_of(CCC)
|
867
|
+
c.opts[:database].should == 'd[b]'
|
868
|
+
c.opts[:host].should == 'domain\\instance'
|
869
|
+
end
|
849
870
|
end
|
850
871
|
|
851
872
|
context "Sequel::Database.connect" do
|
data/spec/core/dataset_spec.rb
CHANGED
@@ -92,6 +92,16 @@ context "Dataset" do
|
|
92
92
|
@dataset.identifier_output_method = :reverse
|
93
93
|
@dataset.send(:output_identifier, "at_b_C").should == :C_b_ta
|
94
94
|
end
|
95
|
+
|
96
|
+
specify "should have output_identifier handle empty identifiers" do
|
97
|
+
@dataset.send(:output_identifier, "").should == :untitled
|
98
|
+
@dataset.identifier_output_method = :upcase
|
99
|
+
@dataset.send(:output_identifier, "").should == :UNTITLED
|
100
|
+
@dataset.identifier_output_method = :downcase
|
101
|
+
@dataset.send(:output_identifier, "").should == :untitled
|
102
|
+
@dataset.identifier_output_method = :reverse
|
103
|
+
@dataset.send(:output_identifier, "").should == :deltitnu
|
104
|
+
end
|
95
105
|
end
|
96
106
|
|
97
107
|
context "Dataset#clone" do
|
@@ -1008,24 +1018,20 @@ context "Dataset#order" do
|
|
1008
1018
|
end
|
1009
1019
|
|
1010
1020
|
context "Dataset#unfiltered" do
|
1011
|
-
before do
|
1012
|
-
@dataset = Sequel::Dataset.new(nil).from(:test)
|
1013
|
-
end
|
1014
|
-
|
1015
1021
|
specify "should remove filtering from the dataset" do
|
1016
|
-
|
1017
|
-
'SELECT * FROM test'
|
1022
|
+
Sequel::Dataset.new(nil).from(:test).filter(:score=>1).unfiltered.sql.should == 'SELECT * FROM test'
|
1018
1023
|
end
|
1019
1024
|
end
|
1020
1025
|
|
1021
|
-
context "Dataset#
|
1022
|
-
|
1023
|
-
|
1026
|
+
context "Dataset#unlimited" do
|
1027
|
+
specify "should remove limit and offset from the dataset" do
|
1028
|
+
Sequel::Dataset.new(nil).from(:test).limit(1, 2).unlimited.sql.should == 'SELECT * FROM test'
|
1024
1029
|
end
|
1025
|
-
|
1030
|
+
end
|
1031
|
+
|
1032
|
+
context "Dataset#unordered" do
|
1026
1033
|
specify "should remove ordering from the dataset" do
|
1027
|
-
|
1028
|
-
'SELECT * FROM test'
|
1034
|
+
Sequel::Dataset.new(nil).from(:test).order(:name).unordered.sql.should == 'SELECT * FROM test'
|
1029
1035
|
end
|
1030
1036
|
end
|
1031
1037
|
|
@@ -1389,6 +1395,25 @@ context "Dataset#empty?" do
|
|
1389
1395
|
end
|
1390
1396
|
end
|
1391
1397
|
|
1398
|
+
context "Dataset#from_self" do
|
1399
|
+
before do
|
1400
|
+
@ds = Sequel::Dataset.new(nil).from(:test).select(:name).limit(1)
|
1401
|
+
end
|
1402
|
+
specify "should set up a default alias" do
|
1403
|
+
@ds.from_self.sql.should == 'SELECT * FROM (SELECT name FROM test LIMIT 1) AS t1'
|
1404
|
+
end
|
1405
|
+
specify "should modify only the new dataset" do
|
1406
|
+
@ds.from_self.select(:bogus).sql.should == 'SELECT bogus FROM (SELECT name FROM test LIMIT 1) AS t1'
|
1407
|
+
end
|
1408
|
+
specify "should use the user-specified alias" do
|
1409
|
+
@ds.from_self(:alias=>:some_name).sql.should == 'SELECT * FROM (SELECT name FROM test LIMIT 1) AS some_name'
|
1410
|
+
end
|
1411
|
+
specify "should use the user-specified alias for joins" do
|
1412
|
+
@ds.from_self(:alias=>:some_name).inner_join(:posts, :alias=>:name).sql.should == \
|
1413
|
+
'SELECT * FROM (SELECT name FROM test LIMIT 1) AS some_name INNER JOIN posts ON (posts.alias = some_name.name)'
|
1414
|
+
end
|
1415
|
+
end
|
1416
|
+
|
1392
1417
|
context "Dataset#join_table" do
|
1393
1418
|
before do
|
1394
1419
|
@d = MockDataset.new(nil).from(:items)
|
@@ -520,6 +520,10 @@ context Sequel::SQL::VirtualRow do
|
|
520
520
|
@d.l{rank(:over, :frame=>:rows){}}.should == 'rank() OVER (ROWS UNBOUNDED PRECEDING)'
|
521
521
|
end
|
522
522
|
|
523
|
+
it "should raise an error if an invalid :frame option is used" do
|
524
|
+
proc{@d.l{rank(:over, :frame=>:blah){}}}.should raise_error(Sequel::Error)
|
525
|
+
end
|
526
|
+
|
523
527
|
it "should support all these options together" do
|
524
528
|
@d.l{count(:over, :* =>true, :partition=>a, :order=>b, :window=>:win, :frame=>:rows){}}.should == 'count(*) OVER ("win" PARTITION BY "a" ORDER BY "b" ROWS UNBOUNDED PRECEDING)'
|
525
529
|
end
|
@@ -527,5 +531,6 @@ context Sequel::SQL::VirtualRow do
|
|
527
531
|
it "should raise an error if window functions are not supported" do
|
528
532
|
@d.meta_def(:supports_window_functions?){false}
|
529
533
|
proc{@d.l{count(:over, :* =>true, :partition=>a, :order=>b, :window=>:win, :frame=>:rows){}}}.should raise_error(Sequel::Error)
|
534
|
+
proc{Sequel::Dataset.new(nil).filter{count(:over, :* =>true, :partition=>a, :order=>b, :window=>:win, :frame=>:rows){}}.sql}.should raise_error(Sequel::Error)
|
530
535
|
end
|
531
536
|
end
|
data/spec/core/schema_spec.rb
CHANGED
@@ -107,16 +107,18 @@ context "DB#create_table" do
|
|
107
107
|
@db.create_table(:cats) do
|
108
108
|
integer :id
|
109
109
|
text :name, :null => false
|
110
|
+
text :name2, :allow_null => false
|
110
111
|
end
|
111
|
-
@db.sqls.should == ["CREATE TABLE cats (id integer, name text NOT NULL)"]
|
112
|
+
@db.sqls.should == ["CREATE TABLE cats (id integer, name text NOT NULL, name2 text NOT NULL)"]
|
112
113
|
end
|
113
114
|
|
114
115
|
specify "should accept null definition" do
|
115
116
|
@db.create_table(:cats) do
|
116
117
|
integer :id
|
117
118
|
text :name, :null => true
|
119
|
+
text :name2, :allow_null => true
|
118
120
|
end
|
119
|
-
@db.sqls.should == ["CREATE TABLE cats (id integer, name text NULL)"]
|
121
|
+
@db.sqls.should == ["CREATE TABLE cats (id integer, name text NULL, name2 text NULL)"]
|
120
122
|
end
|
121
123
|
|
122
124
|
specify "should accept unique definition" do
|
@@ -744,9 +746,6 @@ context "Schema Parser" do
|
|
744
746
|
@sqls = []
|
745
747
|
@db = Sequel::Database.new
|
746
748
|
end
|
747
|
-
after do
|
748
|
-
Sequel.convert_tinyint_to_bool = true
|
749
|
-
end
|
750
749
|
|
751
750
|
specify "should raise an error if there are no columns" do
|
752
751
|
@db.meta_def(:schema_parse_table) do |t, opts|
|
@@ -788,9 +787,7 @@ context "Schema Parser" do
|
|
788
787
|
@db.meta_def(:schema_parse_table) do |t, opts|
|
789
788
|
[[:x, {:type=>schema_column_type(t.to_s)}]]
|
790
789
|
end
|
791
|
-
@db.schema(:tinyint).first.last[:type].should == :
|
792
|
-
Sequel.convert_tinyint_to_bool = false
|
793
|
-
@db.schema(:tinyint, :reload=>true).first.last[:type].should == :integer
|
790
|
+
@db.schema(:tinyint).first.last[:type].should == :integer
|
794
791
|
@db.schema(:interval).first.last[:type].should == :interval
|
795
792
|
@db.schema(:int).first.last[:type].should == :integer
|
796
793
|
@db.schema(:integer).first.last[:type].should == :integer
|
@@ -810,6 +807,7 @@ context "Schema Parser" do
|
|
810
807
|
@db.schema(:"time with time zone").first.last[:type].should == :time
|
811
808
|
@db.schema(:"time without time zone").first.last[:type].should == :time
|
812
809
|
@db.schema(:boolean).first.last[:type].should == :boolean
|
810
|
+
@db.schema(:bit).first.last[:type].should == :boolean
|
813
811
|
@db.schema(:real).first.last[:type].should == :float
|
814
812
|
@db.schema(:float).first.last[:type].should == :float
|
815
813
|
@db.schema(:double).first.last[:type].should == :float
|
@@ -818,5 +816,14 @@ context "Schema Parser" do
|
|
818
816
|
@db.schema(:decimal).first.last[:type].should == :decimal
|
819
817
|
@db.schema(:money).first.last[:type].should == :decimal
|
820
818
|
@db.schema(:bytea).first.last[:type].should == :blob
|
819
|
+
@db.schema(:blob).first.last[:type].should == :blob
|
820
|
+
@db.schema(:image).first.last[:type].should == :blob
|
821
|
+
@db.schema(:nchar).first.last[:type].should == :string
|
822
|
+
@db.schema(:nvarchar).first.last[:type].should == :string
|
823
|
+
@db.schema(:ntext).first.last[:type].should == :string
|
824
|
+
@db.schema(:smalldatetime).first.last[:type].should == :datetime
|
825
|
+
@db.schema(:smallmoney).first.last[:type].should == :decimal
|
826
|
+
@db.schema(:binary).first.last[:type].should == :blob
|
827
|
+
@db.schema(:varbinary).first.last[:type].should == :blob
|
821
828
|
end
|
822
829
|
end
|