sequel 3.34.1 → 3.35.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. data/CHANGELOG +52 -0
  2. data/README.rdoc +3 -1
  3. data/Rakefile +2 -10
  4. data/doc/active_record.rdoc +1 -0
  5. data/doc/migration.rdoc +18 -7
  6. data/doc/model_hooks.rdoc +6 -0
  7. data/doc/opening_databases.rdoc +3 -0
  8. data/doc/prepared_statements.rdoc +0 -1
  9. data/doc/release_notes/3.35.0.txt +144 -0
  10. data/doc/schema_modification.rdoc +16 -1
  11. data/doc/thread_safety.rdoc +17 -0
  12. data/lib/sequel/adapters/do.rb +2 -2
  13. data/lib/sequel/adapters/do/postgres.rb +1 -52
  14. data/lib/sequel/adapters/do/sqlite.rb +0 -5
  15. data/lib/sequel/adapters/firebird.rb +1 -1
  16. data/lib/sequel/adapters/ibmdb.rb +2 -2
  17. data/lib/sequel/adapters/jdbc.rb +23 -19
  18. data/lib/sequel/adapters/jdbc/db2.rb +0 -5
  19. data/lib/sequel/adapters/jdbc/derby.rb +29 -2
  20. data/lib/sequel/adapters/jdbc/firebird.rb +0 -5
  21. data/lib/sequel/adapters/jdbc/h2.rb +1 -1
  22. data/lib/sequel/adapters/jdbc/hsqldb.rb +7 -0
  23. data/lib/sequel/adapters/jdbc/informix.rb +0 -5
  24. data/lib/sequel/adapters/jdbc/jtds.rb +0 -5
  25. data/lib/sequel/adapters/jdbc/mysql.rb +0 -5
  26. data/lib/sequel/adapters/jdbc/postgresql.rb +4 -35
  27. data/lib/sequel/adapters/jdbc/sqlite.rb +0 -5
  28. data/lib/sequel/adapters/jdbc/sqlserver.rb +0 -5
  29. data/lib/sequel/adapters/jdbc/transactions.rb +4 -4
  30. data/lib/sequel/adapters/mysql2.rb +1 -1
  31. data/lib/sequel/adapters/odbc.rb +3 -3
  32. data/lib/sequel/adapters/odbc/mssql.rb +14 -1
  33. data/lib/sequel/adapters/oracle.rb +6 -18
  34. data/lib/sequel/adapters/postgres.rb +36 -53
  35. data/lib/sequel/adapters/shared/db2.rb +16 -2
  36. data/lib/sequel/adapters/shared/mssql.rb +40 -9
  37. data/lib/sequel/adapters/shared/mysql.rb +16 -4
  38. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +2 -2
  39. data/lib/sequel/adapters/shared/oracle.rb +2 -0
  40. data/lib/sequel/adapters/shared/postgres.rb +135 -211
  41. data/lib/sequel/adapters/sqlite.rb +2 -2
  42. data/lib/sequel/adapters/swift.rb +1 -1
  43. data/lib/sequel/adapters/swift/postgres.rb +1 -71
  44. data/lib/sequel/adapters/tinytds.rb +3 -3
  45. data/lib/sequel/core.rb +27 -4
  46. data/lib/sequel/database/connecting.rb +7 -8
  47. data/lib/sequel/database/logging.rb +6 -1
  48. data/lib/sequel/database/misc.rb +20 -4
  49. data/lib/sequel/database/query.rb +38 -18
  50. data/lib/sequel/database/schema_generator.rb +5 -2
  51. data/lib/sequel/database/schema_methods.rb +34 -8
  52. data/lib/sequel/dataset/prepared_statements.rb +1 -1
  53. data/lib/sequel/dataset/sql.rb +18 -24
  54. data/lib/sequel/extensions/core_extensions.rb +0 -23
  55. data/lib/sequel/extensions/migration.rb +22 -8
  56. data/lib/sequel/extensions/pg_auto_parameterize.rb +4 -0
  57. data/lib/sequel/extensions/schema_dumper.rb +1 -1
  58. data/lib/sequel/model.rb +2 -2
  59. data/lib/sequel/model/associations.rb +95 -70
  60. data/lib/sequel/model/base.rb +16 -18
  61. data/lib/sequel/plugins/dirty.rb +214 -0
  62. data/lib/sequel/plugins/identity_map.rb +1 -1
  63. data/lib/sequel/plugins/json_serializer.rb +16 -1
  64. data/lib/sequel/plugins/many_through_many.rb +22 -32
  65. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +2 -2
  66. data/lib/sequel/plugins/prepared_statements.rb +22 -8
  67. data/lib/sequel/plugins/prepared_statements_associations.rb +2 -3
  68. data/lib/sequel/plugins/prepared_statements_with_pk.rb +1 -1
  69. data/lib/sequel/plugins/single_table_inheritance.rb +1 -1
  70. data/lib/sequel/plugins/subclasses.rb +10 -2
  71. data/lib/sequel/plugins/timestamps.rb +1 -1
  72. data/lib/sequel/plugins/xml_serializer.rb +12 -1
  73. data/lib/sequel/sql.rb +1 -1
  74. data/lib/sequel/version.rb +2 -2
  75. data/spec/adapters/postgres_spec.rb +30 -79
  76. data/spec/core/database_spec.rb +46 -2
  77. data/spec/core/dataset_spec.rb +28 -22
  78. data/spec/core/schema_generator_spec.rb +1 -1
  79. data/spec/core/schema_spec.rb +51 -0
  80. data/spec/extensions/arbitrary_servers_spec.rb +0 -4
  81. data/spec/extensions/association_autoreloading_spec.rb +17 -0
  82. data/spec/extensions/association_proxies_spec.rb +4 -4
  83. data/spec/extensions/core_extensions_spec.rb +1 -24
  84. data/spec/extensions/dirty_spec.rb +155 -0
  85. data/spec/extensions/json_serializer_spec.rb +13 -0
  86. data/spec/extensions/migration_spec.rb +28 -15
  87. data/spec/extensions/named_timezones_spec.rb +6 -8
  88. data/spec/extensions/pg_auto_parameterize_spec.rb +6 -5
  89. data/spec/extensions/schema_dumper_spec.rb +3 -1
  90. data/spec/extensions/xml_serializer_spec.rb +13 -0
  91. data/spec/files/{transactionless_migrations → transaction_specified_migrations}/001_create_alt_basic.rb +1 -1
  92. data/spec/files/{transactionless_migrations → transaction_specified_migrations}/002_create_basic.rb +0 -0
  93. data/spec/files/{transaction_migrations → transaction_unspecified_migrations}/001_create_alt_basic.rb +0 -0
  94. data/spec/files/{transaction_migrations → transaction_unspecified_migrations}/002_create_basic.rb +0 -0
  95. data/spec/integration/associations_test.rb +5 -7
  96. data/spec/integration/dataset_test.rb +25 -7
  97. data/spec/integration/plugin_test.rb +1 -1
  98. data/spec/integration/schema_test.rb +16 -1
  99. data/spec/model/associations_spec.rb +2 -2
  100. metadata +14 -9
  101. data/lib/sequel/adapters/odbc/db2.rb +0 -17
