sqlpostgres 1.2.4

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 (207) hide show
  1. data/Gemfile +8 -0
  2. data/Gemfile.lock +22 -0
  3. data/LICENSE.md +23 -0
  4. data/README.rdoc +59 -0
  5. data/Rakefile +32 -0
  6. data/VERSION +1 -0
  7. data/doc/BUGS +2 -0
  8. data/doc/examples/README +6 -0
  9. data/doc/examples/connection.rb +16 -0
  10. data/doc/examples/connection_auto.rb +22 -0
  11. data/doc/examples/connection_ctor.rb +18 -0
  12. data/doc/examples/connection_default.rb +15 -0
  13. data/doc/examples/connection_exec.rb +18 -0
  14. data/doc/examples/connection_manual.rb +12 -0
  15. data/doc/examples/connection_wrapped_new.rb +13 -0
  16. data/doc/examples/connection_wrapped_open.rb +13 -0
  17. data/doc/examples/cursor.rb +38 -0
  18. data/doc/examples/include_module.rb +9 -0
  19. data/doc/examples/include_module2.rb +12 -0
  20. data/doc/examples/insert.rb +30 -0
  21. data/doc/examples/insert2.rb +36 -0
  22. data/doc/examples/insert_bytea.rb +16 -0
  23. data/doc/examples/insert_bytea_array.rb +17 -0
  24. data/doc/examples/insert_default_values.rb +16 -0
  25. data/doc/examples/insert_insert.rb +16 -0
  26. data/doc/examples/insert_insert_default.rb +16 -0
  27. data/doc/examples/insert_insert_select.rb +20 -0
  28. data/doc/examples/insert_select.rb +20 -0
  29. data/doc/examples/interval.rb +17 -0
  30. data/doc/examples/savepoint.rb +38 -0
  31. data/doc/examples/select.rb +33 -0
  32. data/doc/examples/select2.rb +36 -0
  33. data/doc/examples/select_cross_join.rb +18 -0
  34. data/doc/examples/select_distinct.rb +18 -0
  35. data/doc/examples/select_distinct_on +19 -0
  36. data/doc/examples/select_for_update.rb +18 -0
  37. data/doc/examples/select_from.rb +17 -0
  38. data/doc/examples/select_from_subselect.rb +20 -0
  39. data/doc/examples/select_group_by.rb +19 -0
  40. data/doc/examples/select_having.rb +20 -0
  41. data/doc/examples/select_join_on.rb +18 -0
  42. data/doc/examples/select_join_using.rb +18 -0
  43. data/doc/examples/select_limit.rb +19 -0
  44. data/doc/examples/select_natural_join.rb +18 -0
  45. data/doc/examples/select_offset.rb +19 -0
  46. data/doc/examples/select_order_by.rb +20 -0
  47. data/doc/examples/select_select.rb +30 -0
  48. data/doc/examples/select_select_alias.rb +30 -0
  49. data/doc/examples/select_select_expression.rb +31 -0
  50. data/doc/examples/select_select_literal.rb +24 -0
  51. data/doc/examples/select_union.rb +21 -0
  52. data/doc/examples/select_where_array.rb +18 -0
  53. data/doc/examples/select_where_in.rb +18 -0
  54. data/doc/examples/select_where_string.rb +18 -0
  55. data/doc/examples/simple.rb +34 -0
  56. data/doc/examples/transaction.rb +30 -0
  57. data/doc/examples/transaction_abort.rb +30 -0
  58. data/doc/examples/transaction_commit.rb +34 -0
  59. data/doc/examples/translate_substitute_values.rb +17 -0
  60. data/doc/examples/update.rb +32 -0
  61. data/doc/examples/update2.rb +44 -0
  62. data/doc/examples/update_only.rb +17 -0
  63. data/doc/examples/update_set.rb +17 -0
  64. data/doc/examples/update_set_array.rb +16 -0
  65. data/doc/examples/update_set_bytea.rb +16 -0
  66. data/doc/examples/update_set_expression.rb +16 -0
  67. data/doc/examples/update_set_subselect.rb +20 -0
  68. data/doc/examples/update_where.rb +17 -0
  69. data/doc/examples/use_prefix.rb +8 -0
  70. data/doc/examples/use_prefix2.rb +11 -0
  71. data/doc/index.html +31 -0
  72. data/doc/insertexamples.rb +9 -0
  73. data/doc/makemanual +4 -0
  74. data/doc/makerdoc +5 -0
  75. data/doc/manual.dbk +622 -0
  76. data/lib/sqlpostgres/Connection.rb +198 -0
  77. data/lib/sqlpostgres/Cursor.rb +157 -0
  78. data/lib/sqlpostgres/Delete.rb +67 -0
  79. data/lib/sqlpostgres/Exceptions.rb +15 -0
  80. data/lib/sqlpostgres/Insert.rb +279 -0
  81. data/lib/sqlpostgres/NullConnection.rb +22 -0
  82. data/lib/sqlpostgres/PgBit.rb +73 -0
  83. data/lib/sqlpostgres/PgBox.rb +37 -0
  84. data/lib/sqlpostgres/PgCidr.rb +21 -0
  85. data/lib/sqlpostgres/PgCircle.rb +75 -0
  86. data/lib/sqlpostgres/PgInet.rb +21 -0
  87. data/lib/sqlpostgres/PgInterval.rb +208 -0
  88. data/lib/sqlpostgres/PgLineSegment.rb +37 -0
  89. data/lib/sqlpostgres/PgMacAddr.rb +21 -0
  90. data/lib/sqlpostgres/PgPath.rb +64 -0
  91. data/lib/sqlpostgres/PgPoint.rb +65 -0
  92. data/lib/sqlpostgres/PgPolygon.rb +56 -0
  93. data/lib/sqlpostgres/PgTime.rb +77 -0
  94. data/lib/sqlpostgres/PgTimeWithTimeZone.rb +98 -0
  95. data/lib/sqlpostgres/PgTimestamp.rb +93 -0
  96. data/lib/sqlpostgres/PgTwoPoints.rb +54 -0
  97. data/lib/sqlpostgres/PgType.rb +34 -0
  98. data/lib/sqlpostgres/PgWrapper.rb +41 -0
  99. data/lib/sqlpostgres/Savepoint.rb +98 -0
  100. data/lib/sqlpostgres/Select.rb +855 -0
  101. data/lib/sqlpostgres/Transaction.rb +120 -0
  102. data/lib/sqlpostgres/Translate.rb +436 -0
  103. data/lib/sqlpostgres/Update.rb +188 -0
  104. data/lib/sqlpostgres.rb +67 -0
  105. data/test/Assert.rb +72 -0
  106. data/test/Connection.test.rb +246 -0
  107. data/test/Cursor.test.rb +190 -0
  108. data/test/Delete.test.rb +68 -0
  109. data/test/Insert.test.rb +123 -0
  110. data/test/MockPGconn.rb +62 -0
  111. data/test/NullConnection.test.rb +32 -0
  112. data/test/PgBit.test.rb +98 -0
  113. data/test/PgBox.test.rb +108 -0
  114. data/test/PgCidr.test.rb +61 -0
  115. data/test/PgCircle.test.rb +107 -0
  116. data/test/PgInet.test.rb +61 -0
  117. data/test/PgInterval.test.rb +180 -0
  118. data/test/PgLineSegment.test.rb +108 -0
  119. data/test/PgMacAddr.test.rb +61 -0
  120. data/test/PgPath.test.rb +106 -0
  121. data/test/PgPoint.test.rb +100 -0
  122. data/test/PgPolygon.test.rb +95 -0
  123. data/test/PgTime.test.rb +120 -0
  124. data/test/PgTimeWithTimeZone.test.rb +117 -0
  125. data/test/PgTimestamp.test.rb +134 -0
  126. data/test/RandomThings.rb +25 -0
  127. data/test/Savepoint.test.rb +286 -0
  128. data/test/Select.test.rb +930 -0
  129. data/test/Test.rb +62 -0
  130. data/test/TestConfig.rb +21 -0
  131. data/test/TestSetup.rb +13 -0
  132. data/test/TestUtil.rb +92 -0
  133. data/test/Transaction.test.rb +275 -0
  134. data/test/Translate.test.rb +354 -0
  135. data/test/Update.test.rb +227 -0
  136. data/test/roundtrip.test.rb +565 -0
  137. data/test/test +34 -0
  138. data/tools/exampleinserter/ExampleInserter.rb +177 -0
  139. data/tools/rdoc/ChangeLog +796 -0
  140. data/tools/rdoc/EXAMPLE.rb +48 -0
  141. data/tools/rdoc/MANIFEST +58 -0
  142. data/tools/rdoc/Makefile +27 -0
  143. data/tools/rdoc/NEW_FEATURES +226 -0
  144. data/tools/rdoc/README +390 -0
  145. data/tools/rdoc/ToDo +6 -0
  146. data/tools/rdoc/contrib/Index +6 -0
  147. data/tools/rdoc/contrib/xslfo/ChangeLog +181 -0
  148. data/tools/rdoc/contrib/xslfo/README +106 -0
  149. data/tools/rdoc/contrib/xslfo/TODO +10 -0
  150. data/tools/rdoc/contrib/xslfo/convert.xsl +151 -0
  151. data/tools/rdoc/contrib/xslfo/demo/README +21 -0
  152. data/tools/rdoc/contrib/xslfo/demo/rdocfo +99 -0
  153. data/tools/rdoc/contrib/xslfo/fcm.xsl +54 -0
  154. data/tools/rdoc/contrib/xslfo/files.xsl +62 -0
  155. data/tools/rdoc/contrib/xslfo/labeled-lists.xsl +66 -0
  156. data/tools/rdoc/contrib/xslfo/lists.xsl +44 -0
  157. data/tools/rdoc/contrib/xslfo/modules.xsl +152 -0
  158. data/tools/rdoc/contrib/xslfo/rdoc.xsl +75 -0
  159. data/tools/rdoc/contrib/xslfo/source.xsl +66 -0
  160. data/tools/rdoc/contrib/xslfo/styles.xsl +69 -0
  161. data/tools/rdoc/contrib/xslfo/tables.xsl +67 -0
  162. data/tools/rdoc/contrib/xslfo/utils.xsl +21 -0
  163. data/tools/rdoc/debian/changelog +33 -0
  164. data/tools/rdoc/debian/compat +1 -0
  165. data/tools/rdoc/debian/control +20 -0
  166. data/tools/rdoc/debian/copyright +10 -0
  167. data/tools/rdoc/debian/dirs +2 -0
  168. data/tools/rdoc/debian/docs +2 -0
  169. data/tools/rdoc/debian/rdoc.1 +252 -0
  170. data/tools/rdoc/debian/rdoc.manpages +1 -0
  171. data/tools/rdoc/debian/rdoc.pod +149 -0
  172. data/tools/rdoc/debian/rules +9 -0
  173. data/tools/rdoc/dot/dot.rb +255 -0
  174. data/tools/rdoc/etc/rdoc.dtd +203 -0
  175. data/tools/rdoc/install.rb +137 -0
  176. data/tools/rdoc/markup/install.rb +43 -0
  177. data/tools/rdoc/markup/sample/sample.rb +42 -0
  178. data/tools/rdoc/markup/simple_markup/fragments.rb +323 -0
  179. data/tools/rdoc/markup/simple_markup/inline.rb +348 -0
  180. data/tools/rdoc/markup/simple_markup/lines.rb +147 -0
  181. data/tools/rdoc/markup/simple_markup/preprocess.rb +68 -0
  182. data/tools/rdoc/markup/simple_markup/to_html.rb +281 -0
  183. data/tools/rdoc/markup/simple_markup.rb +474 -0
  184. data/tools/rdoc/markup/test/AllTests.rb +2 -0
  185. data/tools/rdoc/markup/test/TestInline.rb +151 -0
  186. data/tools/rdoc/markup/test/TestParse.rb +411 -0
  187. data/tools/rdoc/rdoc/code_objects.rb +536 -0
  188. data/tools/rdoc/rdoc/diagram.rb +331 -0
  189. data/tools/rdoc/rdoc/generators/chm_generator.rb +112 -0
  190. data/tools/rdoc/rdoc/generators/html_generator.rb +1268 -0
  191. data/tools/rdoc/rdoc/generators/template/chm/chm.rb +86 -0
  192. data/tools/rdoc/rdoc/generators/template/html/html.rb +705 -0
  193. data/tools/rdoc/rdoc/generators/template/html/kilmer.rb +377 -0
  194. data/tools/rdoc/rdoc/generators/template/xml/rdf.rb +110 -0
  195. data/tools/rdoc/rdoc/generators/template/xml/xml.rb +110 -0
  196. data/tools/rdoc/rdoc/generators/xml_generator.rb +130 -0
  197. data/tools/rdoc/rdoc/options.rb +451 -0
  198. data/tools/rdoc/rdoc/parsers/parse_c.rb +287 -0
  199. data/tools/rdoc/rdoc/parsers/parse_f95.rb +118 -0
  200. data/tools/rdoc/rdoc/parsers/parse_rb.rb +2311 -0
  201. data/tools/rdoc/rdoc/parsers/parse_simple.rb +37 -0
  202. data/tools/rdoc/rdoc/parsers/parserfactory.rb +75 -0
  203. data/tools/rdoc/rdoc/rdoc.rb +219 -0
  204. data/tools/rdoc/rdoc/template.rb +234 -0
  205. data/tools/rdoc/rdoc/tokenstream.rb +25 -0
  206. data/tools/rdoc/rdoc.rb +9 -0
  207. metadata +291 -0
