sequel 3.12.1 → 3.13.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 (150) hide show
  1. data/CHANGELOG +42 -0
  2. data/README.rdoc +137 -118
  3. data/Rakefile +21 -66
  4. data/doc/active_record.rdoc +9 -9
  5. data/doc/advanced_associations.rdoc +59 -188
  6. data/doc/association_basics.rdoc +15 -2
  7. data/doc/cheat_sheet.rdoc +38 -33
  8. data/doc/dataset_filtering.rdoc +16 -7
  9. data/doc/prepared_statements.rdoc +7 -7
  10. data/doc/querying.rdoc +5 -4
  11. data/doc/release_notes/3.13.0.txt +210 -0
  12. data/doc/sharding.rdoc +1 -1
  13. data/doc/sql.rdoc +5 -5
  14. data/doc/validations.rdoc +11 -11
  15. data/lib/sequel/adapters/ado.rb +1 -1
  16. data/lib/sequel/adapters/do.rb +3 -3
  17. data/lib/sequel/adapters/firebird.rb +3 -3
  18. data/lib/sequel/adapters/jdbc/h2.rb +39 -0
  19. data/lib/sequel/adapters/jdbc/mysql.rb +5 -0
  20. data/lib/sequel/adapters/jdbc/oracle.rb +3 -3
  21. data/lib/sequel/adapters/mysql.rb +7 -4
  22. data/lib/sequel/adapters/oracle.rb +3 -3
  23. data/lib/sequel/adapters/shared/mssql.rb +10 -1
  24. data/lib/sequel/adapters/shared/mysql.rb +63 -0
  25. data/lib/sequel/adapters/shared/postgres.rb +61 -3
  26. data/lib/sequel/adapters/sqlite.rb +105 -18
  27. data/lib/sequel/connection_pool.rb +31 -30
  28. data/lib/sequel/core.rb +58 -58
  29. data/lib/sequel/core_sql.rb +52 -43
  30. data/lib/sequel/database/misc.rb +11 -0
  31. data/lib/sequel/database/query.rb +55 -17
  32. data/lib/sequel/dataset/actions.rb +2 -1
  33. data/lib/sequel/dataset/query.rb +2 -3
  34. data/lib/sequel/dataset/sql.rb +24 -11
  35. data/lib/sequel/extensions/schema_dumper.rb +1 -1
  36. data/lib/sequel/metaprogramming.rb +4 -0
  37. data/lib/sequel/model.rb +37 -19
  38. data/lib/sequel/model/associations.rb +33 -25
  39. data/lib/sequel/model/base.rb +2 -2
  40. data/lib/sequel/model/plugins.rb +7 -2
  41. data/lib/sequel/plugins/active_model.rb +1 -1
  42. data/lib/sequel/plugins/association_pks.rb +2 -2
  43. data/lib/sequel/plugins/association_proxies.rb +1 -1
  44. data/lib/sequel/plugins/boolean_readers.rb +2 -2
  45. data/lib/sequel/plugins/class_table_inheritance.rb +10 -2
  46. data/lib/sequel/plugins/identity_map.rb +3 -3
  47. data/lib/sequel/plugins/instance_hooks.rb +1 -1
  48. data/lib/sequel/plugins/json_serializer.rb +212 -0
  49. data/lib/sequel/plugins/lazy_attributes.rb +1 -1
  50. data/lib/sequel/plugins/list.rb +174 -0
  51. data/lib/sequel/plugins/many_through_many.rb +2 -2
  52. data/lib/sequel/plugins/rcte_tree.rb +6 -7
  53. data/lib/sequel/plugins/tree.rb +118 -0
  54. data/lib/sequel/plugins/xml_serializer.rb +321 -0
  55. data/lib/sequel/sql.rb +315 -206
  56. data/lib/sequel/timezones.rb +40 -17
  57. data/lib/sequel/version.rb +8 -2
  58. data/spec/adapters/firebird_spec.rb +2 -2
  59. data/spec/adapters/informix_spec.rb +1 -1
  60. data/spec/adapters/mssql_spec.rb +2 -2
  61. data/spec/adapters/mysql_spec.rb +2 -2
  62. data/spec/adapters/oracle_spec.rb +1 -1
  63. data/spec/adapters/postgres_spec.rb +36 -6
  64. data/spec/adapters/spec_helper.rb +2 -2
  65. data/spec/adapters/sqlite_spec.rb +1 -1
  66. data/spec/core/connection_pool_spec.rb +3 -3
  67. data/spec/core/core_sql_spec.rb +31 -13
  68. data/spec/core/database_spec.rb +39 -2
  69. data/spec/core/dataset_spec.rb +24 -12
  70. data/spec/core/expression_filters_spec.rb +5 -1
  71. data/spec/core/object_graph_spec.rb +1 -1
  72. data/spec/core/schema_generator_spec.rb +1 -1
  73. data/spec/core/schema_spec.rb +1 -1
  74. data/spec/core/spec_helper.rb +1 -1
  75. data/spec/core/version_spec.rb +1 -1
  76. data/spec/extensions/active_model_spec.rb +82 -67
  77. data/spec/extensions/association_dependencies_spec.rb +1 -1
  78. data/spec/extensions/association_pks_spec.rb +1 -1
  79. data/spec/extensions/association_proxies_spec.rb +1 -1
  80. data/spec/extensions/blank_spec.rb +1 -1
  81. data/spec/extensions/boolean_readers_spec.rb +1 -1
  82. data/spec/extensions/caching_spec.rb +1 -1
  83. data/spec/extensions/class_table_inheritance_spec.rb +3 -2
  84. data/spec/extensions/composition_spec.rb +2 -5
  85. data/spec/extensions/force_encoding_spec.rb +3 -1
  86. data/spec/extensions/hook_class_methods_spec.rb +1 -1
  87. data/spec/extensions/identity_map_spec.rb +1 -1
  88. data/spec/extensions/inflector_spec.rb +1 -1
  89. data/spec/extensions/instance_filters_spec.rb +1 -1
  90. data/spec/extensions/instance_hooks_spec.rb +1 -1
  91. data/spec/extensions/json_serializer_spec.rb +154 -0
  92. data/spec/extensions/lazy_attributes_spec.rb +1 -2
  93. data/spec/extensions/list_spec.rb +251 -0
  94. data/spec/extensions/looser_typecasting_spec.rb +1 -1
  95. data/spec/extensions/many_through_many_spec.rb +3 -3
  96. data/spec/extensions/migration_spec.rb +1 -1
  97. data/spec/extensions/named_timezones_spec.rb +5 -6
  98. data/spec/extensions/nested_attributes_spec.rb +1 -1
  99. data/spec/extensions/optimistic_locking_spec.rb +1 -1
  100. data/spec/extensions/pagination_spec.rb +1 -1
  101. data/spec/extensions/pretty_table_spec.rb +1 -1
  102. data/spec/extensions/query_spec.rb +1 -1
  103. data/spec/extensions/rcte_tree_spec.rb +1 -1
  104. data/spec/extensions/schema_dumper_spec.rb +3 -2
  105. data/spec/extensions/schema_spec.rb +1 -1
  106. data/spec/extensions/serialization_spec.rb +6 -2
  107. data/spec/extensions/sharding_spec.rb +1 -1
  108. data/spec/extensions/single_table_inheritance_spec.rb +1 -1
  109. data/spec/extensions/skip_create_refresh_spec.rb +1 -1
  110. data/spec/extensions/spec_helper.rb +7 -3
  111. data/spec/extensions/sql_expr_spec.rb +1 -1
  112. data/spec/extensions/string_date_time_spec.rb +1 -1
  113. data/spec/extensions/string_stripper_spec.rb +1 -1
  114. data/spec/extensions/subclasses_spec.rb +1 -1
  115. data/spec/extensions/tactical_eager_loading_spec.rb +1 -1
  116. data/spec/extensions/thread_local_timezones_spec.rb +1 -1
  117. data/spec/extensions/timestamps_spec.rb +1 -1
  118. data/spec/extensions/touch_spec.rb +1 -1
  119. data/spec/extensions/tree_spec.rb +119 -0
  120. data/spec/extensions/typecast_on_load_spec.rb +1 -1
  121. data/spec/extensions/update_primary_key_spec.rb +1 -1
  122. data/spec/extensions/validation_class_methods_spec.rb +1 -1
  123. data/spec/extensions/validation_helpers_spec.rb +1 -1
  124. data/spec/extensions/xml_serializer_spec.rb +142 -0
  125. data/spec/integration/associations_test.rb +1 -1
  126. data/spec/integration/database_test.rb +1 -1
  127. data/spec/integration/dataset_test.rb +29 -14
  128. data/spec/integration/eager_loader_test.rb +1 -1
  129. data/spec/integration/migrator_test.rb +1 -1
  130. data/spec/integration/model_test.rb +1 -1
  131. data/spec/integration/plugin_test.rb +316 -1
  132. data/spec/integration/prepared_statement_test.rb +1 -1
  133. data/spec/integration/schema_test.rb +8 -8
  134. data/spec/integration/spec_helper.rb +1 -1
  135. data/spec/integration/timezone_test.rb +1 -1
  136. data/spec/integration/transaction_test.rb +35 -20
  137. data/spec/integration/type_test.rb +1 -1
  138. data/spec/model/association_reflection_spec.rb +1 -1
  139. data/spec/model/associations_spec.rb +49 -34
  140. data/spec/model/base_spec.rb +1 -1
  141. data/spec/model/dataset_methods_spec.rb +4 -4
  142. data/spec/model/eager_loading_spec.rb +1 -1
  143. data/spec/model/hooks_spec.rb +1 -1
  144. data/spec/model/inflector_spec.rb +1 -1
  145. data/spec/model/model_spec.rb +7 -1
  146. data/spec/model/plugins_spec.rb +1 -1
  147. data/spec/model/record_spec.rb +1 -3
  148. data/spec/model/spec_helper.rb +2 -2
  149. data/spec/model/validations_spec.rb +1 -1
  150. metadata +29 -5
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), 'spec_helper')
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper')
2
2
 