@@ -8,7 +8,7 @@ describe Sequel::Schema::Generator do
8
8
  foreign_key :parent_id
9
9
  primary_key :id
10
10
  check 'price > 100'
11
- constraint(:xxx) {:yyy == :zzz}
11
+ constraint(:xxx) {{:yyy => :zzz}}
12
12
  index :title
13
13
  index [:title, :body], :unique => true
14
14
  foreign_key :node_id, :nodes
@@ -287,6 +287,13 @@ describe "DB#create_table" do
287
287
  @db.sqls.should == ["CREATE TABLE cats (id integer)", "CREATE INDEX cats_id_index ON cats (id)"]
288
288
  end
289
289
 
290
+ specify "should accept inline index definition with a hash of options" do
291
+ @db.create_table(:cats) do
292
+ integer :id, :index => {:unique=>true}
293
+ end
294
+ @db.sqls.should == ["CREATE TABLE cats (id integer)", "CREATE UNIQUE INDEX cats_id_index ON cats (id)"]
295
+ end
296
+
290
297
  specify "should accept inline index definition for foreign keys" do
291
298
  @db.create_table(:cats) do
292
299
  foreign_key :project_id, :table => :projects, :on_delete => :cascade, :index => true
@@ -295,6 +302,14 @@ describe "DB#create_table" do
295
302
  "CREATE INDEX cats_project_id_index ON cats (project_id)"]
296
303
  end
297
304
 
