sequel 4.42.1 → 4.43.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.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +35 -1
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +4 -4
  5. data/doc/release_notes/4.43.0.txt +87 -0
  6. data/doc/sql.rdoc +26 -27
  7. data/doc/testing.rdoc +2 -0
  8. data/doc/validations.rdoc +1 -1
  9. data/lib/sequel/adapters/ado.rb +5 -0
  10. data/lib/sequel/adapters/cubrid.rb +5 -0
  11. data/lib/sequel/adapters/ibmdb.rb +5 -0
  12. data/lib/sequel/adapters/jdbc.rb +6 -0
  13. data/lib/sequel/adapters/jdbc/derby.rb +5 -0
  14. data/lib/sequel/adapters/jdbc/hsqldb.rb +9 -5
  15. data/lib/sequel/adapters/jdbc/postgresql.rb +1 -1
  16. data/lib/sequel/adapters/jdbc/sqlite.rb +5 -0
  17. data/lib/sequel/adapters/jdbc/transactions.rb +5 -0
  18. data/lib/sequel/adapters/mock.rb +12 -9
  19. data/lib/sequel/adapters/mysql.rb +6 -0
  20. data/lib/sequel/adapters/mysql2.rb +7 -2
  21. data/lib/sequel/adapters/oracle.rb +5 -0
  22. data/lib/sequel/adapters/shared/db2.rb +7 -1
  23. data/lib/sequel/adapters/shared/mssql.rb +5 -0
  24. data/lib/sequel/adapters/shared/mysql.rb +8 -1
  25. data/lib/sequel/adapters/shared/oracle.rb +20 -12
  26. data/lib/sequel/adapters/shared/postgres.rb +11 -2
  27. data/lib/sequel/adapters/shared/sqlanywhere.rb +6 -0
  28. data/lib/sequel/adapters/shared/sqlite.rb +29 -0
  29. data/lib/sequel/adapters/sqlanywhere.rb +5 -0
  30. data/lib/sequel/adapters/sqlite.rb +13 -0
  31. data/lib/sequel/connection_pool/sharded_single.rb +5 -0
  32. data/lib/sequel/connection_pool/sharded_threaded.rb +5 -0
  33. data/lib/sequel/connection_pool/single.rb +15 -6
  34. data/lib/sequel/database/dataset.rb +3 -0
  35. data/lib/sequel/database/misc.rb +22 -1
  36. data/lib/sequel/database/query.rb +2 -4
  37. data/lib/sequel/dataset/actions.rb +0 -1
  38. data/lib/sequel/dataset/misc.rb +2 -4
  39. data/lib/sequel/dataset/query.rb +23 -6
  40. data/lib/sequel/extensions/_model_constraint_validations.rb +16 -0
  41. data/lib/sequel/extensions/_model_pg_row.rb +47 -0
  42. data/lib/sequel/extensions/looser_typecasting.rb +2 -0
  43. data/lib/sequel/extensions/migration.rb +12 -1
  44. data/lib/sequel/extensions/pg_array.rb +6 -0
  45. data/lib/sequel/extensions/pg_enum.rb +2 -1
  46. data/lib/sequel/extensions/pg_range.rb +6 -0
  47. data/lib/sequel/extensions/pg_row.rb +8 -0
  48. data/lib/sequel/model/associations.rb +3 -1
  49. data/lib/sequel/model/base.rb +14 -3
  50. data/lib/sequel/plugins/constraint_validations.rb +1 -8
  51. data/lib/sequel/plugins/instance_filters.rb +1 -1
  52. data/lib/sequel/plugins/pg_row.rb +1 -40
  53. data/lib/sequel/plugins/prepared_statements.rb +51 -20
  54. data/lib/sequel/plugins/prepared_statements_associations.rb +22 -4
  55. data/lib/sequel/plugins/prepared_statements_with_pk.rb +9 -1
  56. data/lib/sequel/plugins/sharding.rb +5 -0
  57. data/lib/sequel/plugins/update_primary_key.rb +1 -1
  58. data/lib/sequel/version.rb +2 -2
  59. data/spec/adapters/spec_helper.rb +4 -0
  60. data/spec/core/connection_pool_spec.rb +10 -0
  61. data/spec/core/database_spec.rb +29 -0
  62. data/spec/extensions/blacklist_security_spec.rb +4 -4
  63. data/spec/extensions/defaults_setter_spec.rb +1 -1
  64. data/spec/extensions/force_encoding_spec.rb +3 -2
  65. data/spec/extensions/identifier_mangling_spec.rb +7 -0
  66. data/spec/extensions/instance_filters_spec.rb +1 -0
  67. data/spec/extensions/migration_spec.rb +19 -0
  68. data/spec/extensions/pg_array_spec.rb +5 -0
  69. data/spec/extensions/pg_range_spec.rb +5 -0
  70. data/spec/extensions/pg_row_spec.rb +9 -0
  71. data/spec/extensions/prepared_statements_associations_spec.rb +45 -1
  72. data/spec/extensions/prepared_statements_spec.rb +138 -41
  73. data/spec/extensions/prepared_statements_with_pk_spec.rb +7 -0
  74. data/spec/extensions/serialization_spec.rb +6 -6
  75. data/spec/extensions/single_table_inheritance_spec.rb +3 -3
  76. data/spec/extensions/skip_create_refresh_spec.rb +1 -1
  77. data/spec/integration/associations_test.rb +2 -2
  78. data/spec/integration/dataset_test.rb +0 -4
  79. data/spec/integration/eager_loader_test.rb +5 -5
  80. data/spec/integration/plugin_test.rb +8 -6
  81. data/spec/integration/schema_test.rb +2 -2
  82. data/spec/integration/spec_helper.rb +10 -0
  83. data/spec/integration/timezone_test.rb +1 -1
  84. data/spec/integration/transaction_test.rb +5 -5
  85. data/spec/model/associations_spec.rb +13 -6
  86. data/spec/model/base_spec.rb +1 -1
  87. data/spec/model/hooks_spec.rb +4 -4
  88. data/spec/model/model_spec.rb +2 -2
  89. data/spec/model/record_spec.rb +17 -18
  90. metadata +6 -2
