sequel 4.42.1 → 4.43.0

Sign up to get free protection for your applications and to get access to all the features.
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