sequel 3.47.0 → 3.48.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (243) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +230 -0
  3. data/README.rdoc +31 -40
  4. data/Rakefile +1 -14
  5. data/doc/active_record.rdoc +29 -29
  6. data/doc/association_basics.rdoc +4 -13
  7. data/doc/cheat_sheet.rdoc +8 -6
  8. data/doc/code_order.rdoc +89 -0
  9. data/doc/core_extensions.rdoc +3 -3
  10. data/doc/dataset_basics.rdoc +7 -8
  11. data/doc/dataset_filtering.rdoc +7 -2
  12. data/doc/mass_assignment.rdoc +2 -3
  13. data/doc/migration.rdoc +8 -8
  14. data/doc/model_hooks.rdoc +11 -7
  15. data/doc/object_model.rdoc +2 -2
  16. data/doc/opening_databases.rdoc +5 -14
  17. data/doc/prepared_statements.rdoc +5 -9
  18. data/doc/querying.rdoc +23 -28
  19. data/doc/reflection.rdoc +11 -0
  20. data/doc/release_notes/3.48.0.txt +477 -0
  21. data/doc/schema_modification.rdoc +12 -5
  22. data/doc/security.rdoc +2 -2
  23. data/doc/sharding.rdoc +1 -2
  24. data/doc/sql.rdoc +10 -13
  25. data/doc/testing.rdoc +8 -4
  26. data/doc/transactions.rdoc +2 -2
  27. data/doc/validations.rdoc +40 -17
  28. data/doc/virtual_rows.rdoc +2 -2
  29. data/lib/sequel/adapters/ado.rb +25 -20
  30. data/lib/sequel/adapters/ado/access.rb +1 -0
  31. data/lib/sequel/adapters/ado/mssql.rb +1 -0
  32. data/lib/sequel/adapters/db2.rb +9 -7
  33. data/lib/sequel/adapters/dbi.rb +16 -16
  34. data/lib/sequel/adapters/do.rb +17 -18
  35. data/lib/sequel/adapters/do/mysql.rb +1 -0
  36. data/lib/sequel/adapters/do/postgres.rb +2 -0
  37. data/lib/sequel/adapters/do/sqlite.rb +1 -0
  38. data/lib/sequel/adapters/firebird.rb +5 -7
  39. data/lib/sequel/adapters/ibmdb.rb +23 -20
  40. data/lib/sequel/adapters/informix.rb +8 -2
  41. data/lib/sequel/adapters/jdbc.rb +39 -35
  42. data/lib/sequel/adapters/jdbc/as400.rb +1 -0
  43. data/lib/sequel/adapters/jdbc/cubrid.rb +1 -0
  44. data/lib/sequel/adapters/jdbc/db2.rb +1 -0
  45. data/lib/sequel/adapters/jdbc/derby.rb +1 -0
  46. data/lib/sequel/adapters/jdbc/firebird.rb +1 -0
  47. data/lib/sequel/adapters/jdbc/h2.rb +1 -0
  48. data/lib/sequel/adapters/jdbc/hsqldb.rb +1 -0
  49. data/lib/sequel/adapters/jdbc/informix.rb +1 -0
  50. data/lib/sequel/adapters/jdbc/jtds.rb +1 -0
  51. data/lib/sequel/adapters/jdbc/mssql.rb +1 -0
  52. data/lib/sequel/adapters/jdbc/mysql.rb +1 -0
  53. data/lib/sequel/adapters/jdbc/oracle.rb +1 -0
  54. data/lib/sequel/adapters/jdbc/postgresql.rb +2 -0
  55. data/lib/sequel/adapters/jdbc/progress.rb +1 -0
  56. data/lib/sequel/adapters/jdbc/sqlite.rb +1 -0
  57. data/lib/sequel/adapters/jdbc/sqlserver.rb +1 -0
  58. data/lib/sequel/adapters/mock.rb +30 -31
  59. data/lib/sequel/adapters/mysql.rb +6 -7
  60. data/lib/sequel/adapters/mysql2.rb +5 -6
  61. data/lib/sequel/adapters/odbc.rb +22 -20
  62. data/lib/sequel/adapters/odbc/mssql.rb +1 -0
  63. data/lib/sequel/adapters/openbase.rb +4 -1
  64. data/lib/sequel/adapters/oracle.rb +10 -8
  65. data/lib/sequel/adapters/postgres.rb +12 -10
  66. data/lib/sequel/adapters/shared/access.rb +6 -0
  67. data/lib/sequel/adapters/shared/cubrid.rb +2 -0
  68. data/lib/sequel/adapters/shared/db2.rb +2 -0
  69. data/lib/sequel/adapters/shared/firebird.rb +2 -0
  70. data/lib/sequel/adapters/shared/informix.rb +2 -0
  71. data/lib/sequel/adapters/shared/mssql.rb +14 -8
  72. data/lib/sequel/adapters/shared/mysql.rb +6 -0
  73. data/lib/sequel/adapters/shared/oracle.rb +2 -0
  74. data/lib/sequel/adapters/shared/postgres.rb +14 -4
  75. data/lib/sequel/adapters/shared/progress.rb +1 -0
  76. data/lib/sequel/adapters/shared/sqlite.rb +4 -3
  77. data/lib/sequel/adapters/sqlite.rb +6 -7
  78. data/lib/sequel/adapters/swift.rb +20 -21
  79. data/lib/sequel/adapters/swift/mysql.rb +1 -0
  80. data/lib/sequel/adapters/swift/postgres.rb +2 -0
  81. data/lib/sequel/adapters/swift/sqlite.rb +1 -0
  82. data/lib/sequel/adapters/tinytds.rb +5 -6
  83. data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +68 -0
  84. data/lib/sequel/connection_pool.rb +1 -1
  85. data/lib/sequel/core.rb +57 -50
  86. data/lib/sequel/database/connecting.rb +9 -10
  87. data/lib/sequel/database/dataset.rb +11 -6
  88. data/lib/sequel/database/dataset_defaults.rb +61 -69
  89. data/lib/sequel/database/features.rb +21 -0
  90. data/lib/sequel/database/misc.rb +23 -3
  91. data/lib/sequel/database/query.rb +13 -7
  92. data/lib/sequel/database/schema_methods.rb +6 -6
  93. data/lib/sequel/database/transactions.rb +1 -0
  94. data/lib/sequel/dataset/actions.rb +51 -38
  95. data/lib/sequel/dataset/features.rb +1 -0
  96. data/lib/sequel/dataset/graph.rb +9 -33
  97. data/lib/sequel/dataset/misc.rb +30 -5
  98. data/lib/sequel/dataset/mutation.rb +2 -3
  99. data/lib/sequel/dataset/prepared_statements.rb +1 -1
  100. data/lib/sequel/dataset/query.rb +91 -27
  101. data/lib/sequel/dataset/sql.rb +40 -6
  102. data/lib/sequel/deprecated.rb +74 -0
  103. data/lib/sequel/deprecated_core_extensions.rb +135 -0
  104. data/lib/sequel/extensions/columns_introspection.rb +1 -5
  105. data/lib/sequel/extensions/core_extensions.rb +10 -3
  106. data/lib/sequel/extensions/date_arithmetic.rb +1 -0
  107. data/lib/sequel/extensions/empty_array_ignore_nulls.rb +33 -0
  108. data/lib/sequel/extensions/filter_having.rb +58 -0
  109. data/lib/sequel/extensions/graph_each.rb +63 -0
  110. data/lib/sequel/extensions/hash_aliases.rb +44 -0
  111. data/lib/sequel/extensions/looser_typecasting.rb +14 -3
  112. data/lib/sequel/extensions/migration.rb +2 -3
  113. data/lib/sequel/extensions/named_timezones.rb +14 -1
  114. data/lib/sequel/extensions/null_dataset.rb +7 -1
  115. data/lib/sequel/extensions/pagination.rb +15 -5
  116. data/lib/sequel/extensions/pg_auto_parameterize.rb +1 -0
  117. data/lib/sequel/extensions/pg_hstore_ops.rb +48 -14
  118. data/lib/sequel/extensions/pg_json.rb +7 -7
  119. data/lib/sequel/extensions/pg_range_ops.rb +8 -2
  120. data/lib/sequel/extensions/pg_statement_cache.rb +1 -0
  121. data/lib/sequel/extensions/pretty_table.rb +13 -4
  122. data/lib/sequel/extensions/query.rb +21 -4
  123. data/lib/sequel/extensions/ruby18_symbol_extensions.rb +22 -0
  124. data/lib/sequel/extensions/schema_caching.rb +10 -7
  125. data/lib/sequel/extensions/schema_dumper.rb +35 -48
  126. data/lib/sequel/extensions/select_remove.rb +13 -4
  127. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +117 -0
  128. data/lib/sequel/extensions/set_overrides.rb +43 -0
  129. data/lib/sequel/extensions/to_dot.rb +6 -0
  130. data/lib/sequel/model.rb +12 -6
  131. data/lib/sequel/model/associations.rb +80 -38
  132. data/lib/sequel/model/base.rb +137 -52
  133. data/lib/sequel/model/errors.rb +7 -2
  134. data/lib/sequel/plugins/active_model.rb +13 -0
  135. data/lib/sequel/plugins/after_initialize.rb +43 -0
  136. data/lib/sequel/plugins/association_proxies.rb +63 -7
  137. data/lib/sequel/plugins/auto_validations.rb +56 -16
  138. data/lib/sequel/plugins/blacklist_security.rb +63 -0
  139. data/lib/sequel/plugins/class_table_inheritance.rb +9 -0
  140. data/lib/sequel/plugins/constraint_validations.rb +50 -8
  141. data/lib/sequel/plugins/dataset_associations.rb +2 -0
  142. data/lib/sequel/plugins/hook_class_methods.rb +7 -1
  143. data/lib/sequel/plugins/identity_map.rb +4 -0
  144. data/lib/sequel/plugins/json_serializer.rb +32 -13
  145. data/lib/sequel/plugins/optimistic_locking.rb +1 -1
  146. data/lib/sequel/plugins/rcte_tree.rb +4 -4
  147. data/lib/sequel/plugins/scissors.rb +33 -0
  148. data/lib/sequel/plugins/serialization.rb +1 -1
  149. data/lib/sequel/plugins/single_table_inheritance.rb +6 -0
  150. data/lib/sequel/plugins/tree.rb +5 -1
  151. data/lib/sequel/plugins/validation_class_methods.rb +2 -1
  152. data/lib/sequel/plugins/validation_helpers.rb +15 -11
  153. data/lib/sequel/plugins/xml_serializer.rb +12 -3
  154. data/lib/sequel/sql.rb +12 -2
  155. data/lib/sequel/timezones.rb +1 -1
  156. data/lib/sequel/version.rb +1 -1
  157. data/lib/sequel_core.rb +1 -0
  158. data/lib/sequel_model.rb +1 -0
  159. data/spec/adapters/mssql_spec.rb +24 -57
  160. data/spec/adapters/postgres_spec.rb +27 -55
  161. data/spec/adapters/spec_helper.rb +1 -1
  162. data/spec/adapters/sqlite_spec.rb +1 -1
  163. data/spec/bin_spec.rb +251 -0
  164. data/spec/core/database_spec.rb +46 -32
  165. data/spec/core/dataset_spec.rb +233 -181
  166. data/spec/core/deprecated_spec.rb +78 -0
  167. data/spec/core/expression_filters_spec.rb +3 -4
  168. data/spec/core/mock_adapter_spec.rb +9 -9
  169. data/spec/core/object_graph_spec.rb +9 -19
  170. data/spec/core/schema_spec.rb +3 -1
  171. data/spec/core/spec_helper.rb +19 -0
  172. data/spec/core_extensions_spec.rb +80 -30
  173. data/spec/extensions/after_initialize_spec.rb +24 -0
  174. data/spec/extensions/association_proxies_spec.rb +37 -1
  175. data/spec/extensions/auto_validations_spec.rb +20 -4
  176. data/spec/extensions/blacklist_security_spec.rb +87 -0
  177. data/spec/extensions/boolean_readers_spec.rb +2 -1
  178. data/spec/extensions/class_table_inheritance_spec.rb +7 -0
  179. data/spec/extensions/columns_introspection_spec.rb +3 -3
  180. data/spec/extensions/constraint_validations_plugin_spec.rb +83 -5
  181. data/spec/extensions/core_refinements_spec.rb +7 -7
  182. data/spec/extensions/dataset_associations_spec.rb +2 -2
  183. data/spec/extensions/date_arithmetic_spec.rb +1 -1
  184. data/spec/extensions/defaults_setter_spec.rb +2 -1
  185. data/spec/extensions/empty_array_ignore_nulls_spec.rb +24 -0
  186. data/spec/extensions/filter_having_spec.rb +40 -0
  187. data/spec/extensions/graph_each_spec.rb +109 -0
  188. data/spec/extensions/hash_aliases_spec.rb +16 -0
  189. data/spec/extensions/hook_class_methods_spec.rb +2 -2
  190. data/spec/extensions/identity_map_spec.rb +3 -3
  191. data/spec/extensions/json_serializer_spec.rb +19 -19
  192. data/spec/extensions/lazy_attributes_spec.rb +1 -0
  193. data/spec/extensions/list_spec.rb +13 -13
  194. data/spec/extensions/looser_typecasting_spec.rb +10 -3
  195. data/spec/extensions/many_through_many_spec.rb +1 -1
  196. data/spec/extensions/migration_spec.rb +7 -7
  197. data/spec/extensions/named_timezones_spec.rb +6 -0
  198. data/spec/extensions/nested_attributes_spec.rb +2 -2
  199. data/spec/extensions/null_dataset_spec.rb +1 -1
  200. data/spec/extensions/pagination_spec.rb +2 -2
  201. data/spec/extensions/pg_hstore_ops_spec.rb +75 -0
  202. data/spec/extensions/pg_range_ops_spec.rb +4 -2
  203. data/spec/extensions/pg_row_plugin_spec.rb +1 -1
  204. data/spec/extensions/pretty_table_spec.rb +1 -1
  205. data/spec/extensions/query_literals_spec.rb +1 -1
  206. data/spec/extensions/query_spec.rb +3 -3
  207. data/spec/extensions/schema_caching_spec.rb +3 -3
  208. data/spec/extensions/schema_dumper_spec.rb +27 -2
  209. data/spec/extensions/schema_spec.rb +2 -2
  210. data/spec/extensions/scissors_spec.rb +26 -0
  211. data/spec/extensions/select_remove_spec.rb +1 -1
  212. data/spec/extensions/sequel_3_dataset_methods_spec.rb +102 -0
  213. data/spec/extensions/set_overrides_spec.rb +45 -0
  214. data/spec/extensions/single_table_inheritance_spec.rb +10 -0
  215. data/spec/extensions/spec_helper.rb +24 -1
  216. data/spec/extensions/static_cache_spec.rb +1 -1
  217. data/spec/extensions/string_stripper_spec.rb +2 -1
  218. data/spec/extensions/to_dot_spec.rb +1 -1
  219. data/spec/extensions/typecast_on_load_spec.rb +3 -2
  220. data/spec/extensions/update_primary_key_spec.rb +2 -2
  221. data/spec/extensions/validation_class_methods_spec.rb +19 -19
  222. data/spec/extensions/validation_helpers_spec.rb +30 -21
  223. data/spec/extensions/xml_serializer_spec.rb +5 -5
  224. data/spec/integration/associations_test.rb +10 -30
  225. data/spec/integration/dataset_test.rb +20 -24
  226. data/spec/integration/eager_loader_test.rb +5 -5
  227. data/spec/integration/model_test.rb +3 -3
  228. data/spec/integration/plugin_test.rb +7 -39
  229. data/spec/integration/schema_test.rb +4 -38
  230. data/spec/integration/spec_helper.rb +2 -1
  231. data/spec/model/association_reflection_spec.rb +70 -5
  232. data/spec/model/associations_spec.rb +11 -11
  233. data/spec/model/base_spec.rb +25 -8
  234. data/spec/model/class_dataset_methods_spec.rb +143 -0
  235. data/spec/model/dataset_methods_spec.rb +1 -1
  236. data/spec/model/eager_loading_spec.rb +25 -25
  237. data/spec/model/hooks_spec.rb +1 -1
  238. data/spec/model/model_spec.rb +22 -7
  239. data/spec/model/plugins_spec.rb +1 -6
  240. data/spec/model/record_spec.rb +37 -29
  241. data/spec/model/spec_helper.rb +23 -1
  242. data/spec/model/validations_spec.rb +15 -17
  243. metadata +32 -3
