sequel 4.47.0 → 4.48.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 +134 -0
- data/Rakefile +1 -1
- data/doc/release_notes/4.48.0.txt +293 -0
- data/lib/sequel/adapters/ado/access.rb +2 -1
- data/lib/sequel/adapters/do/postgres.rb +5 -2
- data/lib/sequel/adapters/ibmdb.rb +24 -7
- data/lib/sequel/adapters/jdbc.rb +36 -22
- data/lib/sequel/adapters/jdbc/db2.rb +12 -3
- data/lib/sequel/adapters/jdbc/derby.rb +4 -5
- data/lib/sequel/adapters/jdbc/oracle.rb +16 -2
- data/lib/sequel/adapters/jdbc/postgresql.rb +43 -18
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +9 -7
- data/lib/sequel/adapters/jdbc/sqlserver.rb +11 -4
- data/lib/sequel/adapters/mock.rb +24 -19
- data/lib/sequel/adapters/mysql.rb +17 -16
- data/lib/sequel/adapters/mysql2.rb +4 -5
- data/lib/sequel/adapters/oracle.rb +5 -9
- data/lib/sequel/adapters/postgres.rb +89 -102
- data/lib/sequel/adapters/shared/db2.rb +22 -6
- data/lib/sequel/adapters/shared/mssql.rb +5 -4
- data/lib/sequel/adapters/shared/mysql.rb +75 -24
- data/lib/sequel/adapters/shared/postgres.rb +196 -94
- data/lib/sequel/adapters/shared/sqlanywhere.rb +23 -10
- data/lib/sequel/adapters/shared/sqlite.rb +72 -82
- data/lib/sequel/adapters/sqlanywhere.rb +4 -1
- data/lib/sequel/adapters/sqlite.rb +5 -3
- data/lib/sequel/adapters/swift/postgres.rb +5 -2
- data/lib/sequel/adapters/tinytds.rb +0 -5
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -1
- data/lib/sequel/adapters/utils/pg_types.rb +2 -76
- data/lib/sequel/core.rb +2 -2
- data/lib/sequel/database/connecting.rb +5 -5
- data/lib/sequel/database/dataset.rb +6 -3
- data/lib/sequel/database/misc.rb +1 -1
- data/lib/sequel/database/query.rb +3 -0
- data/lib/sequel/database/schema_methods.rb +1 -1
- data/lib/sequel/dataset/actions.rb +18 -10
- data/lib/sequel/dataset/graph.rb +1 -1
- data/lib/sequel/dataset/misc.rb +1 -0
- data/lib/sequel/dataset/prepared_statements.rb +3 -3
- data/lib/sequel/dataset/query.rb +19 -8
- data/lib/sequel/extensions/core_extensions.rb +4 -1
- data/lib/sequel/extensions/duplicate_columns_handler.rb +1 -1
- data/lib/sequel/extensions/empty_array_ignore_nulls.rb +3 -0
- data/lib/sequel/extensions/filter_having.rb +2 -0
- data/lib/sequel/extensions/freeze_datasets.rb +2 -0
- data/lib/sequel/extensions/from_block.rb +1 -1
- data/lib/sequel/extensions/graph_each.rb +2 -2
- data/lib/sequel/extensions/hash_aliases.rb +2 -0
- data/lib/sequel/extensions/identifier_mangling.rb +0 -7
- data/lib/sequel/extensions/meta_def.rb +2 -0
- data/lib/sequel/extensions/migration.rb +6 -6
- data/lib/sequel/extensions/no_auto_literal_strings.rb +1 -1
- data/lib/sequel/extensions/pagination.rb +1 -1
- data/lib/sequel/extensions/pg_array.rb +207 -130
- data/lib/sequel/extensions/pg_hstore.rb +38 -20
- data/lib/sequel/extensions/pg_inet.rb +18 -6
- data/lib/sequel/extensions/pg_interval.rb +19 -12
- data/lib/sequel/extensions/pg_json.rb +25 -14
- data/lib/sequel/extensions/pg_json_ops.rb +2 -2
- data/lib/sequel/extensions/pg_range.rb +133 -100
- data/lib/sequel/extensions/pg_range_ops.rb +4 -3
- data/lib/sequel/extensions/pg_row.rb +68 -39
- data/lib/sequel/extensions/pg_row_ops.rb +11 -5
- data/lib/sequel/extensions/query_literals.rb +2 -0
- data/lib/sequel/extensions/ruby18_symbol_extensions.rb +2 -0
- data/lib/sequel/extensions/s.rb +1 -1
- data/lib/sequel/extensions/schema_dumper.rb +24 -24
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +3 -1
- data/lib/sequel/extensions/sequel_4_dataset_methods.rb +83 -0
- data/lib/sequel/extensions/set_overrides.rb +2 -2
- data/lib/sequel/extensions/string_agg.rb +0 -1
- data/lib/sequel/extensions/symbol_aref.rb +0 -4
- data/lib/sequel/model.rb +25 -57
- data/lib/sequel/model/associations.rb +14 -5
- data/lib/sequel/model/base.rb +96 -32
- data/lib/sequel/plugins/association_pks.rb +73 -46
- data/lib/sequel/plugins/association_proxies.rb +1 -1
- data/lib/sequel/plugins/auto_validations.rb +6 -2
- data/lib/sequel/plugins/boolean_readers.rb +1 -1
- data/lib/sequel/plugins/caching.rb +19 -13
- data/lib/sequel/plugins/class_table_inheritance.rb +19 -10
- data/lib/sequel/plugins/column_conflicts.rb +7 -2
- data/lib/sequel/plugins/column_select.rb +1 -1
- data/lib/sequel/plugins/csv_serializer.rb +8 -8
- data/lib/sequel/plugins/defaults_setter.rb +10 -0
- data/lib/sequel/plugins/eager_each.rb +1 -1
- data/lib/sequel/plugins/force_encoding.rb +2 -2
- data/lib/sequel/plugins/hook_class_methods.rb +9 -12
- data/lib/sequel/plugins/identifier_columns.rb +2 -0
- data/lib/sequel/plugins/instance_filters.rb +3 -1
- data/lib/sequel/plugins/instance_hooks.rb +17 -9
- data/lib/sequel/plugins/json_serializer.rb +17 -10
- data/lib/sequel/plugins/lazy_attributes.rb +8 -7
- data/lib/sequel/plugins/modification_detection.rb +3 -0
- data/lib/sequel/plugins/nested_attributes.rb +5 -1
- data/lib/sequel/plugins/pg_array_associations.rb +5 -0
- data/lib/sequel/plugins/prepared_statements.rb +1 -0
- data/lib/sequel/plugins/rcte_tree.rb +4 -4
- data/lib/sequel/plugins/serialization.rb +3 -10
- data/lib/sequel/plugins/single_table_inheritance.rb +2 -2
- data/lib/sequel/plugins/split_values.rb +6 -5
- data/lib/sequel/plugins/static_cache.rb +31 -25
- data/lib/sequel/plugins/subset_conditions.rb +3 -1
- data/lib/sequel/plugins/table_select.rb +1 -1
- data/lib/sequel/plugins/touch.rb +2 -1
- data/lib/sequel/plugins/validation_class_methods.rb +5 -6
- data/lib/sequel/plugins/validation_helpers.rb +2 -4
- data/lib/sequel/plugins/xml_serializer.rb +4 -4
- data/lib/sequel/sql.rb +2 -2
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +115 -14
- data/spec/adapters/mysql_spec.rb +78 -28
- data/spec/adapters/oracle_spec.rb +24 -24
- data/spec/adapters/postgres_spec.rb +38 -24
- data/spec/adapters/sqlanywhere_spec.rb +88 -86
- data/spec/adapters/sqlite_spec.rb +29 -24
- data/spec/core/connection_pool_spec.rb +17 -0
- data/spec/core/database_spec.rb +6 -0
- data/spec/core/dataset_spec.rb +46 -36
- data/spec/core/schema_spec.rb +16 -0
- data/spec/core/spec_helper.rb +1 -0
- data/spec/core_extensions_spec.rb +6 -2
- data/spec/extensions/active_model_spec.rb +1 -1
- data/spec/extensions/arbitrary_servers_spec.rb +1 -1
- data/spec/extensions/association_pks_spec.rb +34 -2
- data/spec/extensions/auto_literal_strings_spec.rb +5 -1
- data/spec/extensions/auto_validations_spec.rb +2 -0
- data/spec/extensions/boolean_readers_spec.rb +1 -1
- data/spec/extensions/boolean_subsets_spec.rb +1 -1
- data/spec/extensions/class_table_inheritance_spec.rb +48 -2
- data/spec/extensions/column_conflicts_spec.rb +11 -0
- data/spec/extensions/connection_validator_spec.rb +1 -1
- data/spec/extensions/dataset_associations_spec.rb +8 -8
- data/spec/extensions/defaults_setter_spec.rb +1 -1
- data/spec/extensions/filter_having_spec.rb +5 -3
- data/spec/extensions/hash_aliases_spec.rb +3 -1
- data/spec/extensions/identifier_columns_spec.rb +3 -1
- data/spec/extensions/implicit_subquery_spec.rb +4 -2
- data/spec/extensions/json_serializer_spec.rb +18 -0
- data/spec/extensions/lazy_attributes_spec.rb +3 -3
- data/spec/extensions/meta_def_spec.rb +9 -0
- data/spec/extensions/migration_spec.rb +3 -3
- data/spec/extensions/nested_attributes_spec.rb +14 -3
- data/spec/extensions/no_auto_literal_strings_spec.rb +8 -4
- data/spec/extensions/pg_array_associations_spec.rb +29 -18
- data/spec/extensions/pg_array_spec.rb +44 -25
- data/spec/extensions/pg_hstore_spec.rb +10 -0
- data/spec/extensions/pg_inet_spec.rb +26 -0
- data/spec/extensions/pg_interval_spec.rb +20 -0
- data/spec/extensions/pg_json_spec.rb +24 -0
- data/spec/extensions/pg_range_spec.rb +98 -14
- data/spec/extensions/pg_row_spec.rb +14 -4
- data/spec/extensions/prepared_statements_safe_spec.rb +1 -1
- data/spec/extensions/query_literals_spec.rb +3 -1
- data/spec/extensions/schema_dumper_spec.rb +96 -98
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +10 -6
- data/spec/extensions/sequel_4_dataset_methods_spec.rb +121 -0
- data/spec/extensions/single_table_inheritance_spec.rb +1 -1
- data/spec/extensions/spec_helper.rb +7 -1
- data/spec/extensions/static_cache_spec.rb +75 -24
- data/spec/extensions/string_agg_spec.rb +1 -1
- data/spec/extensions/touch_spec.rb +9 -0
- data/spec/extensions/validation_helpers_spec.rb +9 -3
- data/spec/extensions/whitelist_security_spec.rb +26 -0
- data/spec/integration/dataset_test.rb +45 -44
- data/spec/integration/plugin_test.rb +20 -0
- data/spec/integration/prepared_statement_test.rb +3 -0
- data/spec/integration/schema_test.rb +21 -1
- data/spec/integration/transaction_test.rb +40 -40
- data/spec/model/class_dataset_methods_spec.rb +14 -4
- data/spec/model/dataset_methods_spec.rb +12 -3
- data/spec/model/model_spec.rb +8 -0
- metadata +6 -4
- data/spec/adapters/firebird_spec.rb +0 -405
- data/spec/adapters/informix_spec.rb +0 -100
|
@@ -26,6 +26,7 @@ module Sequel
|
|
|
26
26
|
# * Model.each
|
|
27
27
|
# * Model.count (without an argument or block)
|
|
28
28
|
# * Model.map
|
|
29
|
+
# * Model.as_hash
|
|
29
30
|
# * Model.to_hash
|
|
30
31
|
# * Model.to_hash_groups
|
|
31
32
|
#
|
|
@@ -127,41 +128,46 @@ module Sequel
|
|
|
127
128
|
Plugins.inherited_instance_variables(self, :@static_cache_frozen=>nil)
|
|
128
129
|
|
|
129
130
|
# Use the cache instead of a query to get the results.
|
|
130
|
-
def
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
131
|
+
def as_hash(key_column = nil, value_column = nil, opts = OPTS)
|
|
132
|
+
if key_column.nil? && value_column.nil?
|
|
133
|
+
if @static_cache_frozen && !opts[:hash]
|
|
134
|
+
return Hash[cache]
|
|
135
|
+
else
|
|
136
|
+
key_column = primary_key
|
|
137
|
+
end
|
|
136
138
|
end
|
|
137
|
-
end
|
|
138
139
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
140
|
+
h = opts[:hash] || {}
|
|
141
|
+
if value_column
|
|
142
|
+
if value_column.is_a?(Array)
|
|
143
|
+
if key_column.is_a?(Array)
|
|
144
|
+
@all.each{|r| h[r.values.values_at(*key_column)] = r.values.values_at(*value_column)}
|
|
145
|
+
else
|
|
146
|
+
@all.each{|r| h[r[key_column]] = r.values.values_at(*value_column)}
|
|
147
|
+
end
|
|
144
148
|
else
|
|
145
|
-
|
|
149
|
+
if key_column.is_a?(Array)
|
|
150
|
+
@all.each{|r| h[r.values.values_at(*key_column)] = r[value_column]}
|
|
151
|
+
else
|
|
152
|
+
@all.each{|r| h[r[key_column]] = r[value_column]}
|
|
153
|
+
end
|
|
146
154
|
end
|
|
155
|
+
elsif key_column.is_a?(Array)
|
|
156
|
+
@all.each{|r| h[r.values.values_at(*key_column)] = static_cache_object(r)}
|
|
147
157
|
else
|
|
148
|
-
|
|
149
|
-
@all.each{|r| h[r.values.values_at(*key_column)] = r[value_column]}
|
|
150
|
-
else
|
|
151
|
-
@all.each{|r| h[r[key_column]] = r[value_column]}
|
|
152
|
-
end
|
|
158
|
+
@all.each{|r| h[r[key_column]] = static_cache_object(r)}
|
|
153
159
|
end
|
|
154
|
-
|
|
155
|
-
@all.each{|r| h[r.values.values_at(*key_column)] = static_cache_object(r)}
|
|
156
|
-
else
|
|
157
|
-
@all.each{|r| h[r[key_column]] = static_cache_object(r)}
|
|
160
|
+
h
|
|
158
161
|
end
|
|
159
|
-
|
|
162
|
+
|
|
163
|
+
# Alias of as_hash for backwards compatibility.
|
|
164
|
+
def to_hash(*a)
|
|
165
|
+
as_hash(*a)
|
|
160
166
|
end
|
|
161
167
|
|
|
162
168
|
# Use the cache instead of a query to get the results
|
|
163
|
-
def to_hash_groups(key_column, value_column = nil)
|
|
164
|
-
h = {}
|
|
169
|
+
def to_hash_groups(key_column, value_column = nil, opts = OPTS)
|
|
170
|
+
h = opts[:hash] || {}
|
|
165
171
|
if value_column
|
|
166
172
|
if value_column.is_a?(Array)
|
|
167
173
|
if key_column.is_a?(Array)
|
|
@@ -13,7 +13,9 @@ module Sequel
|
|
|
13
13
|
# Album.plugin :subset_conditions
|
|
14
14
|
#
|
|
15
15
|
# # This will now create a published_conditions method
|
|
16
|
-
# Album.
|
|
16
|
+
# Album.dataset_module do
|
|
17
|
+
# subset :published, :published => true
|
|
18
|
+
# end
|
|
17
19
|
#
|
|
18
20
|
# Album.where(Album.published_conditions).sql
|
|
19
21
|
# # SELECT * FROM albums WHERE (published IS TRUE)
|
|
@@ -32,7 +32,7 @@ module Sequel
|
|
|
32
32
|
# has no explicit selection, select table.* from that table.
|
|
33
33
|
def convert_input_dataset(ds)
|
|
34
34
|
ds = super
|
|
35
|
-
if !ds.opts[:select] && (from = ds.opts[:from]) && from.length == 1 && !ds.opts[:join]
|
|
35
|
+
if !ds.opts[:select] && (from = ds.opts[:from]) && from.length == 1 && !ds.opts[:join] # SEQUEL5: Only !ds.opts[:select]
|
|
36
36
|
ds = ds.select_all(ds.first_source)
|
|
37
37
|
end
|
|
38
38
|
ds
|
data/lib/sequel/plugins/touch.rb
CHANGED
|
@@ -136,10 +136,11 @@ module Sequel
|
|
|
136
136
|
# Can't update all values at once, so update each instance individually.
|
|
137
137
|
# Instead if doing a simple save, update via the instance's dataset,
|
|
138
138
|
# to avoid going into an infinite loop in some cases.
|
|
139
|
-
send(
|
|
139
|
+
send(assoc).each{|x| x.this.update(column=>touch_association_value)}
|
|
140
140
|
else
|
|
141
141
|
# Update all values at once for performance reasons.
|
|
142
142
|
ds.update(column=>touch_association_value)
|
|
143
|
+
associations.delete(assoc)
|
|
143
144
|
end
|
|
144
145
|
end
|
|
145
146
|
end
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# frozen-string-literal: true
|
|
2
2
|
|
|
3
3
|
module Sequel
|
|
4
|
-
extension :blank
|
|
5
|
-
|
|
6
4
|
module Plugins
|
|
7
5
|
# Sequel's built-in validation_class_methods plugin adds backwards compatibility
|
|
8
6
|
# for the legacy class-level validation methods (e.g. validates_presence_of :column).
|
|
@@ -11,7 +9,7 @@ module Sequel
|
|
|
11
9
|
# as it is less complex and more flexible. However, this plugin provides reflection
|
|
12
10
|
# support, since it is class-level, while the instance-level validation_helpers
|
|
13
11
|
# plugin does not.
|
|
14
|
-
#
|
|
12
|
+
#
|
|
15
13
|
# Usage:
|
|
16
14
|
#
|
|
17
15
|
# # Add the validation class methods to all model subclasses (called before loading subclasses)
|
|
@@ -118,7 +116,7 @@ module Sequel
|
|
|
118
116
|
validations.each do |att, procs|
|
|
119
117
|
v = case att
|
|
120
118
|
when Array
|
|
121
|
-
att.
|
|
119
|
+
att.map{|a| o.get_column_value(a)}
|
|
122
120
|
else
|
|
123
121
|
o.get_column_value(att)
|
|
124
122
|
end
|
|
@@ -194,11 +192,12 @@ module Sequel
|
|
|
194
192
|
# :tag :: The tag to use for this validation.
|
|
195
193
|
def validates_each(*atts, &block)
|
|
196
194
|
opts = extract_options!(atts)
|
|
195
|
+
blank_meth = db.method(:blank_object?).to_proc
|
|
197
196
|
blk = if (i = opts[:if]) || (am = opts[:allow_missing]) || (an = opts[:allow_nil]) || (ab = opts[:allow_blank])
|
|
198
197
|
proc do |o,a,v|
|
|
199
198
|
next if i && !validation_if_proc(o, i)
|
|
200
199
|
next if an && Array(v).all?(&:nil?)
|
|
201
|
-
next if ab && Array(v).all?(
|
|
200
|
+
next if ab && Array(v).all?(&blank_meth)
|
|
202
201
|
next if am && Array(a).all?{|x| !o.values.has_key?(x)}
|
|
203
202
|
block.call(o,a,v)
|
|
204
203
|
end
|
|
@@ -317,7 +316,7 @@ module Sequel
|
|
|
317
316
|
reflect_validation(:presence, opts, atts)
|
|
318
317
|
atts << opts
|
|
319
318
|
validates_each(*atts) do |o, a, v|
|
|
320
|
-
o.errors.add(a, opts[:message]) if
|
|
319
|
+
o.errors.add(a, opts[:message]) if db.send(:blank_object?, v) && v != false
|
|
321
320
|
end
|
|
322
321
|
end
|
|
323
322
|
|
|
@@ -19,9 +19,7 @@ module Sequel
|
|
|
19
19
|
# atts :: Single attribute symbol or an array of attribute symbols specifying the
|
|
20
20
|
# attribute(s) to validate.
|
|
21
21
|
# Options:
|
|
22
|
-
# :allow_blank :: Whether to skip the validation if the value is blank.
|
|
23
|
-
# make sure all objects respond to blank if you use this option, which you can do by:
|
|
24
|
-
# Sequel.extension :blank
|
|
22
|
+
# :allow_blank :: Whether to skip the validation if the value is blank.
|
|
25
23
|
# :allow_missing :: Whether to skip the validation if the attribute isn't a key in the
|
|
26
24
|
# values hash. This is different from allow_nil, because Sequel only sends the attributes
|
|
27
25
|
# in the values when doing an insert or update. If the attribute is not present, Sequel
|
|
@@ -284,7 +282,7 @@ module Sequel
|
|
|
284
282
|
next if am && !values.has_key?(a)
|
|
285
283
|
v = from_values ? values[a] : get_column_value(a)
|
|
286
284
|
next if an && v.nil?
|
|
287
|
-
next if ab &&
|
|
285
|
+
next if ab && model.db.send(:blank_object?, v)
|
|
288
286
|
if message = yield(a, v, m)
|
|
289
287
|
errors.add(a, message)
|
|
290
288
|
end
|
|
@@ -158,7 +158,7 @@ module Sequel
|
|
|
158
158
|
opts[:builder]
|
|
159
159
|
else
|
|
160
160
|
builder_opts = if opts[:builder_opts]
|
|
161
|
-
opts[:builder_opts]
|
|
161
|
+
Hash[opts[:builder_opts]]
|
|
162
162
|
else
|
|
163
163
|
{}
|
|
164
164
|
end
|
|
@@ -234,10 +234,10 @@ module Sequel
|
|
|
234
234
|
if assocs = opts[:associations]
|
|
235
235
|
assocs = case assocs
|
|
236
236
|
when Symbol
|
|
237
|
-
{assocs=>
|
|
237
|
+
{assocs=>OPTS}
|
|
238
238
|
when Array
|
|
239
239
|
assocs_tmp = {}
|
|
240
|
-
assocs.each{|v| assocs_tmp[v] =
|
|
240
|
+
assocs.each{|v| assocs_tmp[v] = OPTS}
|
|
241
241
|
assocs_tmp
|
|
242
242
|
when Hash
|
|
243
243
|
assocs
|
|
@@ -347,7 +347,7 @@ module Sequel
|
|
|
347
347
|
cols.each do |c|
|
|
348
348
|
attrs = {}
|
|
349
349
|
if types
|
|
350
|
-
attrs[:type] = db_schema.fetch(c,
|
|
350
|
+
attrs[:type] = db_schema.fetch(c, OPTS)[:type]
|
|
351
351
|
end
|
|
352
352
|
v = vals[c]
|
|
353
353
|
if v.nil?
|
data/lib/sequel/sql.rb
CHANGED
|
@@ -1150,7 +1150,7 @@ module Sequel
|
|
|
1150
1150
|
when BooleanExpression
|
|
1151
1151
|
case op = ce.op
|
|
1152
1152
|
when :AND, :OR
|
|
1153
|
-
BooleanExpression.new(OPERTATOR_INVERSIONS[op], *ce.args.
|
|
1153
|
+
BooleanExpression.new(OPERTATOR_INVERSIONS[op], *ce.args.map{|a| BooleanExpression.invert(a)})
|
|
1154
1154
|
else
|
|
1155
1155
|
BooleanExpression.new(OPERTATOR_INVERSIONS[op], *ce.args.dup)
|
|
1156
1156
|
end
|
|
@@ -1764,7 +1764,7 @@ module Sequel
|
|
|
1764
1764
|
def self.like(l, *ces)
|
|
1765
1765
|
l, lre, lci = like_element(l)
|
|
1766
1766
|
lci = (ces.last.is_a?(Hash) ? ces.pop : {})[:case_insensitive] ? true : lci
|
|
1767
|
-
ces.
|
|
1767
|
+
ces.map! do |ce|
|
|
1768
1768
|
r, rre, rci = like_element(ce)
|
|
1769
1769
|
BooleanExpression.new(LIKE_MAP[[lre||rre, lci||rci]], l, r)
|
|
1770
1770
|
end
|
data/lib/sequel/version.rb
CHANGED
|
@@ -5,7 +5,7 @@ module Sequel
|
|
|
5
5
|
MAJOR = 4
|
|
6
6
|
# The minor version of Sequel. Bumped for every non-patch level
|
|
7
7
|
# release, generally around once a month.
|
|
8
|
-
MINOR =
|
|
8
|
+
MINOR = 48
|
|
9
9
|
# The tiny version of Sequel. Usually 0, only bumped for bugfix
|
|
10
10
|
# releases that fix regressions from previous versions.
|
|
11
11
|
TINY = 0
|
data/spec/adapters/db2_spec.rb
CHANGED
|
@@ -28,9 +28,47 @@ describe Sequel::Database do
|
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
+
# SEQUEL5: Remove
|
|
31
32
|
describe "Simple Dataset operations" do
|
|
32
33
|
before(:all) do
|
|
33
|
-
|
|
34
|
+
deprecated do
|
|
35
|
+
Sequel::DB2.use_clob_as_blob = true
|
|
36
|
+
end
|
|
37
|
+
DB.send(:remove_instance_variable, :@use_clob_as_blob) if DB.send(:instance_variable_defined?, :@use_clob_as_blob)
|
|
38
|
+
DB.create_table!(:items) do
|
|
39
|
+
Integer :id, :primary_key => true
|
|
40
|
+
Integer :number
|
|
41
|
+
column :bin_string, 'varchar(20) for bit data'
|
|
42
|
+
column :bin_clob, 'clob'
|
|
43
|
+
end
|
|
44
|
+
@ds = DB[:items]
|
|
45
|
+
end
|
|
46
|
+
after(:each) do
|
|
47
|
+
@ds.delete
|
|
48
|
+
end
|
|
49
|
+
after(:all) do
|
|
50
|
+
deprecated do
|
|
51
|
+
Sequel::DB2.use_clob_as_blob = false
|
|
52
|
+
end
|
|
53
|
+
DB.send(:remove_instance_variable, :@use_clob_as_blob) if DB.send(:instance_variable_defined?, :@use_clob_as_blob)
|
|
54
|
+
DB.drop_table(:items)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it "should insert with a primary key specified" do
|
|
58
|
+
@ds.insert(:id => 1, :number => 10)
|
|
59
|
+
@ds.insert(:id => 100, :number => 20)
|
|
60
|
+
@ds.select_hash(:id, :number).must_equal(1 => 10, 100 => 20)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "should insert into binary columns" do
|
|
64
|
+
@ds.insert(:id => 1, :bin_string => Sequel.blob("\1"), :bin_clob => Sequel.blob("\2"))
|
|
65
|
+
@ds.select(:bin_string, :bin_clob).first.must_equal(:bin_string => "\1", :bin_clob => "\2")
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
describe "Simple Dataset operations" do
|
|
70
|
+
before(:all) do
|
|
71
|
+
DB.use_clob_as_blob = true
|
|
34
72
|
DB.create_table!(:items) do
|
|
35
73
|
Integer :id, :primary_key => true
|
|
36
74
|
Integer :number
|
|
@@ -43,7 +81,7 @@ describe "Simple Dataset operations" do
|
|
|
43
81
|
@ds.delete
|
|
44
82
|
end
|
|
45
83
|
after(:all) do
|
|
46
|
-
|
|
84
|
+
DB.use_clob_as_blob = false
|
|
47
85
|
DB.drop_table(:items)
|
|
48
86
|
end
|
|
49
87
|
|
|
@@ -88,6 +126,7 @@ describe Sequel::Database do
|
|
|
88
126
|
end
|
|
89
127
|
end
|
|
90
128
|
|
|
129
|
+
# SEQUEL5: remove
|
|
91
130
|
describe "Sequel::IBMDB.convert_smallint_to_bool" do
|
|
92
131
|
before do
|
|
93
132
|
@db = DB
|
|
@@ -95,55 +134,117 @@ describe "Sequel::IBMDB.convert_smallint_to_bool" do
|
|
|
95
134
|
@ds = @db[:booltest]
|
|
96
135
|
end
|
|
97
136
|
after do
|
|
137
|
+
deprecated do
|
|
138
|
+
Sequel::IBMDB.convert_smallint_to_bool = true
|
|
139
|
+
end
|
|
140
|
+
@db.drop_table(:booltest)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
deprecated "should consider smallint datatypes as boolean if set, but not larger smallints" do
|
|
144
|
+
@db.schema(:booltest, :reload=>true).first.last[:type].must_equal :boolean
|
|
145
|
+
@db.schema(:booltest, :reload=>true).first.last[:db_type].must_match /smallint/i
|
|
146
|
+
Sequel::IBMDB.convert_smallint_to_bool = false
|
|
147
|
+
@db.schema(:booltest, :reload=>true).first.last[:type].must_equal :integer
|
|
148
|
+
@db.schema(:booltest, :reload=>true).first.last[:db_type].must_match /smallint/i
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
deprecated "should return smallints as bools and integers as integers when set" do
|
|
98
152
|
Sequel::IBMDB.convert_smallint_to_bool = true
|
|
153
|
+
@ds.delete
|
|
154
|
+
@ds.insert(:b=>true, :i=>10)
|
|
155
|
+
@ds.all.must_equal [{:b=>true, :i=>10}]
|
|
156
|
+
@ds.delete
|
|
157
|
+
@ds.insert(:b=>false, :i=>0)
|
|
158
|
+
@ds.all.must_equal [{:b=>false, :i=>0}]
|
|
159
|
+
@ds.delete
|
|
160
|
+
@ds.insert(:b=>true, :i=>1)
|
|
161
|
+
@ds.all.must_equal [{:b=>true, :i=>1}]
|
|
162
|
+
|
|
163
|
+
@ds = @ds.with_convert_smallint_to_bool(false)
|
|
164
|
+
@ds.delete
|
|
165
|
+
@ds.insert(:b=>true, :i=>10)
|
|
166
|
+
@ds.all.must_equal [{:b=>1, :i=>10}]
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
deprecated "should return all smallints as integers when unset" do
|
|
170
|
+
Sequel::IBMDB.convert_smallint_to_bool = false
|
|
171
|
+
@ds.delete
|
|
172
|
+
@ds.insert(:b=>true, :i=>10)
|
|
173
|
+
@ds.all.must_equal [{:b=>1, :i=>10}]
|
|
174
|
+
@ds.delete
|
|
175
|
+
@ds.insert(:b=>false, :i=>0)
|
|
176
|
+
@ds.all.must_equal [{:b=>0, :i=>0}]
|
|
177
|
+
|
|
178
|
+
@ds.delete
|
|
179
|
+
@ds.insert(:b=>1, :i=>10)
|
|
180
|
+
@ds.all.must_equal [{:b=>1, :i=>10}]
|
|
181
|
+
@ds.delete
|
|
182
|
+
@ds.insert(:b=>0, :i=>0)
|
|
183
|
+
@ds.all.must_equal [{:b=>0, :i=>0}]
|
|
184
|
+
|
|
185
|
+
@ds = @ds.with_convert_smallint_to_bool(true)
|
|
186
|
+
@ds.delete
|
|
187
|
+
@ds.insert(:b=>true, :i=>10)
|
|
188
|
+
@ds.all.must_equal [{:b=>true, :i=>10}]
|
|
189
|
+
end
|
|
190
|
+
end if DB.adapter_scheme == :ibmdb
|
|
191
|
+
|
|
192
|
+
describe "Sequel::IBMDB::Database#convert_smallint_to_bool" do
|
|
193
|
+
before do
|
|
194
|
+
@db = DB
|
|
195
|
+
@db.create_table!(:booltest){column :b, 'smallint'; column :i, 'integer'}
|
|
196
|
+
@ds = @db[:booltest]
|
|
197
|
+
end
|
|
198
|
+
after do
|
|
199
|
+
@db.convert_smallint_to_bool = nil # SEQUEL5: true
|
|
99
200
|
@db.drop_table(:booltest)
|
|
100
201
|
end
|
|
101
202
|
|
|
102
203
|
it "should consider smallint datatypes as boolean if set, but not larger smallints" do
|
|
103
204
|
@db.schema(:booltest, :reload=>true).first.last[:type].must_equal :boolean
|
|
104
205
|
@db.schema(:booltest, :reload=>true).first.last[:db_type].must_match /smallint/i
|
|
105
|
-
|
|
206
|
+
@db.convert_smallint_to_bool = false
|
|
106
207
|
@db.schema(:booltest, :reload=>true).first.last[:type].must_equal :integer
|
|
107
208
|
@db.schema(:booltest, :reload=>true).first.last[:db_type].must_match /smallint/i
|
|
108
209
|
end
|
|
109
210
|
|
|
110
211
|
it "should return smallints as bools and integers as integers when set" do
|
|
111
|
-
|
|
212
|
+
@db.convert_smallint_to_bool = true
|
|
112
213
|
@ds.delete
|
|
113
|
-
@ds
|
|
214
|
+
@ds.insert(:b=>true, :i=>10)
|
|
114
215
|
@ds.all.must_equal [{:b=>true, :i=>10}]
|
|
115
216
|
@ds.delete
|
|
116
|
-
@ds
|
|
217
|
+
@ds.insert(:b=>false, :i=>0)
|
|
117
218
|
@ds.all.must_equal [{:b=>false, :i=>0}]
|
|
118
219
|
@ds.delete
|
|
119
|
-
@ds
|
|
220
|
+
@ds.insert(:b=>true, :i=>1)
|
|
120
221
|
@ds.all.must_equal [{:b=>true, :i=>1}]
|
|
121
222
|
|
|
122
223
|
@ds = @ds.with_convert_smallint_to_bool(false)
|
|
123
224
|
@ds.delete
|
|
124
|
-
@ds
|
|
225
|
+
@ds.insert(:b=>true, :i=>10)
|
|
125
226
|
@ds.all.must_equal [{:b=>1, :i=>10}]
|
|
126
227
|
end
|
|
127
228
|
|
|
128
229
|
it "should return all smallints as integers when unset" do
|
|
129
|
-
|
|
230
|
+
@db.convert_smallint_to_bool = false
|
|
130
231
|
@ds.delete
|
|
131
|
-
@ds
|
|
232
|
+
@ds.insert(:b=>true, :i=>10)
|
|
132
233
|
@ds.all.must_equal [{:b=>1, :i=>10}]
|
|
133
234
|
@ds.delete
|
|
134
|
-
@ds
|
|
235
|
+
@ds.insert(:b=>false, :i=>0)
|
|
135
236
|
@ds.all.must_equal [{:b=>0, :i=>0}]
|
|
136
237
|
|
|
137
238
|
@ds.delete
|
|
138
|
-
@ds
|
|
239
|
+
@ds.insert(:b=>1, :i=>10)
|
|
139
240
|
@ds.all.must_equal [{:b=>1, :i=>10}]
|
|
140
241
|
@ds.delete
|
|
141
|
-
@ds
|
|
242
|
+
@ds.insert(:b=>0, :i=>0)
|
|
142
243
|
@ds.all.must_equal [{:b=>0, :i=>0}]
|
|
143
244
|
|
|
144
245
|
@ds = @ds.with_convert_smallint_to_bool(true)
|
|
145
246
|
@ds.delete
|
|
146
|
-
@ds
|
|
247
|
+
@ds.insert(:b=>true, :i=>10)
|
|
147
248
|
@ds.all.must_equal [{:b=>true, :i=>10}]
|
|
148
249
|
end
|
|
149
250
|
end if DB.adapter_scheme == :ibmdb
|
data/spec/adapters/mysql_spec.rb
CHANGED
|
@@ -121,30 +121,30 @@ if [:mysql, :mysql2].include?(DB.adapter_scheme)
|
|
|
121
121
|
it "should return tinyint(1)s as bools and tinyint(4)s as integers when set" do
|
|
122
122
|
@db.convert_tinyint_to_bool = true
|
|
123
123
|
@ds.delete
|
|
124
|
-
@ds
|
|
124
|
+
@ds.insert(:b=>true, :i=>10)
|
|
125
125
|
@ds.all.must_equal [{:b=>true, :i=>10}]
|
|
126
126
|
@ds.delete
|
|
127
|
-
@ds
|
|
127
|
+
@ds.insert(:b=>false, :i=>0)
|
|
128
128
|
@ds.all.must_equal [{:b=>false, :i=>0}]
|
|
129
129
|
@ds.delete
|
|
130
|
-
@ds
|
|
130
|
+
@ds.insert(:b=>true, :i=>1)
|
|
131
131
|
@ds.all.must_equal [{:b=>true, :i=>1}]
|
|
132
132
|
end
|
|
133
133
|
|
|
134
134
|
it "should return all tinyints as integers when unset" do
|
|
135
135
|
@db.convert_tinyint_to_bool = false
|
|
136
136
|
@ds.delete
|
|
137
|
-
@ds
|
|
137
|
+
@ds.insert(:b=>true, :i=>10)
|
|
138
138
|
@ds.all.must_equal [{:b=>1, :i=>10}]
|
|
139
139
|
@ds.delete
|
|
140
|
-
@ds
|
|
140
|
+
@ds.insert(:b=>false, :i=>0)
|
|
141
141
|
@ds.all.must_equal [{:b=>0, :i=>0}]
|
|
142
142
|
|
|
143
143
|
@ds.delete
|
|
144
|
-
@ds
|
|
144
|
+
@ds.insert(:b=>1, :i=>10)
|
|
145
145
|
@ds.all.must_equal [{:b=>1, :i=>10}]
|
|
146
146
|
@ds.delete
|
|
147
|
-
@ds
|
|
147
|
+
@ds.insert(:b=>0, :i=>0)
|
|
148
148
|
@ds.all.must_equal [{:b=>0, :i=>0}]
|
|
149
149
|
end
|
|
150
150
|
|
|
@@ -155,7 +155,7 @@ if [:mysql, :mysql2].include?(DB.adapter_scheme)
|
|
|
155
155
|
def convert_tinyint_to_bool?() false end #mysql2
|
|
156
156
|
end
|
|
157
157
|
ds.delete
|
|
158
|
-
ds
|
|
158
|
+
ds.insert(:b=>true, :i=>10)
|
|
159
159
|
ds.all.must_equal [{:b=>1, :i=>10}]
|
|
160
160
|
@ds.all.must_equal [{:b=>true, :i=>10}]
|
|
161
161
|
end
|
|
@@ -220,8 +220,8 @@ describe "A MySQL dataset" do
|
|
|
220
220
|
end if false # SEQUEL5
|
|
221
221
|
|
|
222
222
|
it "should support regexps" do
|
|
223
|
-
@d
|
|
224
|
-
@d
|
|
223
|
+
@d.insert(:name => 'abc', :value => 1)
|
|
224
|
+
@d.insert(:name => 'bcd', :value => 2)
|
|
225
225
|
@d.filter(:name => /bc/).count.must_equal 2
|
|
226
226
|
@d.filter(:name => /^bc/).count.must_equal 1
|
|
227
227
|
end
|
|
@@ -234,7 +234,7 @@ describe "A MySQL dataset" do
|
|
|
234
234
|
|
|
235
235
|
it "should correctly literalize strings with comment backslashes in them" do
|
|
236
236
|
@d.delete
|
|
237
|
-
@d
|
|
237
|
+
@d.insert(:name => ':\\')
|
|
238
238
|
|
|
239
239
|
@d.first[:name].must_equal ':\\'
|
|
240
240
|
end
|
|
@@ -297,6 +297,9 @@ describe "MySQL join expressions" do
|
|
|
297
297
|
it "should raise error for :full_outer join requests." do
|
|
298
298
|
lambda{@ds.join_table(:full_outer, :nodes)}.must_raise(Sequel::Error)
|
|
299
299
|
end
|
|
300
|
+
it "should raise error for :natural_full join requests." do
|
|
301
|
+
lambda{@ds.join_table(:natural_full, :nodes)}.must_raise(Sequel::Error)
|
|
302
|
+
end
|
|
300
303
|
it "should support natural left joins" do
|
|
301
304
|
@ds.join_table(:natural_left, :nodes).sql.must_equal 'SELECT * FROM `nodes` NATURAL LEFT JOIN `nodes`'
|
|
302
305
|
end
|
|
@@ -309,7 +312,7 @@ describe "MySQL join expressions" do
|
|
|
309
312
|
it "should support natural right outer joins" do
|
|
310
313
|
@ds.join_table(:natural_right_outer, :nodes).sql.must_equal 'SELECT * FROM `nodes` NATURAL RIGHT OUTER JOIN `nodes`'
|
|
311
314
|
end
|
|
312
|
-
|
|
315
|
+
deprecated "should support natural inner joins" do
|
|
313
316
|
@ds.join_table(:natural_inner, :nodes).sql.must_equal 'SELECT * FROM `nodes` NATURAL LEFT JOIN `nodes`'
|
|
314
317
|
end
|
|
315
318
|
it "should support cross joins" do
|
|
@@ -391,7 +394,7 @@ describe "A MySQL database" do
|
|
|
391
394
|
@db.add_column :test2, :xyz, :text
|
|
392
395
|
|
|
393
396
|
@db[:test2].columns.must_equal [:name, :value, :xyz]
|
|
394
|
-
@db[:test2]
|
|
397
|
+
@db[:test2].insert(:name => 'mmm', :value => 111, :xyz => '000')
|
|
395
398
|
@db[:test2].first[:xyz].must_equal '000'
|
|
396
399
|
|
|
397
400
|
@db[:test2].columns.must_equal [:name, :value, :xyz]
|
|
@@ -401,7 +404,7 @@ describe "A MySQL database" do
|
|
|
401
404
|
|
|
402
405
|
@db[:test2].delete
|
|
403
406
|
@db.add_column :test2, :xyz, :text
|
|
404
|
-
@db[:test2]
|
|
407
|
+
@db[:test2].insert(:name => 'mmm', :value => 111, :xyz => 'qqqq')
|
|
405
408
|
|
|
406
409
|
@db[:test2].columns.must_equal [:name, :value, :xyz]
|
|
407
410
|
@db.rename_column :test2, :xyz, :zyx, :type => :text
|
|
@@ -410,7 +413,7 @@ describe "A MySQL database" do
|
|
|
410
413
|
|
|
411
414
|
@db[:test2].delete
|
|
412
415
|
@db.add_column :test2, :tre, :text
|
|
413
|
-
@db[:test2]
|
|
416
|
+
@db[:test2].insert(:name => 'mmm', :value => 111, :tre => 'qqqq')
|
|
414
417
|
|
|
415
418
|
@db[:test2].columns.must_equal [:name, :value, :zyx, :tre]
|
|
416
419
|
@db.rename_column :test2, :tre, :ert, :type => :varchar, :size=>255
|
|
@@ -419,7 +422,7 @@ describe "A MySQL database" do
|
|
|
419
422
|
|
|
420
423
|
@db.add_column :test2, :xyz, :float
|
|
421
424
|
@db[:test2].delete
|
|
422
|
-
@db[:test2]
|
|
425
|
+
@db[:test2].insert(:name => 'mmm', :value => 111, :xyz => 56.78)
|
|
423
426
|
@db.set_column_type :test2, :xyz, :integer
|
|
424
427
|
|
|
425
428
|
@db[:test2].first[:xyz].must_equal 57
|
|
@@ -437,15 +440,62 @@ describe "A MySQL database" do
|
|
|
437
440
|
end
|
|
438
441
|
end
|
|
439
442
|
|
|
443
|
+
# SEQUEL5: Remove
|
|
440
444
|
describe "A MySQL database with table options" do
|
|
441
445
|
before do
|
|
442
446
|
@options = {:engine=>'MyISAM', :charset=>'latin1', :collate => 'latin1_swedish_ci'}
|
|
443
447
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
448
|
+
deprecated do
|
|
449
|
+
Sequel::MySQL.default_engine = 'InnoDB'
|
|
450
|
+
Sequel::MySQL.default_charset = 'utf8'
|
|
451
|
+
Sequel::MySQL.default_collate = 'utf8_general_ci'
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
@db = DB
|
|
455
|
+
@db.drop_table?(:items)
|
|
456
|
+
|
|
457
|
+
DB.sqls.clear
|
|
458
|
+
end
|
|
459
|
+
after do
|
|
460
|
+
@db.drop_table?(:items)
|
|
461
|
+
|
|
462
|
+
deprecated do
|
|
463
|
+
Sequel::MySQL.default_engine = nil
|
|
464
|
+
Sequel::MySQL.default_charset = nil
|
|
465
|
+
Sequel::MySQL.default_collate = nil
|
|
466
|
+
end
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
it "should allow to pass custom options (engine, charset, collate) for table creation" do
|
|
470
|
+
@db.create_table(:items, @options){Integer :size; text :name}
|
|
471
|
+
check_sqls do
|
|
472
|
+
@db.sqls.must_equal ["CREATE TABLE `items` (`size` integer, `name` text) ENGINE=MyISAM DEFAULT CHARSET=latin1 DEFAULT COLLATE=latin1_swedish_ci"]
|
|
473
|
+
end
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
it "should use default options if specified (engine, charset, collate) for table creation" do
|
|
477
|
+
@db.create_table(:items){Integer :size; text :name}
|
|
478
|
+
check_sqls do
|
|
479
|
+
@db.sqls.must_equal ["CREATE TABLE `items` (`size` integer, `name` text) ENGINE=InnoDB DEFAULT CHARSET=utf8 DEFAULT COLLATE=utf8_general_ci"]
|
|
480
|
+
end
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
it "should not use default if option has a nil value" do
|
|
484
|
+
@db.create_table(:items, :engine=>nil, :charset=>nil, :collate=>nil){Integer :size; text :name}
|
|
485
|
+
check_sqls do
|
|
486
|
+
@db.sqls.must_equal ["CREATE TABLE `items` (`size` integer, `name` text)"]
|
|
487
|
+
end
|
|
488
|
+
end
|
|
489
|
+
end
|
|
490
|
+
|
|
491
|
+
describe "A MySQL database with table options" do
|
|
492
|
+
before do
|
|
493
|
+
@options = {:engine=>'MyISAM', :charset=>'latin1', :collate => 'latin1_swedish_ci'}
|
|
447
494
|
|
|
448
495
|
@db = DB
|
|
496
|
+
@db.default_engine = 'InnoDB'
|
|
497
|
+
@db.default_charset = 'utf8'
|
|
498
|
+
@db.default_collate = 'utf8_general_ci'
|
|
449
499
|
@db.drop_table?(:items)
|
|
450
500
|
|
|
451
501
|
DB.sqls.clear
|
|
@@ -453,9 +503,9 @@ describe "A MySQL database with table options" do
|
|
|
453
503
|
after do
|
|
454
504
|
@db.drop_table?(:items)
|
|
455
505
|
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
506
|
+
@db.default_engine = nil
|
|
507
|
+
@db.default_charset = nil
|
|
508
|
+
@db.default_collate = nil
|
|
459
509
|
end
|
|
460
510
|
|
|
461
511
|
it "should allow to pass custom options (engine, charset, collate) for table creation" do
|
|
@@ -707,12 +757,12 @@ describe "A grouped MySQL dataset" do
|
|
|
707
757
|
text :name
|
|
708
758
|
integer :value
|
|
709
759
|
end
|
|
710
|
-
DB[:test2]
|
|
711
|
-
DB[:test2]
|
|
712
|
-
DB[:test2]
|
|
713
|
-
DB[:test2]
|
|
714
|
-
DB[:test2]
|
|
715
|
-
DB[:test2]
|
|
760
|
+
DB[:test2].insert(:name => '11', :value => 10)
|
|
761
|
+
DB[:test2].insert(:name => '11', :value => 20)
|
|
762
|
+
DB[:test2].insert(:name => '11', :value => 30)
|
|
763
|
+
DB[:test2].insert(:name => '12', :value => 10)
|
|
764
|
+
DB[:test2].insert(:name => '12', :value => 20)
|
|
765
|
+
DB[:test2].insert(:name => '13', :value => 10)
|
|
716
766
|
end
|
|
717
767
|
after do
|
|
718
768
|
DB.drop_table?(:test2)
|