sequel 3.24.0 → 3.25.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 +32 -0
- data/doc/association_basics.rdoc +4 -4
- data/doc/dataset_basics.rdoc +4 -4
- data/doc/migration.rdoc +6 -5
- data/doc/opening_databases.rdoc +8 -5
- data/doc/release_notes/3.25.0.txt +88 -0
- data/lib/sequel/adapters/jdbc/postgresql.rb +6 -0
- data/lib/sequel/adapters/jdbc.rb +2 -2
- data/lib/sequel/adapters/shared/postgres.rb +0 -5
- data/lib/sequel/adapters/tinytds.rb +1 -2
- data/lib/sequel/database/schema_generator.rb +6 -4
- data/lib/sequel/database/schema_methods.rb +18 -7
- data/lib/sequel/dataset/misc.rb +0 -9
- data/lib/sequel/dataset/query.rb +80 -21
- data/lib/sequel/dataset.rb +8 -0
- data/lib/sequel/extensions/migration.rb +1 -1
- data/lib/sequel/model/base.rb +15 -6
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/plugins/association_pks.rb +16 -0
- data/lib/sequel/plugins/update_primary_key.rb +1 -1
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mysql_spec.rb +7 -0
- data/spec/core/database_spec.rb +0 -295
- data/spec/core/dataset_spec.rb +70 -1
- data/spec/core/expression_filters_spec.rb +39 -0
- data/spec/core/schema_spec.rb +304 -0
- data/spec/core/spec_helper.rb +29 -0
- data/spec/extensions/association_pks_spec.rb +31 -0
- data/spec/extensions/schema_spec.rb +12 -20
- data/spec/integration/dataset_test.rb +17 -0
- data/spec/integration/prepared_statement_test.rb +15 -0
- data/spec/integration/schema_test.rb +9 -0
- data/spec/model/model_spec.rb +60 -0
- data/spec/model/plugins_spec.rb +17 -0
- data/spec/model/validations_spec.rb +11 -0
- metadata +6 -4
data/spec/core/schema_spec.rb
CHANGED
|
@@ -594,6 +594,16 @@ describe "DB#drop_table" do
|
|
|
594
594
|
@db.drop_table :cats
|
|
595
595
|
@db.sqls.should == ['DROP TABLE cats']
|
|
596
596
|
end
|
|
597
|
+
|
|
598
|
+
specify "should drop multiple tables at once" do
|
|
599
|
+
@db.drop_table :cats, :dogs
|
|
600
|
+
@db.sqls.should == ['DROP TABLE cats', 'DROP TABLE dogs']
|
|
601
|
+
end
|
|
602
|
+
|
|
603
|
+
specify "should take an options hash and support the :cascade option" do
|
|
604
|
+
@db.drop_table :cats, :dogs, :cascade=>true
|
|
605
|
+
@db.sqls.should == ['DROP TABLE cats CASCADE', 'DROP TABLE dogs CASCADE']
|
|
606
|
+
end
|
|
597
607
|
end
|
|
598
608
|
|
|
599
609
|
describe "DB#alter_table" do
|
|
@@ -722,6 +732,13 @@ describe "DB#alter_table" do
|
|
|
722
732
|
@db.sqls.should == ["ALTER TABLE cats DROP COLUMN score"]
|
|
723
733
|
end
|
|
724
734
|
|
|
735
|
+
specify "should support drop_column with :cascade=>true option" do
|
|
736
|
+
@db.alter_table(:cats) do
|
|
737
|
+
drop_column :score, :cascade=>true
|
|
738
|
+
end
|
|
739
|
+
@db.sqls.should == ["ALTER TABLE cats DROP COLUMN score CASCADE"]
|
|
740
|
+
end
|
|
741
|
+
|
|
725
742
|
specify "should support drop_constraint" do
|
|
726
743
|
@db.alter_table(:cats) do
|
|
727
744
|
drop_constraint :valid_score
|
|
@@ -729,6 +746,13 @@ describe "DB#alter_table" do
|
|
|
729
746
|
@db.sqls.should == ["ALTER TABLE cats DROP CONSTRAINT valid_score"]
|
|
730
747
|
end
|
|
731
748
|
|
|
749
|
+
specify "should support drop_constraint with :cascade=>true option" do
|
|
750
|
+
@db.alter_table(:cats) do
|
|
751
|
+
drop_constraint :valid_score, :cascade=>true
|
|
752
|
+
end
|
|
753
|
+
@db.sqls.should == ["ALTER TABLE cats DROP CONSTRAINT valid_score CASCADE"]
|
|
754
|
+
end
|
|
755
|
+
|
|
732
756
|
specify "should support drop_index" do
|
|
733
757
|
@db.alter_table(:cats) do
|
|
734
758
|
drop_index :name
|
|
@@ -776,6 +800,286 @@ describe "DB#alter_table" do
|
|
|
776
800
|
end
|
|
777
801
|
end
|
|
778
802
|
|
|
803
|
+
describe "Database#create_table" do
|
|
804
|
+
before do
|
|
805
|
+
@db = DummyDatabase.new
|
|
806
|
+
end
|
|
807
|
+
|
|
808
|
+
specify "should construct proper SQL" do
|
|
809
|
+
@db.create_table :test do
|
|
810
|
+
primary_key :id, :integer, :null => false
|
|
811
|
+
column :name, :text
|
|
812
|
+
index :name, :unique => true
|
|
813
|
+
end
|
|
814
|
+
@db.sqls.should == [
|
|
815
|
+
'CREATE TABLE test (id integer NOT NULL PRIMARY KEY AUTOINCREMENT, name text)',
|
|
816
|
+
'CREATE UNIQUE INDEX test_name_index ON test (name)'
|
|
817
|
+
]
|
|
818
|
+
end
|
|
819
|
+
|
|
820
|
+
specify "should create a temporary table" do
|
|
821
|
+
@db.create_table :test_tmp, :temp => true do
|
|
822
|
+
primary_key :id, :integer, :null => false
|
|
823
|
+
column :name, :text
|
|
824
|
+
index :name, :unique => true
|
|
825
|
+
end
|
|
826
|
+
|
|
827
|
+
@db.sqls.should == [
|
|
828
|
+
'CREATE TEMPORARY TABLE test_tmp (id integer NOT NULL PRIMARY KEY AUTOINCREMENT, name text)',
|
|
829
|
+
'CREATE UNIQUE INDEX test_tmp_name_index ON test_tmp (name)'
|
|
830
|
+
]
|
|
831
|
+
end
|
|
832
|
+
|
|
833
|
+
specify "should not use default schema when creating a temporary table" do
|
|
834
|
+
@db.default_schema = :foo
|
|
835
|
+
@db.create_table :test_tmp, :temp => true do
|
|
836
|
+
column :name, :text
|
|
837
|
+
end
|
|
838
|
+
@db.sqls.should == ['CREATE TEMPORARY TABLE test_tmp (name text)']
|
|
839
|
+
end
|
|
840
|
+
end
|
|
841
|
+
|
|
842
|
+
describe "Database#alter_table" do
|
|
843
|
+
before do
|
|
844
|
+
@db = DummyDatabase.new
|
|
845
|
+
end
|
|
846
|
+
|
|
847
|
+
specify "should construct proper SQL" do
|
|
848
|
+
@db.alter_table :xyz do
|
|
849
|
+
add_column :aaa, :text, :null => false, :unique => true
|
|
850
|
+
drop_column :bbb
|
|
851
|
+
rename_column :ccc, :ddd
|
|
852
|
+
set_column_type :eee, :integer
|
|
853
|
+
set_column_default :hhh, 'abcd'
|
|
854
|
+
|
|
855
|
+
add_index :fff, :unique => true
|
|
856
|
+
drop_index :ggg
|
|
857
|
+
end
|
|
858
|
+
|
|
859
|
+
@db.sqls.should == [
|
|
860
|
+
'ALTER TABLE xyz ADD COLUMN aaa text NOT NULL UNIQUE',
|
|
861
|
+
'ALTER TABLE xyz DROP COLUMN bbb',
|
|
862
|
+
'ALTER TABLE xyz RENAME COLUMN ccc TO ddd',
|
|
863
|
+
'ALTER TABLE xyz ALTER COLUMN eee TYPE integer',
|
|
864
|
+
"ALTER TABLE xyz ALTER COLUMN hhh SET DEFAULT 'abcd'",
|
|
865
|
+
|
|
866
|
+
'CREATE UNIQUE INDEX xyz_fff_index ON xyz (fff)',
|
|
867
|
+
'DROP INDEX xyz_ggg_index'
|
|
868
|
+
]
|
|
869
|
+
end
|
|
870
|
+
end
|
|
871
|
+
|
|
872
|
+
describe "Database#add_column" do
|
|
873
|
+
before do
|
|
874
|
+
@db = DummyDatabase.new
|
|
875
|
+
end
|
|
876
|
+
|
|
877
|
+
specify "should construct proper SQL" do
|
|
878
|
+
@db.add_column :test, :name, :text, :unique => true
|
|
879
|
+
@db.sqls.should == [
|
|
880
|
+
'ALTER TABLE test ADD COLUMN name text UNIQUE'
|
|
881
|
+
]
|
|
882
|
+
end
|
|
883
|
+
end
|
|
884
|
+
|
|
885
|
+
describe "Database#drop_column" do
|
|
886
|
+
before do
|
|
887
|
+
@db = DummyDatabase.new
|
|
888
|
+
end
|
|
889
|
+
|
|
890
|
+
specify "should construct proper SQL" do
|
|
891
|
+
@db.drop_column :test, :name
|
|
892
|
+
@db.sqls.should == ['ALTER TABLE test DROP COLUMN name']
|
|
893
|
+
end
|
|
894
|
+
|
|
895
|
+
specify "should use CASCADE for :cascade=>true option" do
|
|
896
|
+
@db.drop_column :test, :name, :cascade=>true
|
|
897
|
+
@db.sqls.should == ['ALTER TABLE test DROP COLUMN name CASCADE']
|
|
898
|
+
end
|
|
899
|
+
end
|
|
900
|
+
|
|
901
|
+
describe "Database#rename_column" do
|
|
902
|
+
before do
|
|
903
|
+
@db = DummyDatabase.new
|
|
904
|
+
end
|
|
905
|
+
|
|
906
|
+
specify "should construct proper SQL" do
|
|
907
|
+
@db.rename_column :test, :abc, :def
|
|
908
|
+
@db.sqls.should == [
|
|
909
|
+
'ALTER TABLE test RENAME COLUMN abc TO def'
|
|
910
|
+
]
|
|
911
|
+
end
|
|
912
|
+
end
|
|
913
|
+
|
|
914
|
+
describe "Database#set_column_type" do
|
|
915
|
+
before do
|
|
916
|
+
@db = DummyDatabase.new
|
|
917
|
+
end
|
|
918
|
+
|
|
919
|
+
specify "should construct proper SQL" do
|
|
920
|
+
@db.set_column_type :test, :name, :integer
|
|
921
|
+
@db.sqls.should == [
|
|
922
|
+
'ALTER TABLE test ALTER COLUMN name TYPE integer'
|
|
923
|
+
]
|
|
924
|
+
end
|
|
925
|
+
end
|
|
926
|
+
|
|
927
|
+
describe "Database#set_column_default" do
|
|
928
|
+
before do
|
|
929
|
+
@db = DummyDatabase.new
|
|
930
|
+
end
|
|
931
|
+
|
|
932
|
+
specify "should construct proper SQL" do
|
|
933
|
+
@db.set_column_default :test, :name, 'zyx'
|
|
934
|
+
@db.sqls.should == [
|
|
935
|
+
"ALTER TABLE test ALTER COLUMN name SET DEFAULT 'zyx'"
|
|
936
|
+
]
|
|
937
|
+
end
|
|
938
|
+
end
|
|
939
|
+
|
|
940
|
+
describe "Database#add_index" do
|
|
941
|
+
before do
|
|
942
|
+
@db = DummyDatabase.new
|
|
943
|
+
end
|
|
944
|
+
|
|
945
|
+
specify "should construct proper SQL" do
|
|
946
|
+
@db.add_index :test, :name, :unique => true
|
|
947
|
+
@db.sqls.should == [
|
|
948
|
+
'CREATE UNIQUE INDEX test_name_index ON test (name)'
|
|
949
|
+
]
|
|
950
|
+
end
|
|
951
|
+
|
|
952
|
+
specify "should accept multiple columns" do
|
|
953
|
+
@db.add_index :test, [:one, :two]
|
|
954
|
+
@db.sqls.should == [
|
|
955
|
+
'CREATE INDEX test_one_two_index ON test (one, two)'
|
|
956
|
+
]
|
|
957
|
+
end
|
|
958
|
+
end
|
|
959
|
+
|
|
960
|
+
describe "Database#drop_index" do
|
|
961
|
+
before do
|
|
962
|
+
@db = DummyDatabase.new
|
|
963
|
+
end
|
|
964
|
+
|
|
965
|
+
specify "should construct proper SQL" do
|
|
966
|
+
@db.drop_index :test, :name
|
|
967
|
+
@db.sqls.should == [
|
|
968
|
+
'DROP INDEX test_name_index'
|
|
969
|
+
]
|
|
970
|
+
end
|
|
971
|
+
|
|
972
|
+
end
|
|
973
|
+
|
|
974
|
+
describe "Database#drop_table" do
|
|
975
|
+
before do
|
|
976
|
+
@db = DummyDatabase.new
|
|
977
|
+
end
|
|
978
|
+
|
|
979
|
+
specify "should construct proper SQL" do
|
|
980
|
+
@db.drop_table :test
|
|
981
|
+
@db.sqls.should == ['DROP TABLE test']
|
|
982
|
+
end
|
|
983
|
+
|
|
984
|
+
specify "should accept multiple table names" do
|
|
985
|
+
@db.drop_table :a, :bb, :ccc
|
|
986
|
+
@db.sqls.should == [
|
|
987
|
+
'DROP TABLE a',
|
|
988
|
+
'DROP TABLE bb',
|
|
989
|
+
'DROP TABLE ccc'
|
|
990
|
+
]
|
|
991
|
+
end
|
|
992
|
+
end
|
|
993
|
+
|
|
994
|
+
describe "Database#rename_table" do
|
|
995
|
+
before do
|
|
996
|
+
@db = DummyDatabase.new
|
|
997
|
+
end
|
|
998
|
+
|
|
999
|
+
specify "should construct proper SQL" do
|
|
1000
|
+
@db.rename_table :abc, :xyz
|
|
1001
|
+
@db.sqls.should == ['ALTER TABLE abc RENAME TO xyz']
|
|
1002
|
+
end
|
|
1003
|
+
end
|
|
1004
|
+
|
|
1005
|
+
describe "Database#create_view" do
|
|
1006
|
+
before do
|
|
1007
|
+
@db = DummyDatabase.new
|
|
1008
|
+
end
|
|
1009
|
+
|
|
1010
|
+
specify "should construct proper SQL with raw SQL" do
|
|
1011
|
+
@db.create_view :test, "SELECT * FROM xyz"
|
|
1012
|
+
@db.sqls.should == ['CREATE VIEW test AS SELECT * FROM xyz']
|
|
1013
|
+
@db.sqls.clear
|
|
1014
|
+
@db.create_view :test.identifier, "SELECT * FROM xyz"
|
|
1015
|
+
@db.sqls.should == ['CREATE VIEW test AS SELECT * FROM xyz']
|
|
1016
|
+
end
|
|
1017
|
+
|
|
1018
|
+
specify "should construct proper SQL with dataset" do
|
|
1019
|
+
@db.create_view :test, @db[:items].select(:a, :b).order(:c)
|
|
1020
|
+
@db.sqls.should == ['CREATE VIEW test AS SELECT a, b FROM items ORDER BY c']
|
|
1021
|
+
@db.sqls.clear
|
|
1022
|
+
@db.create_view :test.qualify(:sch), @db[:items].select(:a, :b).order(:c)
|
|
1023
|
+
@db.sqls.should == ['CREATE VIEW sch.test AS SELECT a, b FROM items ORDER BY c']
|
|
1024
|
+
end
|
|
1025
|
+
end
|
|
1026
|
+
|
|
1027
|
+
describe "Database#create_or_replace_view" do
|
|
1028
|
+
before do
|
|
1029
|
+
@db = DummyDatabase.new
|
|
1030
|
+
end
|
|
1031
|
+
|
|
1032
|
+
specify "should construct proper SQL with raw SQL" do
|
|
1033
|
+
@db.create_or_replace_view :test, "SELECT * FROM xyz"
|
|
1034
|
+
@db.sqls.should == ['CREATE OR REPLACE VIEW test AS SELECT * FROM xyz']
|
|
1035
|
+
@db.sqls.clear
|
|
1036
|
+
@db.create_or_replace_view :sch__test, "SELECT * FROM xyz"
|
|
1037
|
+
@db.sqls.should == ['CREATE OR REPLACE VIEW sch.test AS SELECT * FROM xyz']
|
|
1038
|
+
end
|
|
1039
|
+
|
|
1040
|
+
specify "should construct proper SQL with dataset" do
|
|
1041
|
+
@db.create_or_replace_view :test, @db[:items].select(:a, :b).order(:c)
|
|
1042
|
+
@db.sqls.should == ['CREATE OR REPLACE VIEW test AS SELECT a, b FROM items ORDER BY c']
|
|
1043
|
+
@db.sqls.clear
|
|
1044
|
+
@db.create_or_replace_view :test.identifier, @db[:items].select(:a, :b).order(:c)
|
|
1045
|
+
@db.sqls.should == ['CREATE OR REPLACE VIEW test AS SELECT a, b FROM items ORDER BY c']
|
|
1046
|
+
end
|
|
1047
|
+
end
|
|
1048
|
+
|
|
1049
|
+
describe "Database#drop_view" do
|
|
1050
|
+
before do
|
|
1051
|
+
@db = DummyDatabase.new
|
|
1052
|
+
end
|
|
1053
|
+
|
|
1054
|
+
specify "should construct proper SQL" do
|
|
1055
|
+
@db.drop_view :test
|
|
1056
|
+
@db.drop_view :test.identifier
|
|
1057
|
+
@db.drop_view :sch__test
|
|
1058
|
+
@db.drop_view :test.qualify(:sch)
|
|
1059
|
+
@db.sqls.should == ['DROP VIEW test', 'DROP VIEW test', 'DROP VIEW sch.test', 'DROP VIEW sch.test']
|
|
1060
|
+
end
|
|
1061
|
+
|
|
1062
|
+
specify "should drop multiple views at once" do
|
|
1063
|
+
@db.drop_view :cats, :dogs
|
|
1064
|
+
@db.sqls.should == ['DROP VIEW cats', 'DROP VIEW dogs']
|
|
1065
|
+
end
|
|
1066
|
+
|
|
1067
|
+
specify "should take an options hash and support the :cascade option" do
|
|
1068
|
+
@db.drop_view :cats, :dogs, :cascade=>true
|
|
1069
|
+
@db.sqls.should == ['DROP VIEW cats CASCADE', 'DROP VIEW dogs CASCADE']
|
|
1070
|
+
end
|
|
1071
|
+
end
|
|
1072
|
+
|
|
1073
|
+
describe "Database#alter_table_sql" do
|
|
1074
|
+
before do
|
|
1075
|
+
@db = DummyDatabase.new
|
|
1076
|
+
end
|
|
1077
|
+
|
|
1078
|
+
specify "should raise error for an invalid op" do
|
|
1079
|
+
proc {@db.send(:alter_table_sql, :mau, :op => :blah)}.should raise_error(Sequel::Error)
|
|
1080
|
+
end
|
|
1081
|
+
end
|
|
1082
|
+
|
|
779
1083
|
describe "Schema Parser" do
|
|
780
1084
|
before do
|
|
781
1085
|
@sqls = []
|
data/spec/core/spec_helper.rb
CHANGED
|
@@ -60,3 +60,32 @@ class SchemaDummyDatabase < Sequel::Database
|
|
|
60
60
|
@sqls << sql
|
|
61
61
|
end
|
|
62
62
|
end
|
|
63
|
+
|
|
64
|
+
class DummyDataset < Sequel::Dataset
|
|
65
|
+
def first
|
|
66
|
+
raise if @opts[:from] == [:a]
|
|
67
|
+
true
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
class DummyDatabase < Sequel::Database
|
|
72
|
+
attr_reader :sqls
|
|
73
|
+
|
|
74
|
+
def execute(sql, opts={})
|
|
75
|
+
@sqls ||= []
|
|
76
|
+
@sqls << sql
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def transaction; yield; end
|
|
80
|
+
|
|
81
|
+
def dataset
|
|
82
|
+
DummyDataset.new(self)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
class Dummy2Database < Sequel::Database
|
|
87
|
+
attr_reader :sql
|
|
88
|
+
def execute(sql); @sql = sql; end
|
|
89
|
+
def transaction; yield; end
|
|
90
|
+
end
|
|
91
|
+
|
|
@@ -89,4 +89,35 @@ describe "Sequel::Plugins::AssociationPks" do
|
|
|
89
89
|
@db.sqls[3].should == "COMMIT"
|
|
90
90
|
end
|
|
91
91
|
|
|
92
|
+
specify "should automatically convert keys to numbers if the primary key is an integer for one_to_many associations" do
|
|
93
|
+
@Album.db_schema[:id][:type] = :integer
|
|
94
|
+
@Artist.load(:id=>1).album_pks = %w'1 2'
|
|
95
|
+
@db.sqls.should == ["UPDATE albums SET artist_id = 1 WHERE (id IN (1, 2))",
|
|
96
|
+
"UPDATE albums SET artist_id = NULL WHERE ((albums.artist_id = 1) AND (id NOT IN (1, 2)))"]
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
specify "should not automatically convert keys if the primary key is not an integer for many_to_many associations" do
|
|
100
|
+
@Album.db_schema[:id][:type] = :string
|
|
101
|
+
@Artist.load(:id=>1).album_pks = %w'1 2'
|
|
102
|
+
@db.sqls.should == ["UPDATE albums SET artist_id = 1 WHERE (id IN ('1', '2'))",
|
|
103
|
+
"UPDATE albums SET artist_id = NULL WHERE ((albums.artist_id = 1) AND (id NOT IN ('1', '2')))"]
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
specify "should automatically convert keys to numbers if the primary key is an integer for one_to_many associations" do
|
|
107
|
+
@Tag.db_schema[:id][:type] = :integer
|
|
108
|
+
@Album.load(:id=>2).tag_pks = %w'1 3'
|
|
109
|
+
@db.sqls[0].should == "DELETE FROM albums_tags WHERE ((album_id = 2) AND (tag_id NOT IN (1, 3)))"
|
|
110
|
+
@db.sqls[1].should =~ /INSERT INTO albums_tags \((album_id, tag_id|tag_id, album_id)\) VALUES \((2, 1|1, 2)\)/
|
|
111
|
+
@db.sqls.length.should == 2
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
specify "should not automatically convert keys to numbers if the primary key is an integer for many_to_many associations" do
|
|
115
|
+
@Tag.db_schema[:id][:type] = :string
|
|
116
|
+
@Album.load(:id=>2).tag_pks = %w'1 3'
|
|
117
|
+
@db.sqls[0].should == "DELETE FROM albums_tags WHERE ((album_id = 2) AND (tag_id NOT IN ('1', '3')))"
|
|
118
|
+
@db.sqls[1].should =~ /INSERT INTO albums_tags \((album_id, tag_id|tag_id, album_id)\) VALUES \((2, '1'|'1', 2)\)/
|
|
119
|
+
@db.sqls[2].should =~ /INSERT INTO albums_tags \((album_id, tag_id|tag_id, album_id)\) VALUES \((2, '3'|'3', 2)\)/
|
|
120
|
+
@db.sqls.length.should == 3
|
|
121
|
+
end
|
|
122
|
+
|
|
92
123
|
end
|
|
@@ -23,22 +23,19 @@ describe Sequel::Model, "dataset & schema" do
|
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
describe Sequel::Model, "table_exists?" do
|
|
26
|
-
|
|
27
|
-
before(:each) do
|
|
26
|
+
before do
|
|
28
27
|
MODEL_DB.reset
|
|
29
28
|
@model = Class.new(Sequel::Model(:items))
|
|
30
29
|
end
|
|
31
30
|
|
|
32
31
|
it "should get the table name and question the model's db if table_exists?" do
|
|
33
|
-
@model.should_receive(:
|
|
34
|
-
@model.
|
|
35
|
-
@model.table_exists?
|
|
32
|
+
@model.db.should_receive(:table_exists?).and_return(false)
|
|
33
|
+
@model.table_exists?.should == false
|
|
36
34
|
end
|
|
37
35
|
end
|
|
38
36
|
|
|
39
37
|
describe Sequel::Model, "create_table and schema" do
|
|
40
|
-
|
|
41
|
-
before(:each) do
|
|
38
|
+
before do
|
|
42
39
|
MODEL_DB.reset
|
|
43
40
|
@model = Class.new(Sequel::Model) do
|
|
44
41
|
set_schema(:items) do
|
|
@@ -84,19 +81,15 @@ describe Sequel::Model, "create_table and schema" do
|
|
|
84
81
|
end
|
|
85
82
|
|
|
86
83
|
describe Sequel::Model, "drop_table" do
|
|
87
|
-
|
|
88
|
-
before(:each) do
|
|
89
|
-
MODEL_DB.reset
|
|
84
|
+
before do
|
|
90
85
|
@model = Class.new(Sequel::Model(:items))
|
|
86
|
+
MODEL_DB.reset
|
|
91
87
|
end
|
|
92
88
|
|
|
93
89
|
it "should get the drop table SQL for the associated table and then execute the SQL." do
|
|
94
|
-
@model.should_receive(:table_name).and_return(:items)
|
|
95
|
-
@model.db.should_receive(:drop_table_sql).with(:items)
|
|
96
|
-
@model.db.should_receive(:execute).and_return(:true)
|
|
97
90
|
@model.drop_table
|
|
91
|
+
MODEL_DB.sqls.should == ['DROP TABLE items']
|
|
98
92
|
end
|
|
99
|
-
|
|
100
93
|
end
|
|
101
94
|
|
|
102
95
|
describe Sequel::Model, "create_table!" do
|
|
@@ -106,9 +99,8 @@ describe Sequel::Model, "create_table!" do
|
|
|
106
99
|
end
|
|
107
100
|
|
|
108
101
|
it "should drop table if it exists and then create the table" do
|
|
109
|
-
@model.should_receive(:drop_table).and_return(true)
|
|
110
|
-
@model.should_receive(:create_table).and_return(true)
|
|
111
102
|
@model.create_table!
|
|
103
|
+
MODEL_DB.sqls.should == ['DROP TABLE items', 'CREATE TABLE items ()']
|
|
112
104
|
end
|
|
113
105
|
end
|
|
114
106
|
|
|
@@ -120,13 +112,13 @@ describe Sequel::Model, "create_table?" do
|
|
|
120
112
|
|
|
121
113
|
it "should not create the table if it already exists" do
|
|
122
114
|
@model.should_receive(:table_exists?).and_return(true)
|
|
123
|
-
@model.
|
|
124
|
-
|
|
115
|
+
@model.create_table?
|
|
116
|
+
MODEL_DB.sqls.should == []
|
|
125
117
|
end
|
|
126
118
|
|
|
127
119
|
it "should create the table if it doesn't exist" do
|
|
128
120
|
@model.should_receive(:table_exists?).and_return(false)
|
|
129
|
-
@model.
|
|
130
|
-
|
|
121
|
+
@model.create_table?
|
|
122
|
+
MODEL_DB.sqls.should == ['CREATE TABLE items ()']
|
|
131
123
|
end
|
|
132
124
|
end
|
|
@@ -632,6 +632,23 @@ describe "Sequel::Dataset main SQL methods" do
|
|
|
632
632
|
@ds.filter(:a=>20).or(:b=>15).all.should == [{:a=>20, :b=>30}]
|
|
633
633
|
@ds.filter(:a=>10).or(:b=>15).all.should == []
|
|
634
634
|
end
|
|
635
|
+
|
|
636
|
+
it "#select_group should work correctly" do
|
|
637
|
+
@ds.unordered!
|
|
638
|
+
@ds.select_group(:a).all.should == []
|
|
639
|
+
@ds.insert(20, 30)
|
|
640
|
+
@ds.select_group(:a).all.should == [{:a=>20}]
|
|
641
|
+
@ds.select_group(:b).all.should == [{:b=>30}]
|
|
642
|
+
@ds.insert(20, 40)
|
|
643
|
+
@ds.select_group(:a).all.should == [{:a=>20}]
|
|
644
|
+
@ds.order(:b).select_group(:b).all.should == [{:b=>30}, {:b=>40}]
|
|
645
|
+
end
|
|
646
|
+
|
|
647
|
+
it "#select_group should work correctly when aliasing" do
|
|
648
|
+
@ds.unordered!
|
|
649
|
+
@ds.insert(20, 30)
|
|
650
|
+
@ds.select_group(:b___c).all.should == [{:c=>30}]
|
|
651
|
+
end
|
|
635
652
|
|
|
636
653
|
it "#having should work correctly" do
|
|
637
654
|
@ds.unordered!
|
|
@@ -95,6 +95,13 @@ describe "Prepared Statements and Bound Arguments" do
|
|
|
95
95
|
@ds.order(:id).map(:number).should == [10, 20]
|
|
96
96
|
end
|
|
97
97
|
|
|
98
|
+
specify "should support bound variables with NULL values" do
|
|
99
|
+
@ds.delete
|
|
100
|
+
@ds.call(:insert, {:n=>nil}, :number=>@ds.ba(:$n))
|
|
101
|
+
@ds.count.should == 1
|
|
102
|
+
@ds.map(:number).should == [nil]
|
|
103
|
+
end
|
|
104
|
+
|
|
98
105
|
specify "should have insert return primary key value when using bound arguments" do
|
|
99
106
|
@ds.call(:insert, {:n=>20}, :number=>@ds.ba(:$n)).should == 2
|
|
100
107
|
@ds.filter(:id=>2).first[:number].should == 20
|
|
@@ -172,6 +179,14 @@ describe "Prepared Statements and Bound Arguments" do
|
|
|
172
179
|
@ds.order(:id).map(:number).should == [10, 20]
|
|
173
180
|
end
|
|
174
181
|
|
|
182
|
+
specify "should support prepared statements with NULL values" do
|
|
183
|
+
@ds.delete
|
|
184
|
+
@ds.prepare(:insert, :insert_n, :number=>@ds.ba(:$n))
|
|
185
|
+
INTEGRATION_DB.call(:insert_n, :n=>nil)
|
|
186
|
+
@ds.count.should == 1
|
|
187
|
+
@ds.map(:number).should == [nil]
|
|
188
|
+
end
|
|
189
|
+
|
|
175
190
|
specify "should have insert return primary key value when using prepared statements" do
|
|
176
191
|
@ds.prepare(:insert, :insert_n, :number=>@ds.ba(:$n))
|
|
177
192
|
INTEGRATION_DB.call(:insert_n, :n=>20).should == 2
|
|
@@ -183,6 +183,15 @@ describe "Database schema modifiers" do
|
|
|
183
183
|
@db[:items].columns.should == [:b]
|
|
184
184
|
end
|
|
185
185
|
|
|
186
|
+
specify "should have create_table? work correctly with indexes" do
|
|
187
|
+
@db.create_table!(:items){String :a, :index=>true}
|
|
188
|
+
@db.create_table?(:items){String :b, :index=>true}
|
|
189
|
+
@db[:items].columns.should == [:a]
|
|
190
|
+
@db.drop_table(:items) rescue nil
|
|
191
|
+
@db.create_table?(:items){String :b, :index=>true}
|
|
192
|
+
@db[:items].columns.should == [:b]
|
|
193
|
+
end
|
|
194
|
+
|
|
186
195
|
specify "should rename tables correctly" do
|
|
187
196
|
@db.drop_table(:items) rescue nil
|
|
188
197
|
@db.create_table!(:items2){Integer :number}
|
data/spec/model/model_spec.rb
CHANGED
|
@@ -19,6 +19,27 @@ describe "Sequel::Model()" do
|
|
|
19
19
|
c.table_name.should == :blah
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
it "should return a model subclass with a dataset with the default database and given table name if given an SQL::Identifier" do
|
|
23
|
+
c = Sequel::Model(:blah.identifier)
|
|
24
|
+
c.superclass.should == Sequel::Model
|
|
25
|
+
c.db.should == @db
|
|
26
|
+
c.table_name.should == :blah.identifier
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "should return a model subclass with a dataset with the default database and given table name if given an SQL::QualifiedIdentifier" do
|
|
30
|
+
c = Sequel::Model(:blah.qualify(:boo))
|
|
31
|
+
c.superclass.should == Sequel::Model
|
|
32
|
+
c.db.should == @db
|
|
33
|
+
c.table_name.should == :blah.qualify(:boo)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "should return a model subclass with a dataset with the default database and given table name if given an SQL::AliasedExpression" do
|
|
37
|
+
c = Sequel::Model(:blah.as(:boo))
|
|
38
|
+
c.superclass.should == Sequel::Model
|
|
39
|
+
c.db.should == @db
|
|
40
|
+
c.table_name.should == :boo
|
|
41
|
+
end
|
|
42
|
+
|
|
22
43
|
it "should return a model subclass associated to the given database if given a database" do
|
|
23
44
|
db = Sequel::Database.new
|
|
24
45
|
c = Sequel::Model(db)
|
|
@@ -43,6 +64,27 @@ describe "Sequel::Model()" do
|
|
|
43
64
|
end.should_not raise_error
|
|
44
65
|
end
|
|
45
66
|
|
|
67
|
+
it "should work without raising an exception with an SQL::Identifier " do
|
|
68
|
+
proc do
|
|
69
|
+
class ::Album < Sequel::Model(:table.identifier); end
|
|
70
|
+
class ::Album < Sequel::Model(:table.identifier); end
|
|
71
|
+
end.should_not raise_error
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it "should work without raising an exception with an SQL::QualifiedIdentifier " do
|
|
75
|
+
proc do
|
|
76
|
+
class ::Album < Sequel::Model(:table.qualify(:schema)); end
|
|
77
|
+
class ::Album < Sequel::Model(:table.qualify(:schema)); end
|
|
78
|
+
end.should_not raise_error
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it "should work without raising an exception with an SQL::AliasedExpression" do
|
|
82
|
+
proc do
|
|
83
|
+
class ::Album < Sequel::Model(:table.as(:alias)); end
|
|
84
|
+
class ::Album < Sequel::Model(:table.as(:alias)); end
|
|
85
|
+
end.should_not raise_error
|
|
86
|
+
end
|
|
87
|
+
|
|
46
88
|
it "should work without raising an exception with a database" do
|
|
47
89
|
proc do
|
|
48
90
|
class ::Album < Sequel::Model(@db); end
|
|
@@ -112,6 +154,24 @@ describe Sequel::Model, "dataset & schema" do
|
|
|
112
154
|
@model.table_name.should == :foo
|
|
113
155
|
end
|
|
114
156
|
|
|
157
|
+
it "set_dataset should take an SQL::Identifier" do
|
|
158
|
+
@model.db = MODEL_DB
|
|
159
|
+
@model.set_dataset(:foo.identifier)
|
|
160
|
+
@model.table_name.should == :foo.identifier
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
it "set_dataset should take an SQL::QualifiedIdentifier" do
|
|
164
|
+
@model.db = MODEL_DB
|
|
165
|
+
@model.set_dataset(:foo.qualify(:bar))
|
|
166
|
+
@model.table_name.should == :foo.qualify(:bar)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
it "set_dataset should take an SQL::AliasedExpression" do
|
|
170
|
+
@model.db = MODEL_DB
|
|
171
|
+
@model.set_dataset(:foo.as(:bar))
|
|
172
|
+
@model.table_name.should == :bar
|
|
173
|
+
end
|
|
174
|
+
|
|
115
175
|
it "table_name should respect table aliases" do
|
|
116
176
|
@model.set_dataset(:foo___x)
|
|
117
177
|
@model.table_name.should == :x
|
data/spec/model/plugins_spec.rb
CHANGED
|
@@ -233,4 +233,21 @@ describe Sequel::Model, ".plugin" do
|
|
|
233
233
|
end
|
|
234
234
|
lambda{@c.plugin m}.should_not raise_error
|
|
235
235
|
end
|
|
236
|
+
|
|
237
|
+
it "should not raise an error if plugin submodule names exist higher up in the namespace hierarchy" do
|
|
238
|
+
class ::ClassMethods; end
|
|
239
|
+
@c.plugin(m = Module.new)
|
|
240
|
+
Object.send(:remove_const, :ClassMethods)
|
|
241
|
+
@c.plugins.should include(m)
|
|
242
|
+
|
|
243
|
+
class ::InstanceMethods; end
|
|
244
|
+
@c.plugin(m = Module.new)
|
|
245
|
+
Object.send(:remove_const, :InstanceMethods)
|
|
246
|
+
@c.plugins.should include(m)
|
|
247
|
+
|
|
248
|
+
class ::DatasetMethods; end
|
|
249
|
+
@c.plugin(m = Module.new)
|
|
250
|
+
Object.send(:remove_const, :DatasetMethods)
|
|
251
|
+
@c.plugins.should include(m)
|
|
252
|
+
end
|
|
236
253
|
end
|
|
@@ -61,6 +61,17 @@ describe Sequel::Model::Errors do
|
|
|
61
61
|
msgs.should include('blow blieuh', 'blow blich', 'blay bliu')
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
+
specify "should not add column names for LiteralStrings" do
|
|
65
|
+
@errors.full_messages.should == []
|
|
66
|
+
|
|
67
|
+
@errors[:blow] << 'blieuh'
|
|
68
|
+
@errors[:blow] << 'blich'.lit
|
|
69
|
+
@errors[:blay] << 'bliu'
|
|
70
|
+
msgs = @errors.full_messages
|
|
71
|
+
msgs.size.should == 3
|
|
72
|
+
msgs.should include('blow blieuh', 'blich', 'blay bliu')
|
|
73
|
+
end
|
|
74
|
+
|
|
64
75
|
specify "should return the number of error messages using #count" do
|
|
65
76
|
@errors.count.should == 0
|
|
66
77
|
@errors.add(:a, 'b')
|