sequel 3.47.0 → 3.48.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 (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