sequel 4.44.0 → 4.45.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 +110 -0
- data/README.rdoc +8 -9
- data/doc/active_record.rdoc +2 -3
- data/doc/model_plugins.rdoc +1 -1
- data/doc/opening_databases.rdoc +0 -46
- data/doc/release_notes/4.45.0.txt +370 -0
- data/lib/sequel/adapters/cubrid.rb +2 -0
- data/lib/sequel/adapters/do.rb +2 -0
- data/lib/sequel/adapters/jdbc/as400.rb +2 -0
- data/lib/sequel/adapters/jdbc/cubrid.rb +2 -0
- data/lib/sequel/adapters/jdbc/firebirdsql.rb +2 -0
- data/lib/sequel/adapters/jdbc/informix-sqli.rb +2 -0
- data/lib/sequel/adapters/jdbc/jdbcprogress.rb +2 -0
- data/lib/sequel/adapters/jdbc/mysql.rb +1 -0
- data/lib/sequel/adapters/jdbc/postgresql.rb +5 -0
- data/lib/sequel/adapters/mysql.rb +1 -0
- data/lib/sequel/adapters/mysql2.rb +1 -0
- data/lib/sequel/adapters/odbc/oracle.rb +11 -0
- data/lib/sequel/adapters/odbc/progress.rb +2 -0
- data/lib/sequel/adapters/postgres.rb +0 -2
- data/lib/sequel/adapters/shared/cubrid.rb +2 -0
- data/lib/sequel/adapters/shared/firebird.rb +2 -0
- data/lib/sequel/adapters/shared/informix.rb +2 -0
- data/lib/sequel/adapters/shared/mssql.rb +47 -7
- data/lib/sequel/adapters/shared/mysql.rb +16 -1
- data/lib/sequel/adapters/shared/postgres.rb +9 -1
- data/lib/sequel/adapters/shared/progress.rb +2 -0
- data/lib/sequel/adapters/shared/sqlanywhere.rb +1 -1
- data/lib/sequel/adapters/swift.rb +2 -0
- data/lib/sequel/ast_transformer.rb +13 -6
- data/lib/sequel/core.rb +13 -16
- data/lib/sequel/database/connecting.rb +25 -10
- data/lib/sequel/database/dataset.rb +6 -1
- data/lib/sequel/database/dataset_defaults.rb +9 -2
- data/lib/sequel/database/misc.rb +10 -3
- data/lib/sequel/database/schema_methods.rb +4 -0
- data/lib/sequel/dataset/mutation.rb +8 -20
- data/lib/sequel/dataset/prepared_statements.rb +2 -0
- data/lib/sequel/dataset/query.rb +32 -7
- data/lib/sequel/dataset/sql.rb +13 -3
- data/lib/sequel/deprecated.rb +9 -1
- data/lib/sequel/exceptions.rb +37 -8
- data/lib/sequel/extensions/_deprecated_identifier_mangling.rb +117 -0
- data/lib/sequel/extensions/date_arithmetic.rb +1 -0
- data/lib/sequel/extensions/identifier_mangling.rb +3 -2
- data/lib/sequel/extensions/pg_hstore.rb +1 -5
- data/lib/sequel/extensions/schema_dumper.rb +3 -1
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +2 -2
- data/lib/sequel/extensions/string_agg.rb +1 -0
- data/lib/sequel/model.rb +23 -10
- data/lib/sequel/model/associations.rb +17 -5
- data/lib/sequel/model/base.rb +115 -62
- data/lib/sequel/model/dataset_module.rb +10 -3
- data/lib/sequel/model/exceptions.rb +7 -5
- data/lib/sequel/plugins/association_pks.rb +13 -1
- data/lib/sequel/plugins/association_proxies.rb +8 -1
- data/lib/sequel/plugins/before_after_save.rb +1 -0
- data/lib/sequel/plugins/class_table_inheritance.rb +7 -3
- data/lib/sequel/plugins/columns_updated.rb +42 -0
- data/lib/sequel/plugins/composition.rb +10 -5
- data/lib/sequel/plugins/error_splitter.rb +1 -1
- data/lib/sequel/plugins/hook_class_methods.rb +39 -5
- data/lib/sequel/plugins/instance_hooks.rb +58 -5
- data/lib/sequel/plugins/lazy_attributes.rb +10 -5
- data/lib/sequel/plugins/nested_attributes.rb +10 -5
- data/lib/sequel/plugins/prepared_statements.rb +7 -0
- data/lib/sequel/plugins/prepared_statements_associations.rb +2 -0
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +2 -0
- data/lib/sequel/plugins/schema.rb +2 -0
- data/lib/sequel/plugins/scissors.rb +2 -0
- data/lib/sequel/plugins/serialization.rb +10 -5
- data/lib/sequel/plugins/split_values.rb +5 -1
- data/lib/sequel/plugins/static_cache.rb +2 -2
- data/lib/sequel/plugins/tactical_eager_loading.rb +1 -1
- data/lib/sequel/plugins/validation_contexts.rb +49 -0
- data/lib/sequel/plugins/validation_helpers.rb +1 -0
- data/lib/sequel/sql.rb +1 -1
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +31 -0
- data/spec/adapters/mysql_spec.rb +20 -2
- data/spec/adapters/postgres_spec.rb +43 -12
- data/spec/adapters/spec_helper.rb +5 -8
- data/spec/core/database_spec.rb +47 -12
- data/spec/core/dataset_mutation_spec.rb +22 -22
- data/spec/core/dataset_spec.rb +88 -20
- data/spec/core/deprecated_spec.rb +1 -1
- data/spec/core/expression_filters_spec.rb +1 -1
- data/spec/core/mock_adapter_spec.rb +0 -3
- data/spec/core/placeholder_literalizer_spec.rb +1 -1
- data/spec/core/schema_spec.rb +8 -1
- data/spec/core/spec_helper.rb +6 -1
- data/spec/core_extensions_spec.rb +4 -0
- data/spec/deprecation_helper.rb +17 -0
- data/spec/extensions/_deprecated_identifier_mangling_spec.rb +314 -0
- data/spec/extensions/association_pks_spec.rb +61 -13
- data/spec/extensions/association_proxies_spec.rb +3 -3
- data/spec/extensions/class_table_inheritance_spec.rb +39 -0
- data/spec/extensions/columns_updated_spec.rb +35 -0
- data/spec/extensions/composition_spec.rb +6 -1
- data/spec/extensions/hook_class_methods_spec.rb +114 -26
- data/spec/extensions/identifier_mangling_spec.rb +107 -73
- data/spec/extensions/instance_hooks_spec.rb +78 -14
- data/spec/extensions/lazy_attributes_spec.rb +8 -2
- data/spec/extensions/many_through_many_spec.rb +2 -2
- data/spec/extensions/mssql_optimistic_locking_spec.rb +1 -1
- data/spec/extensions/nested_attributes_spec.rb +8 -2
- data/spec/extensions/pg_array_spec.rb +18 -4
- data/spec/extensions/prepared_statements_associations_spec.rb +48 -39
- data/spec/extensions/prepared_statements_with_pk_spec.rb +13 -11
- data/spec/extensions/query_spec.rb +1 -1
- data/spec/extensions/schema_dumper_spec.rb +34 -6
- data/spec/extensions/schema_spec.rb +13 -7
- data/spec/extensions/scissors_spec.rb +3 -1
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +4 -4
- data/spec/extensions/serialization_spec.rb +7 -1
- data/spec/extensions/set_overrides_spec.rb +2 -2
- data/spec/extensions/shared_caching_spec.rb +19 -15
- data/spec/extensions/spec_helper.rb +7 -3
- data/spec/extensions/split_values_spec.rb +45 -10
- data/spec/extensions/string_agg_spec.rb +2 -2
- data/spec/extensions/subset_conditions_spec.rb +3 -3
- data/spec/extensions/tactical_eager_loading_spec.rb +1 -1
- data/spec/extensions/validation_contexts_spec.rb +31 -0
- data/spec/guards_helper.rb +2 -0
- data/spec/integration/associations_test.rb +22 -20
- data/spec/integration/dataset_test.rb +25 -2
- data/spec/integration/model_test.rb +1 -1
- data/spec/integration/plugin_test.rb +11 -16
- data/spec/integration/prepared_statement_test.rb +40 -32
- data/spec/integration/spec_helper.rb +5 -8
- data/spec/model/association_reflection_spec.rb +4 -0
- data/spec/model/associations_spec.rb +37 -10
- data/spec/model/base_spec.rb +6 -0
- data/spec/model/hooks_spec.rb +56 -35
- data/spec/model/model_spec.rb +21 -5
- data/spec/model/record_spec.rb +14 -11
- data/spec/model/spec_helper.rb +7 -1
- data/spec/sequel_warning.rb +11 -0
- metadata +13 -3
|
@@ -11,9 +11,13 @@ unless Object.const_defined?('Sequel') && Sequel.const_defined?('Model')
|
|
|
11
11
|
Sequel::Deprecation.backtrace_filter = true
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
+
# SEQUEL5: Remove
|
|
15
|
+
output = Sequel::Deprecation.output
|
|
16
|
+
Sequel::Deprecation.output = nil
|
|
14
17
|
Sequel.quote_identifiers = false
|
|
15
18
|
Sequel.identifier_input_method = nil
|
|
16
19
|
Sequel.identifier_output_method = nil
|
|
20
|
+
Sequel::Deprecation.output = output
|
|
17
21
|
|
|
18
22
|
Regexp.send(:include, Sequel::SQL::StringMethods)
|
|
19
23
|
String.send(:include, Sequel::SQL::StringMethods)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Sequel::Deprecation.backtrace_filter = lambda{|line, lineno| lineno < 4 || line =~ /_spec\.rb/}
|
|
2
|
+
|
|
3
|
+
class Minitest::HooksSpec
|
|
4
|
+
def self.deprecated(*a, &block)
|
|
5
|
+
it(*a) do
|
|
6
|
+
deprecated{instance_exec(&block)}
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def deprecated
|
|
11
|
+
output = Sequel::Deprecation.output
|
|
12
|
+
Sequel::Deprecation.output = nil
|
|
13
|
+
yield
|
|
14
|
+
ensure
|
|
15
|
+
Sequel::Deprecation.output = output
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
2
|
+
|
|
3
|
+
describe "identifier_mangling extension" do
|
|
4
|
+
after do
|
|
5
|
+
deprecated do
|
|
6
|
+
Sequel.quote_identifiers = false
|
|
7
|
+
Sequel.identifier_input_method = nil
|
|
8
|
+
Sequel.identifier_output_method = nil
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
deprecated "should respect the :quote_identifiers option" do
|
|
13
|
+
db = Sequel::Database.new(:quote_identifiers=>false, :identifier_mangling=>true)
|
|
14
|
+
db.quote_identifiers?.must_equal false
|
|
15
|
+
db = Sequel::Database.new(:quote_identifiers=>true, :identifier_mangling=>true)
|
|
16
|
+
db.quote_identifiers?.must_equal true
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
deprecated "should respect the :quote_identifiers setting" do
|
|
20
|
+
db = Sequel::Database.new(:identifier_mangling=>true)
|
|
21
|
+
db.quote_identifiers?.must_equal false
|
|
22
|
+
db.quote_identifiers = true
|
|
23
|
+
db.quote_identifiers?.must_equal true
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
deprecated "should upcase on input and downcase on output by default" do
|
|
27
|
+
db = Sequel::Database.new(:identifier_mangling=>true)
|
|
28
|
+
db.send(:identifier_input_method_default).must_equal :upcase
|
|
29
|
+
db.send(:identifier_output_method_default).must_equal :downcase
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
deprecated "should respect the :identifier_input_method option" do
|
|
33
|
+
Sequel.identifier_input_method = nil
|
|
34
|
+
Sequel::Database.identifier_input_method.must_equal false
|
|
35
|
+
db = Sequel::Database.new(:identifier_input_method=>nil, :identifier_mangling=>true)
|
|
36
|
+
db.identifier_input_method.must_be_nil
|
|
37
|
+
db.identifier_input_method = :downcase
|
|
38
|
+
db.identifier_input_method.must_equal :downcase
|
|
39
|
+
db = Sequel::Database.new(:identifier_input_method=>:upcase, :identifier_mangling=>true)
|
|
40
|
+
db.identifier_input_method.must_equal :upcase
|
|
41
|
+
db.identifier_input_method = nil
|
|
42
|
+
db.identifier_input_method.must_be_nil
|
|
43
|
+
Sequel.identifier_input_method = :downcase
|
|
44
|
+
Sequel::Database.identifier_input_method.must_equal :downcase
|
|
45
|
+
db = Sequel::Database.new(:identifier_input_method=>nil, :identifier_mangling=>true)
|
|
46
|
+
db.identifier_input_method.must_be_nil
|
|
47
|
+
db.identifier_input_method = :upcase
|
|
48
|
+
db.identifier_input_method.must_equal :upcase
|
|
49
|
+
db = Sequel::Database.new(:identifier_input_method=>:upcase, :identifier_mangling=>true)
|
|
50
|
+
db.identifier_input_method.must_equal :upcase
|
|
51
|
+
db.identifier_input_method = nil
|
|
52
|
+
db.identifier_input_method.must_be_nil
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
deprecated "should respect the :identifier_output_method option" do
|
|
56
|
+
Sequel.identifier_output_method = nil
|
|
57
|
+
Sequel::Database.identifier_output_method.must_equal false
|
|
58
|
+
db = Sequel::Database.new(:identifier_output_method=>nil, :identifier_mangling=>true)
|
|
59
|
+
db.identifier_output_method.must_be_nil
|
|
60
|
+
db.identifier_output_method = :downcase
|
|
61
|
+
db.identifier_output_method.must_equal :downcase
|
|
62
|
+
db = Sequel::Database.new(:identifier_output_method=>:upcase, :identifier_mangling=>true)
|
|
63
|
+
db.identifier_output_method.must_equal :upcase
|
|
64
|
+
db.identifier_output_method = nil
|
|
65
|
+
db.identifier_output_method.must_be_nil
|
|
66
|
+
Sequel.identifier_output_method = :downcase
|
|
67
|
+
Sequel::Database.identifier_output_method.must_equal :downcase
|
|
68
|
+
db = Sequel::Database.new(:identifier_output_method=>nil, :identifier_mangling=>true)
|
|
69
|
+
db.identifier_output_method.must_be_nil
|
|
70
|
+
db.identifier_output_method = :upcase
|
|
71
|
+
db.identifier_output_method.must_equal :upcase
|
|
72
|
+
db = Sequel::Database.new(:identifier_output_method=>:upcase, :identifier_mangling=>true)
|
|
73
|
+
db.identifier_output_method.must_equal :upcase
|
|
74
|
+
db.identifier_output_method = nil
|
|
75
|
+
db.identifier_output_method.must_be_nil
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
deprecated "should use the default Sequel.quote_identifiers value" do
|
|
79
|
+
Sequel.quote_identifiers = true
|
|
80
|
+
Sequel::Database.new(:identifier_mangling=>true).quote_identifiers?.must_equal true
|
|
81
|
+
Sequel.quote_identifiers = false
|
|
82
|
+
Sequel::Database.new(:identifier_mangling=>true).quote_identifiers?.must_equal false
|
|
83
|
+
Sequel::Database.quote_identifiers = true
|
|
84
|
+
Sequel::Database.new(:identifier_mangling=>true).quote_identifiers?.must_equal true
|
|
85
|
+
Sequel::Database.quote_identifiers = false
|
|
86
|
+
Sequel::Database.new(:identifier_mangling=>true).quote_identifiers?.must_equal false
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
deprecated "should use the default Sequel.identifier_input_method value" do
|
|
90
|
+
Sequel.identifier_input_method = :downcase
|
|
91
|
+
Sequel::Database.new(:identifier_mangling=>true).identifier_input_method.must_equal :downcase
|
|
92
|
+
Sequel.identifier_input_method = :upcase
|
|
93
|
+
Sequel::Database.new(:identifier_mangling=>true).identifier_input_method.must_equal :upcase
|
|
94
|
+
Sequel::Database.identifier_input_method = :downcase
|
|
95
|
+
Sequel::Database.new(:identifier_mangling=>true).identifier_input_method.must_equal :downcase
|
|
96
|
+
Sequel::Database.identifier_input_method = :upcase
|
|
97
|
+
Sequel::Database.new(:identifier_mangling=>true).identifier_input_method.must_equal :upcase
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
deprecated "should use the default Sequel.identifier_output_method value" do
|
|
101
|
+
Sequel.identifier_output_method = :downcase
|
|
102
|
+
Sequel::Database.new(:identifier_mangling=>true).identifier_output_method.must_equal :downcase
|
|
103
|
+
Sequel.identifier_output_method = :upcase
|
|
104
|
+
Sequel::Database.new(:identifier_mangling=>true).identifier_output_method.must_equal :upcase
|
|
105
|
+
Sequel::Database.identifier_output_method = :downcase
|
|
106
|
+
Sequel::Database.new(:identifier_mangling=>true).identifier_output_method.must_equal :downcase
|
|
107
|
+
Sequel::Database.identifier_output_method = :upcase
|
|
108
|
+
Sequel::Database.new(:identifier_mangling=>true).identifier_output_method.must_equal :upcase
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
deprecated "should respect the quote_indentifiers_default method if Sequel.quote_identifiers = nil" do
|
|
112
|
+
Sequel.quote_identifiers = nil
|
|
113
|
+
Sequel::Database.new(:identifier_mangling=>true).quote_identifiers?.must_equal true
|
|
114
|
+
x = Class.new(Sequel::Database){def quote_identifiers_default; false end}
|
|
115
|
+
x.new(:identifier_mangling=>true).quote_identifiers?.must_equal false
|
|
116
|
+
y = Class.new(Sequel::Database){def quote_identifiers_default; true end}
|
|
117
|
+
y.new(:identifier_mangling=>true).quote_identifiers?.must_equal true
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
deprecated "should respect the identifier_input_method_default method if Sequel.identifier_input_method is not called" do
|
|
121
|
+
class Sequel::Database
|
|
122
|
+
@identifier_input_method = nil
|
|
123
|
+
end
|
|
124
|
+
x = Class.new(Sequel::Database){def identifier_input_method_default; :downcase end}
|
|
125
|
+
x.new(:identifier_mangling=>true).identifier_input_method.must_equal :downcase
|
|
126
|
+
y = Class.new(Sequel::Database){def identifier_input_method_default; :camelize end}
|
|
127
|
+
y.new(:identifier_mangling=>true).identifier_input_method.must_equal :camelize
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
deprecated "should respect the identifier_output_method_default method if Sequel.identifier_output_method is not called" do
|
|
131
|
+
class Sequel::Database
|
|
132
|
+
@identifier_output_method = nil
|
|
133
|
+
end
|
|
134
|
+
x = Class.new(Sequel::Database){def identifier_output_method_default; :upcase end}
|
|
135
|
+
x.new(:identifier_mangling=>true).identifier_output_method.must_equal :upcase
|
|
136
|
+
y = Class.new(Sequel::Database){def identifier_output_method_default; :underscore end}
|
|
137
|
+
y.new(:identifier_mangling=>true).identifier_output_method.must_equal :underscore
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
describe "Database#input_identifier_meth" do
|
|
142
|
+
deprecated "should be the input_identifer method of a default dataset for this database" do
|
|
143
|
+
db = Sequel::Database.new(:identifier_mangling=>true)
|
|
144
|
+
db.send(:input_identifier_meth).call(:a).must_equal 'a'
|
|
145
|
+
db.identifier_input_method = :upcase
|
|
146
|
+
db.send(:input_identifier_meth).call(:a).must_equal 'A'
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
describe "Database#output_identifier_meth" do
|
|
151
|
+
deprecated "should be the output_identifer method of a default dataset for this database" do
|
|
152
|
+
db = Sequel::Database.new(:identifier_mangling=>true)
|
|
153
|
+
db.send(:output_identifier_meth).call('A').must_equal :A
|
|
154
|
+
db.identifier_output_method = :downcase
|
|
155
|
+
db.send(:output_identifier_meth).call('A').must_equal :a
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
describe "Database#metadata_dataset" do
|
|
160
|
+
deprecated "should be a dataset with the default settings for identifier_mangling" do
|
|
161
|
+
ds = Sequel::Database.new(:identifier_mangling=>true).send(:metadata_dataset)
|
|
162
|
+
ds.literal(:a).must_equal 'A'
|
|
163
|
+
ds.send(:output_identifier, 'A').must_equal :a
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
describe "Dataset" do
|
|
168
|
+
before do
|
|
169
|
+
@dataset = Sequel.mock(:identifier_mangling=>true).dataset
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
deprecated "should get quote_identifiers default from database" do
|
|
173
|
+
db = Sequel::Database.new(:quote_identifiers=>true, :identifier_mangling=>true)
|
|
174
|
+
db[:a].quote_identifiers?.must_equal true
|
|
175
|
+
db = Sequel::Database.new(:quote_identifiers=>false, :identifier_mangling=>true)
|
|
176
|
+
db[:a].quote_identifiers?.must_equal false
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
deprecated "should get identifier_input_method default from database" do
|
|
180
|
+
db = Sequel::Database.new(:identifier_input_method=>:upcase, :identifier_mangling=>true)
|
|
181
|
+
db[:a].identifier_input_method.must_equal :upcase
|
|
182
|
+
db = Sequel::Database.new(:identifier_input_method=>:downcase, :identifier_mangling=>true)
|
|
183
|
+
db[:a].identifier_input_method.must_equal :downcase
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
deprecated "should get identifier_output_method default from database" do
|
|
187
|
+
db = Sequel::Database.new(:identifier_output_method=>:upcase, :identifier_mangling=>true)
|
|
188
|
+
db[:a].identifier_output_method.must_equal :upcase
|
|
189
|
+
db = Sequel::Database.new(:identifier_output_method=>:downcase, :identifier_mangling=>true)
|
|
190
|
+
db[:a].identifier_output_method.must_equal :downcase
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# SEQUEL5: Remove
|
|
194
|
+
unless Sequel.mock(:identifier_mangling=>true).dataset.frozen?
|
|
195
|
+
deprecated "should have quote_identifiers= method which changes literalization of identifiers" do
|
|
196
|
+
@dataset.quote_identifiers = true
|
|
197
|
+
@dataset.literal(:a).must_equal '"a"'
|
|
198
|
+
@dataset.quote_identifiers = false
|
|
199
|
+
@dataset.literal(:a).must_equal 'a'
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
deprecated "should have identifier_input_method= method which changes literalization of identifiers" do
|
|
203
|
+
@dataset.identifier_input_method = :upcase
|
|
204
|
+
@dataset.literal(:a).must_equal 'A'
|
|
205
|
+
@dataset.identifier_input_method = :downcase
|
|
206
|
+
@dataset.literal(:A).must_equal 'a'
|
|
207
|
+
@dataset.identifier_input_method = :reverse
|
|
208
|
+
@dataset.literal(:at_b).must_equal 'b_ta'
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
deprecated "should have identifier_output_method= method which changes identifiers returned from the database" do
|
|
212
|
+
@dataset.send(:output_identifier, "at_b_C").must_equal :at_b_C
|
|
213
|
+
@dataset.identifier_output_method = :upcase
|
|
214
|
+
@dataset.send(:output_identifier, "at_b_C").must_equal :AT_B_C
|
|
215
|
+
@dataset.identifier_output_method = :downcase
|
|
216
|
+
@dataset.send(:output_identifier, "at_b_C").must_equal :at_b_c
|
|
217
|
+
@dataset.identifier_output_method = :reverse
|
|
218
|
+
@dataset.send(:output_identifier, "at_b_C").must_equal :C_b_ta
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
deprecated "should have with_quote_identifiers method which returns cloned dataset with changed literalization of identifiers" do
|
|
223
|
+
@dataset.with_quote_identifiers(true).literal(:a).must_equal '"a"'
|
|
224
|
+
@dataset.with_quote_identifiers(false).literal(:a).must_equal 'a'
|
|
225
|
+
ds = @dataset.freeze.with_quote_identifiers(false)
|
|
226
|
+
ds.literal(:a).must_equal 'a'
|
|
227
|
+
ds.frozen?.must_equal true
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
deprecated "should have with_identifier_input_method method which returns cloned dataset with changed literalization of identifiers" do
|
|
231
|
+
@dataset.with_identifier_input_method(:upcase).literal(:a).must_equal 'A'
|
|
232
|
+
@dataset.with_identifier_input_method(:downcase).literal(:A).must_equal 'a'
|
|
233
|
+
@dataset.with_identifier_input_method(:reverse).literal(:at_b).must_equal 'b_ta'
|
|
234
|
+
ds = @dataset.freeze.with_identifier_input_method(:reverse)
|
|
235
|
+
ds.frozen?.must_equal true
|
|
236
|
+
ds.literal(:at_b).must_equal 'b_ta'
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
deprecated "should have with_identifier_output_method method which returns cloned dataset with changed identifiers returned from the database" do
|
|
240
|
+
@dataset.send(:output_identifier, "at_b_C").must_equal :at_b_C
|
|
241
|
+
@dataset.with_identifier_output_method(:upcase).send(:output_identifier, "at_b_C").must_equal :AT_B_C
|
|
242
|
+
@dataset.with_identifier_output_method(:downcase).send(:output_identifier, "at_b_C").must_equal :at_b_c
|
|
243
|
+
@dataset.with_identifier_output_method(:reverse).send(:output_identifier, "at_b_C").must_equal :C_b_ta
|
|
244
|
+
ds = @dataset.freeze.with_identifier_output_method(:reverse)
|
|
245
|
+
ds.send(:output_identifier, "at_b_C").must_equal :C_b_ta
|
|
246
|
+
ds.frozen?.must_equal true
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
deprecated "should have output_identifier handle empty identifiers" do
|
|
250
|
+
@dataset.send(:output_identifier, "").must_equal :untitled
|
|
251
|
+
@dataset.with_identifier_output_method(:upcase).send(:output_identifier, "").must_equal :UNTITLED
|
|
252
|
+
@dataset.with_identifier_output_method(:downcase).send(:output_identifier, "").must_equal :untitled
|
|
253
|
+
@dataset.with_identifier_output_method(:reverse).send(:output_identifier, "").must_equal :deltitnu
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
describe "Frozen Datasets" do
|
|
258
|
+
before do
|
|
259
|
+
@ds = Sequel.mock(:identifier_mangling=>true)[:test].freeze
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
deprecated "should raise an error when calling mutation methods" do
|
|
263
|
+
proc{@ds.identifier_input_method = :a}.must_raise RuntimeError
|
|
264
|
+
proc{@ds.identifier_output_method = :a}.must_raise RuntimeError
|
|
265
|
+
proc{@ds.quote_identifiers = false}.must_raise RuntimeError
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
describe "identifier_mangling extension" do
|
|
270
|
+
deprecated "should be able to load dialects based on the database name" do
|
|
271
|
+
begin
|
|
272
|
+
qi = class Sequel::Database; @quote_identifiers; end
|
|
273
|
+
ii = class Sequel::Database; @identifier_input_method; end
|
|
274
|
+
io = class Sequel::Database; @identifier_output_method; end
|
|
275
|
+
Sequel.quote_identifiers = nil
|
|
276
|
+
class Sequel::Database; @identifier_input_method=nil; end
|
|
277
|
+
class Sequel::Database; @identifier_output_method=nil; end
|
|
278
|
+
Sequel.mock(:host=>'access').select(Date.new(2011, 12, 13)).sql.must_equal 'SELECT #2011-12-13#'
|
|
279
|
+
Sequel.mock(:host=>'db2').select(1).sql.must_equal 'SELECT 1 FROM "SYSIBM"."SYSDUMMY1"'
|
|
280
|
+
Sequel.mock(:host=>'mssql')[:a].full_text_search(:b, 'c').sql.must_equal "SELECT * FROM [A] WHERE (CONTAINS ([B], 'c'))"
|
|
281
|
+
Sequel.mock(:host=>'mysql')[:a].full_text_search(:b, 'c').sql.must_equal "SELECT * FROM `a` WHERE (MATCH (`b`) AGAINST ('c'))"
|
|
282
|
+
Sequel.mock(:host=>'oracle')[:a].limit(1).sql.must_equal 'SELECT * FROM (SELECT * FROM "A") "T1" WHERE (ROWNUM <= 1)'
|
|
283
|
+
Sequel.mock(:host=>'postgres')[:a].full_text_search(:b, 'c').sql.must_equal "SELECT * FROM \"a\" WHERE (to_tsvector(CAST('simple' AS regconfig), (COALESCE(\"b\", ''))) @@ to_tsquery(CAST('simple' AS regconfig), 'c'))"
|
|
284
|
+
Sequel.mock(:host=>'sqlanywhere').from(:a).offset(1).sql.must_equal 'SELECT TOP 2147483647 START AT (1 + 1) * FROM "A"'
|
|
285
|
+
Sequel.mock(:host=>'sqlite')[:a___b].sql.must_equal "SELECT * FROM `a` AS 'b'"
|
|
286
|
+
ensure
|
|
287
|
+
Sequel.quote_identifiers = qi
|
|
288
|
+
Sequel::Database.send(:instance_variable_set, :@identifier_input_method, ii)
|
|
289
|
+
Sequel::Database.send(:instance_variable_set, :@identifier_output_method, io)
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
describe Sequel::Model, ".[] optimization" do
|
|
295
|
+
before do
|
|
296
|
+
@db = Sequel.mock(:identifier_mangling=>true, :quote_identifiers=>true)
|
|
297
|
+
def @db.schema(*) [[:id, {:primary_key=>true}]] end
|
|
298
|
+
def @db.supports_schema_parsing?() true end
|
|
299
|
+
@c = Class.new(Sequel::Model(@db))
|
|
300
|
+
@ds = @db.dataset.with_quote_identifiers(true)
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
deprecated "should have simple_pk and simple_table respect dataset's identifier input methods" do
|
|
304
|
+
ds = @db.from(:ab).with_identifier_input_method(:reverse)
|
|
305
|
+
@c.set_dataset ds
|
|
306
|
+
@c.simple_table.must_equal '"ba"'
|
|
307
|
+
@c.set_primary_key :cd
|
|
308
|
+
@c.simple_pk.must_equal '"dc"'
|
|
309
|
+
|
|
310
|
+
@c.set_dataset ds.from(:ef__gh)
|
|
311
|
+
@c.simple_table.must_equal '"fe"."hg"'
|
|
312
|
+
end
|
|
313
|
+
end
|
|
314
|
+
|
|
@@ -57,8 +57,8 @@ describe "Sequel::Plugins::AssociationPks" do
|
|
|
57
57
|
@Artist.plugin :association_pks
|
|
58
58
|
@Album.plugin :association_pks
|
|
59
59
|
@Vocalist.plugin :association_pks
|
|
60
|
-
@Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id
|
|
61
|
-
@Album.many_to_many :tags, :class=>@Tag, :join_table=>:albums_tags, :left_key=>:album_id
|
|
60
|
+
@Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id, :delay_pks=>false
|
|
61
|
+
@Album.many_to_many :tags, :class=>@Tag, :join_table=>:albums_tags, :left_key=>:album_id, :delay_pks=>false
|
|
62
62
|
@db.sqls
|
|
63
63
|
end
|
|
64
64
|
|
|
@@ -73,6 +73,13 @@ describe "Sequel::Plugins::AssociationPks" do
|
|
|
73
73
|
@Album.load(:id=>3).tag_pks.must_equal []
|
|
74
74
|
end
|
|
75
75
|
|
|
76
|
+
deprecated "should set associated pks correctly for a one_to_many association when :delay_pks is not set" do
|
|
77
|
+
@Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id
|
|
78
|
+
@Artist.load(:id=>1).album_pks = [1, 2]
|
|
79
|
+
@db.sqls.must_equal ["UPDATE albums SET artist_id = 1 WHERE (id IN (1, 2))",
|
|
80
|
+
"UPDATE albums SET artist_id = NULL WHERE ((albums.artist_id = 1) AND (id NOT IN (1, 2)))"]
|
|
81
|
+
end
|
|
82
|
+
|
|
76
83
|
it "should set associated pks correctly for a one_to_many association" do
|
|
77
84
|
@Artist.load(:id=>1).album_pks = [1, 2]
|
|
78
85
|
@db.sqls.must_equal ["UPDATE albums SET artist_id = 1 WHERE (id IN (1, 2))",
|
|
@@ -111,14 +118,14 @@ describe "Sequel::Plugins::AssociationPks" do
|
|
|
111
118
|
end
|
|
112
119
|
|
|
113
120
|
it "should set associated right-side cpks correctly for a one_to_many association" do
|
|
114
|
-
@Album.one_to_many :vocalists, :class=>@Vocalist, :key=>:album_id
|
|
121
|
+
@Album.one_to_many :vocalists, :class=>@Vocalist, :key=>:album_id, :delay_pks=>false
|
|
115
122
|
@Album.load(:id=>1).vocalist_pks = [["F1", "L1"], ["F2", "L2"]]
|
|
116
123
|
@db.sqls.must_equal ["UPDATE vocalists SET album_id = 1 WHERE ((first, last) IN (('F1', 'L1'), ('F2', 'L2')))",
|
|
117
124
|
"UPDATE vocalists SET album_id = NULL WHERE ((vocalists.album_id = 1) AND ((first, last) NOT IN (('F1', 'L1'), ('F2', 'L2'))))"]
|
|
118
125
|
end
|
|
119
126
|
|
|
120
127
|
it "should set associated right-side cpks correctly for a many_to_many association" do
|
|
121
|
-
@Album.many_to_many :vocalists, :class=>@Vocalist, :join_table=>:albums_vocalists, :left_key=>:album_id, :right_key=>[:first, :last]
|
|
128
|
+
@Album.many_to_many :vocalists, :class=>@Vocalist, :join_table=>:albums_vocalists, :left_key=>:album_id, :right_key=>[:first, :last], :delay_pks=>false
|
|
122
129
|
@Album.load(:id=>2).vocalist_pks = [["F1", "L1"], ["F2", "L2"]]
|
|
123
130
|
sqls = @db.sqls
|
|
124
131
|
sqls[0].must_equal "DELETE FROM albums_vocalists WHERE ((album_id = 2) AND ((first, last) NOT IN (('F1', 'L1'), ('F2', 'L2'))))"
|
|
@@ -142,7 +149,7 @@ describe "Sequel::Plugins::AssociationPks" do
|
|
|
142
149
|
end
|
|
143
150
|
|
|
144
151
|
it "should set associated pks correctly for left-side cpks for a one_to_many association" do
|
|
145
|
-
@Vocalist.one_to_many :instruments, :class=>@Instrument, :key=>[:first, :last]
|
|
152
|
+
@Vocalist.one_to_many :instruments, :class=>@Instrument, :key=>[:first, :last], :delay_pks=>false
|
|
146
153
|
@Vocalist.load(:first=>'F1', :last=>'L1').instrument_pks = [1, 2]
|
|
147
154
|
sqls = @db.sqls
|
|
148
155
|
sqls[0].must_match(/UPDATE instruments SET (first = 'F1', last = 'L1'|last = 'L1', first = 'F1') WHERE \(id IN \(1, 2\)\)/)
|
|
@@ -151,7 +158,7 @@ describe "Sequel::Plugins::AssociationPks" do
|
|
|
151
158
|
end
|
|
152
159
|
|
|
153
160
|
it "should set associated pks correctly for left-side cpks for a many_to_many association" do
|
|
154
|
-
@Vocalist.many_to_many :instruments, :class=>@Instrument, :join_table=>:vocalists_instruments, :left_key=>[:first, :last]
|
|
161
|
+
@Vocalist.many_to_many :instruments, :class=>@Instrument, :join_table=>:vocalists_instruments, :left_key=>[:first, :last], :delay_pks=>false
|
|
155
162
|
@Vocalist.load(:first=>'F2', :last=>'L2').instrument_pks = [1, 2]
|
|
156
163
|
sqls = @db.sqls
|
|
157
164
|
sqls[0].must_equal "DELETE FROM vocalists_instruments WHERE ((first = 'F2') AND (last = 'L2') AND (instrument_id NOT IN (1, 2)))"
|
|
@@ -175,7 +182,7 @@ describe "Sequel::Plugins::AssociationPks" do
|
|
|
175
182
|
end
|
|
176
183
|
|
|
177
184
|
it "should set associated right-side cpks correctly for left-side cpks for a one_to_many association" do
|
|
178
|
-
@Vocalist.one_to_many :hits, :class=>@Hit, :key=>[:first, :last], :order=>:week
|
|
185
|
+
@Vocalist.one_to_many :hits, :class=>@Hit, :key=>[:first, :last], :order=>:week, :delay_pks=>false
|
|
179
186
|
@Vocalist.load(:first=>'F1', :last=>'L1').hit_pks = [[1997, 1], [1997, 2]]
|
|
180
187
|
sqls = @db.sqls
|
|
181
188
|
sqls[0].must_match(/UPDATE hits SET (first = 'F1', last = 'L1'|last = 'L1', first = 'F1') WHERE \(\(year, week\) IN \(\(1997, 1\), \(1997, 2\)\)\)/)
|
|
@@ -184,7 +191,7 @@ describe "Sequel::Plugins::AssociationPks" do
|
|
|
184
191
|
end
|
|
185
192
|
|
|
186
193
|
it "should set associated right-side cpks correctly for left-side cpks for a many_to_many association" do
|
|
187
|
-
@Vocalist.many_to_many :hits, :class=>@Hit, :join_table=>:vocalists_hits, :left_key=>[:first, :last], :right_key=>[:year, :week]
|
|
194
|
+
@Vocalist.many_to_many :hits, :class=>@Hit, :join_table=>:vocalists_hits, :left_key=>[:first, :last], :right_key=>[:year, :week], :delay_pks=>false
|
|
188
195
|
@Vocalist.load(:first=>'F2', :last=>'L2').hit_pks = [[1997, 1], [1997, 2]]
|
|
189
196
|
sqls = @db.sqls
|
|
190
197
|
sqls[0].must_equal "DELETE FROM vocalists_hits WHERE ((first = 'F2') AND (last = 'L2') AND ((year, week) NOT IN ((1997, 1), (1997, 2))))"
|
|
@@ -253,7 +260,7 @@ describe "Sequel::Plugins::AssociationPks" do
|
|
|
253
260
|
it "should automatically convert keys to numbers for appropriate integer primary key for composite key associations" do
|
|
254
261
|
@Hit.db_schema[:year][:type] = :integer
|
|
255
262
|
@Hit.db_schema[:week][:type] = :integer
|
|
256
|
-
@Vocalist.many_to_many :hits, :class=>@Hit, :join_table=>:vocalists_hits, :left_key=>[:first, :last], :right_key=>[:year, :week]
|
|
263
|
+
@Vocalist.many_to_many :hits, :class=>@Hit, :join_table=>:vocalists_hits, :left_key=>[:first, :last], :right_key=>[:year, :week], :delay_pks=>false
|
|
257
264
|
@Vocalist.load(:first=>'F2', :last=>'L2').hit_pks = [['1997', '1'], ['1997', '2']]
|
|
258
265
|
sqls = @db.sqls
|
|
259
266
|
sqls[0].must_equal "DELETE FROM vocalists_hits WHERE ((first = 'F2') AND (last = 'L2') AND ((year, week) NOT IN ((1997, 1), (1997, 2))))"
|
|
@@ -264,12 +271,12 @@ describe "Sequel::Plugins::AssociationPks" do
|
|
|
264
271
|
|
|
265
272
|
@Vocalist.db_schema[:first][:type] = :integer
|
|
266
273
|
@Vocalist.db_schema[:last][:type] = :integer
|
|
267
|
-
@Album.one_to_many :vocalists, :class=>@Vocalist, :key=>:album_id
|
|
274
|
+
@Album.one_to_many :vocalists, :class=>@Vocalist, :key=>:album_id, :delay_pks=>false
|
|
268
275
|
@Album.load(:id=>1).vocalist_pks = [["11", "11"], ["12", "12"]]
|
|
269
276
|
@db.sqls.must_equal ["UPDATE vocalists SET album_id = 1 WHERE ((first, last) IN ((11, 11), (12, 12)))",
|
|
270
277
|
"UPDATE vocalists SET album_id = NULL WHERE ((vocalists.album_id = 1) AND ((first, last) NOT IN ((11, 11), (12, 12))))"]
|
|
271
278
|
|
|
272
|
-
@Album.many_to_many :vocalists, :class=>@Vocalist, :join_table=>:albums_vocalists, :left_key=>:album_id, :right_key=>[:first, :last]
|
|
279
|
+
@Album.many_to_many :vocalists, :class=>@Vocalist, :join_table=>:albums_vocalists, :left_key=>:album_id, :right_key=>[:first, :last], :delay_pks=>false
|
|
273
280
|
@Album.load(:id=>2).vocalist_pks = [["11", "11"], ["12", "12"]]
|
|
274
281
|
sqls = @db.sqls
|
|
275
282
|
sqls[0].must_equal "DELETE FROM albums_vocalists WHERE ((album_id = 2) AND ((first, last) NOT IN ((11, 11), (12, 12))))"
|
|
@@ -281,7 +288,7 @@ describe "Sequel::Plugins::AssociationPks" do
|
|
|
281
288
|
sqls.length.must_equal 6
|
|
282
289
|
end
|
|
283
290
|
|
|
284
|
-
|
|
291
|
+
deprecated "should handle delaying setting of association pks until after saving for new objects, if :delay_pks=>true association option is used" do
|
|
285
292
|
@Artist.one_to_many :albums, :clone=>:albums, :delay_pks=>true
|
|
286
293
|
@Album.many_to_many :tags, :clone=>:tags, :delay_pks=>true
|
|
287
294
|
@Album.db_schema[:id][:type] = :integer
|
|
@@ -316,13 +323,54 @@ describe "Sequel::Plugins::AssociationPks" do
|
|
|
316
323
|
"COMMIT",
|
|
317
324
|
"SELECT * FROM albums WHERE (id = 2) LIMIT 1"
|
|
318
325
|
]
|
|
326
|
+
|
|
327
|
+
al = @Album.load(:id=>1)
|
|
328
|
+
al.tag_pks = [2,3]
|
|
329
|
+
@db.sqls.must_equal [
|
|
330
|
+
"DELETE FROM albums_tags WHERE ((album_id = 1) AND (tag_id NOT IN (2, 3)))",
|
|
331
|
+
"SELECT tag_id FROM albums_tags WHERE (album_id = 1)",
|
|
332
|
+
"BEGIN",
|
|
333
|
+
"INSERT INTO albums_tags (album_id, tag_id) VALUES (1, 3)",
|
|
334
|
+
"COMMIT"
|
|
335
|
+
]
|
|
336
|
+
al.tag_pks.must_equal [1, 2]
|
|
319
337
|
end
|
|
320
338
|
|
|
321
|
-
it "should handle delaying setting of association pks until after saving for existing objects, if :
|
|
339
|
+
it "should handle delaying setting of association pks until after saving for existing objects, if :delay_pks=>:always association option is used" do
|
|
322
340
|
@Artist.one_to_many :albums, :clone=>:albums, :delay_pks=>:always
|
|
323
341
|
@Album.many_to_many :tags, :clone=>:tags, :delay_pks=>:always
|
|
324
342
|
@Album.db_schema[:id][:type] = :integer
|
|
325
343
|
|
|
344
|
+
ar = @Artist.new
|
|
345
|
+
ar.album_pks.must_equal []
|
|
346
|
+
ar.album_pks = ["1","2","3"]
|
|
347
|
+
ar.album_pks.must_equal [1,2,3]
|
|
348
|
+
@db.sqls.must_equal []
|
|
349
|
+
|
|
350
|
+
ar.save
|
|
351
|
+
@db.sqls.must_equal [
|
|
352
|
+
"INSERT INTO artists DEFAULT VALUES",
|
|
353
|
+
"UPDATE albums SET artist_id = 1 WHERE (id IN (1, 2, 3))",
|
|
354
|
+
"UPDATE albums SET artist_id = NULL WHERE ((albums.artist_id = 1) AND (id NOT IN (1, 2, 3)))",
|
|
355
|
+
"SELECT * FROM artists WHERE (id = 1) LIMIT 1",
|
|
356
|
+
]
|
|
357
|
+
|
|
358
|
+
al = @Album.new
|
|
359
|
+
al.tag_pks.must_equal []
|
|
360
|
+
al.tag_pks = [1,2]
|
|
361
|
+
al.tag_pks.must_equal [1, 2]
|
|
362
|
+
@db.sqls.must_equal []
|
|
363
|
+
|
|
364
|
+
al.save
|
|
365
|
+
@db.sqls.must_equal [
|
|
366
|
+
"INSERT INTO albums DEFAULT VALUES",
|
|
367
|
+
"DELETE FROM albums_tags WHERE ((album_id = 2) AND (tag_id NOT IN (1, 2)))",
|
|
368
|
+
"SELECT tag_id FROM albums_tags WHERE (album_id = 2)",
|
|
369
|
+
"BEGIN",
|
|
370
|
+
"INSERT INTO albums_tags (album_id, tag_id) VALUES (2, 1)",
|
|
371
|
+
"COMMIT",
|
|
372
|
+
"SELECT * FROM albums WHERE (id = 2) LIMIT 1"
|
|
373
|
+
]
|
|
326
374
|
ar = @Artist.load(:id=>1)
|
|
327
375
|
ar.album_pks.must_equal [1,2,3]
|
|
328
376
|
@db.sqls
|