@@ -2,7 +2,7 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe "schema_caching extension" do
4
4
  before do
5
- @db = Sequel.mock
5
+ @db = Sequel.mock.extension(:schema_caching)
6
6
  @schemas = {'"table"'=>[[:column, {:db_type=>"integer", :default=>"nextval('table_id_seq'::regclass)", :allow_null=>false, :primary_key=>true, :type=>:integer, :ruby_default=>nil}]]}
7
7
  @filename = "spec/files/test_schema_#$$.dump"
8
8
  @db.instance_variable_set(:@schemas, @schemas)
@@ -20,7 +20,7 @@ describe "schema_caching extension" do
20
20
 
21
21
  it "Database#load_schema_cache should load cached schema from the given file dumped by #dump_schema_cache" do
22
22
  @db.dump_schema_cache(@filename)
23
- db = Sequel::Database.new
23
+ db = Sequel::Database.new.extension(:schema_caching)
24
24
  db.load_schema_cache(@filename)
25
25
  @db.instance_variable_get(:@schemas).should == @schemas
26
26
  end
@@ -33,7 +33,7 @@ describe "schema_caching extension" do
33
33
  end
34
34
 
35
35
  it "Database#load_schema_cache? should load cached schema from the given file if it exists" do
36
- db = Sequel::Database.new
36
+ db = Sequel::Database.new.extension(:schema_caching)
37
37
  File.exist?(@filename).should be_false