305
+ specify "should accept inline index definition for foreign keys with a hash of options" do
306
+ @db.create_table(:cats) do
307
+ foreign_key :project_id, :table => :projects, :on_delete => :cascade, :index => {:unique=>true}
308
+ end
309
+ @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON DELETE CASCADE)",
310
+ "CREATE UNIQUE INDEX cats_project_id_index ON cats (project_id)"]
311
+ end
312
+
298
313
  specify "should accept index definitions" do
299
314
  @db.create_table(:cats) do
300
315
  integer :id
@@ -535,6 +550,20 @@ describe "DB#create_table" do
535
550
  end
536
551
  @db.sqls.should == ["CREATE TABLE cats (a integer, b integer, FOREIGN KEY (a, b) REFERENCES abc(x, y) ON DELETE SET NULL ON UPDATE SET NULL)"]
537
552
  end
553
+
554
+ specify "should accept an :as option to create a table from the results of a dataset" do
555
+ @db.create_table(:cats, :as=>@db[:a])
556
+ @db.sqls.should == ['CREATE TABLE cats AS SELECT * FROM a']
557
+ end
558
+
559
+ specify "should accept an :as option to create a table from a SELECT string" do
560
+ @db.create_table(:cats, :as=>'SELECT * FROM a')
561
+ @db.sqls.should == ['CREATE TABLE cats AS SELECT * FROM a']
562
+ end
563
+
564
+ specify "should raise an Error if both a block and an :as argument are given" do
565
+ proc{@db.create_table(:cats, :as=>@db[:a]){}}.should raise_error(Sequel::Error)
566
+ end
538
567
  end
539
568
 
540
569
  describe "DB#create_table!" do
@@ -1155,6 +1184,28 @@ describe "Schema Parser" do
1155
1184
  proc{@db.schema(:x)}.should raise_error(Sequel::Error)
1156
1185
  end
1157
1186
 
1187
+ specify "should cache data by default" do
1188
+ @db.meta_def(:schema_parse_table) do |t, opts|
1189
+ [[:a, {}]]
1190
+ end
1191
+ @db.schema(:x).should equal(@db.schema(:x))
1192
+ end
1193
+
1194
+ specify "should not cache data if :reload=>true is given" do
1195
+ @db.meta_def(:schema_parse_table) do |t, opts|
1196
+ [[:a, {}]]
1197
+ end
1198
+ @db.schema(:x).should_not equal(@db.schema(:x, :reload=>true))
1199
+ end
1200
+
1201
+ specify "should not cache schema metadata if cache_schema is false" do
1202
+ @db.cache_schema = false
1203
+ @db.meta_def(:schema_parse_table) do |t, opts|
1204
+ [[:a, {}]]
1205
+ end
1206
+ @db.schema(:x).should_not equal(@db.schema(:x))
1207
+ end
1208
+
1158
1209
  specify "should provide options if given a table name" do
1159
1210
  c = nil
1160
1211
  @db.meta_def(:schema_parse_table) do |t, opts|
@@ -1,6 +1,5 @@
1
1
  require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
- if RUBY_VERSION >= '1.8.7'
4
3
  describe "arbtirary servers" do
5
4
  before do
6
5
  @db = Sequel.mock(:servers=>{})
@@ -109,6 +108,3 @@ describe "arbtirary servers" do
109
108
  'SELECT * FROM t -- {:host=>"b"}', 'SELECT * FROM t -- {:host=>"a"}', 'SELECT * FROM t', 'SELECT * FROM t -- {:host=>"c"}', 'SELECT * FROM t']
110
109
  end
111
110
  end
112
- else
113
- skip_warn "arbitrary_servers plugin: only works on ruby 1.8.7+"
114
- end
@@ -24,6 +24,23 @@ describe "AssociationAutoreloading plugin" do
24
24
  MODEL_DB.sqls.should == ['SELECT * FROM artists WHERE (artists.id = 1) LIMIT 1']
25
25
  end
26
26
 
27
+ specify "should handle multiple many_to_one association with the same foreign key" do
28
+ @Album.many_to_one :artist2, :key=>:artist_id, :class=>@Artist
29
+ album = @Album.load(:id => 1, :name=>'Al', :artist_id=>2)
30
+ album.artist
31
+ album.artist2
32
+ MODEL_DB.sqls.should == ['SELECT * FROM artists WHERE (artists.id = 2) LIMIT 1'] * 2
33
+
34
+ album.artist
35
+ album.artist2
36
+ MODEL_DB.sqls.should == []
37
+
38
+ album.artist_id = 1
39
+ album.artist
40
+ album.artist2
41
+ MODEL_DB.sqls.should == ['SELECT * FROM artists WHERE (artists.id = 1) LIMIT 1'] * 2
42
+ end
43
+
27
44
  specify "should not reload when value has not changed" do
28
45
  album = @Album.load(:id => 1, :name=>'Al', :artist_id=>2)
29
46
  album.artist
@@ -31,13 +31,13 @@ describe "Sequel::Plugins::AssociationProxies" do
31
31
 
32
32
  it "should reload the cached association if sent an array method and the reload flag was given" do
33
33
  @t.select{|x| false}.should == []
34
- Item.db.sqls.length == 1
34
+ Item.db.sqls.length.should == 1
35
35
  @t.select{|x| false}.should == []
36
- Item.db.sqls.length == 1
36
+ Item.db.sqls.length.should == 0
37
37
  @i.tags(true).select{|x| false}.should == []
38
- Item.db.sqls.length == 2
38
+ Item.db.sqls.length.should == 1
39
39
  @t.filter(:a=>1).sql.should == "SELECT tags.* FROM tags INNER JOIN items_tags ON ((items_tags.tag_id = tags.id) AND (items_tags.item_id = 1)) WHERE (a = 1)"
40
- Item.db.sqls.length == 2
40
+ Item.db.sqls.length.should == 0
41
41
  end
42
42
 
43
43
  it "should not return a proxy object for associations that do not return an array" do
@@ -3,7 +3,7 @@ require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper')
3
3
  describe "Sequel core extensions" do
4
4
  specify "should not be used inside Sequel, to insure Sequel works without them" do
5
5
  usage = []
6
- match_re = /(\.(all_two_pairs\?|sql_value_list|sql_array|sql_expr|sql_negate|sql_or|sql_string_join|lit|to_sequel_blob|case|sql_expr_if_all_two_pairs)\W)|:\w+\.(qualify|identifier|as|cast|asc|desc|sql_subscript|\*|sql_function)\W/
6
+ match_re = /(\.(sql_value_list|sql_array|sql_expr|sql_negate|sql_or|sql_string_join|lit|to_sequel_blob|case)\W)|:\w+\.(qualify|identifier|as|cast|asc|desc|sql_subscript|\*|sql_function)\W/
7
7
  comment_re = /^\s*#|# core_sql/
8
8
  Dir['lib/sequel/**/*.rb'].each do |f|
9
9
  lines = File.read(f).split("\n").grep(match_re).delete_if{|l| l =~ comment_re}
@@ -18,29 +18,6 @@ describe "Sequel core extensions" do
18
18
  end
19
19
  end
20
20
 
21
- describe "Array#all_two_pairs?" do
22
- specify "should return false if empty" do
23
- [].all_two_pairs?.should == false
24
- end
25
-
26
- specify "should return false if any of the elements is not an array" do
27
- [1].all_two_pairs?.should == false
28
- [[1,2],1].all_two_pairs?.should == false
29
- end
30
-
31
- specify "should return false if any of the elements has a length other than two" do
32
- [[1,2],[]].all_two_pairs?.should == false
33
- [[1,2],[1]].all_two_pairs?.should == false
34
- [[1,2],[1,2,3]].all_two_pairs?.should == false
35
- end
36
-
37
- specify "should return true if all of the elements are arrays with a length of two" do
38
- [[1,2]].all_two_pairs?.should == true
39
- [[1,2],[1,2]].all_two_pairs?.should == true
40
- [[1,2],[1,2],[1,2]].all_two_pairs?.should == true
41
- end
42
- end
43
-
44
21
  describe "Array#case and Hash#case" do
45
22
  before do
46
23
  @d = Sequel::Dataset.new(nil)
@@ -0,0 +1,155 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
+
3
+ describe "Sequel::Plugins::Dirty" do
4
+ before do
5
+ @db = Sequel.mock(:fetch=>{:initial=>'i', :initial_changed=>'ic'}, :numrows=>1)
6
+ @c = Class.new(Sequel::Model(@db[:c]))
7
+ @c.plugin :dirty
8
+ @c.columns :initial, :initial_changed, :missing, :missing_changed
9
+ end
10
+
11
+ shared_examples_for "dirty plugin" do
12
+ it "initial_value should be the current value if value has not changed" do
13
+ @o.initial_value(:initial).should == 'i'
14
+ @o.initial_value(:missing).should == nil
15
+ end
16
+
17
+ it "initial_value should be the intial value if value has changed" do
18
+ @o.initial_value(:initial_changed).should == 'ic'
19
+ @o.initial_value(:missing_changed).should == nil
20
+ end
21
+
22
+ it "initial_value should handle case where initial value is reassigned later" do
23
+ @o.initial_changed = 'ic'
24
+ @o.initial_value(:initial_changed).should == 'ic'
25
+ @o.missing_changed = nil
26
+ @o.initial_value(:missing_changed).should == nil
27
+ end
28
+
29
+ it "changed_columns should handle case where initial value is reassigned later" do
30
+ @o.changed_columns.should == [:initial_changed, :missing_changed]
31
+ @o.initial_changed = 'ic'
32
+ @o.changed_columns.should == [:missing_changed]
33
+ @o.missing_changed = nil
34
+ @o.changed_columns.should == [:missing_changed]
35
+ end
36
+
37
+ it "column_change should give initial and current values if there has been a change made" do
38
+ @o.column_change(:initial_changed).should == ['ic', 'ic2']
39
+ @o.column_change(:missing_changed).should == [nil, 'mc2']
40
+ end
41
+
42
+ it "column_change should be nil if no change has been made" do
43
+ @o.column_change(:initial).should == nil
44
+ @o.column_change(:missing).should == nil
45
+ end
46
+
47
+ it "column_changed? should return whether the column has changed" do
48
+ @o.column_changed?(:initial).should == false
49
+ @o.column_changed?(:initial_changed).should == true
50
+ @o.column_changed?(:missing).should == false
51
+ @o.column_changed?(:missing_changed).should == true
52
+ end
53
+
54
+ it "column_changed? should handle case where initial value is reassigned later" do
55
+ @o.initial_changed = 'ic'
56
+ @o.column_changed?(:initial_changed).should == false
57
+ @o.missing_changed = nil
58
+ @o.column_changed?(:missing_changed).should == false
59
+ end
60
+
61
+ it "changed_columns should handle case where initial value is reassigned later" do
62
+ @o.changed_columns.should == [:initial_changed, :missing_changed]
63
+ @o.initial_changed = 'ic'
64
+ @o.changed_columns.should == [:missing_changed]
65
+ @o.missing_changed = nil
66
+ @o.changed_columns.should == [:missing_changed]
67
+ end
68
+
69
+ it "column_changes should give initial and current values" do
70
+ @o.column_changes.should == {:initial_changed=>['ic', 'ic2'], :missing_changed=>[nil, 'mc2']}
71
+ end
72
+
73
+ it "reset_column should reset the column to its initial value" do
74
+ @o.reset_column(:initial)
75
+ @o.initial.should == 'i'
76
+ @o.reset_column(:initial_changed)
77
+ @o.initial_changed.should == 'ic'
78
+ @o.reset_column(:missing)
79
+ @o.missing.should == nil
80
+ @o.reset_column(:missing_changed)
81
+ @o.missing_changed.should == nil
82
+ end
83
+
84
+ it "reset_column should remove missing values from the values" do
85
+ @o.reset_column(:missing)
86
+ @o.values.has_key?(:missing).should == false
87
+ @o.reset_column(:missing_changed)
88
+ @o.values.has_key?(:missing_changed).should == false
89
+ end
90
+
91
+ it "refresh should clear the cached initial values" do
92
+ @o.refresh
93
+ @o.column_changes.should == {}
94
+ end
95
+
96
+ it "will_change_column should be used to signal in-place modification to column" do
97
+ @o.will_change_column(:initial)
98
+ @o.initial << 'b'
99
+ @o.column_change(:initial).should == ['i', 'ib']
100
+ @o.will_change_column(:initial_changed)
101
+ @o.initial_changed << 'b'
102
+ @o.column_change(:initial_changed).should == ['ic', 'ic2b']
103
+ @o.will_change_column(:missing)
104
+ @o.values[:missing] = 'b'
105
+ @o.column_change(:missing).should == [nil, 'b']
106
+ @o.will_change_column(:missing_changed)
107
+ @o.missing_changed << 'b'
108
+ @o.column_change(:missing_changed).should == [nil, 'mc2b']
109
+ end
110
+
111
+ it "will_change_column should different types of existing objects" do
112
+ [nil, true, false, Class.new{undef_method :clone}.new, Class.new{def clone; raise TypeError; end}.new].each do |v|
113
+ o = @c.new(:initial=>v)
114
+ o.will_change_column(:initial)
115
+ o.initial = 'a'
116
+ o.column_change(:initial).should == [v, 'a']
117
+ end
118
+ end
119
+
120
+ it "save should clear the cached initial values" do
121
+ @o.save
122
+ @o.column_changes.should == {}
123
+ end
124
+
125
+ it "save_changes should clear the cached initial values" do
126
+ @o.save_changes
127
+ @o.column_changes.should == {}
128
+ end
129
+ end
130
+
131
+ describe "with new instance" do
132
+ before do
133
+ @o = @c.new(:initial=>'i', :initial_changed=>'ic')
134
+ @o.initial_changed = 'ic2'
135
+ @o.missing_changed = 'mc2'
136
+ end
137
+
138
+ it_should_behave_like "dirty plugin"
139
+ end
140
+
141
+ describe "with existing instance" do
142
+ before do
143
+ @o = @c[1]
144
+ @o.initial_changed = 'ic2'
145
+ @o.missing_changed = 'mc2'
146
+ end
147
+
148
+ it_should_behave_like "dirty plugin"
149
+
150
+ it "previous_changes should be the previous changes after saving" do
151
+ @o.save
152
+ @o.previous_changes.should == {:initial_changed=>['ic', 'ic2'], :missing_changed=>[nil, 'mc2']}
153
+ end
154
+ end
155
+ end
@@ -116,6 +116,19 @@ describe "Sequel::Plugins::JsonSerializer" do
116
116
  JSON.parse(ds.to_json).should == [@album.values.inject({}){|h, (k, v)| h[k.to_s] = v; h}]
117
117
  end
118
118
 
119
+ it "should have dataset to_json method respect :array option for the array to use" do
120
+ a = Album.load(:id=>1, :name=>'RF', :artist_id=>3)
121
+ JSON.parse(Album.to_json(:array=>[a])).should == [a]
122
+
123
+ a.associations[:artist] = artist = Artist.load(:id=>3, :name=>'YJM')
124
+ JSON.parse(Album.to_json(:array=>[a], :include=>:artist)).first.artist.should == artist
125
+
126
+ artist.associations[:albums] = [a]
127
+ x = JSON.parse(Artist.to_json(:array=>[artist], :include=>:albums))
128
+ x.should == [artist]
129
+ x.first.albums.should == [a]
130
+ end
131
+
119
132
  it "should propagate class default options to instance to_json output" do
120
133
  class ::Album2 < Sequel::Model
121
134
  attr_accessor :blah
@@ -320,23 +320,30 @@ describe "Sequel::IntegerMigrator" do
320
320
  proc{Sequel::IntegerMigrator.apply(@db, "spec/files/timestamped_migrations")}.should raise_error(Sequel::Migrator::Error)
321
321
  end
322
322
 
323
- specify "should use transactions by default" do
324
- Sequel::Migrator.apply(@db, "spec/files/transaction_migrations")
323
+ specify "should not use transactions by default" do
324
+ Sequel::Migrator.apply(@db, "spec/files/transaction_unspecified_migrations")
325
+ @db.sqls.should == ["CREATE TABLE schema_info (version integer DEFAULT 0 NOT NULL)", "SELECT 1 AS one FROM schema_info LIMIT 1", "INSERT INTO schema_info (version) VALUES (0)", "SELECT version FROM schema_info LIMIT 1", "CREATE TABLE sm11111 (smc1 integer)", "UPDATE schema_info SET version = 1", "CREATE TABLE sm (smc1 integer)", "UPDATE schema_info SET version = 2"]
326
+ end
327
+
328
+ specify "should use transactions by default if the database supports transactional ddl" do
329
+ @db.meta_def(:supports_transactional_ddl?){true}
330
+ Sequel::Migrator.apply(@db, "spec/files/transaction_unspecified_migrations")
325
331
  @db.sqls.should == ["CREATE TABLE schema_info (version integer DEFAULT 0 NOT NULL)", "SELECT 1 AS one FROM schema_info LIMIT 1", "INSERT INTO schema_info (version) VALUES (0)", "SELECT version FROM schema_info LIMIT 1", "BEGIN", "CREATE TABLE sm11111 (smc1 integer)", "UPDATE schema_info SET version = 1", "COMMIT", "BEGIN", "CREATE TABLE sm (smc1 integer)", "UPDATE schema_info SET version = 2", "COMMIT"]
326
332
  end
