sequel 2.12.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. data/CHANGELOG +62 -0
  2. data/README.rdoc +3 -3
  3. data/Rakefile +7 -0
  4. data/doc/advanced_associations.rdoc +44 -0
  5. data/doc/release_notes/3.0.0.txt +221 -0
  6. data/lib/sequel/adapters/amalgalite.rb +208 -0
  7. data/lib/sequel/adapters/db2.rb +3 -0
  8. data/lib/sequel/adapters/dbi.rb +9 -0
  9. data/lib/sequel/adapters/do.rb +0 -4
  10. data/lib/sequel/adapters/firebird.rb +16 -18
  11. data/lib/sequel/adapters/informix.rb +5 -3
  12. data/lib/sequel/adapters/jdbc.rb +24 -20
  13. data/lib/sequel/adapters/jdbc/h2.rb +15 -4
  14. data/lib/sequel/adapters/mysql.rb +4 -8
  15. data/lib/sequel/adapters/odbc.rb +0 -4
  16. data/lib/sequel/adapters/oracle.rb +0 -4
  17. data/lib/sequel/adapters/shared/mssql.rb +16 -5
  18. data/lib/sequel/adapters/shared/mysql.rb +87 -86
  19. data/lib/sequel/adapters/shared/oracle.rb +92 -3
  20. data/lib/sequel/adapters/shared/postgres.rb +85 -29
  21. data/lib/sequel/adapters/shared/progress.rb +8 -3
  22. data/lib/sequel/adapters/shared/sqlite.rb +53 -23
  23. data/lib/sequel/adapters/sqlite.rb +4 -7
  24. data/lib/sequel/adapters/utils/unsupported.rb +3 -3
  25. data/lib/sequel/connection_pool.rb +18 -25
  26. data/lib/sequel/core.rb +2 -21
  27. data/lib/sequel/database.rb +60 -44
  28. data/lib/sequel/database/schema_generator.rb +26 -31
  29. data/lib/sequel/database/schema_methods.rb +8 -3
  30. data/lib/sequel/database/schema_sql.rb +114 -28
  31. data/lib/sequel/dataset.rb +14 -41
  32. data/lib/sequel/dataset/convenience.rb +31 -54
  33. data/lib/sequel/dataset/graph.rb +7 -13
  34. data/lib/sequel/dataset/sql.rb +43 -54
  35. data/lib/sequel/extensions/inflector.rb +0 -5
  36. data/lib/sequel/extensions/schema_dumper.rb +238 -0
  37. data/lib/sequel/metaprogramming.rb +0 -20
  38. data/lib/sequel/model.rb +1 -2
  39. data/lib/sequel/model/base.rb +18 -16
  40. data/lib/sequel/model/inflections.rb +6 -9
  41. data/lib/sequel/plugins/caching.rb +0 -6
  42. data/lib/sequel/plugins/hook_class_methods.rb +1 -1
  43. data/lib/sequel/sql.rb +2 -0
  44. data/lib/sequel/version.rb +2 -2
  45. data/spec/adapters/firebird_spec.rb +35 -8
  46. data/spec/adapters/mysql_spec.rb +173 -266
  47. data/spec/adapters/oracle_spec.rb +13 -0
  48. data/spec/adapters/postgres_spec.rb +127 -227
  49. data/spec/adapters/sqlite_spec.rb +13 -171
  50. data/spec/core/connection_pool_spec.rb +15 -4
  51. data/spec/core/core_sql_spec.rb +14 -170
  52. data/spec/core/database_spec.rb +50 -132
  53. data/spec/core/dataset_spec.rb +47 -930
  54. data/spec/core/expression_filters_spec.rb +12 -0
  55. data/spec/core/schema_generator_spec.rb +37 -45
  56. data/spec/core/schema_spec.rb +26 -16
  57. data/spec/core/spec_helper.rb +0 -25
  58. data/spec/extensions/inflector_spec.rb +0 -3
  59. data/spec/extensions/schema_dumper_spec.rb +292 -0
  60. data/spec/extensions/serialization_spec.rb +9 -0
  61. data/spec/extensions/single_table_inheritance_spec.rb +6 -1
  62. data/spec/extensions/spec_helper.rb +1 -3
  63. data/spec/extensions/validation_helpers_spec.rb +4 -4
  64. data/spec/integration/database_test.rb +18 -0
  65. data/spec/integration/dataset_test.rb +112 -1
  66. data/spec/integration/eager_loader_test.rb +70 -9
  67. data/spec/integration/prepared_statement_test.rb +2 -2
  68. data/spec/integration/schema_test.rb +76 -27
  69. data/spec/integration/spec_helper.rb +0 -14
  70. data/spec/integration/transaction_test.rb +27 -0
  71. data/spec/model/associations_spec.rb +0 -36
  72. data/spec/model/base_spec.rb +18 -123
  73. data/spec/model/hooks_spec.rb +2 -235
  74. data/spec/model/inflector_spec.rb +15 -115
  75. data/spec/model/model_spec.rb +0 -120
  76. data/spec/model/plugins_spec.rb +0 -70
  77. data/spec/model/record_spec.rb +35 -93
  78. data/spec/model/spec_helper.rb +0 -27
  79. data/spec/model/validations_spec.rb +0 -931
  80. metadata +9 -14
  81. data/lib/sequel/deprecated.rb +0 -593
  82. data/lib/sequel/deprecated_migration.rb +0 -91
  83. data/lib/sequel/model/deprecated.rb +0 -204
  84. data/lib/sequel/model/deprecated_hooks.rb +0 -103
  85. data/lib/sequel/model/deprecated_inflector.rb +0 -335
  86. data/lib/sequel/model/deprecated_validations.rb +0 -388
  87. data/spec/core/core_ext_spec.rb +0 -156
  88. data/spec/core/migration_spec.rb +0 -263
  89. data/spec/core/pretty_table_spec.rb +0 -58
  90. data/spec/model/caching_spec.rb +0 -217
  91. data/spec/model/schema_spec.rb +0 -92
@@ -8,26 +8,6 @@ module Sequel
8
8
 
9
9
  private
10
10
 
11
- # Make a singleton/class attribute accessor method(s).
12
- # Replaces the construct:
13
- #
14
- # class << self
15
- # attr_accessor *meths
16
- # end
17
- def metaattr_accessor(*meths)
18
- meta_eval{attr_accessor(*meths)}
19
- end
20
-
21
- # Make a singleton/class attribute reader method(s).
22
- # Replaces the construct:
23
- #
24
- # class << self
25
- # attr_reader *meths
26
- # end
27
- def metaattr_reader(*meths)
28
- meta_eval{attr_reader(*meths)}
29
- end
30
-
31
11
  # Evaluate the block in the context of the object's metaclass
32
12
  def meta_eval(&block)
33
13
  metaclass.instance_eval(&block)
data/lib/sequel/model.rb CHANGED
@@ -45,7 +45,7 @@ module Sequel
45
45
  last left_outer_join limit map multi_insert naked order order_by
46
46
  order_more paginate print query range reverse_order right_outer_join
47
47
  select select_all select_more server set set_graph_aliases
48
- single_value to_csv to_hash transform union unfiltered unordered
48
+ single_value to_csv to_hash union unfiltered unordered
49
49
  update where with_sql'.map{|x| x.to_sym}
50
50
 