38
38
  db.load_schema_cache?(@filename)
39
39
  db.instance_variable_get(:@schemas).should == {}
@@ -3,7 +3,7 @@ require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper')
3
3
 
4
4
  describe "Sequel::Schema::Generator dump methods" do
5
5
  before do
6
- @d = Sequel::Database.new
6
+ @d = Sequel::Database.new.extension(:schema_dumper)
7
7
  @g = Sequel::Schema::Generator
8
8
  end
9
9
 
@@ -64,7 +64,7 @@ end
64
64
 
65
65
  describe "Sequel::Database dump methods" do
66
66
  before do
67
- @d = Sequel::Database.new
67
+ @d = Sequel::Database.new.extension(:schema_dumper)
68
68
  @d.meta_def(:tables){|o| [:t1, :t2]}
69
69
  @d.meta_def(:schema) do |t, *o|
70
70
  case t
@@ -99,12 +99,14 @@ describe "Sequel::Database dump methods" do
99
99
 
100
100
  it "should handle foreign keys" do
101
101
  @d.meta_def(:schema){|*s| [[:c1, {:db_type=>'integer', :allow_null=>true}]]}
102
+ @d.meta_def(:supports_foreign_key_parsing?){true}
102
103
  @d.meta_def(:foreign_key_list){|*s| [{:columns=>[:c1], :table=>:t2, :key=>[:c2]}]}