327
333
 
328
- specify "should not use transactions for migrations that disable it" do
329
- Sequel::Migrator.apply(@db, "spec/files/transactionless_migrations")
330
- @db.sqls.should == ["CREATE TABLE schema_info (version integer DEFAULT 0 NOT NULL)", "SELECT 1 AS one FROM schema_info LIMIT 1", "INSERT INTO schema_info (version) VALUES (0)", "SELECT version FROM schema_info LIMIT 1", "CREATE TABLE sm11111 (smc1 integer)", "UPDATE schema_info SET version = 1", "CREATE TABLE sm (smc1 integer)", "UPDATE schema_info SET version = 2"]
334
+ specify "should respect transaction use on a per migration basis" do
335
+ @db.meta_def(:supports_transactional_ddl?){true}
336
+ Sequel::Migrator.apply(@db, "spec/files/transaction_specified_migrations")
337
+ @db.sqls.should == ["CREATE TABLE schema_info (version integer DEFAULT 0 NOT NULL)", "SELECT 1 AS one FROM schema_info LIMIT 1", "INSERT INTO schema_info (version) VALUES (0)", "SELECT version FROM schema_info LIMIT 1", "BEGIN", "CREATE TABLE sm11111 (smc1 integer)", "UPDATE schema_info SET version = 1", "COMMIT", "CREATE TABLE sm (smc1 integer)", "UPDATE schema_info SET version = 2"]
331
338
  end
332
339
 
333
340
  specify "should force transactions if enabled in the migrator" do
334
- Sequel::Migrator.run(@db, "spec/files/transactionless_migrations", :use_transactions=>true)
341
+ Sequel::Migrator.run(@db, "spec/files/transaction_specified_migrations", :use_transactions=>true)
335
342
  @db.sqls.should == ["CREATE TABLE schema_info (version integer DEFAULT 0 NOT NULL)", "SELECT 1 AS one FROM schema_info LIMIT 1", "INSERT INTO schema_info (version) VALUES (0)", "SELECT version FROM schema_info LIMIT 1", "BEGIN", "CREATE TABLE sm11111 (smc1 integer)", "UPDATE schema_info SET version = 1", "COMMIT", "BEGIN", "CREATE TABLE sm (smc1 integer)", "UPDATE schema_info SET version = 2", "COMMIT"]
336
343
  end
337
344
 
338
345
  specify "should not use transactions if disabled in the migrator" do
339
- Sequel::Migrator.run(@db, "spec/files/transaction_migrations", :use_transactions=>false)
346
+ Sequel::Migrator.run(@db, "spec/files/transaction_unspecified_migrations", :use_transactions=>false)
340
347
  @db.sqls.should == ["CREATE TABLE schema_info (version integer DEFAULT 0 NOT NULL)", "SELECT 1 AS one FROM schema_info LIMIT 1", "INSERT INTO schema_info (version) VALUES (0)", "SELECT version FROM schema_info LIMIT 1", "CREATE TABLE sm11111 (smc1 integer)", "UPDATE schema_info SET version = 1", "CREATE TABLE sm (smc1 integer)", "UPDATE schema_info SET version = 2"]
341
348
  end
342
349
  end
@@ -598,26 +605,32 @@ describe "Sequel::TimestampMigrator" do
598
605
 
599
606
  specify "should use TimestampMigrator if TimestampMigrator.apply is called even for integer migrations directory" do
600
607
  Sequel::TimestampMigrator.apply(@db, "spec/files/integer_migrations")
601
- @db.sqls.should == ["SELECT NULL FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "BEGIN", "CREATE TABLE sm1111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_sessions.rb')", "COMMIT", "BEGIN", "CREATE TABLE sm2222 (smc2 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_nodes.rb')", "COMMIT", "BEGIN", "CREATE TABLE sm3333 (smc3 integer)", "INSERT INTO schema_migrations (filename) VALUES ('003_3_create_users.rb')", "COMMIT"]
608
+ @db.sqls.should == ["SELECT NULL FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "CREATE TABLE sm1111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_sessions.rb')", "CREATE TABLE sm2222 (smc2 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_nodes.rb')", "CREATE TABLE sm3333 (smc3 integer)", "INSERT INTO schema_migrations (filename) VALUES ('003_3_create_users.rb')"]
602
609
  end
603
610
 