51
51
  # Class instance variables to set to nil when a subclass is created, for -w compliance
@@ -106,5 +106,4 @@ module Sequel
106
106
  require 'associations', 'model'
107
107
  Model.plugin Model::Associations
108
108
  end
109
- require 'deprecated', 'model'
110
109
  end
@@ -285,7 +285,6 @@ module Sequel
285
285
  raise(Error, "Model.set_dataset takes a Symbol or a Sequel::Dataset")
286
286
  end
287
287
  @dataset.row_proc = Proc.new{|r| load(r)}
288
- @dataset.transform(@transform) if @transform
289
288
  if inherited
290
289
  @simple_table = superclass.simple_table
291
290
  @columns = @dataset.columns rescue nil
@@ -438,8 +437,6 @@ module Sequel
438
437
  def set_columns(new_columns)
439
438
  @columns = new_columns
440
439
  def_column_accessor(*new_columns) if new_columns
441
- # Deprecation.deprecated
442
- @str_columns = nil
443
440
  @columns
444
441
  end
445
442
 
@@ -656,12 +653,9 @@ module Sequel
656
653
  # cached association and changed_columns information. Raises an Error if the record no longer
657
654
  # exists in the database.
658
655
  def refresh
659
- @values = this.first || raise(Error, "Record not found")
660
- changed_columns.clear
661
- associations.clear
662
- self
656
+ _refresh(this)
663
657
  end
664
-
658
+
665
659
  # Alias of refresh, but not aliased directly to make overriding in a plugin easier.
666
660
  def reload
667
661
  refresh
@@ -677,7 +671,7 @@ module Sequel
677
671
  #
678
672
  # Takes the following options:
679
673
  #
680
- # * :changed - save all changed columns, instead of all columns or the columns
674
+ # * :changed - save all changed columns, instead of all columns or the columns given
681
675
  # * :transaction - set to false not to use a transaction
682
676
  # * :validate - set to false not to validate the model before saving
683
677
  def save(*columns)
@@ -777,6 +771,15 @@ module Sequel
777
771
  self
778
772
  end
779
773
 
774
+ # Refresh using a particular dataset, used inside save to make sure the same server
775
+ # is used for reading newly inserted values from the database
776
+ def _refresh(dataset)
777
+ @values = dataset.first || raise(Error, "Record not found")
778
+ changed_columns.clear
779
+ associations.clear
780
+ self
781
+ end
782
+
780
783
  # Internal version of save, split from save to allow running inside
781
784
  # it's own transaction.
782
785
  def _save(columns, opts)
@@ -801,7 +804,11 @@ module Sequel
801
804
  after_create
802
805
  after_save
803
806
  @was_new = nil
804
- refresh if pk
807
+ if pk
808
+ ds = this
809
+ ds = ds.server(:default) unless ds.opts[:server]
810
+ _refresh(ds)
811
+ end
805
812
  else
806
813
  return save_failure(:update) if before_update == false
807
814
  if columns.empty?
@@ -837,16 +844,12 @@ module Sequel
837
844
 
838
845
  # Set the columns, filtered by the only and except arrays.
839
846
  def set_restricted(hash, only, except)
840
- columns_not_set = [nil, false, "", [], {}].include?(model.instance_variable_get(:@columns))
841
847
  meths = setter_methods(only, except)
842
848
  strict = strict_param_setting
843
849
  hash.each do |k,v|
844
850
  m = "#{k}="
845
851
  if meths.include?(m)
846
852
  send(m, v)
847
- elsif columns_not_set && (Symbol === k)
848
- Deprecation.deprecate('Calling Model#set_restricted for a column without a setter method when the model class does not have any columns', 'Use Model#[] for these columns')
849
- self[k] = v
850
853
  elsif strict
851
854
  raise Error, "method #{m} doesn't exist or access is restricted to it"
852
855
  end
@@ -887,8 +890,7 @@ module Sequel
887
890
  # typecast_value method, so database adapters can override/augment the handling
888
891
  # for database specific column types.
889
892
  def typecast_value(column, value)
890
- # Deprecation.deprecate : Remove model.serialized call
891
- return value unless typecast_on_assignment && db_schema && (col_schema = db_schema[column]) && !model.serialized?(column)
893
+ return value unless typecast_on_assignment && db_schema && (col_schema = db_schema[column])
892
894
  value = nil if value == '' and typecast_empty_string_to_nil and col_schema[:type] and ![:string, :blob].include?(col_schema[:type])
893
895
  raise(InvalidValue, "nil/NULL is not allowed for the #{column} column") if raise_on_typecast_failure && value.nil? && (col_schema[:allow_null] == false)
894
896
  begin
@@ -97,8 +97,6 @@ module Sequel
97
97
  end
98
98
 
99
99
  # Setup the default inflections
100
- # Commented out until the deprecated inflector is removed
101
- =begin
102
100
  plural(/$/, 's')
103
101
  plural(/s$/i, 's')
104
102
  plural(/(ax|test)is$/i, '\1es')
@@ -149,14 +147,13 @@ module Sequel
149
147
  irregular('move', 'moves')
150
148
 
151
149
  uncountable(%w(equipment information rice money species series fish sheep))
152
- =end
153
150
 
154
151
  private
155
152
 
156
153
  # Convert the given string to CamelCase. Will also convert '/' to '::' which is useful for converting paths to namespaces.
157
154
  def camelize(s)
158
155
  s = s.to_s
159
- # return s.camelize if s.respond_to?(:camelize)
156
+ return s.camelize if s.respond_to?(:camelize)
160
157
  s = s.gsub(CAMELIZE_MODULE_REGEXP){|x| "::#{x[-1..-1].upcase unless x == SLASH}"}.gsub(CAMELIZE_CONVERT_REGEXP){|x| x[-1..-1].upcase}
161
158
  s
162
159
  end
@@ -166,7 +163,7 @@ module Sequel
166
163
  # or is not initialized.
167
164
  def constantize(s)
168
165
  s = s.to_s
169
- # return s.constantize if s.respond_to?(:constantize)
166
+ return s.constantize if s.respond_to?(:constantize)
170
167
  raise(NameError, "#{inspect} is not a valid constant name!") unless m = VALID_CONSTANT_NAME_REGEXP.match(s.to_s)
171
168
  Object.module_eval("::#{m[1]}", __FILE__, __LINE__)
172
169
  end
@@ -174,14 +171,14 @@ module Sequel
174
171
  # Removes the module part from the expression in the string
175
172
  def demodulize(s)
176
173
  s = s.to_s
177
- # return s.demodulize if s.respond_to?(:demodulize)
174
+ return s.demodulize if s.respond_to?(:demodulize)
178
175
  s.gsub(DEMODULIZE_CONVERT_REGEXP, EMPTY_STRING)
179
176
  end
180
177
 
181
178
  # Returns the plural form of the word in the string.
182
179
  def pluralize(s)
183
180
  s = s.to_s
184
- # return s.pluralize if s.respond_to?(:pluralize)
181
+ return s.pluralize if s.respond_to?(:pluralize)
185
182
  result = s.dup
186
183
  Inflections.plurals.each{|(rule, replacement)| break if result.gsub!(rule, replacement)} unless Inflections.uncountables.include?(s.downcase)
187
184
  result
@@ -190,7 +187,7 @@ module Sequel
190
187
  # The reverse of pluralize, returns the singular form of a word in a string.