103
104
  @d.dump_table_schema(:t6).should == "create_table(:t6) do\n foreign_key :c1, :t2, :key=>[:c2]\nend"
104
105
  end
105
106
 
106
107
  it "should handle primary keys that are also foreign keys" do
107
108
  @d.meta_def(:schema){|*s| [[:c1, {:db_type=>'integer', :primary_key=>true, :allow_null=>true}]]}
109
+ @d.meta_def(:supports_foreign_key_parsing?){true}
108
110
  @d.meta_def(:foreign_key_list){|*s| [{:columns=>[:c1], :table=>:t2, :key=>[:c2]}]}
109
111
  s = @d.dump_table_schema(:t6)
110
112
  s.should =~ /create_table\(:t6\) do\n primary_key :c1, /
@@ -114,6 +116,7 @@ describe "Sequel::Database dump methods" do
114
116
 
115
117
  it "should handle foreign key options" do
116
118
  @d.meta_def(:schema){|*s| [[:c1, {:db_type=>'integer', :allow_null=>true}]]}
119
+ @d.meta_def(:supports_foreign_key_parsing?){true}
117
120
  @d.meta_def(:foreign_key_list){|*s| [{:columns=>[:c1], :table=>:t2, :key=>[:c2], :on_delete=>:restrict, :on_update=>:set_null, :deferrable=>true}]}
118
121
  s = @d.dump_table_schema(:t6)
119
122
  s.should =~ /create_table\(:t6\) do\n foreign_key :c1, :t2, /
@@ -125,6 +128,7 @@ describe "Sequel::Database dump methods" do
125
128
 
126
129
  it "should handle foreign key options in the primary key" do
127
130
  @d.meta_def(:schema){|*s| [[:c1, {:db_type=>'integer', :primary_key=>true, :allow_null=>true}]]}
131
+ @d.meta_def(:supports_foreign_key_parsing?){true}
128
132
  @d.meta_def(:foreign_key_list){|*s| [{:columns=>[:c1], :table=>:t2, :key=>[:c2], :on_delete=>:restrict, :on_update=>:set_null, :deferrable=>true}]}
129
133
  s = @d.dump_table_schema(:t6)
130
134
  s.should =~ /create_table\(:t6\) do\n primary_key :c1, /
@@ -137,6 +141,7 @@ describe "Sequel::Database dump methods" do
137
141
 
138
142
  it "should omit foreign key options that are the same as defaults" do
139
143
  @d.meta_def(:schema){|*s| [[:c1, {:db_type=>'integer', :allow_null=>true}]]}
144
+ @d.meta_def(:supports_foreign_key_parsing?){true}
140
145
  @d.meta_def(:foreign_key_list){|*s| [{:columns=>[:c1], :table=>:t2, :key=>[:c2], :on_delete=>:no_action, :on_update=>:no_action, :deferrable=>false}]}
141
146
  s = @d.dump_table_schema(:t6)
142
147
  s.should =~ /create_table\(:t6\) do\n foreign_key :c1, :t2, /
@@ -148,6 +153,7 @@ describe "Sequel::Database dump methods" do
148
153
 
149
154
  it "should omit foreign key options that are the same as defaults in the primary key" do
150
155
  @d.meta_def(:schema){|*s| [[:c1, {:db_type=>'integer', :primary_key=>true, :allow_null=>true}]]}
156
+ @d.meta_def(:supports_foreign_key_parsing?){true}
151
157
  @d.meta_def(:foreign_key_list){|*s| [{:columns=>[:c1], :table=>:t2, :key=>[:c2], :on_delete=>:no_action, :on_update=>:no_action, :deferrable=>false}]}
152
158
  s = @d.dump_table_schema(:t6)
153
159
  s.should =~ /create_table\(:t6\) do\n primary_key :c1, /
@@ -169,11 +175,13 @@ describe "Sequel::Database dump methods" do
169
175
 
170
176
  it "should use a composite foreign_key calls if there is a composite foreign key" do