3
3
  context "Sequel sql_expr extension" do
4
4
  specify "Object#sql_expr should wrap the object in a GenericComplexExpression" do
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), 'spec_helper')
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper')
2
2
 
3
3
  context "String#to_time" do
4
4
  specify "should convert the string into a Time object" do
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), "spec_helper")
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe "Sequel::Plugins::StringStripper" do
4
4
  before do
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), "spec_helper")
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe Sequel::Model, "Subclasses plugin" do
4
4
  before do
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), "spec_helper")
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe "Sequel::Plugins::TacticalEagerLoading" do
4
4
  before do
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), "spec_helper")
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe "Sequel thread_local_timezones extension" do
4
4
  after do
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), "spec_helper")
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe "Sequel::Plugins::Timestamps" do
4
4
  before do
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), "spec_helper")
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe "Touch plugin" do
4
4
  before do
@@ -0,0 +1,119 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
+
3
+ describe Sequel::Model, "tree plugin" do
4
+ def klass(opts={})
5
+ @db = MODEL_DB
6
+ c = Class.new(Sequel::Model(@db[:nodes]))
7
+ c.class_eval do
8
+ def self.name; 'Node'; end
9
+ columns :id, :name, :parent_id, :i, :pi
10
+ end
11
+ ds = c.dataset
12
+ class << ds
13
+ attr_accessor :row_sets
14
+ def fetch_rows(sql)
15
+ @db << sql
16
+ if rs = row_sets.shift
17
+ rs.each{|row| yield row}
18
+ end
19
+ end
20
+ end
21
+ c.plugin :tree, opts
22
+ c
23
+ end
24
+
25
+ def y(c, *hs)
26
+ ds = c.dataset
27
+ ds.row_sets = hs
28
+ end
29
+
30
+ before do
31
+ @c = klass
32
+ @ds = @c.dataset
33
+ @o = @c.load(:id=>2, :parent_id=>1, :name=>'AA', :i=>3, :pi=>4)
34
+ @db.reset
35
+ end
36
+
37
+ it "should define the correct associations" do
38
+ @c.associations.sort_by{|x| x.to_s}.should == [:children, :parent]
39
+ end
40
+
41
+ it "should define the correct associations when giving options" do
42
+ klass(:children=>{:name=>:cs}, :parent=>{:name=>:p}).associations.sort_by{|x| x.to_s}.should == [:cs, :p]
43
+ end
44
+
45
+ it "should use the correct SQL for lazy associations" do
46
+ @o.parent_dataset.sql.should == 'SELECT * FROM nodes WHERE (nodes.id = 1) LIMIT 1'
47
+ @o.children_dataset.sql.should == 'SELECT * FROM nodes WHERE (nodes.parent_id = 2)'
48
+ end
49
+
50
+ it "should use the correct SQL for lazy associations when giving options" do
51
+ o = klass(:primary_key=>:i, :key=>:pi, :order=>:name, :children=>{:name=>:cs}, :parent=>{:name=>:p}).load(:id=>2, :parent_id=>1, :name=>'AA', :i=>3, :pi=>4)
52
+ o.p_dataset.sql.should == 'SELECT * FROM nodes WHERE (nodes.i = 4) ORDER BY name LIMIT 1'
53
+ o.cs_dataset.sql.should == 'SELECT * FROM nodes WHERE (nodes.pi = 3) ORDER BY name'
54
+ end
55
+
56
+ it "should have parent_column give the symbol of the parent column" do
57
+ @c.parent_column.should == :parent_id
58
+ klass(:key=>:p_id).parent_column.should == :p_id
59
+ end
60
+
61
+ it "should have tree_order give the order of the association" do
62
+ @c.tree_order.should == nil
63
+ klass(:order=>:name).tree_order.should == :name
64
+ klass(:order=>[:parent_id, :name]).tree_order.should == [:parent_id, :name]
65
+ end
66
+
67
+ it "should work correctly in subclasses" do
68
+ o = Class.new(klass(:primary_key=>:i, :key=>:pi, :order=>:name, :children=>{:name=>:cs}, :parent=>{:name=>:p})).load(:id=>2, :parent_id=>1, :name=>'AA', :i=>3, :pi=>4)
69
+ o.p_dataset.sql.should == 'SELECT * FROM nodes WHERE (nodes.i = 4) ORDER BY name LIMIT 1'
70
+ o.cs_dataset.sql.should == 'SELECT * FROM nodes WHERE (nodes.pi = 3) ORDER BY name'
71
+ end
72
+
73
+ it "should have roots return an array of the tree's roots" do
74
+ y(@c, [{:id=>1, :parent_id=>nil, :name=>'r'}])
75
+ @c.roots.should == [@c.load(:id=>1, :parent_id=>nil, :name=>'r')]
76
+ @db.sqls.should == ["SELECT * FROM nodes WHERE (parent_id IS NULL)"]
77
+ end
78
+
79
+ it "should have roots_dataset be a dataset representing the tree's roots" do
80
+ @c.roots_dataset.sql.should == "SELECT * FROM nodes WHERE (parent_id IS NULL)"
81
+ end
82
+
83
+ it "should have ancestors return the ancestors of the current node" do
84
+ y(@c, [{:id=>1, :parent_id=>5, :name=>'r'}], [{:id=>5, :parent_id=>nil, :name=>'r2'}])
85
+ @o.ancestors.should == [@c.load(:id=>1, :parent_id=>5, :name=>'r'), @c.load(:id=>5, :parent_id=>nil, :name=>'r2')]
86
+ @db.sqls.should == ["SELECT * FROM nodes WHERE (nodes.id = 1) LIMIT 1",
87
+ "SELECT * FROM nodes WHERE (nodes.id = 5) LIMIT 1"]
88
+ end
89
+
90
+ it "should have descendants return the descendants of the current node" do
91
+ y(@c, [{:id=>3, :parent_id=>2, :name=>'r'}, {:id=>4, :parent_id=>2, :name=>'r2'}], [{:id=>5, :parent_id=>4, :name=>'r3'}], [])
92
+ @o.descendants.should == [@c.load(:id=>3, :parent_id=>2, :name=>'r'), @c.load(:id=>4, :parent_id=>2, :name=>'r2'), @c.load(:id=>5, :parent_id=>4, :name=>'r3')]
93
+ @db.sqls.should == ["SELECT * FROM nodes WHERE (nodes.parent_id = 2)",
94
+ "SELECT * FROM nodes WHERE (nodes.parent_id = 3)",
95
+ "SELECT * FROM nodes WHERE (nodes.parent_id = 5)",
96
+ "SELECT * FROM nodes WHERE (nodes.parent_id = 4)"]
97
+ end
98
+
99
+ it "should have root return the root of the current node" do
100
+ y(@c, [{:id=>1, :parent_id=>5, :name=>'r'}], [{:id=>5, :parent_id=>nil, :name=>'r2'}])
101
+ @o.root.should == @c.load(:id=>5, :parent_id=>nil, :name=>'r2')
102
+ @db.sqls.should == ["SELECT * FROM nodes WHERE (nodes.id = 1) LIMIT 1",
103
+ "SELECT * FROM nodes WHERE (nodes.id = 5) LIMIT 1"]
104
+ end
105
+
106
+ it "should have self_and_siblings return the children of the current node's parent" do
107
+ y(@c, [{:id=>1, :parent_id=>3, :name=>'r'}], [{:id=>7, :parent_id=>1, :name=>'r2'}, @o.values.dup])
108
+ @o.self_and_siblings.should == [@c.load(:id=>7, :parent_id=>1, :name=>'r2'), @o]
109
+ @db.sqls.should == ["SELECT * FROM nodes WHERE (nodes.id = 1) LIMIT 1",
110
+ "SELECT * FROM nodes WHERE (nodes.parent_id = 1)"]
111
+ end
112
+
113
+ it "should have siblings return the children of the current node's parent, except for the current node" do
114
+ y(@c, [{:id=>1, :parent_id=>3, :name=>'r'}], [{:id=>7, :parent_id=>1, :name=>'r2'}, @o.values.dup])
115
+ @o.siblings.should == [@c.load(:id=>7, :parent_id=>1, :name=>'r2')]
116
+ @db.sqls.should == ["SELECT * FROM nodes WHERE (nodes.id = 1) LIMIT 1",
117
+ "SELECT * FROM nodes WHERE (nodes.parent_id = 1)"]
118
+ end
119
+ end
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), "spec_helper")
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe Sequel::Model, "TypecastOnLoad plugin" do
4
4
  before do
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), "spec_helper")
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe "Sequel::Plugins::UpdatePrimaryKey" do
4
4
  before do
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), "spec_helper")
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe Sequel::Model do
4
4
  before do
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), "spec_helper")
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe "Sequel::Plugins::ValidationHelpers" do
4
4
  before do
