sequel 3.17.0 → 3.18.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 (35) hide show
  1. data/CHANGELOG +22 -0
  2. data/doc/migration.rdoc +34 -0
  3. data/doc/release_notes/3.18.0.txt +121 -0
  4. data/lib/sequel/adapters/jdbc.rb +6 -1
  5. data/lib/sequel/adapters/mysql.rb +11 -1
  6. data/lib/sequel/adapters/mysql2.rb +3 -1
  7. data/lib/sequel/adapters/postgres.rb +1 -1
  8. data/lib/sequel/adapters/shared/sqlite.rb +13 -1
  9. data/lib/sequel/adapters/sqlite.rb +31 -26
  10. data/lib/sequel/connection_pool/sharded_single.rb +5 -1
  11. data/lib/sequel/connection_pool/sharded_threaded.rb +5 -1
  12. data/lib/sequel/dataset/sql.rb +0 -5
  13. data/lib/sequel/extensions/migration.rb +117 -1
  14. data/lib/sequel/extensions/to_dot.rb +137 -0
  15. data/lib/sequel/model/base.rb +1 -1
  16. data/lib/sequel/plugins/instance_hooks.rb +14 -9
  17. data/lib/sequel/plugins/json_serializer.rb +3 -3
  18. data/lib/sequel/sql.rb +1 -1
  19. data/lib/sequel/version.rb +1 -1
  20. data/spec/adapters/sqlite_spec.rb +15 -7
  21. data/spec/core/connection_pool_spec.rb +17 -1
  22. data/spec/core/dataset_spec.rb +9 -0
  23. data/spec/extensions/instance_hooks_spec.rb +46 -0
  24. data/spec/extensions/json_serializer_spec.rb +11 -0
  25. data/spec/extensions/migration_spec.rb +107 -0
  26. data/spec/extensions/spec_helper.rb +1 -1
  27. data/spec/extensions/to_dot_spec.rb +152 -0
  28. data/spec/files/reversible_migrations/001_reversible.rb +5 -0
  29. data/spec/files/reversible_migrations/002_reversible.rb +5 -0
  30. data/spec/files/reversible_migrations/003_reversible.rb +5 -0
  31. data/spec/files/reversible_migrations/004_reversible.rb +5 -0
  32. data/spec/files/reversible_migrations/005_reversible.rb +10 -0
  33. data/spec/integration/migrator_test.rb +54 -0
  34. data/spec/model/association_reflection_spec.rb +19 -0
  35. metadata +13 -4
@@ -8,7 +8,7 @@ unless Sequel.const_defined?('Model')
8
8
  require 'sequel/model'
9
9
  end
10
10
 
11
- Sequel.extension(*%w'string_date_time inflector pagination query pretty_table blank migration schema_dumper looser_typecasting sql_expr thread_local_timezones')
11
+ Sequel.extension(*%w'string_date_time inflector pagination query pretty_table blank migration schema_dumper looser_typecasting sql_expr thread_local_timezones to_dot')
12
12
  {:hook_class_methods=>[], :schema=>[], :validation_class_methods=>[]}.each{|p, opts| Sequel::Model.plugin(p, *opts)}
13
13
 
14
14
  def skip_warn(s)
