sequel 3.34.1 → 3.35.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 (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