sequel 4.39.0 → 4.40.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.
- checksums.yaml +4 -4
- data/CHANGELOG +34 -0
- data/README.rdoc +8 -4
- data/doc/active_record.rdoc +1 -1
- data/doc/advanced_associations.rdoc +7 -7
- data/doc/association_basics.rdoc +7 -7
- data/doc/cheat_sheet.rdoc +5 -3
- data/doc/core_extensions.rdoc +3 -3
- data/doc/dataset_filtering.rdoc +1 -1
- data/doc/object_model.rdoc +16 -7
- data/doc/postgresql.rdoc +3 -3
- data/doc/querying.rdoc +3 -3
- data/doc/release_notes/4.40.0.txt +179 -0
- data/doc/security.rdoc +2 -1
- data/doc/sql.rdoc +34 -18
- data/doc/testing.rdoc +1 -0
- data/doc/virtual_rows.rdoc +11 -2
- data/lib/sequel/adapters/jdbc/derby.rb +7 -1
- data/lib/sequel/adapters/jdbc/h2.rb +15 -1
- data/lib/sequel/adapters/oracle.rb +9 -5
- data/lib/sequel/adapters/postgres.rb +0 -1
- data/lib/sequel/adapters/shared/cubrid.rb +11 -11
- data/lib/sequel/adapters/shared/db2.rb +4 -8
- data/lib/sequel/adapters/shared/mssql.rb +41 -28
- data/lib/sequel/adapters/shared/mysql.rb +9 -6
- data/lib/sequel/adapters/shared/oracle.rb +16 -5
- data/lib/sequel/adapters/shared/postgres.rb +84 -45
- data/lib/sequel/adapters/shared/sqlanywhere.rb +29 -15
- data/lib/sequel/adapters/shared/sqlite.rb +6 -6
- data/lib/sequel/core.rb +61 -10
- data/lib/sequel/database/connecting.rb +2 -1
- data/lib/sequel/database/features.rb +7 -0
- data/lib/sequel/database/query.rb +1 -1
- data/lib/sequel/database/schema_methods.rb +30 -3
- data/lib/sequel/database/transactions.rb +4 -2
- data/lib/sequel/dataset/actions.rb +1 -1
- data/lib/sequel/dataset/graph.rb +6 -1
- data/lib/sequel/dataset/query.rb +14 -7
- data/lib/sequel/dataset/sql.rb +2 -2
- data/lib/sequel/extensions/core_extensions.rb +2 -1
- data/lib/sequel/extensions/pg_row.rb +2 -2
- data/lib/sequel/extensions/s.rb +57 -0
- data/lib/sequel/extensions/set_overrides.rb +5 -1
- data/lib/sequel/extensions/sql_expr.rb +1 -0
- data/lib/sequel/extensions/symbol_aref.rb +71 -0
- data/lib/sequel/extensions/symbol_aref_refinement.rb +41 -0
- data/lib/sequel/extensions/symbol_as.rb +23 -0
- data/lib/sequel/extensions/symbol_as_refinement.rb +35 -0
- data/lib/sequel/model/base.rb +3 -3
- data/lib/sequel/plugins/class_table_inheritance.rb +14 -3
- data/lib/sequel/plugins/column_select.rb +4 -2
- data/lib/sequel/plugins/dataset_associations.rb +12 -4
- data/lib/sequel/plugins/insert_returning_select.rb +1 -1
- data/lib/sequel/plugins/mssql_optimistic_locking.rb +1 -1
- data/lib/sequel/plugins/prepared_statements.rb +1 -0
- data/lib/sequel/sql.rb +40 -8
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/firebird_spec.rb +3 -3
- data/spec/adapters/mssql_spec.rb +40 -40
- data/spec/adapters/mysql_spec.rb +5 -5
- data/spec/adapters/oracle_spec.rb +4 -4
- data/spec/adapters/postgres_spec.rb +135 -124
- data/spec/adapters/spec_helper.rb +1 -0
- data/spec/adapters/sqlite_spec.rb +6 -6
- data/spec/core/dataset_spec.rb +2 -2
- data/spec/core/expression_filters_spec.rb +43 -2
- data/spec/core/schema_spec.rb +35 -1
- data/spec/core_extensions_spec.rb +27 -0
- data/spec/extensions/class_table_inheritance_spec.rb +8 -0
- data/spec/extensions/column_select_spec.rb +8 -0
- data/spec/extensions/core_refinements_spec.rb +1 -1
- data/spec/extensions/dataset_associations_spec.rb +9 -0
- data/spec/extensions/insert_returning_select_spec.rb +20 -0
- data/spec/extensions/prepared_statements_spec.rb +7 -0
- data/spec/extensions/s_spec.rb +60 -0
- data/spec/extensions/symbol_aref_refinement_spec.rb +28 -0
- data/spec/extensions/symbol_as_refinement_spec.rb +21 -0
- data/spec/integration/associations_test.rb +62 -57
- data/spec/integration/dataset_test.rb +54 -54
- data/spec/integration/eager_loader_test.rb +7 -7
- data/spec/integration/plugin_test.rb +20 -20
- data/spec/integration/prepared_statement_test.rb +1 -1
- data/spec/integration/schema_test.rb +21 -0
- data/spec/integration/spec_helper.rb +1 -0
- metadata +12 -2
@@ -15,6 +15,7 @@ begin
|
|
15
15
|
rescue LoadError
|
16
16
|
end
|
17
17
|
|
18
|
+
Sequel.split_symbols = false if ENV['SEQUEL_NO_SPLIT_SYMBOLS']
|
18
19
|
Sequel::Database.extension :duplicate_column_handler if ENV['SEQUEL_DUPLICATE_COLUMN_HANDLER']
|
19
20
|
Sequel::Database.extension :columns_introspection if ENV['SEQUEL_COLUMNS_INTROSPECTION']
|
20
21
|
Sequel::Model.cache_associations = false if ENV['SEQUEL_NO_CACHE_ASSOCIATIONS']
|
@@ -309,12 +309,12 @@ describe "An SQLite dataset" do
|
|
309
309
|
end
|
310
310
|
|
311
311
|
describe "An SQLite dataset AS clause" do
|
312
|
-
it "should use a string literal for :
|
313
|
-
DB.literal(:
|
312
|
+
it "should use a string literal for Sequel[:col].as(:alias)" do
|
313
|
+
DB.literal(Sequel[:c].as(:a)).must_equal "`c` AS 'a'"
|
314
314
|
end
|
315
315
|
|
316
|
-
it "should use a string literal for :
|
317
|
-
DB.literal(:
|
316
|
+
it "should use a string literal for Sequel[:table][:col].as(:alias)" do
|
317
|
+
DB.literal(Sequel[:t][:c].as(:a)).must_equal "`t`.`c` AS 'a'"
|
318
318
|
end
|
319
319
|
|
320
320
|
it "should use a string literal for :column.as(:alias)" do
|
@@ -322,11 +322,11 @@ describe "An SQLite dataset AS clause" do
|
|
322
322
|
end
|
323
323
|
|
324
324
|
it "should use a string literal in the SELECT clause" do
|
325
|
-
DB[:t].select(:
|
325
|
+
DB[:t].select(Sequel[:c].as(:a)).sql.must_equal "SELECT `c` AS 'a' FROM `t`"
|
326
326
|
end
|
327
327
|
|
328
328
|
it "should use a string literal in the FROM clause" do
|
329
|
-
DB[:
|
329
|
+
DB[Sequel[:t].as(:a)].sql.must_equal "SELECT * FROM `t` AS 'a'"
|
330
330
|
end
|
331
331
|
|
332
332
|
it "should use a string literal in the JOIN clause" do
|
data/spec/core/dataset_spec.rb
CHANGED
@@ -5108,13 +5108,13 @@ describe "Dataset emulated complex expression operators" do
|
|
5108
5108
|
it "should emulate >>" do
|
5109
5109
|
@ds.literal(Sequel::SQL::NumericExpression.new(:>>, @n)).must_equal "x"
|
5110
5110
|
@ds.literal(@n >> 1).must_equal "(x / power(2, 1))"
|
5111
|
-
@ds.literal(@n >> 1 >> 2).must_equal "(x / power(2, 1) / power(2, 2))"
|
5111
|
+
@ds.literal(@n >> 1 >> 2).must_equal "((x / power(2, 1)) / power(2, 2))"
|
5112
5112
|
end
|
5113
5113
|
|
5114
5114
|
it "should emulate <<" do
|
5115
5115
|
@ds.literal(Sequel::SQL::NumericExpression.new(:<<, @n)).must_equal "x"
|
5116
5116
|
@ds.literal(@n << 1).must_equal "(x * power(2, 1))"
|
5117
|
-
@ds.literal(@n << 1 << 2).must_equal "(x * power(2, 1) * power(2, 2))"
|
5117
|
+
@ds.literal(@n << 1 << 2).must_equal "((x * power(2, 1)) * power(2, 2))"
|
5118
5118
|
end
|
5119
5119
|
|
5120
5120
|
it "should emulate B~" do
|
@@ -16,8 +16,26 @@ describe "Blockless Ruby Filters" do
|
|
16
16
|
@d.l(:x).must_equal 'x'
|
17
17
|
end
|
18
18
|
|
19
|
-
it "should support qualified columns" do
|
19
|
+
it "should support qualified columns and aliased columns using symbols" do
|
20
20
|
@d.l(:x__y).must_equal 'x.y'
|
21
|
+
@d.l(:x___y).must_equal 'x AS y'
|
22
|
+
@d.l(:x__y___z).must_equal 'x.y AS z'
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should support qualified columns using virtual rows" do
|
26
|
+
@d.l(Sequel.expr{x__y}).must_equal 'x.y'
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should not split symbols or virtual row methods if symbol splitting is disabled" do
|
30
|
+
begin
|
31
|
+
Sequel.split_symbols = false
|
32
|
+
@d.l(:x__y).must_equal 'x__y'
|
33
|
+
@d.l(:x___y).must_equal 'x___y'
|
34
|
+
@d.l(:x__y___z).must_equal 'x__y___z'
|
35
|
+
@d.l(Sequel.expr{x__y}).must_equal 'x__y'
|
36
|
+
ensure
|
37
|
+
Sequel.split_symbols = true
|
38
|
+
end
|
21
39
|
end
|
22
40
|
|
23
41
|
it "should support NOT with SQL functions" do
|
@@ -129,6 +147,21 @@ describe "Blockless Ruby Filters" do
|
|
129
147
|
proc{~Sequel.expr(:x).sql_string}.must_raise(NoMethodError)
|
130
148
|
end
|
131
149
|
|
150
|
+
it "should only allow combining associative operators" do
|
151
|
+
@d.lit(Sequel.expr{a + b + c}).must_equal '(a + b + c)'
|
152
|
+
@d.lit(Sequel.expr{a - b - c}).must_equal '((a - b) - c)'
|
153
|
+
@d.lit(Sequel.expr{a * b * c}).must_equal '(a * b * c)'
|
154
|
+
@d.lit(Sequel.expr{a / b / c}).must_equal '((a / b) / c)'
|
155
|
+
@d.lit(Sequel.expr{a & b & c}).must_equal '(a AND b AND c)'
|
156
|
+
@d.lit(Sequel.expr{a | b | c}).must_equal '(a OR b OR c)'
|
157
|
+
@d.lit(Sequel.expr{a.sql_string + b + c}).must_equal '(a || b || c)'
|
158
|
+
@d.lit(Sequel.expr{a.sql_number >> b >> c}).must_equal '((a >> b) >> c)'
|
159
|
+
@d.lit(Sequel.expr{a.sql_number << b << c}).must_equal '((a << b) << c)'
|
160
|
+
@d.lit(Sequel.expr{a.sql_number % b % c}).must_equal '((a % b) % c)'
|
161
|
+
@d.lit(Sequel.expr{a.sql_number & b & c}).must_equal '(a & b & c)'
|
162
|
+
@d.lit(Sequel.expr{a.sql_number | b | c}).must_equal '(a | b | c)'
|
163
|
+
end
|
164
|
+
|
132
165
|
it "should allow mathematical or string operations on true, false, or nil" do
|
133
166
|
@d.lit(Sequel.expr(:x) + 1).must_equal '(x + 1)'
|
134
167
|
@d.lit(Sequel.expr(:x) - true).must_equal "(x - 't')"
|
@@ -206,7 +239,7 @@ describe "Blockless Ruby Filters" do
|
|
206
239
|
@d.l((Sequel.lit('x') * :y) < 100.01).must_equal '((x * y) < 100.01)'
|
207
240
|
@d.l((Sequel.lit('x') ** :y) < 100.01).must_equal '(power(x, y) < 100.01)'
|
208
241
|
@d.l((Sequel.lit('x') - Sequel.expr(:y)/2) >= 100000000000000000000000000000000000).must_equal '((x - (y / 2)) >= 100000000000000000000000000000000000)'
|
209
|
-
@d.l((Sequel.lit('z') * ((Sequel.lit('x') / :y)/(Sequel.expr(:x) + :y))) <= 100).must_equal '((z * (x / y / (x + y))) <= 100)'
|
242
|
+
@d.l((Sequel.lit('z') * ((Sequel.lit('x') / :y)/(Sequel.expr(:x) + :y))) <= 100).must_equal '((z * ((x / y) / (x + y))) <= 100)'
|
210
243
|
@d.l(~((((Sequel.lit('x') - :y)/(Sequel.expr(:x) + :y))*:z) <= 100)).must_equal '((((x - y) / (x + y)) * z) > 100)'
|
211
244
|
end
|
212
245
|
|
@@ -921,6 +954,14 @@ describe "Sequel core extension replacements" do
|
|
921
954
|
l(Sequel.qualify(:t, :c), "t.c")
|
922
955
|
end
|
923
956
|
|
957
|
+
it "Sequel::SQL::Identifier#[] should return a qualified identifier" do
|
958
|
+
l(Sequel[:t][:c], "t.c")
|
959
|
+
end
|
960
|
+
|
961
|
+
it "Sequel::SQL::QualifiedIdentifier#[] should return a nested qualified identifier" do
|
962
|
+
l(Sequel[:s][:t][:c], "s.t.c")
|
963
|
+
end
|
964
|
+
|
924
965
|
it "Sequel.identifier should return an identifier" do
|
925
966
|
l(Sequel.identifier(:t__c), "t__c")
|
926
967
|
end
|
data/spec/core/schema_spec.rb
CHANGED
@@ -12,10 +12,11 @@ describe "DB#create_table" do
|
|
12
12
|
|
13
13
|
it "should accept the table name in multiple formats" do
|
14
14
|
@db.create_table(:cats__cats) {}
|
15
|
+
@db.create_table(Sequel[:cats][:cats]) {}
|
15
16
|
@db.create_table("cats__cats1") {}
|
16
17
|
@db.create_table(Sequel.identifier(:cats__cats2)) {}
|
17
18
|
@db.create_table(Sequel.qualify(:cats3, :cats)) {}
|
18
|
-
@db.sqls.must_equal ['CREATE TABLE cats.cats ()', 'CREATE TABLE cats__cats1 ()', 'CREATE TABLE cats__cats2 ()', 'CREATE TABLE cats3.cats ()']
|
19
|
+
@db.sqls.must_equal ['CREATE TABLE cats.cats ()', 'CREATE TABLE cats.cats ()', 'CREATE TABLE cats__cats1 ()', 'CREATE TABLE cats__cats2 ()', 'CREATE TABLE cats3.cats ()']
|
19
20
|
end
|
20
21
|
|
21
22
|
it "should raise an error if the table name argument is not valid" do
|
@@ -132,6 +133,23 @@ describe "DB#create_table" do
|
|
132
133
|
@db.sqls.must_equal ['CREATE TABLE cats (id integer CONSTRAINT foo PRIMARY KEY AUTOINCREMENT)']
|
133
134
|
end
|
134
135
|
|
136
|
+
it "should automatically set primary key column NOT NULL if database doesn't do it automatically" do
|
137
|
+
def @db.can_add_primary_key_constraint_on_nullable_columns?; false end
|
138
|
+
@db.create_table(:cats) do
|
139
|
+
primary_key :id
|
140
|
+
end
|
141
|
+
@db.sqls.must_equal ['CREATE TABLE cats (id integer NOT NULL PRIMARY KEY AUTOINCREMENT)']
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should automatically set primary key column NOT NULL when adding constraint if database doesn't do it automatically" do
|
145
|
+
def @db.can_add_primary_key_constraint_on_nullable_columns?; false end
|
146
|
+
@db.create_table(:cats) do
|
147
|
+
String :id
|
148
|
+
primary_key [:id]
|
149
|
+
end
|
150
|
+
@db.sqls.must_equal ['CREATE TABLE cats (id varchar(255) NOT NULL, PRIMARY KEY (id))']
|
151
|
+
end
|
152
|
+
|
135
153
|
it "should handling splitting named column constraints into table constraints if unsupported" do
|
136
154
|
def @db.supports_named_column_constraints?; false end
|
137
155
|
@db.create_table(:cats) do
|
@@ -1100,6 +1118,22 @@ describe "DB#alter_table" do
|
|
1100
1118
|
@db.sqls.must_equal ["ALTER TABLE cats ADD CONSTRAINT cpk PRIMARY KEY (id, type)"]
|
1101
1119
|
end
|
1102
1120
|
|
1121
|
+
it "should set primary key column NOT NULL when using add_primary_key if database doesn't handle it" do
|
1122
|
+
def @db.can_add_primary_key_constraint_on_nullable_columns?; false end
|
1123
|
+
@db.alter_table(:cats) do
|
1124
|
+
add_primary_key :id
|
1125
|
+
end
|
1126
|
+
@db.sqls.must_equal ["ALTER TABLE cats ADD COLUMN id integer NOT NULL PRIMARY KEY AUTOINCREMENT"]
|
1127
|
+
end
|
1128
|
+
|
1129
|
+
it "should set primary key column NOT NULL when adding primary key constraint if database doesn't handle it" do
|
1130
|
+
def @db.can_add_primary_key_constraint_on_nullable_columns?; false end
|
1131
|
+
@db.alter_table(:cats) do
|
1132
|
+
add_primary_key [:id, :type]
|
1133
|
+
end
|
1134
|
+
@db.sqls.must_equal ["ALTER TABLE cats ALTER COLUMN id SET NOT NULL", "ALTER TABLE cats ALTER COLUMN type SET NOT NULL", "ALTER TABLE cats ADD PRIMARY KEY (id, type)"]
|
1135
|
+
end
|
1136
|
+
|
1103
1137
|
it "should support drop_column" do
|
1104
1138
|
@db.alter_table(:cats) do
|
1105
1139
|
drop_column :score
|
@@ -21,6 +21,7 @@ Sequel.extension :core_extensions
|
|
21
21
|
if RUBY_VERSION < '1.9.0'
|
22
22
|
Sequel.extension :ruby18_symbol_extensions
|
23
23
|
end
|
24
|
+
Sequel.extension :symbol_aref
|
24
25
|
|
25
26
|
require 'minitest/autorun'
|
26
27
|
|
@@ -702,3 +703,29 @@ describe "Postgres extensions integration" do
|
|
702
703
|
@db.literal((1..2).pg_range(:int4range)).must_equal "int4range(1,2,'[]')"
|
703
704
|
end
|
704
705
|
end
|
706
|
+
|
707
|
+
describe "symbol_aref extensions" do
|
708
|
+
before do
|
709
|
+
@db = Sequel.mock
|
710
|
+
end
|
711
|
+
|
712
|
+
it "Symbol#[] should create qualified identifier if given a symbol" do
|
713
|
+
@db.literal(:x[:y]).must_equal "x.y"
|
714
|
+
end
|
715
|
+
|
716
|
+
it "Symbol#[] should create qualified identifier if given an identifier" do
|
717
|
+
@db.literal(:x[Sequel[:y]]).must_equal "x.y"
|
718
|
+
end
|
719
|
+
|
720
|
+
it "Symbol#[] should create qualified identifier if given a qualified identifier" do
|
721
|
+
@db.literal(:x[:y[:z]]).must_equal "x.y.z"
|
722
|
+
end
|
723
|
+
|
724
|
+
it "should not affect other arguments to Symbol#[]" do
|
725
|
+
if RUBY_VERSION >= '1.9'
|
726
|
+
:x[0].must_equal "x"
|
727
|
+
else
|
728
|
+
@db.literal(:x[0]).must_equal "x(0)"
|
729
|
+
end
|
730
|
+
end
|
731
|
+
end
|
@@ -51,6 +51,14 @@ describe "class_table_inheritance plugin" do
|
|
51
51
|
Object.send(:remove_const, :Employee)
|
52
52
|
end
|
53
53
|
|
54
|
+
it "should not attempt to use prepared statements" do
|
55
|
+
Manager.plugin :prepared_statements
|
56
|
+
Manager[1]
|
57
|
+
@db.sqls.must_equal ["SELECT employees.id, employees.name, employees.kind, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id) WHERE (managers.id = 1) LIMIT 1"]
|
58
|
+
Manager.load(:id=>1, :kind=>'Manager', :num_staff=>2).save
|
59
|
+
@db.sqls.must_equal ["UPDATE employees SET kind = 'Manager' WHERE (id = 1)", "UPDATE managers SET num_staff = 2 WHERE (id = 1)"]
|
60
|
+
end
|
61
|
+
|
54
62
|
it "#cti_base_model should be the model that loaded the plugin" do
|
55
63
|
Executive.cti_base_model.must_equal Employee
|
56
64
|
end
|
@@ -98,6 +98,14 @@ describe "Sequel::Plugins::ColumnSelect" do
|
|
98
98
|
@Album.dataset.sql.must_equal 'SELECT albums.id, albums.a, albums.b, albums.c FROM albums'
|
99
99
|
end
|
100
100
|
|
101
|
+
it "should handle case where schema parsing and columns does not produce results" do
|
102
|
+
def @db.supports_schema_parsing?() true end
|
103
|
+
def @db.schema_parse_table(t, *) [] end
|
104
|
+
@db.extend_datasets{def columns; raise Sequel::DatabaseError; end}
|
105
|
+
@Album.plugin :column_select
|
106
|
+
@Album.dataset.sql.must_equal 'SELECT * FROM albums'
|
107
|
+
end
|
108
|
+
|
101
109
|
it "works correctly when loaded on model without a dataset" do
|
102
110
|
c = Class.new(Sequel::Model)
|
103
111
|
c.plugin :column_select
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
2
2
|
|
3
|
-
if RUBY_VERSION >= '2.0.0' && RUBY_ENGINE == 'ruby'
|
3
|
+
if (RUBY_VERSION >= '2.0.0' && RUBY_ENGINE == 'ruby') # || (RUBY_VERSION >= '2.3.0' && RUBY_ENGINE == 'jruby')
|
4
4
|
Sequel.extension :core_refinements, :pg_array, :pg_hstore, :pg_row, :pg_range, :pg_row_ops, :pg_range_ops, :pg_array_ops, :pg_hstore_ops, :pg_json, :pg_json_ops
|
5
5
|
using Sequel::CoreRefinements
|
6
6
|
|
@@ -26,6 +26,7 @@ describe "Sequel::Plugins::DatasetAssociations" do
|
|
26
26
|
@Album.columns :id, :name, :artist_id
|
27
27
|
@Tag.columns :id, :name
|
28
28
|
|
29
|
+
@Album.plugin :many_through_many
|
29
30
|
@Artist.plugin :many_through_many
|
30
31
|
@Artist.plugin :pg_array_associations
|
31
32
|
@Tag.plugin :pg_array_associations
|
@@ -33,6 +34,7 @@ describe "Sequel::Plugins::DatasetAssociations" do
|
|
33
34
|
@Artist.one_to_one :first_album, :class=>@Album
|
34
35
|
@Album.many_to_one :artist, :class=>@Artist
|
35
36
|
@Album.many_to_many :tags, :class=>@Tag
|
37
|
+
@Album.many_through_many :mthm_tags, [[:albums_tags, :album_id, :tag_id]], :class=>@Tag
|
36
38
|
@Album.one_through_one :first_tag, :class=>@Tag, :right_key=>:tag_id
|
37
39
|
@Tag.many_to_many :albums, :class=>@Album
|
38
40
|
@Artist.pg_array_to_many :artist_tags, :class=>@Tag, :key=>:tag_ids
|
@@ -83,6 +85,13 @@ describe "Sequel::Plugins::DatasetAssociations" do
|
|
83
85
|
ds.sql.must_equal "SELECT tags.* FROM tags WHERE (tags.id IN (SELECT albums_tags.tag_id FROM artists INNER JOIN albums ON (albums.artist_id = artists.id) INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) INNER JOIN tags ON (tags.id = albums_tags.tag_id) WHERE (albums.artist_id IN (SELECT artists.id FROM artists))))"
|
84
86
|
end
|
85
87
|
|
88
|
+
it "should work for many_through_many associations with a single join table" do
|
89
|
+
ds = @Album.mthm_tags
|
90
|
+
ds.must_be_kind_of(Sequel::Dataset)
|
91
|
+
ds.model.must_equal @Tag
|
92
|
+
ds.sql.must_equal "SELECT tags.* FROM tags WHERE (tags.id IN (SELECT albums_tags.tag_id FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) WHERE (albums_tags.album_id IN (SELECT albums.id FROM albums))))"
|
93
|
+
end
|
94
|
+
|
86
95
|
it "should work for one_through_many associations" do
|
87
96
|
ds = @Artist.otags
|
88
97
|
ds.must_be_kind_of(Sequel::Dataset)
|
@@ -12,6 +12,26 @@ describe "Sequel::Plugins::InsertReturningSelect" do
|
|
12
12
|
@db.sqls
|
13
13
|
end
|
14
14
|
|
15
|
+
it "should work if loaded into a model without a dataset that also uses the lazy_attributes or dataset associations plugins" do
|
16
|
+
c = Sequel::Model(@db)
|
17
|
+
c.plugin :insert_returning_select
|
18
|
+
c.columns :id, :x
|
19
|
+
c.plugin :lazy_attributes
|
20
|
+
c.plugin :dataset_associations
|
21
|
+
|
22
|
+
c.set_dataset @db[:albums].select(:id, :x)
|
23
|
+
c.plugin :lazy_attributes, :x
|
24
|
+
c.many_to_one :c, :key=>:id, :class=>c
|
25
|
+
@db.sqls
|
26
|
+
|
27
|
+
c.dataset.sql.must_equal 'SELECT id FROM albums'
|
28
|
+
c.create(:x=>2)
|
29
|
+
@db.sqls.must_equal ['INSERT INTO albums (x) VALUES (2) RETURNING id']
|
30
|
+
c.load(:id=>2).x
|
31
|
+
@db.sqls.must_equal ['SELECT albums.x FROM albums WHERE (id = 2) LIMIT 1']
|
32
|
+
c.dataset.cs.sql.must_equal "SELECT id FROM albums WHERE (albums.id IN (SELECT albums.id FROM albums))"
|
33
|
+
end
|
34
|
+
|
15
35
|
it "should add a returning clause when inserting using selected columns" do
|
16
36
|
@Album.plugin :insert_returning_select
|
17
37
|
@Album.create(:x=>2).must_equal @Album.load(:id=>1, :x=>2)
|
@@ -17,6 +17,13 @@ describe "prepared_statements plugin" do
|
|
17
17
|
@db.sqls.must_equal ["SELECT id, name, i FROM people WHERE (id = 1) LIMIT 1 -- read_only"]
|
18
18
|
end
|
19
19
|
|
20
|
+
it "should correctly lookup by primary key for joined dataset" do
|
21
|
+
@c.dataset = @c.dataset.from(:people, :people2)
|
22
|
+
@db.sqls
|
23
|
+
@c[1].must_equal @p
|
24
|
+
@db.sqls.must_equal ["SELECT * FROM people, people2 WHERE (people.id = 1) LIMIT 1 -- read_only"]
|
25
|
+
end
|
26
|
+
|
20
27
|
prepared_statements_spec = shared_description do
|
21
28
|
it "should correctly delete instance" do
|
22
29
|
@p.destroy.must_equal @p
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
2
|
+
|
3
|
+
Sequel.extension :s
|
4
|
+
|
5
|
+
describe "s extension as refinement" do
|
6
|
+
include Sequel::S
|
7
|
+
|
8
|
+
before do
|
9
|
+
@db = Sequel.mock
|
10
|
+
end
|
11
|
+
|
12
|
+
it "S should be callable with different arguments" do
|
13
|
+
@db.literal(S(:s) + 1).must_equal "(s + 1)"
|
14
|
+
@db.literal(S('s') + '1').must_equal "('s' || '1')"
|
15
|
+
@db.literal(~S([[:s, 1], [:z, 2]])).must_equal "((s != 1) OR (z != 2))"
|
16
|
+
end
|
17
|
+
|
18
|
+
it "S should be callable with blocks" do
|
19
|
+
@db.literal(S{x + 1}).must_equal "(x + 1)"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "S should raise an error if called with multiple objects" do
|
23
|
+
proc{S(:x, 1)}.must_raise ArgumentError
|
24
|
+
end
|
25
|
+
|
26
|
+
it "S should raise an error if called with objects and block" do
|
27
|
+
proc{S(:x){}}.must_raise Sequel::Error
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
if (RUBY_VERSION >= '2.0.0' && RUBY_ENGINE == 'ruby') # || (RUBY_VERSION >= '2.3.0' && RUBY_ENGINE == 'jruby')
|
33
|
+
using Sequel::S
|
34
|
+
|
35
|
+
describe "s extension as refinement" do
|
36
|
+
before do
|
37
|
+
@db = Sequel.mock
|
38
|
+
end
|
39
|
+
|
40
|
+
it "S should be callable with different arguments" do
|
41
|
+
@db.literal(S(:s) + 1).must_equal "(s + 1)"
|
42
|
+
@db.literal(S('s') + '1').must_equal "('s' || '1')"
|
43
|
+
@db.literal(~S([[:s, 1], [:z, 2]])).must_equal "((s != 1) OR (z != 2))"
|
44
|
+
end
|
45
|
+
|
46
|
+
it "S should be callable with blocks" do
|
47
|
+
@db.literal(S{x + 1}).must_equal "(x + 1)"
|
48
|
+
end
|
49
|
+
|
50
|
+
it "S should raise an error if called with multiple objects" do
|
51
|
+
proc{S(:x, 1)}.must_raise ArgumentError
|
52
|
+
end
|
53
|
+
|
54
|
+
it "S should raise an error if called with objects and block" do
|
55
|
+
proc{S(:x){}}.must_raise Sequel::Error
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
2
|
+
|
3
|
+
if (RUBY_VERSION >= '2.0.0' && RUBY_ENGINE == 'ruby') || (RUBY_VERSION >= '2.3.0' && RUBY_ENGINE == 'jruby')
|
4
|
+
Sequel.extension :symbol_aref_refinement
|
5
|
+
using Sequel::SymbolAref
|
6
|
+
|
7
|
+
describe "symbol_aref_refinement extension" do
|
8
|
+
before do
|
9
|
+
@db = Sequel.mock
|
10
|
+
end
|
11
|
+
|
12
|
+
it "Symbol#[] should create qualified identifier if given a symbol" do
|
13
|
+
@db.literal(:x[:y]).must_equal "x.y"
|
14
|
+
end
|
15
|
+
|
16
|
+
it "Symbol#[] should create qualified identifier if given an identifier" do
|
17
|
+
@db.literal(:x[Sequel[:y]]).must_equal "x.y"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "Symbol#[] should create qualified identifier if given a qualified identifier" do
|
21
|
+
@db.literal(:x[:y[:z]]).must_equal "x.y.z"
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should not affect other arguments to Symbol#[]" do
|
25
|
+
:x[0].must_equal "x"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
2
|
+
|
3
|
+
if (RUBY_VERSION >= '2.0.0' && RUBY_ENGINE == 'ruby') || (RUBY_VERSION >= '2.3.0' && RUBY_ENGINE == 'jruby')
|
4
|
+
Sequel.extension :symbol_as_refinement
|
5
|
+
using Sequel::SymbolAs
|
6
|
+
|
7
|
+
describe "symbol_as_refinement extension" do
|
8
|
+
before do
|
9
|
+
@db = Sequel.mock
|
10
|
+
end
|
11
|
+
|
12
|
+
it "Symbol#as should create aliased expression" do
|
13
|
+
@db.literal(:x.as(:y)).must_equal "x AS y"
|
14
|
+
end
|
15
|
+
|
16
|
+
it "Symbol#as should create aliased expression with columns" do
|
17
|
+
@db.literal(:x.as(:y, [:c1, :c2])).must_equal "x AS y(c1, c2)"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|