@@ -0,0 +1,930 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'bundler/setup'
5
+ $:.unshift(File.dirname(__FILE__))
6
+ require 'TestSetup'
7
+ require 'date'
8
+
9
+ # Much of Select is tested in the "roundtrip" test.
10
+
11
+ class SelectTest < Test
12
+
13
+ include SqlPostgres
14
+ include TestUtil
15
+
16
+ def test
17
+ makeTestConnection do |connection|
18
+ connection.exec("create temporary table #{table1} (i int)")
19
+ select = Select.new(connection)
20
+ select.select('i')
21
+ select.from(table1)
22
+ select.order_by('i')
23
+ assertEquals(select.statement, "select i from #{table1} order by i")
24
+ assertEquals(select.exec, [])
25
+ connection.exec("insert into #{table1} (i) values (1)")
26
+ assertEquals(select.exec, [{'i' => 1}])
27
+ connection.exec("insert into #{table1} (i) values (2)")
28
+ assertEquals(select.exec, [{'i' => 1}, {'i' => 2}])
29
+ end
30
+ end
31
+
32
+ def testDefaultConnection
33
+ makeTestConnection do |connection|
34
+ connection.exec("create temporary table #{table1} (i int)")
35
+ connection.exec("insert into #{table1} values (1)")
36
+ setDefaultConnection(connection) do
37
+ select = Select.new(connection)
38
+ select.select('i')
39
+ select.from(table1)
40
+ assertEquals(select.exec, [{'i'=>1}])
41
+ end
42
+ end
43
+ end
44
+
45
+ def testGiveConnectionToExec
46
+ makeTestConnection do |connection|
47
+ connection.exec("create temporary table #{table1} (i int)")
48
+ connection.exec("insert into #{table1} values (1)")
49
+ setDefaultConnection(connection) do
50
+ select = Select.new
51
+ select.select('i')
52
+ select.from(table1)
53
+ assertEquals(select.exec(connection), [{'i'=>1}])
54
+ end
55
+ end
56
+ end
57
+
58
+ def testOrderBy
59
+ makeTestConnection do |connection|
60
+ connection.exec("create temporary table #{table1} (i int, j int, k int)")
61
+ connection.exec("insert into #{table1} values (0, 0, 0)")
62
+ connection.exec("insert into #{table1} values (0, 0, 1)")
63
+ connection.exec("insert into #{table1} values (0, 1, 0)")
64
+ connection.exec("insert into #{table1} values (0, 1, 1)")
65
+ connection.exec("insert into #{table1} values (1, 0, 0)")
66
+ connection.exec("insert into #{table1} values (1, 0, 1)")
67
+ connection.exec("insert into #{table1} values (1, 1, 0)")
68
+ connection.exec("insert into #{table1} values (1, 1, 1)")
69
+ select = Select.new(connection)
70
+ select.select("i")
71
+ select.select("j")
72
+ select.select("k")
73
+ select.from(table1)
74
+ select.order_by('i')
75
+ select.order_by('j', 'asc')
76
+ select.order_by('k', 'desc')
77
+ assertEquals(select.statement,
78
+ "select i, j, k from #{table1} order by i, j asc, k desc")
79
+ assertEquals(select.exec, [
80
+ {'i'=>0, 'j'=>0, 'k'=>1},
81
+ {'i'=>0, 'j'=>0, 'k'=>0},
82
+ {'i'=>0, 'j'=>1, 'k'=>1},
83
+ {'i'=>0, 'j'=>1, 'k'=>0},
84
+ {'i'=>1, 'j'=>0, 'k'=>1},
85
+ {'i'=>1, 'j'=>0, 'k'=>0},
86
+ {'i'=>1, 'j'=>1, 'k'=>1},
87
+ {'i'=>1, 'j'=>1, 'k'=>0},
88
+ ])
89
+ end
90
+ end
91
+
92
+ def testOrderBy_ArbitraryExpression
93
+ makeTestConnection do |connection|
94
+ connection.exec("create temporary table #{table1} (t text)")
95
+ connection.exec("insert into #{table1} values ('aaa')")
96
+ connection.exec("insert into #{table1} values ('bb')")
97
+ connection.exec("insert into #{table1} values ('c')")
98
+ select = Select.new(connection)
99
+ select.select('t')
100
+ select.from(table1)
101
+ select.order_by('char_length(t)')
102
+ assertEquals(select.statement,
103
+ "select t from #{table1} order by char_length(t)")
104
+ assertEquals(select.exec, [{'t'=>'c'}, {'t'=>'bb'}, {'t'=>'aaa'}])
105
+ end
106
+ end
107
+
108
+ def testOrderBy_ExpressionWithSubstitution
109
+ makeTestConnection do |connection|
110
+ connection.exec("create temporary table #{table1} (t text)")
111
+ connection.exec("insert into #{table1} values ('a')")
112
+ connection.exec("insert into #{table1} values ('b')")
113
+ connection.exec("insert into #{table1} values ('c')")
114
+ select = Select.new(connection)
115
+ select.select('t')
116
+ select.from(table1)
117
+ select.order_by(['case when t = %s then %s else t end', 'b', '0'])
118
+ assertEquals(select.statement,
119
+ "select t from #{table1} order by "\
120
+ "case when t = E'b' then E'0' else t end")
121
+ assertEquals(select.exec, [{'t'=>'b'}, {'t'=>'a'}, {'t'=>'c'}])
122
+ end
123
+ end
124
+
125
+ def testSelectInteger_Expression
126
+ makeTestConnection do |connection|
127
+ select = Select.new(connection)
128
+ select.select(["%s * 2", 2], 'double')
129
+ assertEquals(select.statement, "select 2 * 2 as double")
130
+ assertEquals(select.exec, [{'double'=>4}])
131
+ end
132
+ end
133
+
134
+ def testSelectFloat_Expression
135
+ makeTestConnection do |connection|
136
+ select = Select.new(connection)
137
+ select.select(["%s * 2", 1.414], 'double')
138
+ assertEquals(select.statement, "select 1.414 * 2 as double")
139
+ assertEquals(select.exec, [{'double'=>2.828}])
140
+ end
141
+ end
142
+
143
+ def testSelectString_Expression
144
+ makeTestConnection do |connection|
145
+ select = Select.new(connection)
146
+ select.select(["%s || %s", "Fred's", " Place"], 'title')
147
+ assertEquals(select.statement,
148
+ %q"select E'Fred\\047s' || E' Place' as title")
149
+ assertEquals(select.exec, [{'title'=>"Fred's Place"}])
150
+ end
151
+ end
152
+
153
+ def testSelectTime_Expression
154
+ makeTestConnection do |connection|
155
+ now = Time.local(2001, 1, 1)
156
+ select = Select.new(connection)
157
+ select.select(
158
+ [
159
+ "%s + %s",
160
+ PgTime.new(12, 0, 0),
161
+ PgInterval.new('hours'=>1)
162
+ ],
163
+ 'later')
164
+ assertEquals(select.exec, [{'later'=>PgTime.new(13, 0, 0)}])
165
+ end
166
+ end
167
+
168
+ def testSelectBoolean_Expression
169
+ makeTestConnection do |connection|
170
+ select = Select.new(connection)
171
+ select.select(["not %s", false], 'opposite')
172
+ assertEquals(select.statement, "select not false as opposite")
173
+ assertEquals(select.exec, [{'opposite'=>true}])
174
+ end
175
+ end
176
+
177
+ def test_select_literal
178
+ values = [
179
+ "Fool's errand",
180
+ 1,
181
+ -9223372036854775808,
182
+ +9223372036854775807,
183
+ 1.414,
184
+ 1e290,
185
+ true,
186
+ false,
187
+ PgTime.new(23, 59, 59),
188
+ nil,
189
+ PgInterval.new('days'=>1),
190
+ PgTime.new(12, 0, 0),
191
+ PgTimeWithTimeZone.new(12, 0, 0, -8, 0),
192
+ PgTimestamp.new(2001, 1, 1, 12, 0, 0),
193
+ PgPoint.new(1, 2),
194
+ PgLineSegment.new(0, 1, 2, 3),
195
+ PgBox.new(3, 4, 1, 2),
196
+ PgPath.new(true, PgPoint.new(1, 2), PgPoint.new(3, 4)),
197
+ PgPolygon.new(PgPoint.new(1, 2), PgPoint.new(3, 4)),
198
+ PgCircle.new(1, 2, 3),
199
+ PgBit.new("010101"),
200
+ PgInet.new("1.2.0.0/16"),
201
+ PgCidr.new("1.2.3.0/24"),
202
+ PgMacAddr.new("08:00:2b:01:02:03"),
203
+ ]
204
+ makeTestConnection do |connection|
205
+ for value in values
206
+ assertInfo("For value #{value.inspect}") do
207
+
208
+ select = Select.new(connection)
209
+ select.select_literal(value)
210
+ assertEquals(select.statement,
211
+ "select #{Translate.escape_sql(value)}")
212
+
213
+ select = Select.new(connection)
214
+ select.select_literal(value, 'v')
215
+ assertEquals(select.exec, [{'v'=>value}])
216
+
217
+ end
218
+ end
219
+ end
220
+ end
221
+
222
+ def testSelectExpression
223
+ makeTestConnection do |connection|
224
+ select = Select.new(connection)
225
+ select.select(["%s || %s || %s", "Cat", " ", "Dog"], 'animal')
226
+ assertEquals(select.statement, "select E'Cat' || E' ' || E'Dog' as animal")
227
+ assertEquals(select.exec, [{'animal'=>'Cat Dog'}])
228
+ end
229
+ end
230
+
231
+ def testUserConversion
232
+ makeTestConnection do |connection|
233
+ select = Select.new(connection)
234
+ select.select(["%s", "abc"], 'letters') do |s|
235
+ s.scan(/./)
236
+ end
237
+ assertEquals(select.exec, [{'letters'=>['a', 'b', 'c']}])
238
+ end
239
+ end
240
+
241
+ def testWhere
242
+ makeTestConnection do |connection|
243
+ connection.exec("create temporary table #{table1} (i int)")
244
+ connection.exec("insert into #{table1} values (1)")
245
+ connection.exec("insert into #{table1} values (2)")
246
+ connection.exec("insert into #{table1} values (3)")
247
+ select = Select.new(connection)
248
+ select.select('i')
249
+ select.from(table1)
250
+ select.where("i = 1")
251
+ assertEquals(select.statement, "select i from #{table1} where i = 1")
252
+ assertEquals(select.exec, [{'i'=>1}])
253
+ end
254
+ end
255
+
256
+ def testWhere_Multiple
257
+ makeTestConnection do |connection|
258
+ connection.exec("create temporary table #{table1} (i int)")
259
+ connection.exec("insert into #{table1} values (1)")
260
+ connection.exec("insert into #{table1} values (2)")
261
+ connection.exec("insert into #{table1} values (3)")
262
+ select = Select.new(connection)
263
+ select.select('i')
264
+ select.from(table1)
265
+ select.where("i > 1")
266
+ select.where("i < 3")
267
+ assertEquals(select.statement,
268
+ "select i from #{table1} where i > 1 and i < 3")
269
+ assertEquals(select.exec, [{'i'=>2}])
270
+ end
271
+ end
272
+
273
+ def testWhere_WithValues
274
+ makeTestConnection do |connection|
275
+ connection.exec("create temporary table #{table1} (t text)")
276
+ connection.exec("insert into #{table1} values ('bar')")
277
+ connection.exec("insert into #{table1} values ('baz')")
278
+ select = Select.new(connection)
279
+ select.select('t')
280
+ select.from(table1)
281
+ select.where(["t = %s", 'bar'])
282
+ assertEquals(select.statement, "select t from #{table1} where t = E'bar'")
283
+ assertEquals(select.exec, [{'t'=>'bar'}])
284
+ end
285
+ end
286
+
287
+ def testSelectSubselect
288
+ makeTestConnection do |connection|
289
+ time = PgTime.new(12, 0, 0)
290
+ select1 = Select.new
291
+ select1.select_literal(1)
292
+ select2 = Select.new
293
+ select2.select_literal(time)
294
+ select3 = Select.new(connection)
295
+ select3.select(select1, 'i')
296
+ select3.select(select2, 't')
297
+ assertEquals(select3.exec, [{'i'=>1, 't'=>time}])
298
+ end
299
+ end
300
+
301
+ def testFromAlias
302
+ select = Select.new
303
+ select.select('i')
304
+ select.from('foo', 'bar')
305
+ assertEquals(select.statement, "select i from foo as bar")
306
+ end
307
+
308
+ def testFromSubselect
309
+ makeTestConnection do |connection|
310
+ time = Time.now
311
+ select1 = Select.new
312
+ select1.select_literal(1, 'i')
313
+ select2 = Select.new(connection)
314
+ select2.select('i')
315
+ select2.from(select1, 'foo')
316
+ assertEquals(select2.statement, "select i from (select 1 as i) as foo")
317
+ assertEquals(select2.exec, [{'i'=>1}])
318
+ end
319
+ end
320
+
321
+ def testNoConnection
322
+ select = Select.new
323
+ assertException(NoConnection) do
324
+ select.exec
325
+ end
326
+ end
327
+
328
+ def testGroupBy
329
+ makeTestConnection do |connection|
330
+ connection.exec("create temporary table #{table1} (i int, j int)")
331
+ 1.times do connection.exec("insert into #{table1} values (0, 0)") end
332
+ 2.times do connection.exec("insert into #{table1} values (0, 1)") end
333
+ 3.times do connection.exec("insert into #{table1} values (1, 0)") end
334
+ 4.times do connection.exec("insert into #{table1} values (1, 1)") end
335
+ select = Select.new(connection)
336
+ select.select('i')
337
+ select.select('j')
338
+ select.select('count(*)', 'count')
339
+ select.from(table1)
340
+ select.group_by('i')
341
+ select.group_by('j')
342
+ select.order_by('i')
343
+ select.order_by('j')
344
+ assertEquals(select.statement,
345
+ "select i, j, count(*) as count from #{table1} "\
346
+ "group by i, j order by i, j")
347
+ assertEquals(select.exec,
348
+ [
349
+ {"i"=>0, "j"=>0, "count"=>1},
350
+ {"i"=>0, "j"=>1, "count"=>2},
351
+ {"i"=>1, "j"=>0, "count"=>3},
352
+ {"i"=>1, "j"=>1, "count"=>4}
353
+ ])
354
+ end
355
+ end
356
+
357
+ def testGroupBy_Expression
358
+ makeTestConnection do |connection|
359
+ connection.exec("create temporary table #{table1} (t text)")
360
+ connection.exec("insert into #{table1} values ('alpha')")
361
+ connection.exec("insert into #{table1} values ('beta')")
362
+ connection.exec("insert into #{table1} values ('gamma')")
363
+ select = Select.new(connection)
364
+ select.select('count(*)', 'count')
365
+ select.from(table1)
366
+ select.group_by(['case t when %s then 0 else 1 end', 'alpha'])
367
+ select.order_by('count')
368
+ assertEquals(select.exec, [{'count'=>1}, {'count'=>2}])
369
+ end
370
+ end
371
+
372
+ def testHaving
373
+ makeTestConnection do |connection|
374
+ connection.exec("create temporary table #{table1} (i int)")
375
+ connection.exec("insert into #{table1} values (0)")
376
+ connection.exec("insert into #{table1} values (1)")
377
+ connection.exec("insert into #{table1} values (1)")
378
+ connection.exec("insert into #{table1} values (2)")
379
+ connection.exec("insert into #{table1} values (2)")
380
+ connection.exec("insert into #{table1} values (2)")
381
+ select = Select.new(connection)
382
+ select.select('count(*)', 'count')
383
+ select.from(table1)
384
+ select.group_by('i')
385
+ select.having('count(*) > 1')
386
+ select.having('count(*) < 3')
387
+ assertEquals(select.exec, [{'count'=>2}])
388
+ end
389
+ end
390
+
391
+ def testHaving_Expression
392
+ makeTestConnection do |connection|
393
+ connection.exec("create temporary table #{table1} (i int)")
394
+ connection.exec("insert into #{table1} values (0)")
395
+ connection.exec("insert into #{table1} values (1)")
396
+ connection.exec("insert into #{table1} values (1)")
397
+ select = Select.new(connection)
398
+ select.select('count(*)', 'count')
399
+ select.from(table1)
400
+ select.group_by('i')
401
+ select.having(['count(*) > %s', 1])
402
+ assertEquals(select.exec, [{'count'=>2}])
403
+ end
404
+ end
405
+
406
+ def testCrossJoin
407
+ makeTestConnection do |connection|
408
+ connection.exec("create temporary table #{table1} (i int)")
409
+ connection.exec("create temporary table #{table2} (i int)")
410
+ connection.exec("insert into #{table1} (i) values (1)")
411
+ connection.exec("insert into #{table1} (i) values (2)")
412
+ connection.exec("insert into #{table2} (i) values (3)")
413
+ connection.exec("insert into #{table2} (i) values (4)")
414
+ select = Select.new(connection)
415
+ select.select("#{table1}.i", "i1")
416
+ select.select("#{table2}.i", "i2")
417
+ select.from(table1)
418
+ select.cross_join(table2)
419
+ select.order_by('i1')
420
+ select.order_by('i2')
421
+ assertEquals(select.statement,
422
+ "select #{table1}.i as i1, #{table2}.i as i2 "\
423
+ "from #{table1} cross join #{table2} "\
424
+ "order by i1, i2")
425
+ assertEquals(select.exec, [
426
+ {"i1"=>1, "i2"=>3},
427
+ {"i1"=>1, "i2"=>4},
428
+ {"i1"=>2, "i2"=>3},
429
+ {"i1"=>2, "i2"=>4}
430
+ ])
431
+ end
432
+ end
433
+
434
+ def testNaturalJoin
435
+ makeTestConnection do |connection|
436
+ connection.exec("create temporary table #{table1} (i int)")
437
+ connection.exec("create temporary table #{table2} (i int)")
438
+ connection.exec("insert into #{table1} (i) values (1)")
439
+ connection.exec("insert into #{table1} (i) values (2)")
440
+ connection.exec("insert into #{table2} (i) values (2)")
441
+ connection.exec("insert into #{table2} (i) values (3)")
442
+ select = Select.new(connection)
443
+ select.select("i")
444
+ select.from(table1)
445
+ select.natural_join(table2)
446
+ assertEquals(select.statement,
447
+ "select i from #{table1} natural join #{table2}")
448
+ assertEquals(select.exec, [{'i'=>2}])
449
+ end
450
+ end
451
+
452
+ def testNaturalJoin_ThreeTables
453
+ makeTestConnection do |connection|
454
+ connection.exec("create temporary table #{table1} (i int)")
455
+ connection.exec("create temporary table #{table2} (i int)")
456
+ connection.exec("create temporary table #{table3} (i int)")
457
+ connection.exec("insert into #{table1} (i) values (1)")
458
+ connection.exec("insert into #{table1} (i) values (2)")
459
+ connection.exec("insert into #{table1} (i) values (3)")
460
+ connection.exec("insert into #{table2} (i) values (2)")
461
+ connection.exec("insert into #{table2} (i) values (3)")
462
+ connection.exec("insert into #{table3} (i) values (1)")
463
+ connection.exec("insert into #{table3} (i) values (2)")
464
+ select = Select.new(connection)
465
+ select.select("i")
466
+ select.from(table1)
467
+ select.natural_join(table2)
468
+ select.natural_join(table3)
469
+ assertEquals(select.statement,
470
+ "select i from #{table1} natural join #{table2} "\
471
+ "natural join #{table3}")
472
+ assertEquals(select.exec, [{'i'=>2}])
473
+ end
474
+ end
475
+
476
+ def testJoinUsing
477
+ testCases = [
478
+ [
479
+ "inner",
480
+ [
481
+ {'i1'=>2, 'i2'=>2},
482
+ ]
483
+ ],
484
+ [
485
+ "left outer",
486
+ [
487
+ {'i1'=>1, 'i2'=>nil},
488
+ {'i1'=>2, 'i2'=>2},
489
+ ]
490
+ ],
491
+ [
492
+ "right outer",
493
+ [
494
+ {'i1'=>2, 'i2'=>2},
495
+ {'i1'=>nil, 'i2'=>3},
496
+ ]
497
+ ],
498
+ [
499
+ "full outer",
500
+ [
501
+ {'i1'=>1, 'i2'=>nil},
502
+ {'i1'=>2, 'i2'=>2},
503
+ {'i1'=>nil, 'i2'=>3},
504
+ ]
505
+ ],
506
+ ]
507
+ for joinType, result in testCases
508
+ assertInfo("For joinType=#{joinType.inspect}") do
509
+ makeTestConnection do |connection|
510
+ connection.exec("create temporary table #{table1} (i int)")
511
+ connection.exec("create temporary table #{table2} (i int)")
512
+ connection.exec("insert into #{table1} (i) values (1)")
513
+ connection.exec("insert into #{table1} (i) values (2)")
514
+ connection.exec("insert into #{table2} (i) values (2)")
515
+ connection.exec("insert into #{table2} (i) values (3)")
516
+ select = Select.new(connection)
517
+ select.select("#{table1}.i", 'i1')
518
+ select.select("#{table2}.i", 'i2')
519
+ select.from(table1)
520
+ select.join_using(joinType, table2, 'i')
521
+ select.order_by('i1')
522
+ select.order_by('i2')
523
+ assertEquals(select.statement,
524
+ "select #{table1}.i as i1, #{table2}.i as i2 "\
525
+ "from #{table1} #{joinType} join #{table2} "\
526
+ "using (i) order by i1, i2")
527
+ assertEquals(select.exec, result)
528
+ end
529
+ end
530
+ end
531
+ end
532
+
533
+ def testJoinUsing_MultipleColumns
534
+ makeTestConnection do |connection|
535
+ connection.exec("create temporary table #{table1} (i int, j int)")
536
+ connection.exec("create temporary table #{table2} (i int, j int)")
537
+ connection.exec("insert into #{table1} (i, j) values (1, 1)")
538
+ connection.exec("insert into #{table1} (i, j) values (1, 2)")
539
+ connection.exec("insert into #{table2} (i, j) values (1, 2)")
540
+ connection.exec("insert into #{table2} (i, j) values (2, 2)")
541
+ select = Select.new(connection)
542
+ select.select("i")
543
+ select.select("j")
544
+ select.from(table1)
545
+ select.join_using('inner', table2, 'i', 'j')
546
+ assertEquals(select.statement,
547
+ "select i, j from #{table1} inner join #{table2} "\
548
+ "using (i, j)")
549
+ assertEquals(select.exec, [{'i'=>1, 'j'=>2}])
550
+ end
551
+ end
552
+
553
+ def testJoinOn
554
+ testCases = [
555
+ [
556
+ "inner",
557
+ [
558
+ {"i"=>2, "j"=>2}
559
+ ]
560
+ ],
561
+ [
562
+ "left outer",
563
+ [
564
+ {"i"=>1, "j"=>nil},
565
+ {"i"=>2, 'j'=>2}
566
+ ]
567
+ ],
568
+ [
569
+ "right outer",
570
+ [
571
+ {"i"=>2, "j"=>2},
572
+ {"i"=>nil, 'j'=>3}
573
+ ]
574
+ ],
575
+ [
576
+ "full outer",
577
+ [
578
+ {"i"=>1, "j"=>nil},
579
+ {"i"=>2, "j"=>2},
580
+ {"i"=>nil, 'j'=>3}
581
+ ]
582
+ ],
583
+ ]
584
+ makeTestConnection do |connection|
585
+ connection.exec("create temporary table #{table1} (i int)")
586
+ connection.exec("create temporary table #{table2} (j int)")
587
+ connection.exec("insert into #{table1} (i) values (1)")
588
+ connection.exec("insert into #{table1} (i) values (2)")
589
+ connection.exec("insert into #{table2} (j) values (2)")
590
+ connection.exec("insert into #{table2} (j) values (3)")
591
+ for joinType, result in testCases
592
+ assertInfo("for joinType=#{joinType.inspect}") do
593
+ select = Select.new(connection)
594
+ select.select("i")
595
+ select.select("j")
596
+ select.from(table1)
597
+ select.join_on(joinType, table2, 'i = j')
598
+ select.order_by('i')
599
+ select.order_by('j')
600
+ assertEquals(select.statement,
601
+ "select i, j from #{table1} "\
602
+ "#{joinType} join #{table2} on (i = j) "\
603
+ "order by i, j")
604
+ assertEquals(select.exec, result)
605
+ end
606
+ end
607
+ end
608
+ end
609
+
610
+ def testJoinOn_SubstituteValues
611
+ makeTestConnection do |connection|
612
+ connection.exec("create temporary table #{table1} (i int)")
613
+ connection.exec("create temporary table #{table2} (j int)")
614
+ connection.exec("insert into #{table1} (i) values (1)")
615
+ connection.exec("insert into #{table1} (i) values (2)")
616
+ connection.exec("insert into #{table2} (j) values (1)")
617
+ connection.exec("insert into #{table2} (j) values (2)")
618
+ connection.exec("insert into #{table2} (j) values (3)")
619
+ select = Select.new(connection)
620
+ select.select("i")
621
+ select.select("j")
622
+ select.from(table1)
623
+ select.join_on('inner', table2, ['i = j and i > %s', 1])
624
+ assertEquals(select.statement,
625
+ "select i, j from #{table1} "\
626
+ "inner join #{table2} on (i = j and i > 1)")
627
+ assertEquals(select.exec, [{'i'=>2, 'j'=>2}])
628
+ end
629
+ end
630
+
631
+ def testLimit
632
+ makeTestConnection do |connection|
633
+ connection.exec("create temporary table #{table1} (i int)")
634
+ connection.exec("insert into #{table1} values (1)")
635
+ connection.exec("insert into #{table1} values (2)")
636
+ connection.exec("insert into #{table1} values (3)")
637
+ select = Select.new(connection)
638
+ select.select('i')
639
+ select.from(table1)
640
+ select.order_by('i')
641
+ select.limit(2)
642
+ assertEquals(select.statement,
643
+ "select i from #{table1} order by i limit 2")
644
+ assertEquals(select.exec, [{'i'=>1}, {'i'=>2}])
645
+ end
646
+ end
647
+
648
+ def testOffset
649
+ makeTestConnection do |connection|
650
+ connection.exec("create temporary table #{table1} (i int)")
651
+ connection.exec("insert into #{table1} values (1)")
652
+ connection.exec("insert into #{table1} values (2)")
653
+ connection.exec("insert into #{table1} values (3)")
654
+ select = Select.new(connection)
655
+ select.select('i')
656
+ select.from(table1)
657
+ select.order_by('i')
658
+ select.limit(1)
659
+ select.offset(1)
660
+ assertEquals(select.statement,
661
+ "select i from #{table1} order by i limit 1 offset 1")
662
+ assertEquals(select.exec, [{'i'=>2}])
663
+ end
664
+ end
665
+
666
+ def testDistinct
667
+ makeTestConnection do |connection|
668
+ connection.exec("create temporary table #{table1} (i int)")
669
+ connection.exec("insert into #{table1} values (1)")
670
+ connection.exec("insert into #{table1} values (1)")
671
+ connection.exec("insert into #{table1} values (2)")
672
+ select = Select.new(connection)
673
+ select.distinct
674
+ select.select('i')
675
+ select.from(table1)
676
+ select.order_by('i')
677
+ assertEquals(select.statement,
678
+ "select distinct i from #{table1} order by i")
679
+ assertEquals(select.exec, [{'i'=>1}, {'i'=>2}])
680
+ end
681
+ end
682
+
683
+ def testDistinctOn
684
+ makeTestConnection do |connection|
685
+ connection.exec("create temporary table #{table1} (i int, j int, k int)")
686
+ connection.exec("insert into #{table1} values (0, 0, 0)")
687
+ connection.exec("insert into #{table1} values (0, 0, 1)")
688
+ connection.exec("insert into #{table1} values (0, 1, 0)")
689
+ connection.exec("insert into #{table1} values (0, 1, 1)")
690
+ connection.exec("insert into #{table1} values (1, 0, 0)")
691
+ connection.exec("insert into #{table1} values (1, 0, 1)")
692
+ connection.exec("insert into #{table1} values (1, 1, 0)")
693
+ connection.exec("insert into #{table1} values (1, 1, 1)")
694
+ select = Select.new(connection)
695
+ select.distinct_on('i')
696
+ select.select('i')
697
+ select.select('j')
698
+ select.select('k')
699
+ select.from(table1)
700
+ select.order_by('i')
701
+ select.order_by('j')
702
+ select.order_by('k')
703
+ assertEquals(select.statement,
704
+ "select distinct on (i) i, j, k from #{table1} "\
705
+ "order by i, j, k")
706
+ assertEquals(select.exec, [
707
+ {"i"=>0, "j"=>0, "k"=>0},
708
+ {"i"=>1, "j"=>0, "k"=>0}
709
+ ])
710
+ end
711
+ end
712
+
713
+ def testDistinctOn_TwoColumns
714
+ makeTestConnection do |connection|
715
+ connection.exec("create temporary table #{table1} (i int, j int, k int)")
716
+ connection.exec("insert into #{table1} values (0, 0, 0)")
717
+ connection.exec("insert into #{table1} values (0, 0, 1)")
718
+ connection.exec("insert into #{table1} values (0, 1, 0)")
719
+ connection.exec("insert into #{table1} values (0, 1, 1)")
720
+ connection.exec("insert into #{table1} values (1, 0, 0)")
721
+ connection.exec("insert into #{table1} values (1, 0, 1)")
722
+ connection.exec("insert into #{table1} values (1, 1, 0)")
723
+ connection.exec("insert into #{table1} values (1, 1, 1)")
724
+ select = Select.new(connection)
725
+ select.distinct_on('i')
726
+ select.distinct_on('j')
727
+ select.select('i')
728
+ select.select('j')
729
+ select.select('k')
730
+ select.from(table1)
731
+ select.order_by('i')
732
+ select.order_by('j')
733
+ select.order_by('k')
734
+ assertEquals(select.statement,
735
+ "select distinct on (i, j) i, j, k from #{table1} "\
736
+ "order by i, j, k")
737
+ assertEquals(select.exec, [
738
+ {"i"=>0, "j"=>0, "k"=>0},
739
+ {"i"=>0, "j"=>1, "k"=>0},
740
+ {"i"=>1, "j"=>0, "k"=>0},
741
+ {"i"=>1, "j"=>1, "k"=>0},
742
+ ])
743
+ end
744
+ end
745
+
746
+ def testSetOps
747
+ testCases = [
748
+ [:union, 'union', [1, 2, 3, 4]],
749
+ [:union_all, 'union all', [1, 1, 2, 2, 3, 3, 3, 3, 4]],
750
+ [:intersect, 'intersect', [2, 3]],
751
+ [:intersect_all, 'intersect all', [2, 3, 3]],
752
+ [:except, 'except', [1]],
753
+ [:except_all, 'except all', [1, 1]],
754
+ ]
755
+ makeTestConnection do |connection|
756
+ connection.exec("create temporary table #{table1} (i int)")
757
+ connection.exec("create temporary table #{table2} (i int)")
758
+ connection.exec("insert into #{table1} values (1)")
759
+ connection.exec("insert into #{table1} values (1)")
760
+ connection.exec("insert into #{table1} values (2)")
761
+ connection.exec("insert into #{table1} values (3)")
762
+ connection.exec("insert into #{table1} values (3)")
763
+ connection.exec("insert into #{table2} values (2)")
764
+ connection.exec("insert into #{table2} values (3)")
765
+ connection.exec("insert into #{table2} values (3)")
766
+ connection.exec("insert into #{table2} values (4)")
767
+ subselect = Select.new
768
+ subselect.select('i')
769
+ subselect.from(table2)
770
+ for function, op, expectedValues in testCases
771
+ assertInfo("For function #{function}:") do
772
+ select = Select.new(connection)
773
+ select.select('i')
774
+ select.from(table1)
775
+ select.send(function, subselect)
776
+ select.order_by('i')
777
+ assertEquals(select.statement, "select i from #{table1} "\
778
+ "#{op} (select i from #{table2}) order by i")
779
+ expectedResult = expectedValues.collect do |i| {'i'=>i} end
780
+ assertEquals(select.exec, expectedResult)
781
+ end
782
+ end
783
+ end
784
+ end
785
+
786
+ def testMultipleSetOps
787
+ makeTestConnection do |connection|
788
+ connection.exec("create temporary table #{table1} (i int)")
789
+ connection.exec("create temporary table #{table2} (i int)")
790
+ connection.exec("create temporary table #{table3} (i int)")
791
+ connection.exec("insert into #{table1} values (1)")
792
+ connection.exec("insert into #{table1} values (2)")
793
+ connection.exec("insert into #{table2} values (1)")
794
+ connection.exec("insert into #{table3} values (1)")
795
+ subselect2 = Select.new
796
+ subselect2.select('i')
797
+ subselect2.from(table2)
798
+ subselect3 = Select.new
799
+ subselect3.select('i')
800
+ subselect3.from(table3)
801
+ select = Select.new(connection)
802
+ select.select('i')
803
+ select.from(table1)
804
+ select.except(subselect2)
805
+ select.union(subselect3)
806
+ select.order_by('i')
807
+ assertEquals(select.statement, "select i from #{table1} "\
808
+ "except (select i from #{table2}) "\
809
+ "union (select i from #{table3}) order by i")
810
+ assertEquals(select.exec, [{'i'=>1}, {'i'=>2}])
811
+ end
812
+ end
813
+
814
+ def testUnionWithWhereClause
815
+ makeTestConnection do |connection|
816
+ connection.exec("create temporary table #{table1} (i int)")
817
+ 10.downto(1) do |i|
818
+ connection.exec("insert into #{table1} values (#{i})")
819
+ end
820
+ sql1 = Select.new
821
+ sql1.select('i')
822
+ sql1.from(table1)
823
+ sql1.where('i % 2 = 0')
824
+ sql2 = Select.new(connection)
825
+ sql2.select('i')
826
+ sql2.from(table1)
827
+ sql2.where('i % 1 = 0')
828
+ sql2.union(sql1)
829
+ sql3 = Select.new(connection)
830
+ sql3.select('i')
831
+ sql3.from(sql2, 'foo')
832
+ sql3.order_by('i')
833
+ values = sql3.exec.collect do |row|
834
+ row['i']
835
+ end
836
+ assertEquals(values, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
837
+ end
838
+ end
839
+
840
+ def testMultipleSetOps_Nested
841
+ makeTestConnection do |connection|
842
+ connection.exec("create temporary table #{table1} (i int)")
843
+ connection.exec("create temporary table #{table2} (i int)")
844
+ connection.exec("create temporary table #{table3} (i int)")
845
+ connection.exec("insert into #{table1} values (1)")
846
+ connection.exec("insert into #{table1} values (2)")
847
+ connection.exec("insert into #{table2} values (1)")
848
+ connection.exec("insert into #{table3} values (1)")
849
+ subselect3 = Select.new
850
+ subselect3.select('i')
851
+ subselect3.from(table3)
852
+ subselect2 = Select.new
853
+ subselect2.select('i')
854
+ subselect2.union(subselect3)
855
+ subselect2.from(table2)
856
+ select = Select.new(connection)
857
+ select.select('i')
858
+ select.from(table1)
859
+ select.except(subselect2)
860
+ select.order_by('i')
861
+ assertEquals(select.statement, "select i from #{table1} "\
862
+ "except (select i from #{table2} "\
863
+ "union (select i from #{table3})) order by i")
864
+ assertEquals(select.exec, [{'i'=>2}])
865
+ end
866
+ end
867
+
868
+ def testWhereIn
869
+ makeTestConnection do |connection|
870
+ connection.exec("create temporary table #{table1} (i int)")
871
+ for i in (0..9)
872
+ insert = Insert.new(table1, connection)
873
+ insert.insert('i', i)
874
+ insert.exec
875
+ end
876
+ select = Select.new(connection)
877
+ select.select('i')
878
+ select.from(table1)
879
+ select.where(['i in %s', [:in, 2, 4]])
880
+ assertEquals(select.exec, [{'i'=>2}, {'i'=>4}])
881
+ end
882
+ end
883
+
884
+ def testForUpdate
885
+ makeTestConnection do |db1|
886
+ db1.exec("create temporary table #{table1} (i int)")
887
+ db1.exec("insert into #{table1} (i) values (1)")
888
+ db1.exec("begin")
889
+ sql = Select.new(db1)
890
+ sql.select('i')
891
+ sql.from(table1)
892
+ sql.where(['i = %s', 1])
893
+ sql.for_update
894
+ assertEquals(sql.exec, [{'i'=>1}])
895
+ end
896
+ end
897
+
898
+ def testStatemenIdempotentWithRandomOrder
899
+ sql = Select.new
900
+ sql.select('i')
901
+ sql.from('foo')
902
+ setenv('RANDOM_SQL_ORDER', '1') do
903
+ assertEquals(sql.statement, "select i from foo order by random()")
904
+ assertEquals(sql.statement, "select i from foo order by random()")
905
+ end
906
+ end
907
+
908
+ def test_enum
909
+ enum_name = "foo"
910
+ makeTestConnection do |db1|
911
+ db1.exec("begin")
912
+ db1.exec("create type #{enum_name} as enum ('foo', 'bar', 'baz')")
913
+ db1.exec("create temporary table #{table1} (e #{enum_name})")
914
+ db1.exec("insert into #{table1} (e) values ('foo')")
915
+ sql = Select.new(db1)
916
+ sql.select('e')
917
+ sql.from(table1)
918
+ assertEquals(sql.exec, [{'e' => 'foo'}])
919
+ end
920
+ end
921
+
922
+ end
923
+
924
+ SelectTest.new.run if $0 == __FILE__
925
+
926
+ # Local Variables:
927
+ # tab-width: 2
928
+ # ruby-indent-level: 2
929
+ # indent-tabs-mode: nil
930
+ # End: