sequel 3.12.1 → 3.13.0

Sign up to get free protection for your applications and to get access to all the features.
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