@@ -0,0 +1,152 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
+
3
+ describe Sequel::Model, "to_dot extension" do
4
+ def dot(ds)
5
+ a = []
6
+ ds.send(:_to_dot, a, "", 0, ds, 0)
7
+ a[2..-1]
8
+ end
9
+
10
+ before do
11
+ @db = MODEL_DB
12
+ @ds = @db.dataset
13
+ end
14
+
15
+ it "should output a string suitable for input to the graphviz dot program" do
16
+ @ds.to_dot.should == (<<END
17
+ digraph G {
18
+ 0 [label="self"];
19
+ 0 -> 1 [label=""];
20
+ 1 [label="Dataset"];
21
+ }
22
+ END
23
+ ).strip
24
+ end
25
+
26
+ it "should handle an empty dataset" do
27
+ dot(@ds).should == []
28
+ end
29
+
30
+ it "should handle WITH" do
31
+ a = dot(@ds.with(:a, @ds))
32
+ a[0..3].should == ["1 -> 2 [label=\"with\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"Hash\"];"]
33
+ [["3 -> 4 [label=\"dataset\"];", "4 [label=\"Dataset\"];", "3 -> 5 [label=\"name\"];", "5 [label=\":a\"];"],
34
+ ["3 -> 4 [label=\"name\"];", "4 [label=\":a\"];", "3 -> 5 [label=\"dataset\"];", "5 [label=\"Dataset\"];"]].should include(a[4..-1])
35
+ end
36
+
37
+ it "should handle DISTINCT" do
38
+ dot(@ds.distinct).should == ["1 -> 2 [label=\"distinct\"];", "2 [label=\"Array\"];"]
39
+ end
40
+
41
+ it "should handle FROM" do
42
+ dot(@ds.from(:a)).should == ["1 -> 2 [label=\"from\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\":a\"];"]
43
+ end
44
+
45
+ it "should handle JOIN" do
46
+ dot(@ds.join(:a)).should == ["1 -> 2 [label=\"join\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"INNER JOIN\"];", "3 -> 4 [label=\"table\"];", "4 [label=\":a\"];"]
47
+ end
48
+
49
+ it "should handle WHERE" do
50
+ dot(@ds.filter(true)).should == ["1 -> 2 [label=\"where\"];", "2 [label=\"ComplexExpression: NOOP\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"true\"];"]
51
+ end
52
+
53
+ it "should handle GROUP" do
54
+ dot(@ds.group(:a)).should == ["1 -> 2 [label=\"group\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\":a\"];"]
55
+ end
56
+
57
+ it "should handle HAVING" do
58
+ dot(@ds.having(:a)).should == ["1 -> 2 [label=\"having\"];", "2 [label=\":a\"];"]
59
+ end
60
+
61
+ it "should handle UNION" do
62
+ dot(@ds.union(@ds)).should == ["1 -> 2 [label=\"from\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"AliasedExpression\"];", "3 -> 4 [label=\"expression\"];", "4 [label=\"Dataset\"];", "4 -> 5 [label=\"compounds\"];", "5 [label=\"Array\"];", "5 -> 6 [label=\"0\"];", "6 [label=\"Array\"];", "6 -> 7 [label=\"0\"];", "7 [label=\":union\"];", "6 -> 8 [label=\"1\"];", "8 [label=\"Dataset\"];", "6 -> 9 [label=\"2\"];", "9 [label=\"nil\"];", "3 -> 10 [label=\"alias\"];", "10 [label=\":t1\"];"]
63
+ end
64
+
65
+ it "should handle INTERSECT" do
66
+ dot(@ds.intersect(@ds)).should == ["1 -> 2 [label=\"from\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"AliasedExpression\"];", "3 -> 4 [label=\"expression\"];", "4 [label=\"Dataset\"];", "4 -> 5 [label=\"compounds\"];", "5 [label=\"Array\"];", "5 -> 6 [label=\"0\"];", "6 [label=\"Array\"];", "6 -> 7 [label=\"0\"];", "7 [label=\":intersect\"];", "6 -> 8 [label=\"1\"];", "8 [label=\"Dataset\"];", "6 -> 9 [label=\"2\"];", "9 [label=\"nil\"];", "3 -> 10 [label=\"alias\"];", "10 [label=\":t1\"];"]
67
+ end
68
+
69
+ it "should handle EXCEPT" do
70
+ dot(@ds.except(@ds)).should == ["1 -> 2 [label=\"from\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"AliasedExpression\"];", "3 -> 4 [label=\"expression\"];", "4 [label=\"Dataset\"];", "4 -> 5 [label=\"compounds\"];", "5 [label=\"Array\"];", "5 -> 6 [label=\"0\"];", "6 [label=\"Array\"];", "6 -> 7 [label=\"0\"];", "7 [label=\":except\"];", "6 -> 8 [label=\"1\"];", "8 [label=\"Dataset\"];", "6 -> 9 [label=\"2\"];", "9 [label=\"nil\"];", "3 -> 10 [label=\"alias\"];", "10 [label=\":t1\"];"]
71
+ end
72
+
73
+ it "should handle ORDER" do
74
+ dot(@ds.order(:a)).should == ["1 -> 2 [label=\"order\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\":a\"];"]
75
+ end
76
+
77
+ it "should handle LIMIT and OFFSET" do
78
+ dot(@ds.limit(1, 2)).should == ["1 -> 2 [label=\"limit\"];", "2 [label=\"1\"];", "1 -> 3 [label=\"offset\"];", "3 [label=\"2\"];"]
79
+ end
80
+
81
+ it "should handle FOR UPDATE" do
82
+ dot(@ds.for_update).should == ["1 -> 2 [label=\"lock\"];", "2 [label=\":update\"];"]
83
+ end
84
+
85
+ it "should handle LiteralStrings" do
86
+ dot(@ds.filter('a')).should == ["1 -> 2 [label=\"where\"];", "2 [label=\"\\\"(a)\\\".lit\"];"]
87
+ end
88
+
89
+ it "should handle true, false, nil" do
90
+ dot(@ds.select(true, false, nil)).should == ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"true\"];", "2 -> 4 [label=\"1\"];", "4 [label=\"false\"];", "2 -> 5 [label=\"2\"];", "5 [label=\"nil\"];"]
91
+ end
92
+
93
+ it "should handle SQL::ComplexExpressions" do
94
+ dot(@ds.filter(:a=>:b)).should == ["1 -> 2 [label=\"where\"];", "2 [label=\"ComplexExpression: =\"];", "2 -> 3 [label=\"0\"];", "3 [label=\":a\"];", "2 -> 4 [label=\"1\"];", "4 [label=\":b\"];"]
95
+ end
96
+
97
+ it "should handle SQL::Identifiers" do
98
+ dot(@ds.select{a}).should == ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"Identifier\"];", "3 -> 4 [label=\"value\"];", "4 [label=\":a\"];"]
99
+ end
100
+
101
+ it "should handle SQL::QualifiedIdentifiers" do
102
+ dot(@ds.select{a__b}).should == ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"QualifiedIdentifier\"];", "3 -> 4 [label=\"table\"];", "4 [label=\"\\\"a\\\"\"];", "3 -> 5 [label=\"column\"];", "5 [label=\"\\\"b\\\"\"];"]
103
+ end
104
+
105
+ it "should handle SQL::OrderedExpressions" do
106
+ dot(@ds.order(:a.desc(:nulls=>:last))).should == ["1 -> 2 [label=\"order\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"OrderedExpression: DESC NULLS LAST\"];", "3 -> 4 [label=\"expression\"];", "4 [label=\":a\"];"]
107
+ end
108
+
109
+ it "should handle SQL::AliasedExpressions" do
110
+ dot(@ds.from(:a.as(:b))).should == ["1 -> 2 [label=\"from\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"AliasedExpression\"];", "3 -> 4 [label=\"expression\"];", "4 [label=\":a\"];", "3 -> 5 [label=\"alias\"];", "5 [label=\":b\"];"]
111
+ end
112
+
113
+ it "should handle SQL::CaseExpressions" do
114
+ dot(@ds.select({:a=>:b}.case(:c, :d))).should == ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"CaseExpression\"];", "3 -> 4 [label=\"expression\"];", "4 [label=\":d\"];", "3 -> 5 [label=\"conditions\"];", "5 [label=\"Array\"];", "5 -> 6 [label=\"0\"];", "6 [label=\"Array\"];", "6 -> 7 [label=\"0\"];", "7 [label=\":a\"];", "6 -> 8 [label=\"1\"];", "8 [label=\":b\"];", "3 -> 9 [label=\"default\"];", "9 [label=\":c\"];"]
115
+ end
116
+
117
+ it "should handle SQL::Cast" do
118
+ dot(@ds.select(:a.cast(Integer))).should == ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"Cast\"];", "3 -> 4 [label=\"expr\"];", "4 [label=\":a\"];", "3 -> 5 [label=\"type\"];", "5 [label=\"Integer\"];"]
119
+ end
120
+
121
+ it "should handle SQL::Function" do
122
+ dot(@ds.select{a(b)}).should == ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"Function: a\"];", "3 -> 4 [label=\"0\"];", "4 [label=\"Identifier\"];", "4 -> 5 [label=\"value\"];", "5 [label=\":b\"];"]
123
+ end
124
+
125
+ it "should handle SQL::Subscript" do
126
+ dot(@ds.select(:a.sql_subscript(1))).should == ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"Subscript: a\"];", "3 -> 4 [label=\"f\"];", "4 [label=\":a\"];", "3 -> 5 [label=\"sub\"];", "5 [label=\"Array\"];", "5 -> 6 [label=\"0\"];", "6 [label=\"1\"];"]
127
+ end
128
+
129
+ it "should handle SQL::WindowFunction" do
130
+ dot(@ds.select{sum(:over, :partition=>(:a)){}}).should == ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"WindowFunction\"];", "3 -> 4 [label=\"function\"];", "4 [label=\"Function: sum\"];", "3 -> 5 [label=\"window\"];", "5 [label=\"Window\"];", "5 -> 6 [label=\"opts\"];", "6 [label=\"Hash\"];", "6 -> 7 [label=\"partition\"];", "7 [label=\":a\"];"]
131
+ end
132
+
133
+ it "should handle SQL::PlaceholderLiteralString" do
134
+ dot(@ds.where("?", true)).should == ["1 -> 2 [label=\"where\"];", "2 [label=\"PlaceholderLiteralString: \\\"(?)\\\"\"];", "2 -> 3 [label=\"args\"];", "3 [label=\"Array\"];", "3 -> 4 [label=\"0\"];", "4 [label=\"true\"];"]
135
+ end
136
+
137
+ it "should handle JOIN ON" do
138
+ dot(@ds.from(:a).join(:d, :b=>:c)).should == ["1 -> 2 [label=\"from\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\":a\"];", "1 -> 4 [label=\"join\"];", "4 [label=\"Array\"];", "4 -> 5 [label=\"0\"];", "5 [label=\"INNER JOIN ON\"];", "5 -> 6 [label=\"table\"];", "6 [label=\":d\"];", "5 -> 7 [label=\"on\"];", "7 [label=\"Array\"];", "7 -> 8 [label=\"0\"];", "8 [label=\"Array\"];", "8 -> 9 [label=\"0\"];", "9 [label=\"QualifiedIdentifier\"];", "9 -> 10 [label=\"table\"];", "10 [label=\"\\\"d\\\"\"];", "9 -> 11 [label=\"column\"];", "11 [label=\"\\\"b\\\"\"];", "8 -> 12 [label=\"1\"];", "12 [label=\"QualifiedIdentifier\"];", "12 -> 13 [label=\"table\"];", "13 [label=\"\\\"a\\\"\"];", "12 -> 14 [label=\"column\"];", "14 [label=\"\\\"c\\\"\"];"]
139
+ end
140
+
141
+ it "should handle JOIN USING" do
142
+ dot(@ds.from(:a).join(:d, [:c], :table_alias=>:c)).should == ["1 -> 2 [label=\"from\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\":a\"];", "1 -> 4 [label=\"join\"];", "4 [label=\"Array\"];", "4 -> 5 [label=\"0\"];", "5 [label=\"INNER JOIN USING\"];", "5 -> 6 [label=\"table\"];", "6 [label=\":d\"];", "5 -> 7 [label=\"alias\"];", "7 [label=\":c\"];", "5 -> 8 [label=\"using\"];", "8 [label=\"Array\"];", "8 -> 9 [label=\"0\"];", "9 [label=\":c\"];"]
143
+ end
144
+
145
+ it "should handle other types" do
146
+ o = Object.new
147
+ def o.inspect
148
+ "blah"
149
+ end
150
+ dot(@ds.select(o)).should == ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"Unhandled: blah\"];"]
151
+ end
152
+ end
@@ -0,0 +1,5 @@
1
+ Sequel.migration do
2
+ change do
3
+ create_table(:a){Integer :a}
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ Sequel.migration do
2
+ change do
3
+ add_column :a, :b, String
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ Sequel.migration do
2
+ change do
3
+ rename_column :a, :b, :c
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ Sequel.migration do
2
+ change do
3
+ rename_table :a, :b
4
+ end
5
+ end
@@ -0,0 +1,10 @@
1
+ Sequel.migration do
2
+ change do
3
+ alter_table(:b) do
4
+ add_column :d, String
5
+ end
6
+ alter_table(:b) do
7
+ rename_column :d, :e
8
+ end
9
+ end
10
+ end
@@ -184,4 +184,58 @@ describe Sequel::Migrator do
184
184
  [:schema_info, :sm1111, :sm2222, :schema_migrations, :sm3333, :sm1122, :sm2233].each{|n| @db.table_exists?(n).should be_true}
185
185
  @db[:schema_migrations].select_order_map(:filename).should == %w'001_create_sessions.rb 002_create_nodes.rb 003_3_create_users.rb 1273253850_create_artists.rb 1273253852_create_albums.rb'
186
186
  end
187
+
188
+ specify "should handle reversible migrations" do
189
+ @dir = 'spec/files/reversible_migrations'
190
+ @db.drop_table(:a) rescue nil
191
+ @db.drop_table(:b) rescue nil
192
+ @m.apply(@db, @dir, 1)
193
+ [:schema_info, :a].each{|n| @db.table_exists?(n).should be_true}
194
+ [:schema_migrations, :b].each{|n| @db.table_exists?(n).should be_false}
195
+ @db[:a].columns.should == [:a]
196
+
197
+ @m.apply(@db, @dir, 2)
198
+ [:schema_info, :a].each{|n| @db.table_exists?(n).should be_true}
199
+ [:schema_migrations, :b].each{|n| @db.table_exists?(n).should be_false}
200
+ @db[:a].columns.should == [:a, :b]
201
+
202
+ @m.apply(@db, @dir, 3)
203
+ [:schema_info, :a].each{|n| @db.table_exists?(n).should be_true}
204
+ [:schema_migrations, :b].each{|n| @db.table_exists?(n).should be_false}
205
+ @db[:a].columns.should == [:a, :c]
206
+
207
+ @m.apply(@db, @dir, 4)
208
+ [:schema_info, :b].each{|n| @db.table_exists?(n).should be_true}
209
+ [:schema_migrations, :a].each{|n| @db.table_exists?(n).should be_false}
210
+ @db[:b].columns.should == [:a, :c]
211
+
212
+ @m.apply(@db, @dir, 5)
213
+ [:schema_info, :b].each{|n| @db.table_exists?(n).should be_true}
214
+ [:schema_migrations, :a].each{|n| @db.table_exists?(n).should be_false}
215
+ @db[:b].columns.should == [:a, :c, :e]
216
+
217
+ @m.apply(@db, @dir, 4)
218
+ [:schema_info, :b].each{|n| @db.table_exists?(n).should be_true}
219
+ [:schema_migrations, :a].each{|n| @db.table_exists?(n).should be_false}
220
+ @db[:b].columns.should == [:a, :c]
221
+
222
+ @m.apply(@db, @dir, 3)
223
+ [:schema_info, :a].each{|n| @db.table_exists?(n).should be_true}
224
+ [:schema_migrations, :b].each{|n| @db.table_exists?(n).should be_false}
225
+ @db[:a].columns.should == [:a, :c]
226
+
227
+ @m.apply(@db, @dir, 2)
228
+ [:schema_info, :a].each{|n| @db.table_exists?(n).should be_true}
229
+ [:schema_migrations, :b].each{|n| @db.table_exists?(n).should be_false}
230
+ @db[:a].columns.should == [:a, :b]
231
+
232
+ @m.apply(@db, @dir, 1)
233
+ [:schema_info, :a].each{|n| @db.table_exists?(n).should be_true}
234
+ [:schema_migrations, :b].each{|n| @db.table_exists?(n).should be_false}
235
+ @db[:a].columns.should == [:a]
236
+
237
+ @m.apply(@db, @dir, 0)
238
+ [:schema_info].each{|n| @db.table_exists?(n).should be_true}
239
+ [:schema_migrations, :a, :b].each{|n| @db.table_exists?(n).should be_false}
240
+ end
187
241
  end