171
177
  @d.meta_def(:schema){|*s| [[:c1, {:db_type=>'integer'}], [:c2, {:db_type=>'integer'}]]}
178
+ @d.meta_def(:supports_foreign_key_parsing?){true}
172
179
  @d.meta_def(:foreign_key_list){|*s| [{:columns=>[:c1, :c2], :table=>:t2, :key=>[:c3, :c4]}]}
173
180
  @d.dump_table_schema(:t1).should == "create_table(:t1) do\n Integer :c1\n Integer :c2\n \n foreign_key [:c1, :c2], :t2, :key=>[:c3, :c4]\nend"
174
181
  end
175
182
 
176
183
  it "should include index information if available" do
184
+ @d.meta_def(:supports_index_parsing?){true}
177
185
  @d.meta_def(:indexes) do |t|
178
186
  {:i1=>{:columns=>[:c1], :unique=>false},
179
187
  :t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>true}}
@@ -227,6 +235,7 @@ END_MIG
227
235
  @d.meta_def(:schema) do |t|
228
236
  t == :t1 ? [[:c2, {:db_type=>'integer'}]] : [[:c1, {:db_type=>'integer', :primary_key=>true}]]
229
237
  end
238
+ @d.meta_def(:supports_foreign_key_parsing?){true}
230
239
  @d.meta_def(:foreign_key_list) do |t|
231
240
  t == :t1 ? [{:columns=>[:c2], :table=>:t2, :key=>[:c1]}] : []
232
241
  end
@@ -250,6 +259,7 @@ END_MIG
250
259
  @d.meta_def(:schema) do |t|
251
260
  t == :t1 ? [[:c2, {:db_type=>'integer'}]] : [[:c1, {:db_type=>'integer'}]]
252
261
  end
262
+ @d.meta_def(:supports_foreign_key_parsing?){true}
253
263
  @d.meta_def(:foreign_key_list) do |t|
254
264
  t == :t1 ? [{:columns=>[:c2], :table=>:t2, :key=>[:c1]}] : [{:columns=>[:c1], :table=>:t1, :key=>[:c2]}]
255
265
  end
@@ -277,6 +287,7 @@ END_MIG
277
287
  @d.meta_def(:schema) do |t|
278
288
  t == :t1 ? [[:c2, {:db_type=>'integer'}]] : [[:c1, {:db_type=>'integer', :primary_key=>true}]]
279
289
  end
290
+ @d.meta_def(:supports_foreign_key_parsing?){true}
280
291
  @d.meta_def(:foreign_key_list) do |t|
281
292
  raise Sequel::DatabaseError unless [:t1, :t2].include?(t)
282
293
  t == :t1 ? [{:columns=>[:c2], :table=>:t2, :key=>[:c1]}] : []
@@ -318,6 +329,7 @@ END_MIG
318
329
  end
319
330
 
320
331
  it "should honor the :index_names => false option to not include names of indexes" do
332
+ @d.meta_def(:supports_index_parsing?){true}
321
333
  @d.meta_def(:indexes) do |t|
322
334
  {:i1=>{:columns=>[:c1], :unique=>false},
323
335
  :t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>true}}
@@ -349,6 +361,7 @@ END_MIG
349
361
  end
350
362
 
351
363
  it "should make :index_names => :namespace option a noop if there is a global index namespace" do
364
+ @d.meta_def(:supports_index_parsing?){true}
352
365
  @d.meta_def(:indexes) do |t|
353
366
  {:i1=>{:columns=>[:c1], :unique=>false},
354
367
  :t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>false}}
@@ -381,6 +394,7 @@ END_MIG
381
394
 
382
395
  it "should honor the :index_names => :namespace option to include names of indexes with prepended table name if there is no global index namespace" do
383
396
  @d.meta_def(:global_index_namespace?){false}
397
+ @d.meta_def(:supports_index_parsing?){true}
384
398
  @d.meta_def(:indexes) do |t|
385
399
  {:i1=>{:columns=>[:c1], :unique=>false},
386
400
  :t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>false}}
@@ -412,6 +426,7 @@ END_MIG
412
426
  end
413
427
 
414
428
  it "should honor the :indexes => false option to not include indexes" do
429
+ @d.meta_def(:supports_index_parsing?){true}
415
430
  @d.meta_def(:indexes) do |t|
416
431
  {:i1=>{:columns=>[:c1], :unique=>false},
417
432
  :t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>true}}
@@ -444,6 +459,7 @@ END_MIG
444
459
  end
445
460
 
446
461
  it "should have :foreign_keys option override :indexes => false disabling of foreign keys" do
462
+ @d.meta_def(:supports_foreign_key_parsing?){true}
447
463
  @d.meta_def(:foreign_key_list) do |t|
448
464
  t == :t1 ? [{:columns=>[:c2], :table=>:t2, :key=>[:c1]}] : []
449
465
  end
@@ -452,6 +468,7 @@ END_MIG
452
468
 
453
469
  it "should support dumping just indexes as a migration" do
454
470
  @d.meta_def(:tables){|o| [:t1]}
471
+ @d.meta_def(:supports_index_parsing?){true}
455
472
  @d.meta_def(:indexes) do |t|
456
473
  {:i1=>{:columns=>[:c1], :unique=>false},
457
474
  :t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>true}}
@@ -468,6 +485,7 @@ END_MIG
468
485
 
469
486
  it "should honor the :index_names => false option to not include names of indexes when dumping just indexes as a migration" do
470
487
  @d.meta_def(:tables){|o| [:t1]}
488
+ @d.meta_def(:supports_index_parsing?){true}
471
489
  @d.meta_def(:indexes) do |t|
472
490
  {:i1=>{:columns=>[:c1], :unique=>false},
473
491
  :t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>true}}
@@ -484,6 +502,7 @@ END_MIG
484
502
 
485
503
  it "should honor the :index_names => :namespace option be a noop if there is a global index namespace" do
