epugh-sequel 0.0.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 (134) hide show
  1. data/README.rdoc +652 -0
  2. data/VERSION.yml +4 -0
  3. data/bin/sequel +104 -0
  4. data/lib/sequel.rb +1 -0
  5. data/lib/sequel/adapters/ado.rb +85 -0
  6. data/lib/sequel/adapters/db2.rb +132 -0
  7. data/lib/sequel/adapters/dbi.rb +101 -0
  8. data/lib/sequel/adapters/do.rb +197 -0
  9. data/lib/sequel/adapters/do/mysql.rb +38 -0
  10. data/lib/sequel/adapters/do/postgres.rb +92 -0
  11. data/lib/sequel/adapters/do/sqlite.rb +31 -0
  12. data/lib/sequel/adapters/firebird.rb +307 -0
  13. data/lib/sequel/adapters/informix.rb +75 -0
  14. data/lib/sequel/adapters/jdbc.rb +485 -0
  15. data/lib/sequel/adapters/jdbc/h2.rb +62 -0
  16. data/lib/sequel/adapters/jdbc/mysql.rb +56 -0
  17. data/lib/sequel/adapters/jdbc/oracle.rb +23 -0
  18. data/lib/sequel/adapters/jdbc/postgresql.rb +101 -0
  19. data/lib/sequel/adapters/jdbc/sqlite.rb +43 -0
  20. data/lib/sequel/adapters/mysql.rb +370 -0
  21. data/lib/sequel/adapters/odbc.rb +184 -0
  22. data/lib/sequel/adapters/openbase.rb +57 -0
  23. data/lib/sequel/adapters/oracle.rb +140 -0
  24. data/lib/sequel/adapters/postgres.rb +453 -0
  25. data/lib/sequel/adapters/shared/mssql.rb +93 -0
  26. data/lib/sequel/adapters/shared/mysql.rb +341 -0
  27. data/lib/sequel/adapters/shared/oracle.rb +62 -0
  28. data/lib/sequel/adapters/shared/postgres.rb +743 -0
  29. data/lib/sequel/adapters/shared/progress.rb +34 -0
  30. data/lib/sequel/adapters/shared/sqlite.rb +263 -0
  31. data/lib/sequel/adapters/sqlite.rb +243 -0
  32. data/lib/sequel/adapters/utils/date_format.rb +21 -0
  33. data/lib/sequel/adapters/utils/stored_procedures.rb +75 -0
  34. data/lib/sequel/adapters/utils/unsupported.rb +62 -0
  35. data/lib/sequel/connection_pool.rb +258 -0
  36. data/lib/sequel/core.rb +204 -0
  37. data/lib/sequel/core_sql.rb +185 -0
  38. data/lib/sequel/database.rb +687 -0
  39. data/lib/sequel/database/schema_generator.rb +324 -0
  40. data/lib/sequel/database/schema_methods.rb +164 -0
  41. data/lib/sequel/database/schema_sql.rb +324 -0
  42. data/lib/sequel/dataset.rb +422 -0
  43. data/lib/sequel/dataset/convenience.rb +237 -0
  44. data/lib/sequel/dataset/prepared_statements.rb +220 -0
  45. data/lib/sequel/dataset/sql.rb +1105 -0
  46. data/lib/sequel/deprecated.rb +529 -0
  47. data/lib/sequel/exceptions.rb +44 -0
  48. data/lib/sequel/extensions/blank.rb +42 -0
  49. data/lib/sequel/extensions/inflector.rb +288 -0
  50. data/lib/sequel/extensions/pagination.rb +96 -0
  51. data/lib/sequel/extensions/pretty_table.rb +78 -0
  52. data/lib/sequel/extensions/query.rb +48 -0
  53. data/lib/sequel/extensions/string_date_time.rb +47 -0
  54. data/lib/sequel/metaprogramming.rb +44 -0
  55. data/lib/sequel/migration.rb +212 -0
  56. data/lib/sequel/model.rb +142 -0
  57. data/lib/sequel/model/association_reflection.rb +263 -0
  58. data/lib/sequel/model/associations.rb +1024 -0
  59. data/lib/sequel/model/base.rb +911 -0
  60. data/lib/sequel/model/deprecated.rb +188 -0
  61. data/lib/sequel/model/deprecated_hooks.rb +103 -0
  62. data/lib/sequel/model/deprecated_inflector.rb +335 -0
  63. data/lib/sequel/model/deprecated_validations.rb +384 -0
  64. data/lib/sequel/model/errors.rb +37 -0
  65. data/lib/sequel/model/exceptions.rb +7 -0
  66. data/lib/sequel/model/inflections.rb +230 -0
  67. data/lib/sequel/model/plugins.rb +74 -0
  68. data/lib/sequel/object_graph.rb +230 -0
  69. data/lib/sequel/plugins/caching.rb +122 -0
  70. data/lib/sequel/plugins/hook_class_methods.rb +122 -0
  71. data/lib/sequel/plugins/schema.rb +53 -0
  72. data/lib/sequel/plugins/single_table_inheritance.rb +63 -0
  73. data/lib/sequel/plugins/validation_class_methods.rb +373 -0
  74. data/lib/sequel/sql.rb +854 -0
  75. data/lib/sequel/version.rb +11 -0
  76. data/lib/sequel_core.rb +1 -0
  77. data/lib/sequel_model.rb +1 -0
  78. data/spec/adapters/ado_spec.rb +46 -0
  79. data/spec/adapters/firebird_spec.rb +376 -0
  80. data/spec/adapters/informix_spec.rb +96 -0
  81. data/spec/adapters/mysql_spec.rb +875 -0
  82. data/spec/adapters/oracle_spec.rb +272 -0
  83. data/spec/adapters/postgres_spec.rb +692 -0
  84. data/spec/adapters/spec_helper.rb +10 -0
  85. data/spec/adapters/sqlite_spec.rb +550 -0
  86. data/spec/core/connection_pool_spec.rb +526 -0
  87. data/spec/core/core_ext_spec.rb +156 -0
  88. data/spec/core/core_sql_spec.rb +528 -0
  89. data/spec/core/database_spec.rb +1214 -0
  90. data/spec/core/dataset_spec.rb +3513 -0
  91. data/spec/core/expression_filters_spec.rb +363 -0
  92. data/spec/core/migration_spec.rb +261 -0
  93. data/spec/core/object_graph_spec.rb +280 -0
  94. data/spec/core/pretty_table_spec.rb +58 -0
  95. data/spec/core/schema_generator_spec.rb +167 -0
  96. data/spec/core/schema_spec.rb +778 -0
  97. data/spec/core/spec_helper.rb +82 -0
  98. data/spec/core/version_spec.rb +7 -0
  99. data/spec/extensions/blank_spec.rb +67 -0
  100. data/spec/extensions/caching_spec.rb +201 -0
  101. data/spec/extensions/hook_class_methods_spec.rb +470 -0
  102. data/spec/extensions/inflector_spec.rb +122 -0
  103. data/spec/extensions/pagination_spec.rb +99 -0
  104. data/spec/extensions/pretty_table_spec.rb +91 -0
  105. data/spec/extensions/query_spec.rb +85 -0
  106. data/spec/extensions/schema_spec.rb +111 -0
  107. data/spec/extensions/single_table_inheritance_spec.rb +53 -0
  108. data/spec/extensions/spec_helper.rb +90 -0
  109. data/spec/extensions/string_date_time_spec.rb +93 -0
  110. data/spec/extensions/validation_class_methods_spec.rb +1054 -0
  111. data/spec/integration/dataset_test.rb +160 -0
  112. data/spec/integration/eager_loader_test.rb +683 -0
  113. data/spec/integration/prepared_statement_test.rb +130 -0
  114. data/spec/integration/schema_test.rb +183 -0
  115. data/spec/integration/spec_helper.rb +75 -0
  116. data/spec/integration/type_test.rb +96 -0
  117. data/spec/model/association_reflection_spec.rb +93 -0
  118. data/spec/model/associations_spec.rb +1780 -0
  119. data/spec/model/base_spec.rb +494 -0
  120. data/spec/model/caching_spec.rb +217 -0
  121. data/spec/model/dataset_methods_spec.rb +78 -0
  122. data/spec/model/eager_loading_spec.rb +1165 -0
  123. data/spec/model/hooks_spec.rb +472 -0
  124. data/spec/model/inflector_spec.rb +126 -0
  125. data/spec/model/model_spec.rb +588 -0
  126. data/spec/model/plugins_spec.rb +142 -0
  127. data/spec/model/record_spec.rb +1243 -0
  128. data/spec/model/schema_spec.rb +92 -0
  129. data/spec/model/spec_helper.rb +124 -0
  130. data/spec/model/validations_spec.rb +1080 -0
  131. data/spec/rcov.opts +6 -0
  132. data/spec/spec.opts +0 -0
  133. data/spec/spec_config.rb.example +10 -0
  134. metadata +202 -0