@@ -0,0 +1,142 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
+
3
+ begin
4
+ require 'nokogiri'
5
+ rescue LoadError => e
6
+ skip_warn "xml_serializer plugin: can't load nokogiri (#{e.class}: #{e})"
7
+ else
8
+ describe "Sequel::Plugins::XmlSerializer" do
9
+ before do
10
+ class ::Artist < Sequel::Model
11
+ plugin :xml_serializer
12
+ columns :id, :name
13
+ @db_schema = {:id=>{:type=>:integer}, :name=>{:type=>:string}}
14
+ one_to_many :albums
15
+ end
16
+ class ::Album < Sequel::Model
17
+ attr_accessor :blah
18
+ plugin :xml_serializer
19
+ columns :id, :name, :artist_id
20
+ @db_schema = {:id=>{:type=>:integer}, :name=>{:type=>:string}, :artist_id=>{:type=>:integer}}
21
+ many_to_one :artist
22
+ end
23
+ @artist = Artist.load(:id=>2, :name=>'YJM')
24
+ @artist.associations[:albums] = []
25
+ @album = Album.load(:id=>1, :name=>'RF')
26
+ @album.artist = @artist
27
+ @album.blah = 'Blah'
28
+ end
29
+ after do
30
+ Object.send(:remove_const, :Artist)
31
+ Object.send(:remove_const, :Album)
32
+ end
33
+
34
+ it "should round trip successfully" do
35
+ Artist.from_xml(@artist.to_xml).should == @artist
36
+ Album.from_xml(@album.to_xml).should == @album
37
+ end
38
+
39
+ it "should handle the :only option" do
40
+ Artist.from_xml(@artist.to_xml(:only=>:name)).should == Artist.load(:name=>@artist.name)
41
+ Album.from_xml(@album.to_xml(:only=>[:id, :name])).should == Album.load(:id=>@album.id, :name=>@album.name)
42
+ end
43
+
44
+ it "should handle the :except option" do
45
+ Artist.from_xml(@artist.to_xml(:except=>:id)).should == Artist.load(:name=>@artist.name)
46
+ Album.from_xml(@album.to_xml(:except=>[:id, :artist_id])).should == Album.load(:name=>@album.name)
47
+ end
48
+
49
+ it "should handle the :include option for associations" do
50
+ Artist.from_xml(@artist.to_xml(:include=>:albums)).albums.should == [@album]
51
+ Album.from_xml(@album.to_xml(:include=>:artist)).artist.should == @artist
52
+ end
53
+
54
+ it "should handle the :include option for arbitrary attributes" do
55
+ Album.from_xml(@album.to_xml(:include=>:blah)).blah.should == @album.blah
56
+ end
57
+
58
+ it "should handle multiple inclusions using an array for the :include option" do
59
+ a = Album.from_xml(@album.to_xml(:include=>[:blah, :artist]))
60
+ a.blah.should == @album.blah
61
+ a.artist.should == @artist
62
+ end
63
+
64
+ it "should handle cascading using a hash for the :include option" do
65
+ Artist.from_xml(@artist.to_xml(:include=>{:albums=>{:include=>:artist}})).albums.map{|a| a.artist}.should == [@artist]
66
+ Album.from_xml(@album.to_xml(:include=>{:artist=>{:include=>:albums}})).artist.albums.should == [@album]
67
+
68
+ Artist.from_xml(@artist.to_xml(:include=>{:albums=>{:only=>:name}})).albums.should == [Album.load(:name=>@album.name)]
69
+ Album.from_xml(@album.to_xml(:include=>{:artist=>{:except=>:name}})).artist.should == Artist.load(:id=>@artist.id)
70
+
71
+ Artist.from_xml(@artist.to_xml(:include=>{:albums=>{:include=>{:artist=>{:include=>:albums}}}})).albums.map{|a| a.artist.albums}.should == [[@album]]
72
+ Album.from_xml(@album.to_xml(:include=>{:artist=>{:include=>{:albums=>{:only=>:name}}}})).artist.albums.should == [Album.load(:name=>@album.name)]
73
+ end
74
+
75
+ it "should handle the :include option cascading with an empty hash" do
76
+ Album.from_xml(@album.to_xml(:include=>{:artist=>{}})).artist.should == @artist
77
+ Album.from_xml(@album.to_xml(:include=>{:blah=>{}})).blah.should == @album.blah
78
+ end
79
+
80
+ it "should support #from_xml to set column values" do
81
+ @artist.from_xml('<album><name>AS</name></album>')
82
+ @artist.name.should == 'AS'
83
+ @artist.id.should == 2
84
+ end
85
+
86
+ it "should support a :name_proc option when serializing and deserializing" do
87
+ Album.from_xml(@album.to_xml(:name_proc=>proc{|s| s.reverse}), :name_proc=>proc{|s| s.reverse}).should == @album
88
+ end
89
+
90
+ it "should support a :camelize option when serializing and :underscore option when deserializing" do
91
+ Album.from_xml(@album.to_xml(:camelize=>true), :underscore=>true).should == @album
92
+ end
93
+
94
+ it "should support a :camelize option when serializing and :underscore option when deserializing" do
95
+ Album.from_xml(@album.to_xml(:dasherize=>true), :underscore=>true).should == @album
96
+ end
97
+
98
+ it "should support an :encoding option when serializing" do
99
+ ["<?xml version=\"1.0\" encoding=\"utf-8\"?><artist><id>2</id><name>YJM</name></artist>",
100
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?><artist><name>YJM</name><id>2</id></artist>"].should include(@artist.to_xml(:encoding=>'utf-8').gsub(/\n */m, ''))
101
+ end
102
+
103
+ it "should support a :builder_opts option when serializing" do
104
+ ["<?xml version=\"1.0\" encoding=\"utf-8\"?><artist><id>2</id><name>YJM</name></artist>",
105
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?><artist><name>YJM</name><id>2</id></artist>"].should include(@artist.to_xml(:builder_opts=>{:encoding=>'utf-8'}).gsub(/\n */m, ''))
106
+ end
107
+
108
+ it "should support an :types option when serializing" do
109
+ ["<?xml version=\"1.0\"?><artist><id type=\"integer\">2</id><name type=\"string\">YJM</name></artist>",
110
+ "<?xml version=\"1.0\"?><artist><name type=\"string\">YJM</name><id type=\"integer\">2</id></artist>"].should include(@artist.to_xml(:types=>true).gsub(/\n */m, ''))
111
+ end
112
+
113
+ it "should support an :root_name option when serializing" do
114
+ ["<?xml version=\"1.0\"?><ar><id>2</id><name>YJM</name></ar>",
115
+ "<?xml version=\"1.0\"?><ar><name>YJM</name><id>2</id></ar>"].should include(@artist.to_xml(:root_name=>'ar').gsub(/\n */m, ''))
116
+ end
117
+
118
+ it "should support an :array_root_name option when serializing arrays" do
119
+ artist = @artist
120
+ Artist.dataset.meta_def(:all){[artist]}
121
+ ["<?xml version=\"1.0\"?><ars><ar><id>2</id><name>YJM</name></ar></ars>",
122
+ "<?xml version=\"1.0\"?><ars><ar><name>YJM</name><id>2</id></ar></ars>"].should include(Artist.to_xml(:array_root_name=>'ars', :root_name=>'ar').gsub(/\n */m, ''))
123
+ end
124
+
125
+ it "should raise an exception for xml tags that aren't associations, columns, or setter methods" do
126
+ Album.send(:undef_method, :blah=)
127
+ proc{Album.from_xml(@album.to_xml(:include=>:blah))}.should raise_error(Sequel::Error)
128
+ end
129
+
130
+ it "should support a to_xml class and dataset method" do
131
+ album = @album
132
+ Album.dataset.meta_def(:all){[album]}
133
+ Album.array_from_xml(Album.to_xml).should == [@album]
134
+ Album.array_from_xml(Album.to_xml(:include=>:artist)).map{|x| x.artist}.should == [@artist]
135
+ Album.array_from_xml(Album.dataset.to_xml(:only=>:name)).should == [Album.load(:name=>@album.name)]
136
+ end
137
+
138
+ it "should raise an error if the dataset does not have a row_proc" do
139
+ proc{Album.dataset.naked.to_xml}.should raise_error(Sequel::Error)
140
+ end
141
+ end
142
+ end
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), 'spec_helper.rb')
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
2
2
 
3
3
  shared_examples_for "regular and composite key associations" do
4
4
  specify "should return no objects if none are associated" do
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), 'spec_helper.rb')
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
2
2
 
3
3
  describe Sequel::Database do
4
4
  specify "should provide disconnect functionality" do
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), 'spec_helper.rb')
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
2
2
 
3
3
  describe "Simple Dataset operations" do
4
4
  before do
@@ -656,32 +656,47 @@ describe "Sequel::Dataset DSL support" do
656
656
  @ds.get{a / b}.to_i.should == 2
657
657
  end
658
658
 
659
- cspecify "should work with standard bitwise mathematical operators", :mssql, :h2 do
660
- @ds.insert(24, 2)
661
- @ds.get{a.sql_number << b}.to_i.should == 96
662
- @ds.get{a.sql_number >> b}.to_i.should == 6
659
+ specify "should work with bitwise shift operators" do
660
+ @ds.insert(3, 2)
661
+ @ds.get{a.sql_number << b}.to_i.should == 12
662
+ @ds.get{a.sql_number >> b}.to_i.should == 0
663
663
  @ds.delete
664
+ @ds.insert(3, 1)
665
+ @ds.get{a.sql_number << b}.to_i.should == 6
666
+ @ds.get{a.sql_number >> b}.to_i.should == 1
667
+ end
668
+
669
+ specify "should work with bitwise AND and OR operators" do
664
670
  @ds.insert(3, 5)