@@ -173,3 +173,22 @@ describe Sequel::Model::Associations::AssociationReflection, "#associated_object
173
173
  end
174
174
  end
175
175
 
176
+ describe Sequel::Model::Associations::AssociationReflection, "#remove_before_destroy?" do
177
+ before do
178
+ @c = Class.new(Sequel::Model)
179
+ end
180
+
181
+ it "should be true for many_to_one and many_to_many associations" do
182
+ @c.many_to_one :c, :class=>@c
183
+ @c.association_reflection(:c).remove_before_destroy?.should be_true
184
+ @c.many_to_many :cs, :class=>@c
185
+ @c.association_reflection(:cs).remove_before_destroy?.should be_true
186
+ end
187
+ it "should be false for one_to_one and one_to_many associations" do
188
+ @c.one_to_one :c, :class=>@c
189
+ @c.association_reflection(:c).remove_before_destroy?.should be_false
190
+ @c.one_to_many :cs, :class=>@c
191
+ @c.association_reflection(:cs).remove_before_destroy?.should be_false
192
+ end
193
+ end
194
+
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel
3
3
  version: !ruby/object:Gem::Version
4
- hash: 67
4
+ hash: 79
5
5
  prerelease: false
6
6
  segments:
7
7
  - 3
8
- - 17
8
+ - 18
9
9
  - 0
