sequel 2.12.0 → 3.0.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 (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