viking-sequel 3.10.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 (237) hide show
  1. data/CHANGELOG +3134 -0
  2. data/COPYING +19 -0
  3. data/README.rdoc +723 -0
  4. data/Rakefile +193 -0
  5. data/bin/sequel +196 -0
  6. data/doc/advanced_associations.rdoc +644 -0
  7. data/doc/cheat_sheet.rdoc +218 -0
  8. data/doc/dataset_basics.rdoc +106 -0
  9. data/doc/dataset_filtering.rdoc +158 -0
  10. data/doc/opening_databases.rdoc +296 -0
  11. data/doc/prepared_statements.rdoc +104 -0
  12. data/doc/reflection.rdoc +84 -0
  13. data/doc/release_notes/1.0.txt +38 -0
  14. data/doc/release_notes/1.1.txt +143 -0
  15. data/doc/release_notes/1.3.txt +101 -0
  16. data/doc/release_notes/1.4.0.txt +53 -0
  17. data/doc/release_notes/1.5.0.txt +155 -0
  18. data/doc/release_notes/2.0.0.txt +298 -0
  19. data/doc/release_notes/2.1.0.txt +271 -0
  20. data/doc/release_notes/2.10.0.txt +328 -0
  21. data/doc/release_notes/2.11.0.txt +215 -0
  22. data/doc/release_notes/2.12.0.txt +534 -0
  23. data/doc/release_notes/2.2.0.txt +253 -0
  24. data/doc/release_notes/2.3.0.txt +88 -0
  25. data/doc/release_notes/2.4.0.txt +106 -0
  26. data/doc/release_notes/2.5.0.txt +137 -0
  27. data/doc/release_notes/2.6.0.txt +157 -0
  28. data/doc/release_notes/2.7.0.txt +166 -0
  29. data/doc/release_notes/2.8.0.txt +171 -0
  30. data/doc/release_notes/2.9.0.txt +97 -0
  31. data/doc/release_notes/3.0.0.txt +221 -0
  32. data/doc/release_notes/3.1.0.txt +406 -0
  33. data/doc/release_notes/3.10.0.txt +286 -0
  34. data/doc/release_notes/3.2.0.txt +268 -0
  35. data/doc/release_notes/3.3.0.txt +192 -0
  36. data/doc/release_notes/3.4.0.txt +325 -0
  37. data/doc/release_notes/3.5.0.txt +510 -0
  38. data/doc/release_notes/3.6.0.txt +366 -0
  39. data/doc/release_notes/3.7.0.txt +179 -0
  40. data/doc/release_notes/3.8.0.txt +151 -0
  41. data/doc/release_notes/3.9.0.txt +233 -0
  42. data/doc/schema.rdoc +36 -0
  43. data/doc/sharding.rdoc +113 -0
  44. data/doc/virtual_rows.rdoc +205 -0
  45. data/lib/sequel.rb +1 -0
  46. data/lib/sequel/adapters/ado.rb +90 -0
  47. data/lib/sequel/adapters/ado/mssql.rb +30 -0
  48. data/lib/sequel/adapters/amalgalite.rb +176 -0
  49. data/lib/sequel/adapters/db2.rb +139 -0
  50. data/lib/sequel/adapters/dbi.rb +113 -0
  51. data/lib/sequel/adapters/do.rb +188 -0
  52. data/lib/sequel/adapters/do/mysql.rb +49 -0
  53. data/lib/sequel/adapters/do/postgres.rb +91 -0
  54. data/lib/sequel/adapters/do/sqlite.rb +40 -0
  55. data/lib/sequel/adapters/firebird.rb +283 -0
  56. data/lib/sequel/adapters/informix.rb +77 -0
  57. data/lib/sequel/adapters/jdbc.rb +587 -0
  58. data/lib/sequel/adapters/jdbc/as400.rb +58 -0
  59. data/lib/sequel/adapters/jdbc/h2.rb +133 -0
  60. data/lib/sequel/adapters/jdbc/mssql.rb +57 -0
  61. data/lib/sequel/adapters/jdbc/mysql.rb +78 -0
  62. data/lib/sequel/adapters/jdbc/oracle.rb +50 -0
  63. data/lib/sequel/adapters/jdbc/postgresql.rb +108 -0
  64. data/lib/sequel/adapters/jdbc/sqlite.rb +55 -0
  65. data/lib/sequel/adapters/mysql.rb +421 -0
  66. data/lib/sequel/adapters/odbc.rb +143 -0
  67. data/lib/sequel/adapters/odbc/mssql.rb +42 -0
  68. data/lib/sequel/adapters/openbase.rb +64 -0
  69. data/lib/sequel/adapters/oracle.rb +131 -0
  70. data/lib/sequel/adapters/postgres.rb +504 -0
  71. data/lib/sequel/adapters/shared/mssql.rb +490 -0
  72. data/lib/sequel/adapters/shared/mysql.rb +498 -0
  73. data/lib/sequel/adapters/shared/oracle.rb +195 -0
  74. data/lib/sequel/adapters/shared/postgres.rb +830 -0
  75. data/lib/sequel/adapters/shared/progress.rb +44 -0
  76. data/lib/sequel/adapters/shared/sqlite.rb +389 -0
  77. data/lib/sequel/adapters/sqlite.rb +224 -0
  78. data/lib/sequel/adapters/utils/stored_procedures.rb +84 -0
  79. data/lib/sequel/connection_pool.rb +99 -0
  80. data/lib/sequel/connection_pool/sharded_single.rb +84 -0
  81. data/lib/sequel/connection_pool/sharded_threaded.rb +211 -0
  82. data/lib/sequel/connection_pool/single.rb +29 -0
  83. data/lib/sequel/connection_pool/threaded.rb +150 -0
  84. data/lib/sequel/core.rb +293 -0
  85. data/lib/sequel/core_sql.rb +241 -0
  86. data/lib/sequel/database.rb +1079 -0
  87. data/lib/sequel/database/schema_generator.rb +327 -0
  88. data/lib/sequel/database/schema_methods.rb +203 -0
  89. data/lib/sequel/database/schema_sql.rb +320 -0
  90. data/lib/sequel/dataset.rb +32 -0
  91. data/lib/sequel/dataset/actions.rb +441 -0
  92. data/lib/sequel/dataset/features.rb +86 -0
  93. data/lib/sequel/dataset/graph.rb +254 -0
  94. data/lib/sequel/dataset/misc.rb +119 -0
  95. data/lib/sequel/dataset/mutation.rb +64 -0
  96. data/lib/sequel/dataset/prepared_statements.rb +227 -0
  97. data/lib/sequel/dataset/query.rb +709 -0
  98. data/lib/sequel/dataset/sql.rb +996 -0
  99. data/lib/sequel/exceptions.rb +51 -0
  100. data/lib/sequel/extensions/blank.rb +43 -0
  101. data/lib/sequel/extensions/inflector.rb +242 -0
  102. data/lib/sequel/extensions/looser_typecasting.rb +21 -0
  103. data/lib/sequel/extensions/migration.rb +239 -0
  104. data/lib/sequel/extensions/named_timezones.rb +61 -0
  105. data/lib/sequel/extensions/pagination.rb +100 -0
  106. data/lib/sequel/extensions/pretty_table.rb +82 -0
  107. data/lib/sequel/extensions/query.rb +52 -0
  108. data/lib/sequel/extensions/schema_dumper.rb +271 -0
  109. data/lib/sequel/extensions/sql_expr.rb +122 -0
  110. data/lib/sequel/extensions/string_date_time.rb +46 -0
  111. data/lib/sequel/extensions/thread_local_timezones.rb +48 -0
  112. data/lib/sequel/metaprogramming.rb +9 -0
  113. data/lib/sequel/model.rb +120 -0
  114. data/lib/sequel/model/associations.rb +1514 -0
  115. data/lib/sequel/model/base.rb +1069 -0
  116. data/lib/sequel/model/default_inflections.rb +45 -0
  117. data/lib/sequel/model/errors.rb +39 -0
  118. data/lib/sequel/model/exceptions.rb +21 -0
  119. data/lib/sequel/model/inflections.rb +162 -0
  120. data/lib/sequel/model/plugins.rb +70 -0
  121. data/lib/sequel/plugins/active_model.rb +59 -0
  122. data/lib/sequel/plugins/association_dependencies.rb +103 -0
  123. data/lib/sequel/plugins/association_proxies.rb +41 -0
  124. data/lib/sequel/plugins/boolean_readers.rb +53 -0
  125. data/lib/sequel/plugins/caching.rb +141 -0
  126. data/lib/sequel/plugins/class_table_inheritance.rb +214 -0
  127. data/lib/sequel/plugins/composition.rb +138 -0
  128. data/lib/sequel/plugins/force_encoding.rb +72 -0
  129. data/lib/sequel/plugins/hook_class_methods.rb +126 -0
  130. data/lib/sequel/plugins/identity_map.rb +116 -0
  131. data/lib/sequel/plugins/instance_filters.rb +98 -0
  132. data/lib/sequel/plugins/instance_hooks.rb +57 -0
  133. data/lib/sequel/plugins/lazy_attributes.rb +77 -0
  134. data/lib/sequel/plugins/many_through_many.rb +208 -0
  135. data/lib/sequel/plugins/nested_attributes.rb +206 -0
  136. data/lib/sequel/plugins/optimistic_locking.rb +81 -0
  137. data/lib/sequel/plugins/rcte_tree.rb +281 -0
  138. data/lib/sequel/plugins/schema.rb +66 -0
  139. data/lib/sequel/plugins/serialization.rb +166 -0
  140. data/lib/sequel/plugins/single_table_inheritance.rb +74 -0
  141. data/lib/sequel/plugins/subclasses.rb +45 -0
  142. data/lib/sequel/plugins/tactical_eager_loading.rb +61 -0
  143. data/lib/sequel/plugins/timestamps.rb +87 -0
  144. data/lib/sequel/plugins/touch.rb +118 -0
  145. data/lib/sequel/plugins/typecast_on_load.rb +72 -0
  146. data/lib/sequel/plugins/validation_class_methods.rb +405 -0
  147. data/lib/sequel/plugins/validation_helpers.rb +223 -0
  148. data/lib/sequel/sql.rb +1020 -0
  149. data/lib/sequel/timezones.rb +161 -0
  150. data/lib/sequel/version.rb +12 -0
  151. data/lib/sequel_core.rb +1 -0
  152. data/lib/sequel_model.rb +1 -0
  153. data/spec/adapters/firebird_spec.rb +407 -0
  154. data/spec/adapters/informix_spec.rb +97 -0
  155. data/spec/adapters/mssql_spec.rb +403 -0
  156. data/spec/adapters/mysql_spec.rb +1019 -0
  157. data/spec/adapters/oracle_spec.rb +286 -0
  158. data/spec/adapters/postgres_spec.rb +969 -0
  159. data/spec/adapters/spec_helper.rb +51 -0
  160. data/spec/adapters/sqlite_spec.rb +432 -0
  161. data/spec/core/connection_pool_spec.rb +808 -0
  162. data/spec/core/core_sql_spec.rb +417 -0
  163. data/spec/core/database_spec.rb +1662 -0
  164. data/spec/core/dataset_spec.rb +3827 -0
  165. data/spec/core/expression_filters_spec.rb +595 -0
  166. data/spec/core/object_graph_spec.rb +296 -0
  167. data/spec/core/schema_generator_spec.rb +159 -0
  168. data/spec/core/schema_spec.rb +830 -0
  169. data/spec/core/spec_helper.rb +56 -0
  170. data/spec/core/version_spec.rb +7 -0
  171. data/spec/extensions/active_model_spec.rb +76 -0
  172. data/spec/extensions/association_dependencies_spec.rb +127 -0
  173. data/spec/extensions/association_proxies_spec.rb +50 -0
  174. data/spec/extensions/blank_spec.rb +67 -0
  175. data/spec/extensions/boolean_readers_spec.rb +92 -0
  176. data/spec/extensions/caching_spec.rb +250 -0
  177. data/spec/extensions/class_table_inheritance_spec.rb +252 -0
  178. data/spec/extensions/composition_spec.rb +194 -0
  179. data/spec/extensions/force_encoding_spec.rb +117 -0
  180. data/spec/extensions/hook_class_methods_spec.rb +470 -0
  181. data/spec/extensions/identity_map_spec.rb +202 -0
  182. data/spec/extensions/inflector_spec.rb +181 -0
  183. data/spec/extensions/instance_filters_spec.rb +55 -0
  184. data/spec/extensions/instance_hooks_spec.rb +133 -0
  185. data/spec/extensions/lazy_attributes_spec.rb +153 -0
  186. data/spec/extensions/looser_typecasting_spec.rb +39 -0
  187. data/spec/extensions/many_through_many_spec.rb +884 -0
  188. data/spec/extensions/migration_spec.rb +332 -0
  189. data/spec/extensions/named_timezones_spec.rb +72 -0
  190. data/spec/extensions/nested_attributes_spec.rb +396 -0
  191. data/spec/extensions/optimistic_locking_spec.rb +100 -0
  192. data/spec/extensions/pagination_spec.rb +99 -0
  193. data/spec/extensions/pretty_table_spec.rb +91 -0
  194. data/spec/extensions/query_spec.rb +85 -0
  195. data/spec/extensions/rcte_tree_spec.rb +205 -0
  196. data/spec/extensions/schema_dumper_spec.rb +357 -0
  197. data/spec/extensions/schema_spec.rb +127 -0
  198. data/spec/extensions/serialization_spec.rb +209 -0
  199. data/spec/extensions/single_table_inheritance_spec.rb +96 -0
  200. data/spec/extensions/spec_helper.rb +91 -0
  201. data/spec/extensions/sql_expr_spec.rb +89 -0
  202. data/spec/extensions/string_date_time_spec.rb +93 -0
  203. data/spec/extensions/subclasses_spec.rb +52 -0
  204. data/spec/extensions/tactical_eager_loading_spec.rb +65 -0
  205. data/spec/extensions/thread_local_timezones_spec.rb +45 -0
  206. data/spec/extensions/timestamps_spec.rb +150 -0
  207. data/spec/extensions/touch_spec.rb +155 -0
  208. data/spec/extensions/typecast_on_load_spec.rb +69 -0
  209. data/spec/extensions/validation_class_methods_spec.rb +984 -0
  210. data/spec/extensions/validation_helpers_spec.rb +438 -0
  211. data/spec/integration/associations_test.rb +281 -0
  212. data/spec/integration/database_test.rb +26 -0
  213. data/spec/integration/dataset_test.rb +963 -0
  214. data/spec/integration/eager_loader_test.rb +734 -0
  215. data/spec/integration/model_test.rb +130 -0
  216. data/spec/integration/plugin_test.rb +814 -0
  217. data/spec/integration/prepared_statement_test.rb +213 -0
  218. data/spec/integration/schema_test.rb +361 -0
  219. data/spec/integration/spec_helper.rb +73 -0
  220. data/spec/integration/timezone_test.rb +55 -0
  221. data/spec/integration/transaction_test.rb +122 -0
  222. data/spec/integration/type_test.rb +96 -0
  223. data/spec/model/association_reflection_spec.rb +175 -0
  224. data/spec/model/associations_spec.rb +2633 -0
  225. data/spec/model/base_spec.rb +418 -0
  226. data/spec/model/dataset_methods_spec.rb +78 -0
  227. data/spec/model/eager_loading_spec.rb +1391 -0
  228. data/spec/model/hooks_spec.rb +240 -0
  229. data/spec/model/inflector_spec.rb +26 -0
  230. data/spec/model/model_spec.rb +593 -0
  231. data/spec/model/plugins_spec.rb +236 -0
  232. data/spec/model/record_spec.rb +1500 -0
  233. data/spec/model/spec_helper.rb +97 -0
  234. data/spec/model/validations_spec.rb +153 -0
  235. data/spec/rcov.opts +6 -0
  236. data/spec/spec_config.rb.example +10 -0
  237. metadata +346 -0