@@ -56,49 +56,10 @@ module Sequel
56
56
  # loaded, load the custom database extensions, and automatically register the
57
57
  # row type if the model has a dataset.
58
58
  def self.configure(model)
59
- model.db.extension(:pg_row)
60
- model.db.extend(DatabaseMethods)
59
+ model.db.extension(:pg_row, :_model_pg_row)
61
60
  model.register_row_type if model.instance_variable_get(:@dataset)
62
61
  end
63
62
 
64
- module DatabaseMethods
65
- ESCAPE_RE = /("|\\)/.freeze
66
- ESCAPE_REPLACEMENT = '\\\\\1'.freeze
67
- COMMA = ','
68
-
69
- # Handle Sequel::Model instances in bound variables.
70
- def bound_variable_arg(arg, conn)
71
- case arg
72
- when Sequel::Model
73
- "(#{arg.values.values_at(*arg.columns).map{|v| bound_variable_array(v)}.join(COMMA)})"
74
- else
75
- super
76
- end
77
- end
78
-
79
- # If a Sequel::Model instance is given, return it as-is
80
- # instead of attempting to convert it.
81
- def row_type(db_type, v)
82
- if v.is_a?(Sequel::Model)
83
- v
84
- else
85
- super
86
- end
87
- end
88
-
89
- private
90
-
91
- # Handle Sequel::Model instances in bound variable arrays.
92
- def bound_variable_array(arg)
93
- case arg
94
- when Sequel::Model
95
- "\"(#{arg.values.values_at(*arg.columns).map{|v| bound_variable_array(v)}.join(COMMA).gsub(ESCAPE_RE, ESCAPE_REPLACEMENT)})\""
96
- else
97
- super
98
- end
99
- end
100
- end
101
-
102
63
  module ClassMethods
103
64
  # Register the model's row type with the database.
104
65
  def register_row_type
@@ -1,22 +1,11 @@
1
1
  # frozen-string-literal: true
2
2
 
3
3
  module Sequel
4
- class Model
5
- module InstanceMethods
6
- # Whether prepared statements should be used for the given type of query
7
- # (:insert, :insert_select, :refresh, :update, or :delete). True by default,
8
- # can be overridden in other plugins to disallow prepared statements for
9
- # specific types of queries.
10
- def use_prepared_statements_for?(type)
11
- true
12
- end
13
- end
14
- end
15
-
16
4
  module Plugins
17
5
  # The prepared_statements plugin modifies the model to use prepared statements for
18
- # instance level deletes and saves, as well as class level lookups by
19
- # primary key.
6
+ # instance level saves (inserts and updates). It also will use prepared statements for
7
+ # deletes, refreshes, and class level lookups by primary key, if it thinks that using
8
+ # a prepared statement will be faster in such cases.
20
9
  #
21
10
  # Note that this plugin is unsafe in some circumstances, as it can allow up to
22
11
  # 2^N prepared statements to be created for each type of insert and update query, where
@@ -132,7 +121,7 @@ module Sequel
132
121
 
133
122
  # Use a prepared statement to query the database for the row matching the given primary key.
134
123
  def primary_key_lookup(pk)
135
- return super if dataset.joined_dataset?
124
+ return super unless use_prepared_statements_for_pk_lookup?
136
125
  prepared_lookup.call(primary_key_hash(pk))
137
126
  end
138
127
 
@@ -148,6 +137,12 @@ module Sequel
148
137
  ps = yield
149
138
  Sequel.synchronize{h[subtype] = ps}
150
139
  end
140
+
141
+ # Whether to use prepared statements for lookups by primary key. True if the default
142
+ # primary key lookup isn't optimized.
143
+ def use_prepared_statements_for_pk_lookup?
144
+ !@fast_pk_lookup_sql && !dataset.joined_dataset?
145
+ end
151
146
  end
152
147
 
153
148
  module InstanceMethods
@@ -156,7 +151,7 @@ module Sequel
156
151
  # Use a prepared statement to delete the row.
157
152
  def _delete_without_checking
158
153
  if use_prepared_statements_for?(:delete)
159
- model.send(:prepared_delete).call(pk_hash)
154
+ _set_prepared_statement_server(model.send(:prepared_delete)).call(pk_hash)
160
155
  else
161
156
  super
162
157
  end
@@ -165,7 +160,7 @@ module Sequel
165
160
  # Use a prepared statement to insert the values into the model's dataset.
166
161
  def _insert_raw(ds)
167
162
  if use_prepared_statements_for?(:insert)
168
- model.send(:prepared_insert, @values.keys).call(@values)
163
+ _set_prepared_statement_server(model.send(:prepared_insert, @values.keys)).call(@values)
169
164
  else
170
165
  super
171
166
  end
@@ -176,7 +171,7 @@ module Sequel
176
171
  def _insert_select_raw(ds)
177
172
  if use_prepared_statements_for?(:insert_select)
178
173
  if ps = model.send(:prepared_insert_select, @values.keys)
179
- ps.call(@values)
174
+ _set_prepared_statement_server(ps).call(@values)
180
175
  end
181
176
  else
182
177
  super
@@ -186,7 +181,7 @@ module Sequel
186
181
  # Use a prepared statement to refresh this model's column values.
187
182
  def _refresh_get(ds)
188
183
  if use_prepared_statements_for?(:refresh)
189
- model.send(:prepared_refresh).call(pk_hash)
184
+ _set_prepared_statement_server(model.send(:prepared_refresh)).call(pk_hash)
190
185
  else
191
186
  super
192
187
  end
@@ -195,11 +190,47 @@ module Sequel
195
190
  # Use a prepared statement to update this model's columns in the database.
196
191
  def _update_without_checking(columns)
197
192
  if use_prepared_statements_for?(:update)
198
- model.send(:prepared_update, columns.keys).call(Hash[columns].merge!(pk_hash))
193
+ _set_prepared_statement_server(model.send(:prepared_update, columns.keys)).call(Hash[columns].merge!(pk_hash))
199
194
  else
200
195
  super
201
196
  end
202
197
  end
198
+
199
+ # If a server is set for the instance, return a prepared statement that will use that server.
200
+ def _set_prepared_statement_server(ps)
201
+ if @server
202
+ ps.server(@server)
203
+ else
204
+ ps
205
+ end
206
+ end
207
+
208
+ # Whether prepared statements should be used for the given type of query
209
+ # (:insert, :insert_select, :refresh, :update, or :delete). True by default,
210
+ # can be overridden in other plugins to disallow prepared statements for
211
+ # specific types of queries.
212
+ def use_prepared_statements_for?(type)
213
+ if defined?(super)
214
+ result = super
215
+ return result unless result.nil?
216
+ end
217
+
218
+ case type
219
+ when :insert, :insert_select, :update
220
+ true
221
+ when :delete
222
+ return true unless model.fast_instance_delete_sql
223
+
224
+ # Using deletes for prepared statements appears faster on Oracle and DB2,
225
+ # but not for most other database types if optimized SQL is used.
226
+ db_type = model.db.database_type
227
+ db_type == :oracle || db_type == :db2
228
+ when :refresh
229
+ !model.fast_pk_lookup_sql
230
+ else
231
+ raise Error, "unsupported type used: #{type.inspect}"
232
+ end
233
+ end
203
234
  end
204
235
  end
205
236
  end
@@ -8,6 +8,10 @@ module Sequel
8
8
  # statements for associations where it will not work, assuming you load the
9
9
  # plugin before defining the associations.
10
10
  #
11
+ # Note that in most cases, this plugin will probably make things slower,
12
+ # so you should only use it if you really want to use prepared statements
13
+ # to load associations.
14
+ #
11
15
  # Usage:
12
16
  #
13
17
  # # Make all model subclasses more safe when using prepared statements (called before loading subclasses)
@@ -27,6 +31,12 @@ module Sequel
27
31
  module InstanceMethods
28
32
  private
29
33
 
34
+ # Mark that associated objects should use the same server.
35
+ def _associated_objects_use_same_server?
36
+ return super if defined?(super)
37
+ false
38
+ end
39
+
30
40
  # Return a bound variable hash that maps the keys in +ks+ (qualified by the +table+)
31
41
  # to the values of the results of sending the methods in +vs+.
32
42
  def association_bound_variable_hash(table, ks, vs)
@@ -36,6 +46,8 @@ module Sequel
36
46
  # Given an association reflection, return a bound variable hash for the given
37
47
  # association for this instance's values.
38
48
  def association_bound_variables(opts)
49
+ return if opts[:instance_specific]
50
+
39
51
  case opts[:type]
40
52
  when :many_to_one
41
53
  association_bound_variable_hash(opts.associated_class.table_name, opts.primary_keys, opts[:keys])
@@ -53,7 +65,7 @@ module Sequel
53
65
  # instance. Return false if such a prepared statement cannot be created.
54
66
  def association_prepared_statement(opts, assoc_bv)
55
67
  return unless model.cache_associations
56
- opts.send(:cached_fetch, :prepared_statement) do
68
+ ps = opts.send(:cached_fetch, :prepared_statement) do
57
69
  unless opts[:instance_specific]
58
70
  ds, bv = _associated_dataset(opts, {}).unbind
59
71
 
@@ -80,12 +92,18 @@ module Sequel
80
92
  ds.clone(:log_sql=>true).prepare(opts.returns_array? ? :select : :first, :"smpsap_#{NEXT.call}")
81
93
  end
82
94
  end
95
+
96
+ if ps && @server && _associated_objects_use_same_server?
97
+ ps = ps.server(@server)
98
+ end
99
+
100
+ ps
83
101
  end
84
102
 
85
103
  # Use a prepared statement if possible to load the associated object,
86
104
  # unless a dynamic callback is given.
87
105
  def _load_associated_object(opts, dynamic_opts)
88
- if !dynamic_opts[:callback] && (bv = association_bound_variables(opts)) && (ps ||= association_prepared_statement(opts, bv))
106
+ if !dynamic_opts[:callback] && (bv = association_bound_variables(opts)) && (ps = association_prepared_statement(opts, bv))
89
107
  ps.call(bv)
90
108
  else
91
109
  super
@@ -95,7 +113,7 @@ module Sequel
95
113
  # Use a prepared statement if possible to load the associated object,
96
114
  # unless the associated model uses caching.
97
115
  def _load_associated_object_via_primary_key(opts)
98
- if !opts.associated_class.respond_to?(:cache_get_pk) && (bv = association_bound_variables(opts)) && (ps ||= association_prepared_statement(opts, bv))
116
+ if !opts.associated_class.respond_to?(:cache_get_pk) && (bv = association_bound_variables(opts)) && (ps = association_prepared_statement(opts, bv))
99
117
  ps.call(bv)
100
118
  else
101
119
  super
@@ -105,7 +123,7 @@ module Sequel
105
123
  # Use a prepared statement if possible to load the associated objects,
106
124
  # unless a dynamic callback is given.
107
125
  def _load_associated_object_array(opts, dynamic_opts)
108
- if !dynamic_opts[:callback] && (bv = association_bound_variables(opts)) && (ps ||= association_prepared_statement(opts, bv))
126
+ if !dynamic_opts[:callback] && (bv = association_bound_variables(opts)) && (ps = association_prepared_statement(opts, bv))
109
127
  ps.call(bv)
110
128
  else
111
129
  super
@@ -14,6 +14,10 @@ module Sequel
14
14
  # service attack by allocating an arbitrary number of prepared statements. You have been
15
15
  # warned.
16
16
  #
17
+ # Note that in most cases, this plugin will probably make things slower,
18
+ # so you should only use it if you really want to use prepared statements
19
+ # for Dataset#with_pk.
20
+ #
17
21
  # Usage:
18
22
  #
19
23
  # # Make all model subclasses use prepared statements for Dataset#with_pk (called before loading subclasses)
@@ -51,7 +55,11 @@ module Sequel
51
55
  rescue UnbindDuplicate
52
56
  super
53
57
  else
54
- model.send(:prepared_lookup_dataset, ds).call(bv)
58
+ ps = model.send(:prepared_lookup_dataset, ds)
59
+ if server = @opts[:server]
60
+ ps = ps.server(server)
61
+ end
62
+ ps.call(bv)
55
63
  end
56
64
  end
57
65
  end
@@ -83,6 +83,11 @@ module Sequel
83
83
  nil
84
84
  end
85
85
 
86
+ # Mark that associated objects should use the same server.
87
+ def _associated_objects_use_same_server?
88
+ true
89
+ end
90
+
86
91
  # Ensure that the join table for many_to_many associations uses the correct shard.
87
92
  def _join_table_dataset(opts)
88
93
  use_server(super)
@@ -63,7 +63,7 @@ module Sequel
63
63
  if type == :update
64
64
  false
65
65
  else
66
- super
66
+ super if defined?(super)
67
67
  end
68
68
  end
69
69
  end
@@ -5,10 +5,10 @@ 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 = 42
8
+ MINOR = 43
9
9
  # The tiny version of Sequel. Usually 0, only bumped for bugfix
10
10
  # releases that fix regressions from previous versions.
11
- TINY = 1
11
+ TINY = 0
12
12
 
13
13
  # The version of Sequel you are using, as a string (e.g. "2.11.0")
14
14
  VERSION = [MAJOR, MINOR, TINY].join('.').freeze
@@ -20,6 +20,10 @@ Sequel.split_symbols = false if ENV['SEQUEL_NO_SPLIT_SYMBOLS']
20
20
  Sequel::Database.extension :duplicate_column_handler if ENV['SEQUEL_DUPLICATE_COLUMN_HANDLER']
21
21
  Sequel::Database.extension :columns_introspection if ENV['SEQUEL_COLUMNS_INTROSPECTION']
22
22
  Sequel::Model.cache_associations = false if ENV['SEQUEL_NO_CACHE_ASSOCIATIONS']
23
+ if ENV['SEQUEL_MODEL_PREPARED_STATEMENTS']
24
+ Sequel::Model.plugin :prepared_statements
25
+ Sequel::Model.plugin :prepared_statements_associations
26
+ end
23
27
  Sequel.cache_anonymous_models = false
24
28
 
25
29
  class Sequel::Database
@@ -905,6 +905,16 @@ describe "A single threaded pool with multiple servers" do
905
905
  end
906
906
 
907
907
  AllConnectionPoolClassesSpecs = shared_description do
908
+ it "should work correctly after being frozen" do
909
+ o = Object.new
910
+ db = mock_db.call{o}
911
+ cp = @class.new(db, {})
912
+ db.instance_variable_set(:@pool, cp)
913
+ db.freeze
914
+ cp.frozen?.must_equal true
915
+ db.synchronize{|c| c.must_be_same_as o}
916
+ end
917
+
908
918
  it "should have pool correctly handle disconnect errors not raised as DatabaseDisconnectError" do
909
919
  db = mock_db.call{Object.new}
910
920
  def db.dec; @dec ||= Class.new(StandardError) end
@@ -109,6 +109,28 @@ describe "A new Database" do
109
109
  end if RUBY_VERSION >= '1.9.3'
110
110
  end
111
111
 
112
+ describe "Database#freeze" do
113
+ before do
114
+ @db = Sequel.mock.freeze
115
+ end
116
+
117
+ it "should freeze internal structures" do
118
+ @db.instance_exec do
119
+ frozen?.must_equal true
120
+ opts.frozen?.must_equal true
121
+ pool.frozen?.must_equal true
122
+ loggers.frozen?.must_equal true
123
+ @dataset_class.frozen?.must_equal true
124
+ @dataset_modules.frozen?.must_equal true
125
+ @schema_type_classes.frozen?.must_equal true
126
+ from(:a).frozen?.must_equal true
127
+ metadata_dataset.frozen?.must_equal true
128
+ end
129
+
130
+ proc{@db.extend_datasets{}}.must_raise RuntimeError, TypeError
131
+ end
132
+ end
133
+
112
134
  describe "Database#disconnect" do
113
135
  it "should call pool.disconnect" do
114
136
  d = Sequel::Database.new
@@ -2390,6 +2412,13 @@ describe "Database extensions" do
2390
2412
  @db.extension(:foo).a.must_equal 1
2391
2413
  end
2392
2414
 
2415
+ it "should not call the block multiple times if extension loaded more than once" do
2416
+ @db.opts[:foo] = []
2417
+ Sequel::Database.register_extension(:foo){|db| db.opts[:foo] << 1}
2418
+ @db.extension(:foo).opts[:foo].must_equal [1]
2419
+ @db.extension(:foo).opts[:foo].must_equal [1]
2420
+ end
2421
+
2393
2422
  it "should be able to register an extension with a block and have Database#extension call the block" do
2394
2423
  Sequel::Database.register_extension(:foo){|db| db.opts[:foo] = 1}
2395
2424
  @db.extension(:foo).opts[:foo].must_equal 1
@@ -31,9 +31,9 @@ describe Sequel::Model, "#(set|update)_except" do
31
31
 
32
32
  it "#update_except should not update given attributes" do
33
33
  @o1.update_except({:x => 1, :y => 2, :z=>3, :id=>4}, [:y, :z])
34
- DB.sqls.must_equal ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
34
+ DB.sqls.must_equal ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE id = 10"]
35
35
  @c.new.update_except({:x => 1, :y => 2, :z=>3, :id=>4}, :y, :z)
36
- DB.sqls.must_equal ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
36
+ DB.sqls.must_equal ["INSERT INTO items (x) VALUES (1)", "SELECT * FROM items WHERE id = 10"]
37
37
  end
38
38
  end
39
39
 
@@ -68,7 +68,7 @@ describe Sequel::Model, ".restricted_columns " do
68
68
  i = @c.new
69
69
  i.update(:x => 7, :z => 9)
70
70
  i.values.must_equal(:x => 7)
71
- DB.sqls.must_equal ["INSERT INTO blahblah (x) VALUES (7)", "SELECT * FROM blahblah WHERE (id = 10) LIMIT 1"]
71
+ DB.sqls.must_equal ["INSERT INTO blahblah (x) VALUES (7)", "SELECT * FROM blahblah WHERE id = 10"]
72
72
  end
73
73
 
74
74
  it "should have allowed take precedence over restricted" do
@@ -83,6 +83,6 @@ describe Sequel::Model, ".restricted_columns " do
83
83
  i = @c.new
84
84
  i.update(:y => 7, :z => 9)
85
85
  i.values.must_equal(:y => 7)
86
- DB.sqls.must_equal ["INSERT INTO blahblah (y) VALUES (7)", "SELECT * FROM blahblah WHERE (id = 10) LIMIT 1"]
86
+ DB.sqls.must_equal ["INSERT INTO blahblah (y) VALUES (7)", "SELECT * FROM blahblah WHERE id = 10"]
87
87
  end
88
88
  end
@@ -57,7 +57,7 @@ describe "Sequel::Plugins::DefaultsSetter" do
57
57
  o = c.new
58
58
  o.a = o.a
59
59
  o.save
60
- @db.sqls.must_equal ["INSERT INTO foo (a) VALUES (CURRENT_TIMESTAMP)", "SELECT * FROM foo WHERE (id = 1) LIMIT 1"]
60
+ @db.sqls.must_equal ["INSERT INTO foo (a) VALUES (CURRENT_TIMESTAMP)", "SELECT * FROM foo WHERE id = 1"]
61
61
  end
62
62
 
63
63
  it "should not override a given value" do
@@ -2,8 +2,7 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
  if RUBY_VERSION >= '1.9.0'
3
3
  describe "force_encoding plugin" do
4
4
  before do
5
- @c = Class.new(Sequel::Model) do
6
- end
5
+ @c = Class.new(Sequel::Model)
7
6
  @c.columns :id, :x
8
7
  @c.plugin :force_encoding, 'UTF-8'
9
8
  @e1 = Encoding.find('UTF-8')
@@ -90,6 +89,7 @@ describe "force_encoding plugin" do
90
89
  {:id=>1, :x=>s}
91
90
  end
92
91
  end
92
+ @c.instance_variable_set(:@fast_pk_lookup_sql, nil)
93
93
  o.save
94
94
  o.x.must_equal 'blah'
95
95
  o.x.encoding.must_equal @e1
@@ -104,6 +104,7 @@ describe "force_encoding plugin" do
104
104
  {:id=>1, :x=>s}
105
105
  end
106
106
  end
107
+ @c.instance_variable_set(:@fast_pk_lookup_sql, nil)
107
108
  o.refresh
108
109
  o.x.must_equal 'blah'
109
110
  o.x.encoding.must_equal @e1