486
504
  @d.meta_def(:tables){|o| [:t1, :t2]}
505
+ @d.meta_def(:supports_index_parsing?){true}
487
506
  @d.meta_def(:indexes) do |t|
488
507
  {:i1=>{:columns=>[:c1], :unique=>false},
489
508
  :t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>false}}
@@ -504,6 +523,7 @@ END_MIG
504
523
  it "should honor the :index_names => :namespace option to include names of indexes with prepended table name when dumping just indexes as a migration if there is no global index namespace" do
505
524
  @d.meta_def(:global_index_namespace?){false}
506
525
  @d.meta_def(:tables){|o| [:t1, :t2]}
526
+ @d.meta_def(:supports_index_parsing?){true}
507
527
  @d.meta_def(:indexes) do |t|
508
528
  {:i1=>{:columns=>[:c1], :unique=>false},
509
529
  :t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>false}}
@@ -548,6 +568,7 @@ END_MIG
548
568
  @d.meta_def(:schema) do |t|
549
569
  t == :t1 ? [[:c2, {:db_type=>'integer'}]] : [[:c1, {:db_type=>'integer'}]]
550
570
  end
571
+ @d.meta_def(:supports_foreign_key_parsing?){true}
551
572
  @d.meta_def(:foreign_key_list) do |t, *a|
552
573
  case t
553
574
  when :t1
@@ -601,6 +622,8 @@ END_MIG
601
622
 
602
623
  it "should not use a literal string as a fallback if using MySQL with the :same_db option" do
603
624
  @d.meta_def(:database_type){:mysql}
625
+ @d.meta_def(:supports_index_parsing?){false}
626
+ @d.meta_def(:supports_foreign_key_parsing?){false}
604
627
  @d.meta_def(:schema) do |t, *os|
605
628
  s = [[:c10, {:db_type=>'foo', :default=>"'6 weeks'", :type=>nil, :allow_null=>true}]]
606
629
  s.each{|_, c| c[:ruby_default] = column_schema_to_ruby_default(c[:default], c[:type])}
@@ -739,6 +762,7 @@ END_MIG
739
762
 
740
763
  it "should use explicit type for non integer foreign_key types" do
741
764
  @d.meta_def(:schema){|*s| [[:c1, {:db_type=>'date', :primary_key=>true}]]}
765
+ @d.meta_def(:supports_foreign_key_parsing?){true}
742
766
  @d.meta_def(:foreign_key_list){|t, *a| [{:columns=>[:c1], :table=>:t3, :key=>[:c1]}] if t == :t4}
743
767
  ["create_table(:t4) do\n foreign_key :c1, :t3, :type=>Date, :key=>[:c1]\n \n primary_key [:c1]\nend",
744
768
  "create_table(:t4) do\n foreign_key :c1, :t3, :key=>[:c1], :type=>Date\n \n primary_key [:c1]\nend"].should include(@d.dump_table_schema(:t4))
@@ -748,6 +772,7 @@ END_MIG
748
772
 
749
773
  it "should correctly handing autoincrementing primary keys that are also foreign keys" do
750
774
  @d.meta_def(:schema){|*s| [[:c1, {:db_type=>'integer', :primary_key=>true}]]}
775
+ @d.meta_def(:supports_foreign_key_parsing?){true}
751
776
  @d.meta_def(:foreign_key_list){|t, *a| [{:columns=>[:c1], :table=>:t3, :key=>[:c1]}] if t == :t4}
752
777
  ["create_table(:t4) do\n primary_key :c1, :table=>:t3, :key=>[:c1]\nend",
753
778
  "create_table(:t4) do\n primary_key :c1, :key=>[:c1], :table=>:t3\nend"].should include(@d.dump_table_schema(:t4))
@@ -91,12 +91,12 @@ describe Sequel::Model, "schema methods" do
91
91
 
92
92
  it "drop_table? should drop the table if it exists" do
93
93
  @model.drop_table?
94
- MODEL_DB.sqls.should == ["SELECT NULL FROM items LIMIT 1", 'DROP TABLE items']
94
+ MODEL_DB.sqls.should == ["SELECT NULL AS nil FROM items LIMIT 1", 'DROP TABLE items']
95
95
  end
96
96
 
97
97
  it "create_table! should drop table if it exists and then create the table" do
98
98
  @model.create_table!
99
- MODEL_DB.sqls.should == ["SELECT NULL FROM items LIMIT 1", 'DROP TABLE items', 'CREATE TABLE items ()']
99
+ MODEL_DB.sqls.should == ["SELECT NULL AS nil FROM items LIMIT 1", 'DROP TABLE items', 'CREATE TABLE items ()']
100
100
  end
101
101
 
102
102
  it "create_table? should not create the table if it already exists" do
@@ -0,0 +1,26 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
+
3
+ describe "scissors plugin" do
4
+ before do
5
+ @m = Class.new(Sequel::Model(:items))
6
+ @m.use_transactions = true
7
+ @m.plugin :scissors
8
+ @m.db.sqls
9
+ end
10
+
11
+ it "Model.delete should delete from the dataset" do
12
+ @m.delete
13
+ @m.db.sqls.should == ['DELETE FROM items']
14
+ end
15
+
16
+ it "Model.update should update the dataset" do
17
+ @m.update(:a=>1)
18
+ @m.db.sqls.should == ['UPDATE items SET a = 1']
19
+ end
20
+
21
+ it "Model.destory each instance in the dataset" do
22
+ @m.dataset._fetch = {:id=>1}
23
+ @m.destroy
24
+ @m.db.sqls.should == ['BEGIN', 'SELECT * FROM items', 'DELETE FROM items WHERE id = 1', 'COMMIT']
25
+ end
26
+ end
@@ -2,7 +2,7 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe "Dataset#select_remove" do
4
4
  before do
5
- @d = Sequel.mock.from(:test)
5
+ @d = Sequel.mock.from(:test).extension(:select_remove)
6
6
  @d.columns :a, :b, :c