604
- specify "should use transactions by default" do
605
- Sequel::TimestampMigrator.apply(@db, "spec/files/transaction_migrations")
611
+ specify "should not use transactions by default" do
612
+ Sequel::TimestampMigrator.apply(@db, "spec/files/transaction_unspecified_migrations")
613
+ @db.sqls.should == ["SELECT NULL FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "CREATE TABLE sm11111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_alt_basic.rb')", "CREATE TABLE sm (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_basic.rb')"]
614
+ end
615
+
616
+ specify "should use transactions by default if database supports transactional ddl" do
617
+ @db.meta_def(:supports_transactional_ddl?){true}
618
+ Sequel::TimestampMigrator.apply(@db, "spec/files/transaction_unspecified_migrations")
606
619
  @db.sqls.should == ["SELECT NULL FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "BEGIN", "CREATE TABLE sm11111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_alt_basic.rb')", "COMMIT", "BEGIN", "CREATE TABLE sm (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_basic.rb')", "COMMIT"]
607
620
  end
608
621
 
609
- specify "should not use transactions for migrations that disable it" do
610
- Sequel::TimestampMigrator.apply(@db, "spec/files/transactionless_migrations")
611
- @db.sqls.should == ["SELECT NULL FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "CREATE TABLE sm11111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_alt_basic.rb')", "CREATE TABLE sm (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_basic.rb')"]
622
+ specify "should support transaction use on a per migration basis" do
623
+ Sequel::TimestampMigrator.apply(@db, "spec/files/transaction_specified_migrations")
624
+ @db.sqls.should == ["SELECT NULL FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "BEGIN", "CREATE TABLE sm11111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_alt_basic.rb')", "COMMIT", "CREATE TABLE sm (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_basic.rb')"]
612
625
  end
613
626
 
614
627
  specify "should force transactions if enabled by the migrator" do
615
- Sequel::TimestampMigrator.run(@db, "spec/files/transactionless_migrations", :use_transactions=>true)
628
+ Sequel::TimestampMigrator.run(@db, "spec/files/transaction_specified_migrations", :use_transactions=>true)
616
629
  @db.sqls.should == ["SELECT NULL FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "BEGIN", "CREATE TABLE sm11111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_alt_basic.rb')", "COMMIT", "BEGIN", "CREATE TABLE sm (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_basic.rb')", "COMMIT"]
617
630
  end
618
631
 
619
632
  specify "should not use transactions if disabled in the migrator" do
620
- Sequel::TimestampMigrator.run(@db, "spec/files/transaction_migrations", :use_transactions=>false)
633
+ Sequel::TimestampMigrator.run(@db, "spec/files/transaction_unspecified_migrations", :use_transactions=>false)
621
634
  @db.sqls.should == ["SELECT NULL FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "CREATE TABLE sm11111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_alt_basic.rb')", "CREATE TABLE sm (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_basic.rb')"]
622
635
  end
623
636
  end
@@ -35,14 +35,12 @@ describe "Sequel named_timezones extension" do
35
35
  Sequel.database_timezone.should == @tz_out
36
36
  end
37
37
 
38
- unless RUBY_VERSION == '1.8.6' && RUBY_PLATFORM =~ /win/
39
- it "should convert datetimes going into the database to named database_timezone" do
40
- ds = @db[:a]
41
- def ds.supports_timestamp_timezones?; true; end
42
- def ds.supports_timestamp_usecs?; false; end
43
- ds.insert([@dt, DateTime.civil(2009,6,1,3,20,30,-7/24.0), DateTime.civil(2009,6,1,6,20,30,-1/6.0)])
44
- @db.sqls.should == ["INSERT INTO a VALUES ('2009-06-01 06:20:30-0400', '2009-06-01 06:20:30-0400', '2009-06-01 06:20:30-0400')"]
45
- end
38
+ it "should convert datetimes going into the database to named database_timezone" do
39
+ ds = @db[:a]
40
+ def ds.supports_timestamp_timezones?; true; end
41
+ def ds.supports_timestamp_usecs?; false; end
42
+ ds.insert([@dt, DateTime.civil(2009,6,1,3,20,30,-7/24.0), DateTime.civil(2009,6,1,6,20,30,-1/6.0)])
43
+ @db.sqls.should == ["INSERT INTO a VALUES ('2009-06-01 06:20:30-0400', '2009-06-01 06:20:30-0400', '2009-06-01 06:20:30-0400')"]
46
44
  end
47
45
 
48
46
  it "should convert datetimes coming out of the database from database_timezone to application_timezone" do