sequel 3.2.0 → 3.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|