7
7
  end
8
8
 
@@ -0,0 +1,102 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
+
3
+ describe "Dataset#to_csv" do
4
+ before do
5
+ @ds = Sequel.mock(:fetch=>[{:a=>1, :b=>2, :c=>3}, {:a=>4, :b=>5, :c=>6}, {:a=>7, :b=>8, :c=>9}])[:items].columns(:a, :b, :c).extension(:sequel_3_dataset_methods)
6
+ end
7
+
8
+ specify "should format a CSV representation of the records" do
9
+ @ds.to_csv.should == "a, b, c\r\n1, 2, 3\r\n4, 5, 6\r\n7, 8, 9\r\n"
10
+ end
11
+
12
+ specify "should exclude column titles if so specified" do
13
+ @ds.to_csv(false).should == "1, 2, 3\r\n4, 5, 6\r\n7, 8, 9\r\n"
14
+ end
15
+ end
16
+
17
+ describe "Dataset#[]=" do
18
+ specify "should perform an update on the specified filter" do
19
+ db = Sequel.mock
20
+ ds = db[:items].extension(:sequel_3_dataset_methods)
21
+ ds[:a => 1] = {:x => 3}
22
+ db.sqls.should == ['UPDATE items SET x = 3 WHERE (a = 1)']
23
+ end
24
+ end
25
+
26
+ describe "Dataset#insert_multiple" do
27
+ before do
28
+ @db = Sequel.mock(:autoid=>2)
29
+ @ds = @db[:items].extension(:sequel_3_dataset_methods)
30
+ end
31
+
32
+ specify "should insert all items in the supplied array" do
33
+ @ds.insert_multiple(['aa', 5, 3, {:a => 2}])
34
+ @db.sqls.should == ["INSERT INTO items VALUES ('aa')",
35
+ "INSERT INTO items VALUES (5)",
36
+ "INSERT INTO items VALUES (3)",
37
+ "INSERT INTO items (a) VALUES (2)"]
38
+ end
39
+
40
+ specify "should pass array items through the supplied block if given" do
41
+ @ds.insert_multiple(["inevitable", "hello", "the ticking clock"]){|i| i.gsub('l', 'r')}
42
+ @db.sqls.should == ["INSERT INTO items VALUES ('inevitabre')",
43
+ "INSERT INTO items VALUES ('herro')",
44
+ "INSERT INTO items VALUES ('the ticking crock')"]
45
+ end
46
+
47
+ specify "should return array of inserted ids" do
48
+ @ds.insert_multiple(['aa', 5, 3, {:a => 2}]).should == [2, 3, 4, 5]
49
+ end
50
+
51
+ specify "should work exactly like in metioned in the example" do
52
+ @ds.insert_multiple([{:x=>1}, {:x=>2}]){|row| row[:y] = row[:x] * 2 ; row }
53
+ sqls = @db.sqls
54
+ ["INSERT INTO items (x, y) VALUES (1, 2)", "INSERT INTO items (y, x) VALUES (2, 1)"].should include(sqls[0])
55
+ ["INSERT INTO items (x, y) VALUES (2, 4)", "INSERT INTO items (y, x) VALUES (4, 2)"].should include(sqls[1])
56
+ end
57
+ end
58
+
59
+ describe "Dataset#db=" do
60
+ specify "should change the dataset's database" do
61
+ db = Sequel.mock
62
+ ds = db[:items].extension(:sequel_3_dataset_methods)
63
+ db2 = Sequel.mock
64
+ ds.db = db2
65
+ ds.db.should == db2
66
+ ds.db.should_not == db
67
+ end
68
+ end
69
+
70
+ describe "Dataset#opts=" do
71
+ specify "should change the dataset's opts" do
72
+ db = Sequel.mock
73
+ ds = db[:items].extension(:sequel_3_dataset_methods)
74
+ db2 = Sequel.mock
75
+ ds.sql.should == 'SELECT * FROM items'
76
+ ds.opts = {}
77
+ ds.sql.should == 'SELECT *'
78
+ ds.opts.should == {}
79
+ end
80
+ end
81
+
82
+ describe "Dataset#set" do
83
+ specify "should act as alias to #update" do
84
+ db = Sequel.mock
85
+ ds = db[:items].extension(:sequel_3_dataset_methods)
86
+ ds.set({:x => 3})
87
+ db.sqls.should == ['UPDATE items SET x = 3']
88
+ end
89
+ end
90
+
91
+ describe "Sequel::Dataset#qualify_to_first_source" do
92
+ specify "should qualify to the first source" do
93
+ Sequel.mock.dataset.extension(:sequel_3_dataset_methods).from(:t).filter{a<b}.qualify_to_first_source.sql.should == 'SELECT t.* FROM t WHERE (t.a < t.b)'
94
+ end
95
+ end
96
+
97
+ describe "Sequel::Dataset#qualify_to" do
98
+ specify "should qualify to the given table" do
99
+ Sequel.mock.dataset.extension(:sequel_3_dataset_methods).from(:t).filter{a<b}.qualify_to(:e).sql.should == 'SELECT e.* FROM t WHERE (e.a < e.b)'
100
+ end
101
+ end
102
+
@@ -0,0 +1,45 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
+
3
+ describe "Sequel::Dataset #set_defaults" do
4
+ before do
5
+ @ds = Sequel.mock.dataset.from(:items).extension(:set_overrides).set_defaults(:x=>1)
6
+ end
7
+
8
+ specify "should set the default values for inserts" do
9
+ @ds.insert_sql.should == "INSERT INTO items (x) VALUES (1)"
10
+ @ds.insert_sql(:x=>2).should == "INSERT INTO items (x) VALUES (2)"
11
+ @ds.insert_sql(:y=>2).should =~ /INSERT INTO items \([xy], [xy]\) VALUES \([21], [21]\)/
12
+ @ds.set_defaults(:y=>2).insert_sql.should =~ /INSERT INTO items \([xy], [xy]\) VALUES \([21], [21]\)/
13
+ @ds.set_defaults(:x=>2).insert_sql.should == "INSERT INTO items (x) VALUES (2)"
14
+ end
15
+
16
+ specify "should set the default values for updates" do
17
+ @ds.update_sql.should == "UPDATE items SET x = 1"
18
+ @ds.update_sql(:x=>2).should == "UPDATE items SET x = 2"
19
+ @ds.update_sql(:y=>2).should =~ /UPDATE items SET (x = 1|y = 2), (x = 1|y = 2)/
20
+ @ds.set_defaults(:y=>2).update_sql.should =~ /UPDATE items SET (x = 1|y = 2), (x = 1|y = 2)/
21
+ @ds.set_defaults(:x=>2).update_sql.should == "UPDATE items SET x = 2"
22
+ end
23
+ end
24
+
25
+ describe "Sequel::Dataset #set_overrides" do
26
+ before do
27
+ @ds = Sequel.mock.dataset.from(:items).extension(:set_overrides).set_overrides(:x=>1)
28
+ end
29
+
30
+ specify "should override the given values for inserts" do
31
+ @ds.insert_sql.should == "INSERT INTO items (x) VALUES (1)"
32
+ @ds.insert_sql(:x=>2).should == "INSERT INTO items (x) VALUES (1)"
33
+ @ds.insert_sql(:y=>2).should =~ /INSERT INTO items \([xy], [xy]\) VALUES \([21], [21]\)/
34
+ @ds.set_overrides(:y=>2).insert_sql.should =~ /INSERT INTO items \([xy], [xy]\) VALUES \([21], [21]\)/
35
+ @ds.set_overrides(:x=>2).insert_sql.should == "INSERT INTO items (x) VALUES (1)"
36
+ end
37
+
38
+ specify "should override the given values for updates" do
39
+ @ds.update_sql.should == "UPDATE items SET x = 1"
40
+ @ds.update_sql(:x=>2).should == "UPDATE items SET x = 1"
41
+ @ds.update_sql(:y=>2).should =~ /UPDATE items SET (x = 1|y = 2), (x = 1|y = 2)/
42
+ @ds.set_overrides(:y=>2).update_sql.should =~ /UPDATE items SET (x = 1|y = 2), (x = 1|y = 2)/
43
+ @ds.set_overrides(:x=>2).update_sql.should == "UPDATE items SET x = 1"
44
+ end
45
+ end
@@ -121,6 +121,16 @@ describe Sequel::Model, "single table inheritance plugin" do
121
121
  Object.send(:remove_const, :StiTest4)