@@ -0,0 +1,56 @@
1
+ require 'rubygems'
2
+ unless Object.const_defined?('Sequel')
3
+ $:.unshift(File.join(File.dirname(__FILE__), "../../lib/"))
4
+ require 'sequel/core'
5
+ end
6
+
7
+ class MockDataset < Sequel::Dataset
8
+ def insert(*args)
9
+ @db.execute insert_sql(*args)
10
+ end
11
+
12
+ def update(*args)
13
+ @db.execute update_sql(*args)
14
+ end
15
+
16
+ def fetch_rows(sql)
17
+ @db.execute(sql)
18
+ yield({:id => 1, :x => 1})
19
+ end
20
+
21
+ def quoted_identifier(c)
22
+ "\"#{c}\""
23
+ end
24
+ end
25
+
26
+ class MockDatabase < Sequel::Database
27
+ set_adapter_scheme :mock
28
+ @@quote_identifiers = false
29
+ self.identifier_input_method = nil
30
+ self.identifier_output_method = nil
31
+ attr_reader :sqls
32
+
33
+ def execute(sql, opts={})
34
+ @sqls ||= []
35
+ @sqls << sql
36
+ end
37
+
38
+ def reset
39
+ @sqls = []
40
+ end
41
+
42
+ def transaction(opts={}); yield; end
43
+
44
+ def dataset; MockDataset.new(self); end
45
+ end
46
+
47
+ class SchemaDummyDatabase < Sequel::Database
48
+ attr_reader :sqls
49
+ self.identifier_input_method = nil
50
+ self.identifier_output_method = nil
51
+
52
+ def execute(sql, opts={})
53
+ @sqls ||= []
54
+ @sqls << sql
55
+ end
56
+ end
@@ -0,0 +1,7 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ context "Sequel.version" do
4
+ specify "should be in the form X.Y.Z with all being numbers" do
5
+ Sequel.version.should =~ /\A\d+\.\d+\.\d+\z/
6
+ end
7
+ end
@@ -0,0 +1,76 @@
1
+ require File.join(File.dirname(__FILE__), "spec_helper")
2
+ if RUBY_PLATFORM !~ /(win|w)32|java$/
3
+ describe "ActiveModel plugin" do
4
+ specify "should be compliant to the ActiveModel spec" do
5
+ s = ''
6
+ IO.popen('-') do |f|
7
+ if f
8
+ s = f.read
9
+ else
10
+ begin
11
+ require 'rubygems'
12
+ require 'active_model'
13
+ rescue LoadError
14
+ puts "0 failures, 0 errors, skipping tests"
15
+ else
16
+ require 'test/unit'
17
+ require "test/unit/ui/console/testrunner"
18
+ class AMLintTest < Test::Unit::TestCase
19
+ def setup
20
+ @c = Class.new(Sequel::Model) do
21
+ set_primary_key :id
22
+ columns :id, :id2
23
+ def delete; end
24
+ end
25
+ @c.plugin :active_model
26
+ @m = @model = @c.new
27
+ @o = @c.load({})
28
+ end
29
+ include ActiveModel::Lint::Tests
30
+
31
+ # Should return self, not a proxy object
32
+ def test__to_model
33
+ assert_equal @m.to_model.object_id.should, @m.object_id
34
+ end
35
+
36
+ def test__to_key
37
+ assert_equal nil, @m.to_key
38
+ @o.id = 1
39
+ assert_equal [1], @o.to_key
40
+ @c.set_primary_key [:id2, :id]
41
+ @o.id2 = 2
42
+ assert_equal [2, 1], @o.to_key
43
+ @o.destroy
44
+ assert_equal nil, @o.to_key
45
+ end
46
+
47
+ def test__to_param
48
+ assert_equal nil, @m.to_param
49
+ @o.id = 1
50
+ assert_equal '1', @o.to_param
51
+ @c.set_primary_key [:id2, :id]
52
+ @o.id2 = 2
53
+ assert_equal '2-1', @o.to_param
54
+ @o.meta_def(:to_param_joiner){'|'}
55
+ assert_equal '2|1', @o.to_param
56
+ @o.destroy
57
+ assert_equal nil, @o.to_param
58
+ end
59
+
60
+ def test__persisted?
61
+ assert_equal false, @m.persisted?
62
+ assert_equal true, @o.persisted?
63
+ @m.destroy
64
+ @o.destroy
65
+ assert_equal false, @m.persisted?
66
+ assert_equal false, @o.persisted?
67
+ end
68
+ end
69
+ Test::Unit::UI::Console::TestRunner.run(AMLintTest)
70
+ end
71
+ end
72
+ end
73
+ s.should =~ /0 failures, 0 errors/
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,127 @@
1
+ require File.join(File.dirname(__FILE__), "spec_helper")
2
+
3
+ describe "AssociationDependencies plugin" do
4
+ before do
5
+ mods = @mods = []
6
+ @c = Class.new(Sequel::Model)
7
+ @c.plugin :association_dependencies
8
+ @Artist = Class.new(@c).set_dataset(:artists)
9
+ ds1 = @Artist.dataset
10
+ def ds1.fetch_rows(s)
11
+ (MODEL_DB.sqls ||= []) << s
12
+ yield({:id=>2, :name=>'Ar'})
13
+ end
14
+ @Album = Class.new(@c).set_dataset(:albums)
15
+ ds1 = @Album.dataset
16
+ def ds1.fetch_rows(s)
17
+ (MODEL_DB.sqls ||= []) << s
18
+ yield({:id=>1, :name=>'Al', :artist_id=>2})
19
+ end
20
+ @Artist.columns :id, :name
21
+ @Album.columns :id, :name, :artist_id
22
+ @Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id
23
+ @Artist.one_to_one :first_album, :class=>@Album, :key=>:artist_id, :conditions=>{:position=>1}
24
+ @Artist.many_to_many :other_artists, :class=>@Artist, :join_table=>:aoa, :left_key=>:l, :right_key=>:r
25
+ @Album.many_to_one :artist, :class=>@Artist
26
+ MODEL_DB.reset
27
+ end
28
+
29
+ specify "should allow destroying associated many_to_one associated object" do
30
+ @Album.add_association_dependencies :artist=>:destroy
31
+ @Album.load(:id=>1, :name=>'Al', :artist_id=>2).destroy
32
+ MODEL_DB.sqls.should == ['DELETE FROM albums WHERE (id = 1)', 'SELECT * FROM artists WHERE (artists.id = 2) LIMIT 1', 'DELETE FROM artists WHERE (id = 2)']
33
+ end
34
+
35
+ specify "should allow deleting associated many_to_one associated object" do
36
+ @Album.add_association_dependencies :artist=>:delete
37
+ @Album.load(:id=>1, :name=>'Al', :artist_id=>2).destroy
38
+ MODEL_DB.sqls.should == ['DELETE FROM albums WHERE (id = 1)', 'DELETE FROM artists WHERE (artists.id = 2)']
39
+ end
40
+
41
+ specify "should allow destroying associated one_to_one associated object" do
42
+ @Artist.add_association_dependencies :first_album=>:destroy
43
+ @Artist.load(:id=>2, :name=>'Ar').destroy
44
+ MODEL_DB.sqls.should == ['SELECT * FROM albums WHERE ((albums.artist_id = 2) AND (position = 1)) LIMIT 1', 'DELETE FROM albums WHERE (id = 1)', 'DELETE FROM artists WHERE (id = 2)']
45
+ end
46
+
47
+ specify "should allow deleting associated one_to_one associated object" do
48
+ @Artist.add_association_dependencies :first_album=>:delete
49
+ @Artist.load(:id=>2, :name=>'Ar').destroy
50
+ MODEL_DB.sqls.should == ['DELETE FROM albums WHERE ((albums.artist_id = 2) AND (position = 1))', 'DELETE FROM artists WHERE (id = 2)']
51
+ end
52
+
53
+ specify "should allow destroying associated one_to_many objects" do
54
+ @Artist.add_association_dependencies :albums=>:destroy
55
+ @Artist.load(:id=>2, :name=>'Ar').destroy
56
+ MODEL_DB.sqls.should == ['SELECT * FROM albums WHERE (albums.artist_id = 2)', 'DELETE FROM albums WHERE (id = 1)', 'DELETE FROM artists WHERE (id = 2)']
57
+ end
58
+
59
+ specify "should allow deleting associated one_to_many objects" do
60
+ @Artist.add_association_dependencies :albums=>:delete
61
+ @Artist.load(:id=>2, :name=>'Ar').destroy
62
+ MODEL_DB.sqls.should == ['DELETE FROM albums WHERE (albums.artist_id = 2)', 'DELETE FROM artists WHERE (id = 2)']
63
+ end
64
+
65
+ specify "should allow nullifying associated one_to_one objects" do
66
+ @Artist.add_association_dependencies :first_album=>:nullify
67
+ @Artist.load(:id=>2, :name=>'Ar').destroy
68
+ MODEL_DB.sqls.should == ['UPDATE albums SET artist_id = NULL WHERE ((artist_id = 2) AND (position = 1))', 'DELETE FROM artists WHERE (id = 2)']
69
+ end
70
+
71
+ specify "should allow nullifying associated one_to_many objects" do
72
+ @Artist.add_association_dependencies :albums=>:nullify
73
+ @Artist.load(:id=>2, :name=>'Ar').destroy
74
+ MODEL_DB.sqls.should == ['UPDATE albums SET artist_id = NULL WHERE (artist_id = 2)', 'DELETE FROM artists WHERE (id = 2)']
75
+ end
76
+
77
+ specify "should allow nullifying associated many_to_many associations" do
78
+ @Artist.add_association_dependencies :other_artists=>:nullify
79
+ @Artist.load(:id=>2, :name=>'Ar').destroy
80
+ MODEL_DB.sqls.should == ['DELETE FROM aoa WHERE (l = 2)', 'DELETE FROM artists WHERE (id = 2)']
81
+ end
82
+
83
+ specify "should raise an error if attempting to nullify a many_to_one association" do
84
+ proc{@Album.add_association_dependencies :artist=>:nullify}.should raise_error(Sequel::Error)
85
+ end
86
+
87
+ specify "should raise an error if using an unrecognized dependence action" do
88
+ proc{@Album.add_association_dependencies :artist=>:blah}.should raise_error(Sequel::Error)
89
+ end
90
+
91
+ specify "should raise an error if a nonexistent association is used" do
92
+ proc{@Album.add_association_dependencies :blah=>:delete}.should raise_error(Sequel::Error)
93
+ end
94
+
95
+ specify "should raise an error if a invalid association type is used" do
96
+ @Artist.plugin :many_through_many
97
+ @Artist.many_through_many :other_albums, [[:id, :id, :id]]
98
+ proc{@Artist.add_association_dependencies :other_albums=>:nullify}.should raise_error(Sequel::Error)
99
+ end
100
+
101
+ specify "should raise an error if using a many_to_many association type without nullify" do
102
+ proc{@Artist.add_association_dependencies :other_artists=>:delete}.should raise_error(Sequel::Error)
103
+ end
104
+
105
+ specify "should allow specifying association dependencies in the plugin call" do
106
+ @Album.plugin :association_dependencies, :artist=>:destroy
107
+ @Album.load(:id=>1, :name=>'Al', :artist_id=>2).destroy
108
+ MODEL_DB.sqls.should == ['DELETE FROM albums WHERE (id = 1)', 'SELECT * FROM artists WHERE (artists.id = 2) LIMIT 1', 'DELETE FROM artists WHERE (id = 2)']
109
+ end
110
+
111
+ specify "should work with subclasses" do
112
+ c = Class.new(@Album)
113
+ c.add_association_dependencies :artist=>:destroy
114
+ c.load(:id=>1, :name=>'Al', :artist_id=>2).destroy
115
+ MODEL_DB.sqls.should == ['DELETE FROM albums WHERE (id = 1)', 'SELECT * FROM artists WHERE (artists.id = 2) LIMIT 1', 'DELETE FROM artists WHERE (id = 2)']
116
+ MODEL_DB.reset
117
+
118
+ @Album.load(:id=>1, :name=>'Al', :artist_id=>2).destroy
119
+ MODEL_DB.sqls.should == ['DELETE FROM albums WHERE (id = 1)']
120
+ MODEL_DB.reset
121
+
122
+ @Album.add_association_dependencies :artist=>:destroy
123
+ c2 = Class.new(@Album)
124
+ c2.load(:id=>1, :name=>'Al', :artist_id=>2).destroy
125
+ MODEL_DB.sqls.should == ['DELETE FROM albums WHERE (id = 1)', 'SELECT * FROM artists WHERE (artists.id = 2) LIMIT 1', 'DELETE FROM artists WHERE (id = 2)']
126
+ end
127
+ end
@@ -0,0 +1,50 @@
1
+ require File.join(File.dirname(__FILE__), "spec_helper")
2
+
3
+ describe "Sequel::Plugins::AssociationProxies" do
4
+ before do
5
+ class ::Tag < Sequel::Model
6
+ end
7
+ class ::Item < Sequel::Model
8
+ plugin :association_proxies
9
+ many_to_many :tags
10
+ end
11
+ @i = Item.load(:id=>1)
12
+ @t = @i.tags
13
+ Item.db.reset
14
+ end
15
+ after do
16
+ Object.send(:remove_const, :Tag)
17
+ Object.send(:remove_const, :Item)
18
+ end
19
+
20
+ it "should send method calls to the associated object array if sent an array method" do
21
+ @i.associations.has_key?(:tags).should == false
22
+ @t.select{|x| false}.should == []
23
+ @i.associations.has_key?(:tags).should == true
24
+ end
25
+
26
+ it "should send method calls to the association dataset sent another method" do
27
+ @i.associations.has_key?(:tags).should == false
28
+ @t.filter(:a=>1).sql.should == "SELECT tags.* FROM tags INNER JOIN items_tags ON ((items_tags.tag_id = tags.id) AND (items_tags.item_id = 1)) WHERE (a = 1)"
29
+ @i.associations.has_key?(:tags).should == false
30
+ end
31
+
32
+ it "should reload the cached association if sent an array method and the reload flag was given" do
33
+ @t.select{|x| false}.should == []
34
+ Item.db.sqls.length == 1
35
+ @t.select{|x| false}.should == []
36
+ Item.db.sqls.length == 1
37
+ @i.tags(true).select{|x| false}.should == []
38
+ Item.db.sqls.length == 2
39
+ @t.filter(:a=>1).sql.should == "SELECT tags.* FROM tags INNER JOIN items_tags ON ((items_tags.tag_id = tags.id) AND (items_tags.item_id = 1)) WHERE (a = 1)"
40
+ Item.db.sqls.length == 2
41
+ end
42
+
43
+ it "should not return a proxy object for associations that do not return an array" do
44
+ Item.many_to_one :tag
45
+ proc{@i.tag.filter(:a=>1)}.should raise_error(NoMethodError)
46
+
47
+ Tag.one_to_one :item
48
+ proc{Tag.load(:id=>1, :item_id=>2).item.filter(:a=>1)}.should raise_error(NoMethodError)
49
+ end
50
+ end
@@ -0,0 +1,67 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ context "Object#blank?" do
4
+ specify "it should be true if the object responds true to empty?" do
5
+ [].blank?.should == true
6
+ {}.blank?.should == true
7
+ o = Object.new
8
+ def o.empty?; true; end
9
+ o.blank?.should == true
10
+ end
11
+
12
+ specify "it should be false if the object doesn't respond true to empty?" do
13
+ [2].blank?.should == false
14
+ {1=>2}.blank?.should == false
15
+ Object.new.blank?.should == false
16
+ end
17
+ end
18
+
19
+ context "Numeric#blank?" do
20
+ specify "it should always be false" do
21
+ 1.blank?.should == false
22
+ 0.blank?.should == false
23
+ -1.blank?.should == false
24
+ 1.0.blank?.should == false
25
+ 0.0.blank?.should == false
26
+ -1.0.blank?.should == false
27
+ 10000000000000000.blank?.should == false
28
+ -10000000000000000.blank?.should == false
29
+ 10000000000000000.0.blank?.should == false
30
+ -10000000000000000.0.blank?.should == false
31
+ end
32
+ end
33
+
34
+ context "NilClass#blank?" do
35
+ specify "it should always be true" do
36
+ nil.blank?.should == true
37
+ end
38
+ end
39
+
40
+ context "TrueClass#blank?" do
41
+ specify "it should always be false" do
42
+ true.blank?.should == false
43
+ end
44
+ end
45
+
46
+ context "FalseClass#blank?" do
47
+ specify "it should always be true" do
48
+ false.blank?.should == true
49
+ end
50
+ end
51
+
52
+ context "String#blank?" do
53
+ specify "it should be true if the string is empty" do
54
+ ''.blank?.should == true
55
+ end
56
+ specify "it should be true if the string is composed of just whitespace" do
57
+ ' '.blank?.should == true
58
+ "\r\n\t".blank?.should == true
59
+ (' '*4000).blank?.should == true
60
+ ("\r\n\t"*4000).blank?.should == true
61
+ end
62
+ specify "it should be false if the string has any non whitespace characters" do
63
+ '1'.blank?.should == false
64
+ ("\r\n\t"*4000 + 'a').blank?.should == false
65
+ ("\r\na\t"*4000).blank?.should == false
66
+ end
67
+ end
@@ -0,0 +1,92 @@
1
+ require File.join(File.dirname(__FILE__), "spec_helper")
2
+
3
+ describe Sequel::Model, "BooleanReaders plugin" do
4
+ before do
5
+ @db = Sequel::Database.new({})
6
+ def @db.schema(*args)
7
+ [[:id, {}], [:y, {:type=>:integer, :db_type=>'tinyint(1)'}], [:b, {:type=>:boolean, :db_type=>'boolean'}]]
8
+ end
9
+
10
+ @c = Class.new(Sequel::Model(@db[:items]))
11
+ @p = proc do
12
+ @columns = [:id, :b, :y]
13
+ def columns; @columns; end
14
+ end
15
+ @c.instance_eval(&@p)
16
+ end
17
+
18
+ specify "should create attribute? readers for all boolean attributes" do
19
+ @c.plugin(:boolean_readers)
20
+ o = @c.new
21
+ o.b?.should == nil
22
+ o.b = '1'
23
+ o.b?.should == true
24
+ o.b = '0'
25
+ o.b?.should == false
26
+ o.b = ''
27
+ o.b?.should == nil
28
+ end
29
+
30
+ specify "should not create attribute? readers for non-boolean attributes" do
31
+ @c.plugin(:boolean_readers)
32
+ proc{@c.new.y?}.should raise_error(NoMethodError)
33
+ proc{@c.new.id?}.should raise_error(NoMethodError)
34
+ end
35
+
36
+ specify "should accept a block to determine if an attribute is boolean" do
37
+ @c.plugin(:boolean_readers){|c| db_schema[c][:db_type] == 'tinyint(1)'}
38
+ proc{@c.new.b?}.should raise_error(NoMethodError)
39
+ o = @c.new
40
+ o.y.should == nil
41
+ o.y?.should == nil
42
+ o.y = '1'
43
+ o.y.should == 1
44
+ o.y?.should == true
45
+ o.y = '0'
46
+ o.y.should == 0
47
+ o.y?.should == false
48
+ o.y = ''
49
+ o.y.should == nil
50
+ o.y?.should == nil
51
+ end
52
+
53
+ specify "should create boolean readers when set_dataset is defined" do
54
+ c = Class.new(Sequel::Model(@db))
55
+ c.instance_eval(&@p)
56
+ c.plugin(:boolean_readers)
57
+ c.set_dataset(@db[:a])
58
+ o = c.new
59
+ o.b?.should == nil
60
+ o.b = '1'
61
+ o.b?.should == true
62
+ o.b = '0'
63
+ o.b?.should == false
64
+ o.b = ''
65
+ o.b?.should == nil
66
+ proc{o.i?}.should raise_error(NoMethodError)
67
+
68
+ c = Class.new(Sequel::Model(@db))
69
+ c.instance_eval(&@p)
70
+ c.plugin(:boolean_readers){|x| db_schema[x][:db_type] == 'tinyint(1)'}
71
+ c.set_dataset(@db[:a])
72
+ o = c.new
73
+ o.y.should == nil
74
+ o.y?.should == nil
75
+ o.y = '1'
76
+ o.y.should == 1
77
+ o.y?.should == true
78
+ o.y = '0'
79
+ o.y.should == 0
80
+ o.y?.should == false
81
+ o.y = ''
82
+ o.y.should == nil
83
+ o.y?.should == nil
84
+ proc{o.b?}.should raise_error(NoMethodError)
85
+ end
86
+
87
+ specify "should handle cases where getting the columns raises an error" do
88
+ @c.meta_def(:columns){raise Sequel::Error}
89
+ proc{@c.plugin(:boolean_readers)}.should_not raise_error
90
+ proc{@c.new.b?}.should raise_error(NoMethodError)
91
+ end
92
+ end