191
188
  def singularize(s)
192
189
  s = s.to_s
193
- # return s.singularize if s.respond_to?(:singularize)
190
+ return s.singularize if s.respond_to?(:singularize)
194
191
  result = s.dup
195
192
  Inflections.singulars.each{|(rule, replacement)| break if result.gsub!(rule, replacement)} unless Inflections.uncountables.include?(s.downcase)
196
193
  result
@@ -200,7 +197,7 @@ module Sequel
200
197
  # Also changes '::' to '/' to convert namespaces to paths.
201
198
  def underscore(s)
202
199
  s = s.to_s
203
- # return s.underscore if s.respond_to?(:underscore)
200
+ return s.underscore if s.respond_to?(:underscore)
204
201
  s.gsub(UNDERSCORE_MODULE_REGEXP, SLASH).gsub(UNDERSCORE_CONVERT_REGEXP1, UNDERSCORE_CONVERT_REPLACE).
205
202
  gsub(UNDERSCORE_CONVERT_REGEXP2, UNDERSCORE_CONVERT_REPLACE).tr(DASH, UNDERSCORE).downcase
206
203
  end
@@ -104,12 +104,6 @@ module Sequel
104
104
  super
105
105
  end
106
106
 
107
- # Remove the object from the cache when updating
108
- def update_values(*args)
109
- cache_delete
110
- super
111
- end
112
-
113
107
  private
114
108
 
115
109
  # Delete this object from the cache
@@ -107,7 +107,7 @@ module Sequel
107
107
  end
108
108
 
109
109
  module InstanceMethods
110
- Model::HOOKS.each{|h| class_eval("def #{h}; run_hooks(:#{h}); end", __FILE__, __LINE__)}
110
+ Model::HOOKS.each{|h| class_eval("def #{h}; return false if super == false; run_hooks(:#{h}); end", __FILE__, __LINE__)}
111
111
 
112
112
  private
113
113
 
data/lib/sequel/sql.rb CHANGED
@@ -657,6 +657,8 @@ module Sequel
657
657
 
658
658
  # Represents a qualified (column with table or table with schema) reference.
659
659
  class QualifiedIdentifier < GenericExpression
660
+ include QualifyingMethods
661
+
660
662
  # The column to reference
661
663
  attr_reader :column
662
664
 
@@ -1,6 +1,6 @@
1
1
  module Sequel
2
- MAJOR = 2
3
- MINOR = 12
2
+ MAJOR = 3
3
+ MINOR = 0
4
4
  TINY = 0
5
5
 
6
6
  VERSION = [MAJOR, MINOR, TINY].join('.')
@@ -25,6 +25,14 @@ FIREBIRD_DB.create_table! :test5 do
25
25
  integer :val
26
26
  end
27
27
 
28
+ FIREBIRD_DB.create_table! :test6 do
29
+ primary_key :xid
30
+ blob :val
31
+ String :val2
32
+ varchar :val3, :size=>200
33
+ text :val4
34
+ end
35
+
28
36
  context "A Firebird database" do
29
37
  before do
30
38
  @db = FIREBIRD_DB
@@ -234,7 +242,7 @@ context "A Firebird database" do
234
242
  g = Sequel::Schema::Generator.new(FIREBIRD_DB) do
235
243
  primary_key :id, :sequence_name => "seq_test"
236
244
  end