122
122
  end
123
123
 
124
+ specify "should have working row_proc if using set_dataset in subclass to remove columns" do
125
+ StiTest2.plugin :single_table_inheritance, :kind
126
+ class ::StiTest3 < ::StiTest2
127
+ set_dataset(dataset.select(*(columns - [:blah])))
128
+ end
129
+ class ::StiTest4 < ::StiTest3; end
130
+ StiTest3.dataset._fetch = {:id=>1, :kind=>'StiTest4'}
131
+ StiTest3[1].should == StiTest4.load(:id=>1, :kind=>'StiTest4')
132
+ end
133
+
124
134
  it "should work with custom procs with strings" do
125
135
  StiTest2.plugin :single_table_inheritance, :kind, :model_map=>proc{|v| v == 1 ? 'StiTest3' : 'StiTest4'}, :key_map=>proc{|klass| klass.name == 'StiTest3' ? 1 : 2}
126
136
  class ::StiTest3 < ::StiTest2; end
@@ -17,6 +17,8 @@ unless Object.const_defined?('Sequel') && Sequel.const_defined?('Model')
17
17
  $:.unshift(File.join(File.dirname(File.expand_path(__FILE__)), "../../lib/"))
18
18
  require 'sequel/no_core_ext'
19
19
  end
20
+ Sequel::Deprecation.backtrace_filter = lambda{|line, lineno| lineno < 4 || line =~ /_spec\.rb/}
21
+ SEQUEL_EXTENSIONS_NO_DEPRECATION_WARNING = true
20
22
 
21
23
  begin
22
24
  # Attempt to load ActiveSupport blank extension and inflector first, so Sequel
@@ -42,6 +44,26 @@ def skip_warn(s)
42
44
  warn "Skipping test of #{s}" if ENV["SKIPPED_TEST_WARN"]
43
45
  end
44
46
 
47
+ (defined?(RSpec) ? RSpec::Core::ExampleGroup : Spec::Example::ExampleGroup).class_eval do
48
+ if ENV['SEQUEL_DEPRECATION_WARNINGS']
49
+ class << self
50
+ alias qspecify specify
51
+ end
52
+ else
53
+ def self.qspecify(*a, &block)
54
+ specify(*a) do
55
+ begin
56
+ output = Sequel::Deprecation.output
57
+ Sequel::Deprecation.output = false
58
+ instance_exec(&block)
59
+ ensure
60
+ Sequel::Deprecation.output = output
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+
45
67
  Sequel.quote_identifiers = false
46
68
  Sequel.identifier_input_method = nil
47
69
  Sequel.identifier_output_method = nil
@@ -61,9 +83,10 @@ class << Sequel::Model
61
83
  end
62
84
 
63
85
  Sequel::Model.use_transactions = false
64
- Sequel::Model.cache_anonymous_models = false
86
+ Sequel.cache_anonymous_models = false
65
87
 
66
88
  db = Sequel.mock(:fetch=>{:id => 1, :x => 1}, :numrows=>1, :autoid=>proc{|sql| 10})
67
89
  def db.schema(*) [[:id, {:primary_key=>true}]] end
68
90
  def db.reset() sqls end
91
+ def db.supports_schema_parsing?() true end
69
92
  Sequel::Model.db = MODEL_DB = db