665
671
  @ds.get{a.sql_number | b}.to_i.should == 7
666
672
  @ds.get{a.sql_number & b}.to_i.should == 1
667
673
  end
668
674
 
669
- cspecify "should work with the bitwise compliment operator", :mysql, :h2 do
675
+ cspecify "should work with the bitwise compliment operator", :h2 do
676
+ @ds.insert(-3, 3)
677
+ @ds.get{~a.sql_number}.to_i.should == 2
678
+ @ds.get{~b.sql_number}.to_i.should == -4
679
+ end
680
+
681
+ cspecify "should work with the bitwise xor operator", :sqlite do
670
682
  @ds.insert(3, 5)
671
- @ds.get{~a.sql_number}.to_i.should == -4
683
+ @ds.get{a.sql_number ^ b}.to_i.should == 6
672
684
  end
673
685
 
674
- cspecify "should work with inequality operators", :mssql do
686
+ specify "should work with inequality operators" do
687
+ @ds.insert(10, 11)
688
+ @ds.insert(11, 11)
689
+ @ds.insert(20, 19)
675
690
  @ds.insert(20, 20)
676
- ['0', 0, false].should include(@ds.get{a > b})
677
- ['0', 0, false].should include(@ds.get{a < b})
678
- ['1', 1, true].should include(@ds.get{a <= b})
679
- ['1', 1, true].should include(@ds.get{a >= b})
691
+ @ds.filter{a > b}.select_order_map(:a).should == [20]
692
+ @ds.filter{a >= b}.select_order_map(:a).should == [11, 20, 20]
693
+ @ds.filter{a < b}.select_order_map(:a).should == [10]
694
+ @ds.filter{a <= b}.select_order_map(:a).should == [10, 11, 20]
680
695
  end
681
696
 
682
- cspecify "should work with casting and string concatentation", :mssql do
697
+ specify "should work with casting and string concatentation" do
683
698
  @ds.insert(20, 20)
684
- @ds.get{a.cast_string + b}.should == '2020'
699
+ @ds.get{a.cast_string + b.cast_string}.should == '2020'
685
700
  end
686
701
 
687
702
  it "should work with ordering" do
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), 'spec_helper.rb')
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
2
2
 
3
3
  describe "Eagerly loading a tree structure" do
4
4
  before do
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), 'spec_helper.rb')
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
2
2
 
3
3
  Sequel.extension :migration
4
4
  describe Sequel::Migrator do
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), 'spec_helper.rb')
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
2
2
 
3
3
  describe "Sequel::Model basic support" do
4
4
  before do