237
- FIREBIRD_DB.create_table_sql_list(:posts, *g.create_info).should == [[
245
+ FIREBIRD_DB.send(:create_table_sql_list, :posts, *g.create_info).should == [[
238
246
  "CREATE TABLE POSTS (ID integer PRIMARY KEY )",
239
247
  "CREATE SEQUENCE SEQ_TEST",
240
248
  " CREATE TRIGGER BI_POSTS_ID for POSTS\n ACTIVE BEFORE INSERT position 0\n as begin\n if ((new.ID is null) or (new.ID = 0)) then\n begin\n new.ID = next value for seq_test;\n end\n end\n\n"
@@ -245,7 +253,7 @@ context "A Firebird database" do
245
253
  g = Sequel::Schema::Generator.new(FIREBIRD_DB) do
246
254
  primary_key :id, :sequence_start_position => 999
247
255
  end
248
- FIREBIRD_DB.create_table_sql_list(:posts, *g.create_info).should == [[
256
+ FIREBIRD_DB.send(:create_table_sql_list, :posts, *g.create_info).should == [[
249
257
  "CREATE TABLE POSTS (ID integer PRIMARY KEY )",
250
258
  "CREATE SEQUENCE SEQ_POSTS_ID",
251
259
  "ALTER SEQUENCE SEQ_POSTS_ID RESTART WITH 999",
@@ -257,7 +265,7 @@ context "A Firebird database" do
257
265
  g = Sequel::Schema::Generator.new(FIREBIRD_DB) do
258
266
  primary_key :id, :sequence_name => "seq_test", :sequence_start_position => 999
259
267
  end
260
- FIREBIRD_DB.create_table_sql_list(:posts, *g.create_info).should == [[
268
+ FIREBIRD_DB.send(:create_table_sql_list, :posts, *g.create_info).should == [[
261
269
  "CREATE TABLE POSTS (ID integer PRIMARY KEY )",
262
270
  "CREATE SEQUENCE SEQ_TEST",
263
271
  "ALTER SEQUENCE SEQ_TEST RESTART WITH 999",
@@ -269,7 +277,7 @@ context "A Firebird database" do
269
277
  g = Sequel::Schema::Generator.new(FIREBIRD_DB) do
270
278
  primary_key :id, :trigger_name => "trig_test"
271
279
  end
272
- FIREBIRD_DB.create_table_sql_list(:posts, *g.create_info).should == [[
280
+ FIREBIRD_DB.send(:create_table_sql_list, :posts, *g.create_info).should == [[
273
281
  "CREATE TABLE POSTS (ID integer PRIMARY KEY )",
274
282
  "CREATE SEQUENCE SEQ_POSTS_ID",
275
283
  " CREATE TRIGGER TRIG_TEST for POSTS\n ACTIVE BEFORE INSERT position 0\n as begin\n if ((new.ID is null) or (new.ID = 0)) then\n begin\n new.ID = next value for seq_posts_id;\n end\n end\n\n"
@@ -280,7 +288,7 @@ context "A Firebird database" do
280
288
  g = Sequel::Schema::Generator.new(FIREBIRD_DB) do
281
289
  primary_key :id, :create_sequence => false
282
290
  end
283
- FIREBIRD_DB.create_table_sql_list(:posts, *g.create_info).should == [[
291
+ FIREBIRD_DB.send(:create_table_sql_list, :posts, *g.create_info).should == [[
284
292
  "CREATE TABLE POSTS (ID integer PRIMARY KEY )",
285
293
  " CREATE TRIGGER BI_POSTS_ID for POSTS\n ACTIVE BEFORE INSERT position 0\n as begin\n if ((new.ID is null) or (new.ID = 0)) then\n begin\n new.ID = next value for seq_posts_id;\n end\n end\n\n"
286
294
  ], nil]
@@ -290,7 +298,7 @@ context "A Firebird database" do
290
298
  g = Sequel::Schema::Generator.new(FIREBIRD_DB) do
291
299
  primary_key :id, :create_trigger => false
292
300
  end
293
- FIREBIRD_DB.create_table_sql_list(:posts, *g.create_info).should == [[
301
+ FIREBIRD_DB.send(:create_table_sql_list, :posts, *g.create_info).should == [[
294
302
  "CREATE TABLE POSTS (ID integer PRIMARY KEY )",
295
303
  "CREATE SEQUENCE SEQ_POSTS_ID",
296
304
  ], "DROP SEQUENCE SEQ_POSTS_ID"]
@@ -300,7 +308,7 @@ context "A Firebird database" do
300
308
  g = Sequel::Schema::Generator.new(FIREBIRD_DB) do
301
309
  primary_key :id, :create_sequence => false, :create_trigger => false
302
310
  end
303
- FIREBIRD_DB.create_table_sql_list(:posts, *g.create_info).should == [[
311
+ FIREBIRD_DB.send(:create_table_sql_list, :posts, *g.create_info).should == [[
304
312
  "CREATE TABLE POSTS (ID integer PRIMARY KEY )"
305
313
  ], nil]
306
314
  end
@@ -348,7 +356,8 @@ context "Postgres::Dataset#insert" do
348
356
  end
349
357
 
350
358
  specify "should using call insert_returning_sql" do
351
- @ds.should_receive(:single_value).once.with(:sql=>'INSERT INTO TEST5 (VAL) VALUES (10) RETURNING XID', :server=> :default)
359
+ # @ds.should_receive(:single_value).once.with(:sql=>'INSERT INTO TEST5 (VAL) VALUES (10) RETURNING XID', :server=> :default)
360
+ @ds.should_receive(:single_value).once
352
361
  @ds.insert(:val=>10)
353
362
  end
354
363
 
@@ -374,3 +383,21 @@ context "Postgres::Dataset#insert" do
374
383
  end
375
384
  end
376
385
 
386
+ context "Postgres::Dataset#insert" do
387
+ before do
388
+ @ds = FIREBIRD_DB[:test6]
389
+ @ds.delete
390
+ end
391
+
392
+ specify "should insert and retrieve a blob successfully" do
393
+ value1 = "\1\2\2\2\2222\2\2\2"
394
+ value2 = "abcd"
395
+ value3 = "efgh"
396
+ value4 = "ijkl"
397
+ id1 = @ds.insert(:val=>value1, :val2=>value2, :val3=>value3, :val4=>value4)
398
+ @ds.first(:XID=>id1)[:val].should == value1
399
+ @ds.first(:XID=>id1)[:val2].should == value2
400
+ @ds.first(:XID=>id1)[:val3].should == value3
401
+ @ds.first(:XID=>id1)[:val4].should == value4
402
+ end
403
+ end
@@ -13,17 +13,10 @@ end
13
13
 
14
14
  MYSQL_URI = URI.parse(MYSQL_DB.uri)
15
15
 
16
- MYSQL_DB.create_table! :items do
17
- text :name
18
- integer :value, :index => true
19
- end
20
16
  MYSQL_DB.create_table! :test2 do
21
17
  text :name
22
18
  integer :value
23
19
  end
24
- MYSQL_DB.create_table! :booltest do
25
- tinyint :value
26
- end
27
20
  def MYSQL_DB.sqls
28
21
  (@sqls ||= [])
29
22
  end
@@ -32,6 +25,9 @@ def logger.method_missing(m, msg)
32
25
  MYSQL_DB.sqls << msg
33
26
  end
34
27
  MYSQL_DB.logger = logger
28
+ MYSQL_DB.drop_table(:items) rescue nil
29
+ MYSQL_DB.drop_table(:dolls) rescue nil
30
+ MYSQL_DB.drop_table(:booltest) rescue nil
35
31
 
36
32
  if MYSQL_DB.class.adapter_scheme == :do
37
33
  SQL_BEGIN = 'Transaction.begin'
@@ -46,111 +42,77 @@ end
46
42
  context "MySQL", '#create_table' do
47
43
  before do
48
44
  @db = MYSQL_DB
45
+ MYSQL_DB.sqls.clear
49
46
  end
50
- after(:each) do
51
- @db.drop_table :dolls
47
+ after do
48
+ @db.drop_table(:dolls) rescue nil
52
49
  end
50
+
53
51
  specify "should allow to specify options for MySQL" do
54
- @db.create_table(:dolls, :engine => 'MyISAM', :charset => 'latin2') { text :name }
52
+ @db.create_table(:dolls, :engine => 'MyISAM', :charset => 'latin2'){text :name}
55
53
  @db.sqls.should == ["CREATE TABLE dolls (name text) ENGINE=MyISAM DEFAULT CHARSET=latin2"]
56
54
  end
55
+
56
+ specify "should create a temporary table" do
57
+ @db.create_table(:tmp_dolls, :temp => true, :engine => 'MyISAM', :charset => 'latin2'){text :name}
58
+ @db.sqls.should == ["CREATE TEMPORARY TABLE tmp_dolls (name text) ENGINE=MyISAM DEFAULT CHARSET=latin2"]
59
+ end
57
60
  end
58
61
 
59
62
  context "A MySQL database" do
60
63
  before do
61
64
  @db = MYSQL_DB
65
+ @db.create_table(:booltest){TrueClass :value}
62
66
  end
63
67
  after do
64
68
  Sequel.convert_tinyint_to_bool = true
69
+ @db.drop_table(:booltest)
65
70
  end
66
71
 
67
72
  specify "should provide the server version" do
68
73
  @db.server_version.should >= 40000
69
74
  end
70
75
 
71
- specify "should support sequential primary keys" do
72
- @db.create_table!(:with_pk) {primary_key :id; text :name}
73
- @db[:with_pk] << {:name => 'abc'}
74
- @db[:with_pk] << {:name => 'def'}
75
- @db[:with_pk] << {:name => 'ghi'}
76
- @db[:with_pk].order(:name).all.should == [
77
- {:id => 1, :name => 'abc'},
78
- {:id => 2, :name => 'def'},
79
- {:id => 3, :name => 'ghi'}
80
- ]
81
- end
82
-
83
- specify "should provide disconnect functionality" do
84
- @db.pool.size.should == 1
85
- @db.disconnect
86
- @db.pool.size.should == 0
87
- end
88
-
89
- specify "should convert Mysql::Errors to Sequel::Errors" do
90
- proc{@db << "SELECT 1 + blah;"}.should raise_error(Sequel::Error)
91
- end
92
-
93
76
  specify "should correctly parse the schema" do
94
77
  @db.schema(:booltest, :reload=>true).should == [[:value, {:type=>:boolean, :allow_null=>true, :primary_key=>false, :default=>nil, :db_type=>"tinyint(4)"}]]
95
78
 
96
79
  Sequel.convert_tinyint_to_bool = false
97
80
  @db.schema(:booltest, :reload=>true).should == [[:value, {:type=>:integer, :allow_null=>true, :primary_key=>false, :default=>nil, :db_type=>"tinyint(4)"}]]
98
81
  end
82
+
83
+ specify "should accept and return tinyints as bools or integers when configured to do so" do
84
+ MYSQL_DB[:booltest].delete
85
+ MYSQL_DB[:booltest] << {:value=>true}
86
+ MYSQL_DB[:booltest].all.should == [{:value=>true}]
87
+ MYSQL_DB[:booltest].delete
88
+ MYSQL_DB[:booltest] << {:value=>false}
89
+ MYSQL_DB[:booltest].all.should == [{:value=>false}]
90
+
91
+ Sequel.convert_tinyint_to_bool = false
92
+ MYSQL_DB[:booltest].delete
93
+ MYSQL_DB[:booltest] << {:value=>true}
94
+ MYSQL_DB[:booltest].all.should == [{:value=>1}]
95
+ MYSQL_DB[:booltest].delete
96
+ MYSQL_DB[:booltest] << {:value=>false}
97
+ MYSQL_DB[:booltest].all.should == [{:value=>0}]
98
+
99
+ MYSQL_DB[:booltest].delete
100
+ MYSQL_DB[:booltest] << {:value=>1}
101
+ MYSQL_DB[:booltest].all.should == [{:value=>1}]
102
+ MYSQL_DB[:booltest].delete
103
+ MYSQL_DB[:booltest] << {:value=>0}
104
+ MYSQL_DB[:booltest].all.should == [{:value=>0}]
105
+ end
99
106
  end
100
107
 
101
108
  context "A MySQL dataset" do
102
109
  before do
110
+ MYSQL_DB.create_table(:items){String :name; Integer :value}
103
111
  @d = MYSQL_DB[:items]
104
- @d.delete # remove all records
105
112
  MYSQL_DB.sqls.clear
106
113
  end
107
-
108
- specify "should return the correct record count" do
109
- @d.count.should == 0
110
- @d << {:name => 'abc', :value => 123}
111
- @d << {:name => 'abc', :value => 456}
112
- @d << {:name => 'def', :value => 789}
113
- @d.count.should == 3
114
- end
115
-
116
- specify "should return the correct records" do
117
- @d.to_a.should == []
118
- @d << {:name => 'abc', :value => 123}
119
- @d << {:name => 'abc', :value => 456}
120
- @d << {:name => 'def', :value => 789}
121
-
122
- @d.order(:value).to_a.should == [
123
- {:name => 'abc', :value => 123},
124
- {:name => 'abc', :value => 456},
125
- {:name => 'def', :value => 789}
126
- ]
127
- end
128
-
129
- specify "should update records correctly" do
130
- @d << {:name => 'abc', :value => 123}
131
- @d << {:name => 'abc', :value => 456}
132
- @d << {:name => 'def', :value => 789}
133
- @d.filter(:name => 'abc').update(:value => 530)
134
-
135
- # the third record should stay the same
136
- # floating-point precision bullshit
137
- @d[:name => 'def'][:value].should == 789
138
- @d.filter(:value => 530).count.should == 2
139
- end
140
-
141
- specify "should delete records correctly" do
142
- @d << {:name => 'abc', :value => 123}
143
- @d << {:name => 'abc', :value => 456}
144
- @d << {:name => 'def', :value => 789}
145
- @d.filter(:name => 'abc').delete
146
-
147
- @d.count.should == 1
148
- @d.first[:name].should == 'def'
149
- end
150
-
151
- specify "should be able to literalize booleans" do
152
- proc {@d.literal(true)}.should_not raise_error
153
- proc {@d.literal(false)}.should_not raise_error
114
+ after do
115
+ MYSQL_DB.drop_table(:items)
154
116
  end
155
117
 
156
118
  specify "should quote columns and tables using back-ticks if quoting identifiers" do
@@ -223,37 +185,6 @@ context "A MySQL dataset" do
223
185
  'UPDATE items SET value = 1 LIMIT 10'
224
186
  end
225
187
 
226
- specify "should support transactions" do
227
- MYSQL_DB.transaction do
228
- @d << {:name => 'abc', :value => 1}
229
- end
230
-
231
- @d.count.should == 1
232
- end
233
-
234
- specify "should correctly rollback transactions" do
235
- proc do
236
- MYSQL_DB.transaction do
237
- @d << {:name => 'abc'}
238
- raise Interrupt, 'asdf'
239
- end
240
- end.should raise_error(Interrupt)
241
-
242
- MYSQL_DB.sqls.should == [SQL_BEGIN, "INSERT INTO items (name) VALUES ('abc')", SQL_ROLLBACK]
243
- end
244
-
245
- specify "should handle returning inside of the block by committing" do
246
- def MYSQL_DB.ret_commit
247
- transaction do
248
- self[:items] << {:name => 'abc'}
249
- return
250
- self[:items] << {:name => 'd'}
251
- end
252
- end
253
- MYSQL_DB.ret_commit
254
- MYSQL_DB.sqls.should == [SQL_BEGIN, "INSERT INTO items (name) VALUES ('abc')", SQL_COMMIT]
255
- end
256
-
257
188
  specify "should support regexps" do
258
189
  @d << {:name => 'abc', :value => 1}
259
190
  @d << {:name => 'bcd', :value => 2}
@@ -273,9 +204,6 @@ context "MySQL datasets" do
273
204
  before do
274
205
  @d = MYSQL_DB[:orders]
275
206
  end
276
- after do
277
- Sequel.convert_tinyint_to_bool = true
278
- end
279
207
 
280
208
  specify "should correctly quote column references" do
281
209
  @d.quote_identifiers = true
@@ -286,30 +214,6 @@ context "MySQL datasets" do
286
214
  group_by(:minute.sql_function(:from_unixtime.sql_function(:ack))).sql.should == \
287
215
  "SELECT `market`, minute(from_unixtime(`ack`)) AS `minute` FROM `orders` WHERE ((`ack` > #{@d.literal(ack_stamp)}) AND (`market` = 'ICE')) GROUP BY minute(from_unixtime(`ack`))"
288
216
  end
289
-
290
- specify "should accept and return tinyints as bools or integers when configured to do so" do
291
- MYSQL_DB[:booltest].delete
292
- MYSQL_DB[:booltest] << {:value=>true}
293
- MYSQL_DB[:booltest].all.should == [{:value=>true}]
294
- MYSQL_DB[:booltest].delete
295
- MYSQL_DB[:booltest] << {:value=>false}
296
- MYSQL_DB[:booltest].all.should == [{:value=>false}]
297
-
298
- Sequel.convert_tinyint_to_bool = false
299
- MYSQL_DB[:booltest].delete
300
- MYSQL_DB[:booltest] << {:value=>true}
301
- MYSQL_DB[:booltest].all.should == [{:value=>1}]
302
- MYSQL_DB[:booltest].delete
303
- MYSQL_DB[:booltest] << {:value=>false}
304
- MYSQL_DB[:booltest].all.should == [{:value=>0}]
305
-
306
- MYSQL_DB[:booltest].delete
307
- MYSQL_DB[:booltest] << {:value=>1}
308
- MYSQL_DB[:booltest].all.should == [{:value=>1}]
309
- MYSQL_DB[:booltest].delete
310
- MYSQL_DB[:booltest] << {:value=>0}
311
- MYSQL_DB[:booltest].all.should == [{:value=>0}]
312
- end
313
217
  end
314
218
 
315
219
  context "MySQL join expressions" do
@@ -454,89 +358,109 @@ context "A MySQL database" do
454
358
  end
455
359
  end
456
360
 
457
- context "A MySQL database", "with table options" do
458
- before(:all) do
459
- @options = {}
460
- @options[:engine] = 'MyISAM'
461
- @options[:charset] = 'latin2'
462
- @options[:collate] = 'swedish'
361
+ context "A MySQL database with table options" do
362
+ before do
363
+ @options = {:engine=>'MyISAM', :charset=>'latin1', :collate => 'latin1_swedish_ci'}
463
364
 
464
365
  Sequel::MySQL.default_engine = 'InnoDB'
465
366
  Sequel::MySQL.default_charset = 'utf8'
466
- Sequel::MySQL.default_collate = 'utf8'
367
+ Sequel::MySQL.default_collate = 'utf8_general_ci'
467
368
 
468
369
  @db = MYSQL_DB
469
- @g = Sequel::Schema::Generator.new(@db) do
470
- integer :size
471
- text :name
472
- end
370
+ @db.drop_table(:items) rescue nil
371
+
372
+ MYSQL_DB.sqls.clear
473
373
  end
474
-
475
- after(:all) do
374
+ after do
375
+ @db.drop_table(:items) rescue nil
476
376
  Sequel::MySQL.default_engine = nil
477
377
  Sequel::MySQL.default_charset = nil
478
378
  Sequel::MySQL.default_collate = nil
479
379
  end
480
380
 
481
381
  specify "should allow to pass custom options (engine, charset, collate) for table creation" do
482
- statements = @db.send(:create_table_sql_list, :items, *(@g.create_info << @options))
483
- statements.should == [
484
- "CREATE TABLE items (size integer, name text) ENGINE=MyISAM DEFAULT CHARSET=latin2 DEFAULT COLLATE=swedish"
485
- ]
382
+ @db.create_table(:items, @options){Integer :size; text :name}
383
+ @db.sqls.should == ["CREATE TABLE items (size integer, name text) ENGINE=MyISAM DEFAULT CHARSET=latin1 DEFAULT COLLATE=latin1_swedish_ci"]
486
384
  end
487
385
 
488
386
  specify "should use default options if specified (engine, charset, collate) for table creation" do
489
- statements = @db.send(:create_table_sql_list, :items, *(@g.create_info))
490
- statements.should == [
491
- "CREATE TABLE items (size integer, name text) ENGINE=InnoDB DEFAULT CHARSET=utf8 DEFAULT COLLATE=utf8"
492
- ]
387
+ @db.create_table(:items){Integer :size; text :name}
388
+ @db.sqls.should == ["CREATE TABLE items (size integer, name text) ENGINE=InnoDB DEFAULT CHARSET=utf8 DEFAULT COLLATE=utf8_general_ci"]
493
389
  end
494
390
 
495
391
  specify "should not use default if option has a nil value" do
496
- statements = @db.send(:create_table_sql_list, :items, *(@g.create_info << {:engine=>nil, :charset=>nil, :collate=>nil}))
497
- statements.should == [
498
- "CREATE TABLE items (size integer, name text)"
499
- ]
392
+ @db.create_table(:items, :engine=>nil, :charset=>nil, :collate=>nil){Integer :size; text :name}
393
+ @db.sqls.should == ["CREATE TABLE items (size integer, name text)"]
500
394
  end
501
395
  end
502
396
 
503
397
  context "A MySQL database" do
504
398
  before do
505
399
  @db = MYSQL_DB
400
+ @db.drop_table(:items) rescue nil
401
+ MYSQL_DB.sqls.clear
402
+ end
403
+ after do
404
+ @db.drop_table(:items) rescue nil
506
405
  end
507
406
 
508
407
  specify "should support defaults for boolean columns" do
509
- g = Sequel::Schema::Generator.new(@db) do
510
- boolean :active1, :default => true
511
- boolean :active2, :default => false
512
- end
513
- statements = @db.send(:create_table_sql_list, :items, *g.create_info)
514
- statements.should == [
515
- "CREATE TABLE items (active1 boolean DEFAULT 1, active2 boolean DEFAULT 0)"
516
- ]
408
+ @db.create_table(:items){TrueClass :active1, :default=>true; FalseClass :active2, :default => false}
409
+ @db.sqls.should == ["CREATE TABLE items (active1 tinyint DEFAULT 1, active2 tinyint DEFAULT 0)"]
517
410
  end
518
411
 
519
412
  specify "should correctly format CREATE TABLE statements with foreign keys" do
520
- g = Sequel::Schema::Generator.new(@db) do
521
- foreign_key :p_id, :table => :users, :key => :id,
522
- :null => false, :on_delete => :cascade
523
- end
524
- @db.send(:create_table_sql_list, :items, *g.create_info).should == [
525
- "CREATE TABLE items (p_id integer NOT NULL, FOREIGN KEY (p_id) REFERENCES users(id) ON DELETE CASCADE)"
526
- ]
413
+ @db.create_table(:items){Integer :id; foreign_key :p_id, :items, :key => :id, :null => false, :on_delete => :cascade}
414
+ @db.sqls.should == ["CREATE TABLE items (id integer, p_id integer NOT NULL, FOREIGN KEY (p_id) REFERENCES items(id) ON DELETE CASCADE)"]
527
415
  end
528
416
 
529
- specify "should correctly format ALTER TABLE statements with foreign keys" do
530
- g = Sequel::Schema::AlterTableGenerator.new(@db) do
531
- add_foreign_key :p_id, :users, :key => :id, :null => false, :on_delete => :cascade
417
+ specify "should correctly format ALTER TABLE statements with foreign keys" do
418
+ @db.create_table(:items){Integer :id}
419
+ @db.alter_table(:items){add_foreign_key :p_id, :users, :key => :id, :null => false, :on_delete => :cascade}
420
+ @db.sqls.should == ["CREATE TABLE items (id integer)", "ALTER TABLE items ADD COLUMN p_id integer NOT NULL", "ALTER TABLE items ADD FOREIGN KEY (p_id) REFERENCES users(id) ON DELETE CASCADE"]
421
+ end
422
+
423
+ specify "should have rename_column support keep existing options" do
424
+ @db.create_table(:items){Integer :id, :null=>false, :default=>5}
425
+ @db.alter_table(:items){rename_column :id, :nid}
426
+ @db.sqls.should == ["CREATE TABLE items (id integer NOT NULL DEFAULT 5)", "DESCRIBE items", "ALTER TABLE items CHANGE COLUMN id nid int(11) NOT NULL DEFAULT 5"]
427
+ @db[:items].insert
428
+ @db[:items].all.should == [{:nid=>5}]
429
+ proc{@db[:items].insert(:nid=>nil)}.should raise_error(Sequel::DatabaseError)
430
+ end
431
+
432
+ specify "should have set_column_type support keep existing options" do
433
+ @db.create_table(:items){Integer :id, :null=>false, :default=>5}
434
+ @db.alter_table(:items){set_column_type :id, Bignum}
435
+ @db.sqls.should == ["CREATE TABLE items (id integer NOT NULL DEFAULT 5)", "DESCRIBE items", "ALTER TABLE items CHANGE COLUMN id id bigint NOT NULL DEFAULT 5"]
436
+ @db[:items].insert
437
+ @db[:items].all.should == [{:id=>5}]
438
+ proc{@db[:items].insert(:id=>nil)}.should raise_error(Sequel::DatabaseError)
439
+ @db[:items].delete
440
+ @db[:items].insert(2**40)
441
+ @db[:items].all.should == [{:id=>2**40}]
442
+ end
443
+
444
+ specify "should have set_column_default support keep existing options" do
445
+ @db.create_table(:items){Integer :id, :null=>false, :default=>5}
446
+ @db.alter_table(:items){set_column_default :id, 6}
447
+ @db.sqls.should == ["CREATE TABLE items (id integer NOT NULL DEFAULT 5)", "DESCRIBE items", "ALTER TABLE items CHANGE COLUMN id id int(11) NOT NULL DEFAULT 6"]
448
+ @db[:items].insert
449
+ @db[:items].all.should == [{:id=>6}]
450
+ proc{@db[:items].insert(:id=>nil)}.should raise_error(Sequel::DatabaseError)
451
+ end
452
+
453
+ specify "should have set_column_allow_null support keep existing options" do
454
+ @db.create_table(:items){Integer :id, :null=>false, :default=>5}
455
+ @db.alter_table(:items){set_column_allow_null :id, true}
456
+ @db.sqls.should == ["CREATE TABLE items (id integer NOT NULL DEFAULT 5)", "DESCRIBE items", "ALTER TABLE items CHANGE COLUMN id id int(11) NULL DEFAULT 5"]
457
+ @db[:items].insert
458
+ @db[:items].all.should == [{:id=>5}]
459
+ proc{@db[:items].insert(:id=>nil)}.should_not
532
460
  end
533
- @db.send(:alter_table_sql_list, :items, g.operations).should == [[
534
- "ALTER TABLE items ADD COLUMN p_id integer NOT NULL",
535
- "ALTER TABLE items ADD FOREIGN KEY (p_id) REFERENCES users(id) ON DELETE CASCADE"
536
- ]]
537
- end
538
461
 
539
462
  specify "should accept repeated raw sql statements using Database#<<" do
463
+ @db.create_table(:items){String :name; Integer :value}
540
464
  @db << 'DELETE FROM items'
541
465
  @db[:items].count.should == 0
542
466
 
@@ -548,8 +472,7 @@ end
548
472
  end
549
473
 
550
474
  specify "should handle multiple select statements at once" do
551
- @db << 'DELETE FROM items; '
552
-
475
+ @db.create_table(:items){String :name; Integer :value}
553
476
  @db[:items].delete
554
477
  @db[:items].insert(:name => 'tutu', :value => 1234)
555
478
  @db["SELECT * FROM items; SELECT * FROM items"].all.should == \
@@ -600,71 +523,73 @@ context "A grouped MySQL dataset" do
600
523
  end
601
524
 
602
525
  context "A MySQL database" do
603
- specify "should support fulltext indexes" do
604
- g = Sequel::Schema::Generator.new(MYSQL_DB) do
605
- text :title
606
- text :body
607
- full_text_index [:title, :body]
608
- end
609
- MYSQL_DB.send(:create_table_sql_list, :posts, *g.create_info).should == [
526
+ before do
527
+ @db = MYSQL_DB
528
+ @db.drop_table(:posts) rescue nil
529
+ @db.sqls.clear
530
+ end
531
+ after do
532
+ @db.drop_table(:posts) rescue nil
533
+ end
534
+
535
+ specify "should support fulltext indexes and full_text_search" do
536
+ @db.create_table(:posts){text :title; text :body; full_text_index :title; full_text_index [:title, :body]}
537
+ @db.sqls.should == [
610
538
  "CREATE TABLE posts (title text, body text)",
539
+ "CREATE FULLTEXT INDEX posts_title_index ON posts (title)",
611
540
  "CREATE FULLTEXT INDEX posts_title_body_index ON posts (title, body)"
612
541
  ]
613
- end
614
-
615
- specify "should support full_text_search" do
616
- MYSQL_DB[:posts].full_text_search(:title, 'ruby').sql.should ==
617
- "SELECT * FROM posts WHERE (MATCH (title) AGAINST ('ruby'))"
618
542
 
619
- MYSQL_DB[:posts].full_text_search([:title, :body], ['ruby', 'sequel']).sql.should ==
620
- "SELECT * FROM posts WHERE (MATCH (title, body) AGAINST ('ruby', 'sequel'))"
621
-
622
- MYSQL_DB[:posts].full_text_search(:title, '+ruby -rails', :boolean => true).sql.should ==
623
- "SELECT * FROM posts WHERE (MATCH (title) AGAINST ('+ruby -rails' IN BOOLEAN MODE))"
543
+ @db[:posts].insert(:title=>'ruby rails', :body=>'y')
544
+ @db[:posts].insert(:title=>'sequel', :body=>'ruby')
545
+ @db[:posts].insert(:title=>'ruby scooby', :body=>'x')
546
+ @db.sqls.clear
547
+
548
+ @db[:posts].full_text_search(:title, 'rails').all.should == [{:title=>'ruby rails', :body=>'y'}]
549
+ @db[:posts].full_text_search([:title, :body], ['sequel', 'ruby']).all.should == [{:title=>'sequel', :body=>'ruby'}]
550
+ @db[:posts].full_text_search(:title, '+ruby -rails', :boolean => true).all.should == [{:title=>'ruby scooby', :body=>'x'}]
551
+ @db.sqls.should == [
552
+ "SELECT * FROM posts WHERE (MATCH (title) AGAINST ('rails'))",
553
+ "SELECT * FROM posts WHERE (MATCH (title, body) AGAINST ('sequel ruby'))",
554
+ "SELECT * FROM posts WHERE (MATCH (title) AGAINST ('+ruby -rails' IN BOOLEAN MODE))"]
624
555
  end
625
556
 
626
557
  specify "should support spatial indexes" do
627
- g = Sequel::Schema::Generator.new(MYSQL_DB) do
628
- point :geom
629
- spatial_index [:geom]
630
- end
631
- MYSQL_DB.send(:create_table_sql_list, :posts, *g.create_info).should == [
632
- "CREATE TABLE posts (geom point)",
558
+ @db.create_table(:posts){point :geom, :null=>false; spatial_index [:geom]}
559
+ @db.sqls.should == [
560
+ "CREATE TABLE posts (geom point NOT NULL)",
633
561
  "CREATE SPATIAL INDEX posts_geom_index ON posts (geom)"
634
562
  ]
635
563
  end
636
564
 
637
565
  specify "should support indexes with index type" do
638
- g = Sequel::Schema::Generator.new(MYSQL_DB) do
639
- text :title
640
- index :title, :type => :hash
641
- end
642
- MYSQL_DB.send(:create_table_sql_list, :posts, *g.create_info).should == [
643
- "CREATE TABLE posts (title text)",
644
- "CREATE INDEX posts_title_index ON posts (title) USING hash"
566
+ @db.create_table(:posts){Integer :id; index :id, :type => :btree}
567
+ @db.sqls.should == [
568
+ "CREATE TABLE posts (id integer)",
569
+ "CREATE INDEX posts_id_index USING btree ON posts (id)"
645
570
  ]
646
571
  end
647
572
 
648
573
  specify "should support unique indexes with index type" do
649
- g = Sequel::Schema::Generator.new(MYSQL_DB) do
650
- text :title
651
- index :title, :type => :hash, :unique => true
652
- end
653
- MYSQL_DB.send(:create_table_sql_list, :posts, *g.create_info).should == [
654
- "CREATE TABLE posts (title text)",
655
- "CREATE UNIQUE INDEX posts_title_index ON posts (title) USING hash"
574
+ @db.create_table(:posts){Integer :id; index :id, :type => :btree, :unique => true}
575
+ @db.sqls.should == [
576
+ "CREATE TABLE posts (id integer)",
577
+ "CREATE UNIQUE INDEX posts_id_index USING btree ON posts (id)"
656
578
  ]
657
579
  end
658
580
  end
659
581
 
660
- context "MySQL::Dataset#insert" do
582
+ context "MySQL::Dataset#insert and related methods" do
661
583
  before do
584
+ MYSQL_DB.create_table(:items){String :name; Integer :value}
662
585
  @d = MYSQL_DB[:items]
663
- @d.delete
664
586
  MYSQL_DB.sqls.clear
665
587
  end
588
+ after do
589
+ MYSQL_DB.drop_table(:items)
590
+ end
666
591
 
667
- specify "should insert record with default values when no arguments given" do
592
+ specify "#insert should insert record with default values when no arguments given" do
668
593
  @d.insert
669
594
 
670
595
  MYSQL_DB.sqls.should == [
@@ -676,7 +601,7 @@ context "MySQL::Dataset#insert" do
676
601
  ]
677
602
  end
678
603
 
679
- specify "should insert record with default values when empty hash given" do
604
+ specify "#insert should insert record with default values when empty hash given" do
680
605
  @d.insert({})
681
606
 
682
607
  MYSQL_DB.sqls.should == [
@@ -688,7 +613,7 @@ context "MySQL::Dataset#insert" do
688
613
  ]
689
614
  end
690
615
 
691
- specify "should insert record with default values when empty array given" do
616
+ specify "#insert should insert record with default values when empty array given" do
692
617
  @d.insert []
693
618
 
694
619
  MYSQL_DB.sqls.should == [
@@ -699,16 +624,8 @@ context "MySQL::Dataset#insert" do
699
624
  {:name => nil, :value => nil}
700
625
  ]
701
626
  end
702
- end
703
627
 
704
- context "MySQL::Dataset#multi_insert" do
705
- before do
706
- @d = MYSQL_DB[:items]
707
- @d.delete
708
- MYSQL_DB.sqls.clear
709
- end
710
-
711
- specify "should insert multiple records in a single statement" do
628
+ specify "#multi_insert should insert multiple records in a single statement" do
712
629
  @d.multi_insert([{:name => 'abc'}, {:name => 'def'}])
713
630
 
714
631
  MYSQL_DB.sqls.should == [
@@ -722,7 +639,7 @@ context "MySQL::Dataset#multi_insert" do
722
639
  ]
723
640
  end
724
641
 
725
- specify "should split the list of records into batches if :commit_every option is given" do
642
+ specify "#multi_insert should split the list of records into batches if :commit_every option is given" do
726
643
  @d.multi_insert([{:value => 1}, {:value => 2}, {:value => 3}, {:value => 4}],
727
644
  :commit_every => 2)
728
645
 
@@ -743,7 +660,7 @@ context "MySQL::Dataset#multi_insert" do
743
660
  ]
744
661
  end
745
662
 
746
- specify "should split the list of records into batches if :slice option is given" do
663
+ specify "#multi_insert should split the list of records into batches if :slice option is given" do
747
664
  @d.multi_insert([{:value => 1}, {:value => 2}, {:value => 3}, {:value => 4}],
748
665
  :slice => 2)
749
666
 
@@ -764,7 +681,7 @@ context "MySQL::Dataset#multi_insert" do
764
681
  ]
765
682
  end
766
683
 
767
- specify "should support inserting using columns and values arrays" do
684
+ specify "#import should support inserting using columns and values arrays" do
768
685
  @d.import([:name, :value], [['abc', 1], ['def', 2]])
769
686
 
770
687
  MYSQL_DB.sqls.should == [
@@ -778,16 +695,8 @@ context "MySQL::Dataset#multi_insert" do
778
695
  {:name => 'def', :value => 2}
779
696
  ]
780
697
  end
781
- end
782
-
783
- context "MySQL::Dataset#insert_ignore" do
784
- before do
785
- @d = MYSQL_DB[:items]
786
- @d.delete
787
- MYSQL_DB.sqls.clear
788
- end
789
698
 
790
- specify "should add the IGNORE keyword when inserting" do
699
+ specify "#insert_ignore should add the IGNORE keyword when inserting" do
791
700
  @d.insert_ignore.multi_insert([{:name => 'abc'}, {:name => 'def'}])
792
701
 
793
702
  MYSQL_DB.sqls.should == [
@@ -800,16 +709,8 @@ context "MySQL::Dataset#insert_ignore" do
800
709
  {:name => 'abc', :value => nil}, {:name => 'def', :value => nil}
801
710
  ]
802
711
  end
803
- end
804
-
805
- context "MySQL::Dataset#on_duplicate_key_update" do
806
- before do
807
- @d = MYSQL_DB[:items]
808
- @d.delete
809
- MYSQL_DB.sqls.clear
810
- end
811
712
 
812
- specify "should add the ON DUPLICATE KEY UPDATE and ALL columns when no args given" do
713
+ specify "#on_duplicate_key_update should add the ON DUPLICATE KEY UPDATE and ALL columns when no args given" do
813
714
  @d.on_duplicate_key_update.import([:name,:value],
814
715
  [['abc', 1], ['def',2]]
815
716
  )
@@ -824,7 +725,8 @@ context "MySQL::Dataset#on_duplicate_key_update" do
824
725
  {:name => 'abc', :value => 1}, {:name => 'def', :value => 2}
825
726
  ]
826
727
  end
827
- specify "should add the ON DUPLICATE KEY UPDATE and columns specified when args are given" do
728
+
729
+ specify "#on_duplicate_key_update should add the ON DUPLICATE KEY UPDATE and columns specified when args are given" do
828
730
  @d.on_duplicate_key_update(:value).import([:name,:value],
829
731
  [['abc', 1], ['def',2]]
830
732
  )
@@ -844,14 +746,13 @@ end
844
746
 
845
747
  context "MySQL::Dataset#replace" do
846
748
  before do
847
- MYSQL_DB.drop_table(:items) if MYSQL_DB.table_exists?(:items)
848
- MYSQL_DB.create_table :items do
849
- integer :id, :unique => true
850
- integer :value, :index => true
851
- end
749
+ MYSQL_DB.create_table(:items){Integer :id, :unique=>true; Integer :value}
852
750
  @d = MYSQL_DB[:items]
853
751
  MYSQL_DB.sqls.clear
854
752
  end
753
+ after do
754
+ MYSQL_DB.drop_table(:items)
755
+ end
855
756
 
856
757
  specify "should create a record if the condition is not met" do
857
758
  @d.replace(:id => 111, :value => 333)
@@ -896,7 +797,13 @@ end
896
797
 
897
798
  unless MYSQL_DB.class.adapter_scheme == :do
898
799
  context "MySQL Stored Procedures" do
800
+ before do
801
+ MYSQL_DB.create_table(:items){Integer :id; Integer :value}
802
+ @d = MYSQL_DB[:items]
803
+ MYSQL_DB.sqls.clear
804
+ end
899
805
  after do
806
+ MYSQL_DB.drop_table(:items)
900
807
  MYSQL_DB.execute('DROP PROCEDURE test_sproc')
901
808
  end
902
809