10
- version: 3.17.0
10
+ version: 3.18.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jeremy Evans
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-11-05 00:00:00 -07:00
18
+ date: 2010-12-01 00:00:00 -08:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
@@ -81,6 +81,7 @@ extra_rdoc_files:
81
81
  - doc/release_notes/3.15.0.txt
82
82
  - doc/release_notes/3.16.0.txt
83
83
  - doc/release_notes/3.17.0.txt
84
+ - doc/release_notes/3.18.0.txt
84
85
  files:
85
86
  - COPYING
86
87
  - CHANGELOG
@@ -129,6 +130,7 @@ files:
129
130
  - doc/release_notes/3.15.0.txt
130
131
  - doc/release_notes/3.16.0.txt
131
132
  - doc/release_notes/3.17.0.txt
133
+ - doc/release_notes/3.18.0.txt
132
134
  - doc/sharding.rdoc
133
135
  - doc/sql.rdoc
134
136
  - doc/virtual_rows.rdoc
@@ -206,6 +208,7 @@ files:
206
208
  - spec/extensions/list_spec.rb
207
209
  - spec/extensions/tree_spec.rb
208
210
  - spec/extensions/xml_serializer_spec.rb
211
+ - spec/extensions/to_dot_spec.rb
209
212
  - spec/integration/associations_test.rb
210
213
  - spec/integration/database_test.rb
211
214
  - spec/integration/dataset_test.rb
@@ -269,6 +272,11 @@ files:
269
272
  - spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB
270
273
  - spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB
271
274
  - spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB
275
+ - spec/files/reversible_migrations/001_reversible.rb
276
+ - spec/files/reversible_migrations/002_reversible.rb
277
+ - spec/files/reversible_migrations/003_reversible.rb
278
+ - spec/files/reversible_migrations/004_reversible.rb
279
+ - spec/files/reversible_migrations/005_reversible.rb
272
280
  - lib/sequel.rb
273
281
  - lib/sequel/adapters/ado.rb
274
282
  - lib/sequel/adapters/ado/mssql.rb
@@ -345,6 +353,7 @@ files:
345
353
  - lib/sequel/extensions/sql_expr.rb
346
354
  - lib/sequel/extensions/string_date_time.rb
347
355
  - lib/sequel/extensions/thread_local_timezones.rb
356
+ - lib/sequel/extensions/to_dot.rb
348
357
  - lib/sequel/metaprogramming.rb
349
358
  - lib/sequel/model.rb
350
359
  - lib/sequel/model/associations.rb