@@ -0,0 +1,280 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe Sequel::Dataset, " graphing" do
4
+ before do
5
+ dbc = Class.new
6
+ @db = dbc.new
7
+ @ds1 = Sequel::Dataset.new(@db).from(:points)
8
+ @ds2 = Sequel::Dataset.new(@db).from(:lines)
9
+ @ds3 = Sequel::Dataset.new(@db).from(:graphs)
10
+ dss = {:points=>@ds1, :lines=>@ds2, :graphs=>@ds3}
11
+ dbc.send(:define_method, :[]){|ds| dss[ds]}
12
+ def @ds1.columns; [:id, :x, :y] end
13
+ def @ds2.columns; [:id, :x, :y, :graph_id] end
14
+ def @ds3.columns; [:id, :name, :x, :y, :lines_x] end
15
+ end
16
+
17
+ it "#graph should not modify the current dataset's opts" do
18
+ o1 = @ds1.opts
19
+ o2 = o1.dup
20
+ ds1 = @ds1.graph(@ds2, :x=>:id)
21
+ @ds1.opts.should == o1
22
+ @ds1.opts.should == o2
23
+ ds1.opts.should_not == o1
24
+ end
25
+
26
+ it "#graph should accept a dataset as the dataset" do
27
+ ds = @ds1.graph(@ds2, :x=>:id)
28
+ ds.sql.should == 'SELECT points.id, points.x, points.y, lines.id AS lines_id, lines.x AS lines_x, lines.y AS lines_y, lines.graph_id FROM points LEFT OUTER JOIN lines ON (lines.x = points.id)'
29
+ end
30
+
31
+ it "#graph should accept a symbol table name as the dataset" do
32
+ ds = @ds1.graph(:lines, :x=>:id)
33
+ ds.sql.should == 'SELECT points.id, points.x, points.y, lines.id AS lines_id, lines.x AS lines_x, lines.y AS lines_y, lines.graph_id FROM points LEFT OUTER JOIN lines ON (lines.x = points.id)'
34
+ end
35
+
36
+ it "#graph should accept an object that responds to dataset as the dataset" do
37
+ oc = Class.new
38
+ o = oc.new
39
+ ds = @ds2
40
+ oc.send(:define_method, :dataset){ds}
41
+ ds = @ds1.graph(o, :x=>:id)
42
+ ds.sql.should == 'SELECT points.id, points.x, points.y, lines.id AS lines_id, lines.x AS lines_x, lines.y AS lines_y, lines.graph_id FROM points LEFT OUTER JOIN lines ON (lines.x = points.id)'
43
+ ds = :lines
44
+ oc.send(:define_method, :dataset){ds}
45
+ ds = @ds1.graph(o, :x=>:id)
46
+ ds.sql.should == 'SELECT points.id, points.x, points.y, lines.id AS lines_id, lines.x AS lines_x, lines.y AS lines_y, lines.graph_id FROM points LEFT OUTER JOIN lines ON (lines.x = points.id)'
47
+ end
48
+
49
+ it "#graph should raise an error if a symbol, dataset, or model is not used" do
50
+ proc{@ds1.graph(Object.new, :x=>:id)}.should raise_error(Sequel::Error)
51
+ end
52
+
53
+ it "#graph should accept a :table_alias option" do
54
+ ds = @ds1.graph(:lines, {:x=>:id}, :table_alias=>:planes)
55
+ ds.sql.should == 'SELECT points.id, points.x, points.y, planes.id AS planes_id, planes.x AS planes_x, planes.y AS planes_y, planes.graph_id FROM points LEFT OUTER JOIN lines AS planes ON (planes.x = points.id)'
56
+ end
57
+
58
+ it "#graph should accept a :implicit_qualifier option" do
59
+ ds = @ds1.graph(:lines, {:x=>:id}, :implicit_qualifier=>:planes)
60
+ ds.sql.should == 'SELECT points.id, points.x, points.y, lines.id AS lines_id, lines.x AS lines_x, lines.y AS lines_y, lines.graph_id FROM points LEFT OUTER JOIN lines ON (lines.x = planes.id)'
61
+ end
62
+
63
+ it "#graph should accept a :join_type option" do
64
+ ds = @ds1.graph(:lines, {:x=>:id}, :join_type=>:inner)
65
+ ds.sql.should == 'SELECT points.id, points.x, points.y, lines.id AS lines_id, lines.x AS lines_x, lines.y AS lines_y, lines.graph_id FROM points INNER JOIN lines ON (lines.x = points.id)'
66
+ end
67
+
68
+ it "#graph should not select any columns from the graphed table if :select option is false" do
69
+ ds = @ds1.graph(:lines, {:x=>:id}, :select=>false).graph(:graphs, :id=>:graph_id)
70
+ ds.sql.should == 'SELECT points.id, points.x, points.y, graphs.id AS graphs_id, graphs.name, graphs.x AS graphs_x, graphs.y AS graphs_y, graphs.lines_x FROM points LEFT OUTER JOIN lines ON (lines.x = points.id) LEFT OUTER JOIN graphs ON (graphs.id = lines.graph_id)'
71
+ end
72
+
73
+ it "#graph should use the given columns if :select option is used" do
74
+ ds = @ds1.graph(:lines, {:x=>:id}, :select=>[:x, :graph_id]).graph(:graphs, :id=>:graph_id)
75
+ ds.sql.should == 'SELECT points.id, points.x, points.y, lines.x AS lines_x, lines.graph_id, graphs.id AS graphs_id, graphs.name, graphs.x AS graphs_x, graphs.y AS graphs_y, graphs.lines_x AS graphs_lines_x FROM points LEFT OUTER JOIN lines ON (lines.x = points.id) LEFT OUTER JOIN graphs ON (graphs.id = lines.graph_id)'
76
+ end
77
+
78
+ it "#graph should pass all join_conditions to join_table" do
79
+ ds = @ds1.graph(@ds2, [[:x, :id], [:y, :id]])
80
+ ds.sql.should == 'SELECT points.id, points.x, points.y, lines.id AS lines_id, lines.x AS lines_x, lines.y AS lines_y, lines.graph_id FROM points LEFT OUTER JOIN lines ON ((lines.x = points.id) AND (lines.y = points.id))'
81
+ end
82
+
83
+ it "#graph should accept a block instead of conditions and pass it to join_table" do
84
+ ds = @ds1.graph(@ds2){|ja, lja, js| [[:x.qualify(ja), :id.qualify(lja)], [:y.qualify(ja), :id.qualify(lja)]]}
85
+ ds.sql.should == 'SELECT points.id, points.x, points.y, lines.id AS lines_id, lines.x AS lines_x, lines.y AS lines_y, lines.graph_id FROM points LEFT OUTER JOIN lines ON ((lines.x = points.id) AND (lines.y = points.id))'
86
+ end
87
+
88
+ it "#graph should not add columns if graph is called after set_graph_aliases" do
89
+ ds = @ds1.set_graph_aliases([[:x,[:points, :x]], [:y,[:lines, :y]]])
90
+ ds.sql.should == 'SELECT points.x, lines.y FROM points'
91
+ ds = ds.graph(:lines, :x=>:id)
92
+ ds.sql.should == 'SELECT points.x, lines.y FROM points LEFT OUTER JOIN lines ON (lines.x = points.id)'
93
+ end
94
+
95
+ it "#graph should allow graphing of multiple datasets" do
96
+ ds = @ds1.graph(@ds2, :x=>:id).graph(@ds3, :id=>:graph_id)
97
+ ds.sql.should == 'SELECT points.id, points.x, points.y, lines.id AS lines_id, lines.x AS lines_x, lines.y AS lines_y, lines.graph_id, graphs.id AS graphs_id, graphs.name, graphs.x AS graphs_x, graphs.y AS graphs_y, graphs.lines_x AS graphs_lines_x FROM points LEFT OUTER JOIN lines ON (lines.x = points.id) LEFT OUTER JOIN graphs ON (graphs.id = lines.graph_id)'
98
+ end
99
+
100
+ it "#graph should allow graphing of the same dataset multiple times" do
101
+ ds = @ds1.graph(@ds2, :x=>:id).graph(@ds2, {:y=>:points__id}, :table_alias=>:graph)
102
+ ds.sql.should == 'SELECT points.id, points.x, points.y, lines.id AS lines_id, lines.x AS lines_x, lines.y AS lines_y, lines.graph_id, graph.id AS graph_id_0, graph.x AS graph_x, graph.y AS graph_y, graph.graph_id AS graph_graph_id FROM points LEFT OUTER JOIN lines ON (lines.x = points.id) LEFT OUTER JOIN lines AS graph ON (graph.y = points.id)'
103
+ end
104
+
105
+ it "#graph should raise an error if the table/table alias has already been used" do
106
+ proc{@ds1.graph(@ds1, :x=>:id)}.should raise_error(Sequel::Error)
107
+ proc{@ds1.graph(@ds2, :x=>:id)}.should_not raise_error
108
+ proc{@ds1.graph(@ds2, :x=>:id).graph(@ds2, :x=>:id)}.should raise_error(Sequel::Error)
109
+ proc{@ds1.graph(@ds2, :x=>:id).graph(@ds2, {:x=>:id}, :table_alias=>:blah)}.should_not raise_error
110
+ end
111
+
112
+ it "#set_graph_aliases and #add_graph_aliases should not modify the current dataset's opts" do
113
+ o1 = @ds1.opts
114
+ o2 = o1.dup
115
+ ds1 = @ds1.set_graph_aliases(:x=>[:graphs,:id])
116
+ @ds1.opts.should == o1
117
+ @ds1.opts.should == o2
118
+ ds1.opts.should_not == o1
119
+ o3 = ds1.opts
120
+ o4 = o3.dup
121
+ ds2 = ds1.add_graph_aliases(:y=>[:blah,:id])
122
+ ds1.opts.should == o3
123
+ ds1.opts.should == o3
124
+ ds2.opts.should_not == o2
125
+ end
126
+
127
+ it "#set_graph_aliases should specify the graph mapping" do
128
+ ds = @ds1.graph(:lines, :x=>:id)
129
+ ds.sql.should == 'SELECT points.id, points.x, points.y, lines.id AS lines_id, lines.x AS lines_x, lines.y AS lines_y, lines.graph_id FROM points LEFT OUTER JOIN lines ON (lines.x = points.id)'
130
+ ds = ds.set_graph_aliases(:x=>[:points, :x], :y=>[:lines, :y])
131
+ ['SELECT points.x, lines.y FROM points LEFT OUTER JOIN lines ON (lines.x = points.id)',
132
+ 'SELECT lines.y, points.x FROM points LEFT OUTER JOIN lines ON (lines.x = points.id)'
133
+ ].should(include(ds.sql))
134
+ end
135
+
136
+ it "#add_graph_aliases should add columns to the graph mapping" do
137
+ @ds1.graph(:lines, :x=>:id).set_graph_aliases(:x=>[:points, :q]).add_graph_aliases(:y=>[:lines, :r]).sql.should == 'SELECT points.q AS x, lines.r AS y FROM points LEFT OUTER JOIN lines ON (lines.x = points.id)'
138
+ end
139
+
140
+ it "#set_graph_aliases should allow a third entry to specify an expression to use other than the default" do
141
+ ds = @ds1.graph(:lines, :x=>:id).set_graph_aliases(:x=>[:points, :x, 1], :y=>[:lines, :y, :random.sql_function])
142
+ ['SELECT 1 AS x, random() AS y FROM points LEFT OUTER JOIN lines ON (lines.x = points.id)',
143
+ 'SELECT random() AS y, 1 AS x FROM points LEFT OUTER JOIN lines ON (lines.x = points.id)'
144
+ ].should(include(ds.sql))
145
+ end
146
+
147
+ it "#set_graph_aliases should only alias columns if necessary" do
148
+ ds = @ds1.set_graph_aliases(:x=>[:points, :x], :y=>[:lines, :y])
149
+ ['SELECT points.x, lines.y FROM points',
150
+ 'SELECT lines.y, points.x FROM points'
151
+ ].should(include(ds.sql))
152
+
153
+ ds = @ds1.set_graph_aliases(:x1=>[:points, :x], :y=>[:lines, :y])
154
+ ['SELECT points.x AS x1, lines.y FROM points',
155
+ 'SELECT lines.y, points.x AS x1 FROM points'
156
+ ].should(include(ds.sql))
157
+ end
158
+
159
+ it "#graph_each should split the result set into component tables" do
160
+ ds = @ds1.graph(@ds2, :x=>:id)
161
+ def ds.fetch_rows(sql, &block)
162
+ yield({:id=>1,:x=>2,:y=>3,:lines_id=>4,:lines_x=>5,:lines_y=>6,:graph_id=>7})
163
+ end
164
+ results = ds.all
165
+ results.length.should == 1
166
+ results.first.should == {:points=>{:id=>1, :x=>2, :y=>3}, :lines=>{:id=>4, :x=>5, :y=>6, :graph_id=>7}}
167
+
168
+ ds = @ds1.graph(@ds2, :x=>:id).graph(@ds3, :id=>:graph_id)
169
+ def ds.fetch_rows(sql, &block)
170
+ yield({:id=>1,:x=>2,:y=>3,:lines_id=>4,:lines_x=>5,:lines_y=>6,:graph_id=>7, :graphs_id=>8, :name=>9, :graphs_x=>10, :graphs_y=>11, :graphs_lines_x=>12})
171
+ end
172
+ results = ds.all
173
+ results.length.should == 1
174
+ results.first.should == {:points=>{:id=>1, :x=>2, :y=>3}, :lines=>{:id=>4, :x=>5, :y=>6, :graph_id=>7}, :graphs=>{:id=>8, :name=>9, :x=>10, :y=>11, :lines_x=>12}}
175
+
176
+ ds = @ds1.graph(@ds2, :x=>:id).graph(@ds2, {:y=>:points__id}, :table_alias=>:graph)
177
+ def ds.fetch_rows(sql, &block)
178
+ yield({:id=>1,:x=>2,:y=>3,:lines_id=>4,:lines_x=>5,:lines_y=>6,:graph_id=>7, :graph_id_0=>8, :graph_x=>9, :graph_y=>10, :graph_graph_id=>11})
179
+ end
180
+ results = ds.all
181
+ results.length.should == 1
182
+ results.first.should == {:points=>{:id=>1, :x=>2, :y=>3}, :lines=>{:id=>4, :x=>5, :y=>6, :graph_id=>7}, :graph=>{:id=>8, :x=>9, :y=>10, :graph_id=>11}}
183
+ end
184
+
185
+ it "#graph_each should give a nil value instead of a hash when all values for a table are nil" do
186
+ ds = @ds1.graph(@ds2, :x=>:id)
187
+ def ds.fetch_rows(sql, &block)
188
+ yield({:id=>1,:x=>2,:y=>3,:lines_id=>nil,:lines_x=>nil,:lines_y=>nil,:graph_id=>nil})
189
+ end
190
+ results = ds.all
191
+ results.length.should == 1
192
+ results.first.should == {:points=>{:id=>1, :x=>2, :y=>3}, :lines=>nil}
193
+
194
+ ds = @ds1.graph(@ds2, :x=>:id).graph(@ds3, :id=>:graph_id)
195
+ def ds.fetch_rows(sql, &block)
196
+ yield({:id=>1,:x=>2,:y=>3,:lines_id=>4,:lines_x=>5,:lines_y=>6,:graph_id=>7, :graphs_id=>nil, :name=>nil, :graphs_x=>nil, :graphs_y=>nil, :graphs_lines_x=>nil})
197
+ yield({:id=>2,:x=>4,:y=>5,:lines_id=>nil,:lines_x=>nil,:lines_y=>nil,:graph_id=>nil, :graphs_id=>nil, :name=>nil, :graphs_x=>nil, :graphs_y=>nil, :graphs_lines_x=>nil})
198
+ yield({:id=>3,:x=>5,:y=>6,:lines_id=>4,:lines_x=>5,:lines_y=>6,:graph_id=>7, :graphs_id=>7, :name=>8, :graphs_x=>9, :graphs_y=>10, :graphs_lines_x=>11})
199
+ yield({:id=>3,:x=>5,:y=>6,:lines_id=>7,:lines_x=>5,:lines_y=>8,:graph_id=>9, :graphs_id=>9, :name=>10, :graphs_x=>10, :graphs_y=>11, :graphs_lines_x=>12})
200
+ end
201
+ results = ds.all
202
+ results.length.should == 4
203
+ results[0].should == {:points=>{:id=>1, :x=>2, :y=>3}, :lines=>{:id=>4, :x=>5, :y=>6, :graph_id=>7}, :graphs=>nil}
204
+ results[1].should == {:points=>{:id=>2, :x=>4, :y=>5}, :lines=>nil, :graphs=>nil}
205
+ results[2].should == {:points=>{:id=>3, :x=>5, :y=>6}, :lines=>{:id=>4, :x=>5, :y=>6, :graph_id=>7}, :graphs=>{:id=>7, :name=>8, :x=>9, :y=>10, :lines_x=>11}}
206
+ results[3].should == {:points=>{:id=>3, :x=>5, :y=>6}, :lines=>{:id=>7, :x=>5, :y=>8, :graph_id=>9}, :graphs=>{:id=>9, :name=>10, :x=>10, :y=>11, :lines_x=>12}}
207
+ end
208
+
209
+ it "#graph_each should not give a nil value instead of a hash when any value for a table is false" do
210
+ ds = @ds1.graph(@ds2, :x=>:id)
211
+ def ds.fetch_rows(sql, &block)
212
+ block.call(:id=>1,:x=>2,:y=>3,:lines_id=>nil,:lines_x=>false,:lines_y=>nil,:graph_id=>nil)
213
+ end
214
+ ds.all.should == [{:points=>{:id=>1, :x=>2, :y=>3}, :lines=>{:id=>nil, :x=>false, :y=>nil, :graph_id=>nil}}]
215
+ end
216
+
217
+ it "#graph_each should not included tables graphed with the :select => false option in the result set" do
218
+ ds = @ds1.graph(:lines, {:x=>:id}, :select=>false).graph(:graphs, :id=>:graph_id)
219
+ def ds.fetch_rows(sql, &block)
220
+ yield({:id=>1,:x=>2,:y=>3,:graphs_id=>8, :name=>9, :graphs_x=>10, :graphs_y=>11, :lines_x=>12})
221
+ end
222
+ results = ds.all
223
+ results.length.should == 1
224
+ results.first.should == {:points=>{:id=>1, :x=>2, :y=>3}, :graphs=>{:id=>8, :name=>9, :x=>10, :y=>11, :lines_x=>12}}
225
+ end
226
+
227
+ it "#graph_each should only include the columns selected with #set_graph_aliases and #add_graph_aliases, if called" do
228
+ ds = @ds1.graph(:lines, :x=>:id).set_graph_aliases(:x=>[:points, :x], :y=>[:lines, :y])
229
+ def ds.fetch_rows(sql, &block)
230
+ yield({:x=>2,:y=>3})
231
+ end
232
+ results = ds.all
233
+ results.length.should == 1
234
+ results.first.should == {:points=>{:x=>2}, :lines=>{:y=>3}}
235
+
236
+ ds = @ds1.graph(:lines, :x=>:id).set_graph_aliases(:x=>[:points, :x])
237
+ def ds.fetch_rows(sql, &block)
238
+ yield({:x=>2})
239
+ end
240
+ results = ds.all
241
+ results.length.should == 1
242
+ results.first.should == {:points=>{:x=>2}, :lines=>nil}
243
+
244
+ ds = ds.add_graph_aliases(:q=>[:points, :r, 18])
245
+ def ds.fetch_rows(sql, &block)
246
+ yield({:x=>2, :q=>18})
247
+ end
248
+ ds.all.should == [{:points=>{:x=>2, :r=>18}, :lines=>nil}]
249
+ end
250
+
251
+ it "#graph_each should correctly map values when #set_graph_aliases is used with a third argument for each entry" do
252
+ ds = @ds1.graph(:lines, :x=>:id).set_graph_aliases(:x=>[:points, :z1, 2], :y=>[:lines, :z2, :random.sql_function])
253
+ def ds.fetch_rows(sql, &block)
254
+ yield({:x=>2,:y=>3})
255
+ end
256
+ results = ds.all
257
+ results.length.should == 1
258
+ results.first.should == {:points=>{:z1=>2}, :lines=>{:z2=>3}}
259
+ end
260
+
261
+ it "#graph_each should run the row_proc and transform for graphed datasets" do
262
+ @ds1.row_proc = proc{|h| h.keys.each{|k| h[k] *= 2}; h}
263
+ @ds2.row_proc = proc{|h| h.keys.each{|k| h[k] *= 3}; h}
264
+ @ds1.transform(:x=>[
265
+ proc{|v| 123},
266
+ proc{|v| 123}
267
+ ])
268
+ @ds2.transform(:x=>[
269
+ proc{|v| 321},
270
+ proc{|v| 321}
271
+ ])
272
+ ds = @ds1.graph(@ds2, :x=>:id)
273
+ def ds.fetch_rows(sql, &block)
274
+ yield({:id=>1,:x=>2,:y=>3,:lines_id=>4,:lines_x=>5,:lines_y=>6,:graph_id=>7})
275
+ end
276
+ results = ds.all
277
+ results.length.should == 1
278
+ results.first.should == {:points=>{:id=>2, :x=>246, :y=>6}, :lines=>{:id=>12, :x=>963, :y=>18, :graph_id=>21}}
279
+ end
280
+ end
@@ -0,0 +1,58 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ require 'stringio'
4
+
5
+ context "PrettyTable" do
6
+ setup do
7
+ @data1 = [
8
+ {:x => 3, :y => 4}
9
+ ]
10
+
11
+ @data2 = [
12
+ {:a => 23, :b => 45},
13
+ {:a => 45, :b => 2377}
14
+ ]
15
+
16
+ @data3 = [
17
+ {:aaa => 1},
18
+ {:bb => 2},
19
+ {:c => 3}
20
+ ]
21
+
22
+ @output = StringIO.new
23
+ @orig_stdout = $stdout
24
+ $stdout = @output
25
+ end
26
+
27
+ teardown do
28
+ $stdout = @orig_stdout
29
+ end
30
+
31
+ specify "should infer the columns if not given" do
32
+ Sequel::PrettyTable.print(@data1)
33
+ @output.rewind
34
+ @output.read.should =~ \
35
+ /\n(\|x\|y\|)|(\|y\|x\|)\n/
36
+ end
37
+
38
+ specify "should calculate the maximum width of each column correctly" do
39
+ Sequel::PrettyTable.print(@data2, [:a, :b])
40
+ @output.rewind
41
+ @output.read.should == \
42
+ "+--+----+\n|a |b |\n+--+----+\n|23| 45|\n|45|2377|\n+--+----+\n"
43
+ end
44
+
45
+ specify "should also take header width into account" do
46
+ Sequel::PrettyTable.print(@data3, [:aaa, :bb, :c])
47
+ @output.rewind
48
+ @output.read.should == \
49
+ "+---+--+-+\n|aaa|bb|c|\n+---+--+-+\n| 1| | |\n| | 2| |\n| | |3|\n+---+--+-+\n"
50
+ end
51
+
52
+ specify "should print only the specified columns" do
53
+ Sequel::PrettyTable.print(@data2, [:a])
54
+ @output.rewind
55
+ @output.read.should == \
56
+ "+--+\n|a |\n+--+\n|23|\n|45|\n+--+\n"
57
+ end
58
+ end
@@ -0,0 +1,167 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe Sequel::Schema::Generator do
4
+ before do
5
+ @generator = Sequel::Schema::Generator.new(SchemaDummyDatabase.new) do
6
+ string :title
7
+ column :body, :text
8
+ foreign_key :parent_id
9
+ primary_key :id
10
+ check 'price > 100'
11
+ constraint(:xxx) {:yyy == :zzz}
12
+ index :title
13
+ index [:title, :body]
14
+ foreign_key :node_id, :nodes
15
+ primary_key [:title, :parent_id], :name => :cpk
16
+ foreign_key [:node_id, :prop_id], :nodes_props, :name => :cfk
17
+ end
18
+ @columns, @indexes = @generator.create_info
19
+ end
20
+
21
+ {:name => :id, :primary_key => true}.each do |column, expected|
22
+ it "uses default primary key #{column}" do
23
+ @columns.first[column].should == expected
24
+ end
25
+ end
26
+
27
+ it "counts primary key, column and constraint definitions as columns" do
28
+ @columns.size.should == 9
29
+ end
30
+
31
+ it "places primary key first" do
32
+ @columns[0][:primary_key].should be_true
33
+ @columns[1][:primary_key].should_not be_true
34
+ @columns[2][:primary_key].should_not be_true
35
+ end
36
+
37
+ it "retrieves primary key name" do
38
+ @generator.primary_key_name.should == :id
39
+ end
40
+
41
+ it "keeps columns in order" do
42
+ @columns[1][:name].should == :title
43
+ @columns[1][:type].should == :string
44
+ @columns[2][:name].should == :body
45
+ @columns[2][:type].should == :text
46
+ end
47
+
48
+ it "creates foreign key column" do
49
+ @columns[3][:name].should == :parent_id
50
+ @columns[3][:type].should == Integer
51
+ @columns[6][:name].should == :node_id
52
+ @columns[6][:type].should == Integer
53
+ end
54
+
55
+ it "uses table for foreign key columns, if specified" do
56
+ @columns[6][:table].should == :nodes
57
+ @columns[3][:table].should == nil
58
+ @columns[8][:table].should == :nodes_props
59
+ end
60
+
61
+ it "finds columns" do
62
+ [:title, :body, :parent_id, :id].each do |col|
63
+ @generator.has_column?(col).should be_true
64
+ end
65
+ @generator.has_column?(:foo).should_not be_true
66
+ end
67
+
68
+ it "creates constraints" do
69
+ @columns[4][:name].should == nil
70
+ @columns[4][:type].should == :check
71
+ @columns[4][:check].should == ['price > 100']
72
+
73
+ @columns[5][:name].should == :xxx
74
+ @columns[5][:type].should == :check
75
+ @columns[5][:check].should be_a_kind_of(Proc)
76
+
77
+ @columns[7][:name].should == :cpk
78
+ @columns[7][:type].should == :check
79
+ @columns[7][:constraint_type].should == :primary_key
80
+ @columns[7][:columns].should == [ :title, :parent_id ]
81
+
82
+ @columns[8][:name].should == :cfk
83
+ @columns[8][:type].should == :check
84
+ @columns[8][:constraint_type].should == :foreign_key
85
+ @columns[8][:columns].should == [ :node_id, :prop_id ]
86
+ @columns[8][:table].should == :nodes_props
87
+ end
88
+
89
+ it "creates indexes" do
90
+ @indexes[0][:columns].should include(:title)
91
+ @indexes[1][:columns].should include(:title)
92
+ @indexes[1][:columns].should include(:body)
93
+ end
94
+ end
95
+
96
+ describe Sequel::Schema::AlterTableGenerator do
97
+ before do
98
+ @generator = Sequel::Schema::AlterTableGenerator.new(SchemaDummyDatabase.new) do
99
+ add_column :aaa, :text
100
+ drop_column :bbb
101
+ rename_column :ccc, :ho
102
+ set_column_type :ddd, :float
103
+ set_column_default :eee, 1
104
+ add_index [:fff, :ggg]
105
+ drop_index :hhh
106
+ add_full_text_index :blah
107
+ add_spatial_index :geom
108
+ add_index :blah, :type => :hash
109
+ add_index :blah, :where => {:something => true}
110
+ add_constraint :con1, 'fred > 100'
111
+ drop_constraint :con2
112
+ add_unique_constraint [:aaa, :bbb, :ccc], :name => :con3
113
+ add_primary_key :id
114
+ add_foreign_key :node_id, :nodes
115
+ add_primary_key [:aaa, :bbb]
116
+ add_foreign_key [:node_id, :prop_id], :nodes_props
117
+ end
118
+ end
119
+
120
+ specify "should generate operation records" do
121
+ @generator.operations.should == [
122
+ {:op => :add_column, :name => :aaa, :type => :text},
123
+ {:op => :drop_column, :name => :bbb},
124
+ {:op => :rename_column, :name => :ccc, :new_name => :ho},
125
+ {:op => :set_column_type, :name => :ddd, :type => :float},
126
+ {:op => :set_column_default, :name => :eee, :default => 1},
127
+ {:op => :add_index, :columns => [:fff, :ggg]},
128
+ {:op => :drop_index, :columns => [:hhh]},
129
+ {:op => :add_index, :columns => [:blah], :type => :full_text},
130
+ {:op => :add_index, :columns => [:geom], :type => :spatial},
131
+ {:op => :add_index, :columns => [:blah], :type => :hash},
132
+ {:op => :add_index, :columns => [:blah], :where => {:something => true}},
133
+ {:op => :add_constraint, :type => :check, :constraint_type => :check, :name => :con1, :check => ['fred > 100']},
134
+ {:op => :drop_constraint, :name => :con2},
135
+ {:op => :add_constraint, :type => :check, :constraint_type => :unique, :name => :con3, :columns => [:aaa, :bbb, :ccc]},
136
+ {:op => :add_column, :name => :id, :type => Integer, :primary_key=>true, :auto_increment=>true},
137
+ {:op => :add_column, :name => :node_id, :type => Integer, :table=>:nodes},
138
+ {:op => :add_constraint, :type => :check, :constraint_type => :primary_key, :columns => [:aaa, :bbb]},
139
+ {:op => :add_constraint, :type => :check, :constraint_type => :foreign_key, :columns => [:node_id, :prop_id], :table => :nodes_props}
140
+ ]
141
+ end
142
+ end
143
+
144
+ describe "Sequel::Schema::Generator generic type methods" do
145
+ before do
146
+ @generator = Sequel::Schema::Generator.new(SchemaDummyDatabase.new) do
147
+ String :a
148
+ Integer :b
149
+ Fixnum :c
150
+ Bignum :d
151
+ Float :e
152
+ BigDecimal :f
153
+ Date :g
154
+ DateTime :h
155
+ Time :i
156
+ Numeric :j
157
+ File :k
158
+ TrueClass :l
159
+ FalseClass :m
160
+ end
161
+ @columns, @indexes = @generator.create_info
162
+ end
163
+
164
+ it "should store the type class in :type for each column" do
165
+ @columns.map{|c| c[:type]}.should == [String, Integer, Fixnum, Bignum, Float, BigDecimal, Date, DateTime, Time, Numeric, File, TrueClass, FalseClass]
166
+ end
167
+ end