sqlpostgres 1.2.6 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. data/Changelog.md +18 -0
  2. data/Gemfile +2 -0
  3. data/Gemfile.lock +12 -0
  4. data/README.rdoc +5 -2
  5. data/Rakefile +5 -24
  6. data/VERSION +1 -1
  7. data/lib/sqlpostgres/Connection.rb +8 -3
  8. data/lib/sqlpostgres/Cursor.rb +2 -2
  9. data/lib/sqlpostgres/Insert.rb +1 -1
  10. data/lib/sqlpostgres/PgBit.rb +1 -1
  11. data/lib/sqlpostgres/PgBox.rb +1 -1
  12. data/lib/sqlpostgres/PgCidr.rb +1 -1
  13. data/lib/sqlpostgres/PgCircle.rb +1 -1
  14. data/lib/sqlpostgres/PgInet.rb +1 -1
  15. data/lib/sqlpostgres/PgInterval.rb +1 -1
  16. data/lib/sqlpostgres/PgLineSegment.rb +1 -1
  17. data/lib/sqlpostgres/PgMacAddr.rb +1 -1
  18. data/lib/sqlpostgres/PgPath.rb +1 -1
  19. data/lib/sqlpostgres/PgPoint.rb +1 -1
  20. data/lib/sqlpostgres/PgPolygon.rb +1 -1
  21. data/lib/sqlpostgres/PgTime.rb +1 -1
  22. data/lib/sqlpostgres/PgTimeWithTimeZone.rb +1 -1
  23. data/lib/sqlpostgres/PgTimestamp.rb +1 -1
  24. data/lib/sqlpostgres/PgTwoPoints.rb +1 -1
  25. data/lib/sqlpostgres/PgWrapper.rb +1 -1
  26. data/lib/sqlpostgres/Select.rb +25 -25
  27. data/lib/sqlpostgres/Translate.rb +7 -29
  28. data/lib/sqlpostgres/Update.rb +1 -1
  29. data/rake_tasks/db.rake +17 -0
  30. data/rake_tasks/default.rake +1 -0
  31. data/rake_tasks/jeweler.rake +18 -0
  32. data/rake_tasks/test.rake +2 -0
  33. data/rake_tasks/test_spec.rake +3 -0
  34. data/rake_tasks/test_unit.rake +4 -0
  35. data/spec/Translate_spec.rb +533 -0
  36. data/spec/config/.gitignore +1 -0
  37. data/spec/config/config.yml +10 -0
  38. data/spec/config/database.yml.template +6 -0
  39. data/spec/connection_spec.rb +515 -0
  40. data/spec/cursor_spec.rb +288 -0
  41. data/spec/lib/database_config.rb +33 -0
  42. data/spec/lib/database_server.rb +42 -0
  43. data/spec/lib/postgres_template.rb +60 -0
  44. data/spec/lib/target_database_servers.rb +55 -0
  45. data/spec/lib/temporary_table.rb +45 -0
  46. data/spec/lib/test_config.rb +24 -0
  47. data/spec/lib/test_connection.rb +29 -0
  48. data/spec/lib/test_database.rb +57 -0
  49. data/spec/roundtrip_spec.rb +582 -0
  50. data/spec/spec_helper.rb +10 -0
  51. data/spec/support/all_characters.rb +18 -0
  52. data/spec/support/clear_default_connection.rb +5 -0
  53. data/spec/support/temporary_table.rb +24 -0
  54. data/spec/support/test_connections.rb +10 -0
  55. data/sqlpostgres.gemspec +35 -4
  56. data/test/Connection.test.rb +7 -5
  57. data/test/Select.test.rb +1 -1
  58. data/test/TestConfig.rb +9 -0
  59. data/test/TestUtil.rb +17 -3
  60. metadata +66 -9
  61. data/test/Translate.test.rb +0 -354
  62. data/test/roundtrip.test.rb +0 -565
@@ -0,0 +1,45 @@
1
+ module TestSupport
2
+
3
+ class TemporaryTable
4
+
5
+ def self.create(*args)
6
+ table = new(*args)
7
+ table.drop if table.exists?
8
+ table.create
9
+ begin
10
+ yield
11
+ ensure
12
+ table.drop
13
+ end
14
+ end
15
+
16
+ def initialize(args)
17
+ @connection = args[:connection]
18
+ @table_name = args[:table_name]
19
+ @columns = args[:columns]
20
+ end
21
+
22
+ def exists?
23
+ sql = SqlPostgres::Select.new(@connection)
24
+ sql.select_literal(1)
25
+ sql.from('pg_class')
26
+ sql.where(['relname = %s', @table_name])
27
+ !sql.exec.empty?
28
+ end
29
+
30
+ def create
31
+ statement = [
32
+ 'create temporary table', @table_name,
33
+ "(#{@columns.join(', ')})",
34
+ ].join(' ')
35
+ @connection.exec statement
36
+ end
37
+
38
+ def drop
39
+ statement = "drop table #{@table_name}"
40
+ @connection.exec statement
41
+ end
42
+
43
+ end
44
+
45
+ end
@@ -0,0 +1,24 @@
1
+ require 'forwardable'
2
+
3
+ module TestSupport
4
+ class TestConfig
5
+
6
+ extend Forwardable
7
+
8
+ def initialize
9
+ @config = load_config
10
+ end
11
+
12
+ def_delegator :@config, :[]
13
+
14
+ private
15
+
16
+ PATH = File.expand_path('../config/config.yml',
17
+ File.dirname(__FILE__))
18
+
19
+ def load_config
20
+ YAML.load_file(PATH)
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,29 @@
1
+ require 'memoizer'
2
+
3
+ module TestSupport
4
+ class TestConnection
5
+
6
+ include Memoizer
7
+
8
+ def initialize(test_database, client_encoding)
9
+ @test_database = test_database
10
+ @client_encoding = client_encoding
11
+ end
12
+
13
+ def context
14
+ "(#{@test_database.context} client-encoding=#{@client_encoding})"
15
+ end
16
+
17
+ def connection
18
+ SqlPostgres::Connection.new(connection_args)
19
+ end
20
+ memoize :connection
21
+
22
+ private
23
+
24
+ def connection_args
25
+ @test_database.connection_args.merge('encoding' => @client_encoding)
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,57 @@
1
+ require 'memoizer'
2
+ require File.expand_path('test_connection', File.dirname(__FILE__))
3
+
4
+ module TestSupport
5
+ class TestDatabase
6
+
7
+ include Memoizer
8
+
9
+ attr_reader :connection_args
10
+
11
+ NAME_PREFIX = 'sqlpostgres_test_'
12
+
13
+ def initialize(name, connection_args, encoding)
14
+ @name = name
15
+ @connection_args = connection_args
16
+ @encoding = encoding
17
+ end
18
+
19
+ def create(template)
20
+ template.create_database(db_name, database_encoding)
21
+ end
22
+
23
+ def drop(template)
24
+ template.drop_database(db_name)
25
+ end
26
+
27
+ def context
28
+ "db=#{@name} db-encoding=#{database_encoding}"
29
+ end
30
+
31
+ def test_connections
32
+ client_encodings.map do |client_encoding|
33
+ TestConnection.new(self, client_encoding)
34
+ end
35
+ end
36
+ memoize :test_connections
37
+
38
+ def connection_args
39
+ @connection_args.merge('db_name' => db_name)
40
+ end
41
+
42
+ def db_name
43
+ "#{NAME_PREFIX}#{database_encoding}"
44
+ end
45
+
46
+ private
47
+
48
+ def database_encoding
49
+ @encoding['database_encoding']
50
+ end
51
+
52
+ def client_encodings
53
+ @encoding['client_encodings']
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,582 @@
1
+ $: << File.dirname(__FILE__)
2
+ require 'spec_helper'
3
+
4
+ module SqlPostgres
5
+
6
+ describe "Inserting and then Selecting" do
7
+
8
+ include_context "AllCharacters"
9
+
10
+ def self.testCases
11
+ [
12
+ [
13
+ ["integer", "int", "int4"],
14
+ [-2147483648, +2147483647, nil]
15
+ ],
16
+ [
17
+ ["smallint", "int2"],
18
+ [-32768, +32767, nil]
19
+ ],
20
+ [
21
+ [
22
+ "smallint[]", "int2[]",
23
+ "integer[]", "int[]", "int4[]",
24
+ "bigint[]", "int8[]",
25
+ ],
26
+ [[], [1], [1, 2], [-1, 0, 1], [[1, 2], [3, 4]], [[1, 2], [3, 4]], nil],
27
+ ],
28
+ [
29
+ ["bigint", "int8"],
30
+ [-9223372036854775808, +9223372036854775807, nil]
31
+ ],
32
+ [
33
+ ["real", "float4"],
34
+ [-1e30, -3.14159, +3.14159, 1e30, nil]
35
+ ],
36
+ [
37
+ ["real[]", "float4[]"],
38
+ [
39
+ [[-1e30, -3.14159], [+3.14159, 1e30]],
40
+ nil
41
+ ]
42
+ ],
43
+ [
44
+ ["decimal (7, 6)", "numeric (7, 6)"],
45
+ [BigDecimal("-3.14159"), BigDecimal("+3.14159"), nil]
46
+ ],
47
+ [
48
+ ["double precision", "float8"],
49
+ [-1e290, -3.1415926535897, +3.1415926535897, 1e290, nil]
50
+ ],
51
+ [
52
+ ["double precision[]", "float8[]"],
53
+ [
54
+ [[-1e290, -3.1415926535897], [+3.1415926535897, 1e290]],
55
+ nil
56
+ ]
57
+ ],
58
+ [
59
+ ["serial", "serial4"],
60
+ [1, +2147483647]
61
+ ],
62
+ [
63
+ ["bigserial", "serial8"],
64
+ [1, +9223372036854775807]
65
+ ],
66
+ [
67
+ ["text", "varchar(255)", "character varying (255)"],
68
+ [
69
+ "",
70
+ "Fool's gold",
71
+ allCharactersExceptNull,
72
+ nil
73
+ ]
74
+ ],
75
+ [
76
+ ["text[]", "varchar(255)[]", "character varying(255)[]"],
77
+ [
78
+ [], ["foo"], ["foo", "bar", "fool's gold"],
79
+ ["\\", "fool's", "a,b,c", "{}", "\"Hello!\"", "\001"],
80
+ # Can't get this character arrays to work with the full
81
+ # suite of characters, but we don't use character arrays
82
+ # anyhow.
83
+ # [allCharactersExceptNull],
84
+ [["a", "b"], ["c", "d"]],
85
+ nil,
86
+ ]
87
+ ],
88
+ [
89
+ ["character(4)", "char(4)"],
90
+ ["foo ", "'\"\001 ", nil]
91
+ ],
92
+ [
93
+ ["character(4)[]", "char(4)[]"],
94
+ [
95
+ [["foo ", "'\"\001 "], [" ", " a b"]],
96
+ nil
97
+ ]
98
+ ],
99
+ [
100
+ ["character", "char"],
101
+ ["a", "\001", "'", '"', nil]
102
+ ],
103
+ [
104
+ ["character[]", "char[]"],
105
+ [["a", "b"], ["c", "d"]],
106
+ nil
107
+ ],
108
+ [
109
+ ['"char"'],
110
+ ["\001", "\037", " ", "~", "\127", "\130", "\277", "\300", "\377"],
111
+ ],
112
+ [
113
+ ["name"],
114
+ ["foo", nil]
115
+ ],
116
+ [
117
+ ["name[]"],
118
+ [
119
+ [["foo", "bar"], ["baz", "quux"]],
120
+ nil
121
+ ]
122
+ ],
123
+ [
124
+ ["bytea"],
125
+ [
126
+ "",
127
+ allCharacters,
128
+ nil,
129
+ "\xc1\xb7",
130
+ "\\123",
131
+ "\\668G\345\256L\245",
132
+ ],
133
+ ],
134
+ # Can't get this to work, but we don't use byte array arrays anyhow.
135
+ # [
136
+ # ["bytea[]"],
137
+ # [
138
+ # [["foo", "bar"], ["baz", "quux"]],
139
+ # ["\\", "\000", allCharacters],
140
+ # nil
141
+ # ]
142
+ # ],
143
+ [
144
+ ["timestamp", "timestamp without time zone"],
145
+ [
146
+ PgTimestamp.new(1900, 1, 1, 0, 0, 0),
147
+ PgTimestamp.new(1999, 12, 31, 23, 59, 59),
148
+ nil
149
+ ]
150
+ ],
151
+ [
152
+ ["timestamp[]", "timestamp without time zone[]"],
153
+ [
154
+ [
155
+ PgTimestamp.new(1900, 1, 1, 0, 0, 0),
156
+ PgTimestamp.new(1999, 12, 31, 23, 59, 59)
157
+ ],
158
+ nil
159
+ ]
160
+ ],
161
+ [
162
+ ["timestamp with time zone"],
163
+ [
164
+ {
165
+ 'in'=>DateTime.civil(2001, 1, 1, 0, 0, 0, Rational(7, 24)),
166
+ 'out'=>DateTime.civil(2000, 12, 31, 10, 0, 0, Rational(-7, 24)),
167
+ },
168
+ DateTime.civil(1900, 12, 31, 23, 59, 59, Rational(0, 24)),
169
+ nil
170
+ ]
171
+ ],
172
+ [
173
+ ["timestamp with time zone[]"],
174
+ [
175
+ [
176
+ DateTime.civil(2001, 1, 1, 0, 0, 0, Rational(7, 24)),
177
+ DateTime.civil(1900, 12, 31, 23, 59, 59, Rational(0, 24)),
178
+ ],
179
+ nil
180
+ ]
181
+ ],
182
+ [
183
+ ["interval"],
184
+ [
185
+ PgInterval.new,
186
+ PgInterval.new('seconds'=>1),
187
+ PgInterval.new('minutes'=>1),
188
+ PgInterval.new('hours'=>1),
189
+ PgInterval.new('days'=>1),
190
+ PgInterval.new('days'=>2),
191
+ {
192
+ 'in'=>PgInterval.new('weeks'=>1),
193
+ 'out'=>PgInterval.new('days'=>7),
194
+ },
195
+ PgInterval.new('months'=>1),
196
+ PgInterval.new('months'=>2),
197
+ PgInterval.new('years'=>1),
198
+ PgInterval.new('years'=>2),
199
+ {
200
+ 'in'=>PgInterval.new('decades'=>1),
201
+ 'out'=>PgInterval.new('years'=>10),
202
+ },
203
+ {
204
+ 'in'=>PgInterval.new('centuries'=>1),
205
+ 'out'=>PgInterval.new('years'=>100),
206
+ },
207
+ {
208
+ 'in'=>PgInterval.new('millennia'=>1),
209
+ 'out'=>PgInterval.new('years'=>1000),
210
+ },
211
+ {
212
+ 'in'=>PgInterval.new('millennia'=>1, 'centuries'=>2, 'decades'=>3,
213
+ 'years'=>4, 'months'=>5, 'weeks'=>6,
214
+ 'days'=>7, 'hours'=>8, 'minutes'=>9,
215
+ 'seconds'=>10),
216
+ 'out'=>PgInterval.new('years'=>1234, 'months'=>5, 'days'=>49,
217
+ 'hours'=>8, 'minutes'=>9, 'seconds'=>10),
218
+ },
219
+ PgInterval.new('days'=>-1),
220
+ {
221
+ 'in'=>PgInterval.new('days'=>1, 'ago'=>true),
222
+ 'out'=>PgInterval.new('days'=>-1),
223
+ },
224
+ {
225
+ 'in'=>PgInterval.new('days'=>-1, 'ago'=>true),
226
+ 'out'=>PgInterval.new('days'=>1),
227
+ },
228
+ PgInterval.new('seconds'=>1.1),
229
+ {
230
+ 'in'=>PgInterval.new('hours'=>1, 'minutes'=>-1, 'seconds'=>1),
231
+ 'out'=>PgInterval.new('hours'=>0, 'minutes'=>59, 'seconds'=>1),
232
+ },
233
+ nil
234
+ ]
235
+ ],
236
+ [
237
+ ["interval[]"],
238
+ [
239
+ [
240
+ [
241
+ PgInterval.new('days'=>1),
242
+ PgInterval.new('hours'=>2),
243
+ ],
244
+ [
245
+ PgInterval.new('minutes'=>3),
246
+ PgInterval.new('seconds'=>4),
247
+ ],
248
+ ],
249
+ nil,
250
+ ]
251
+ ],
252
+ [
253
+ ["date"],
254
+ [Date.civil(2001, 1, 1), Date.civil(1900, 12, 31), nil]
255
+ ],
256
+ [
257
+ ["date[]"],
258
+ [[Date.civil(2001, 1, 1), Date.civil(1900, 12, 31)], nil]
259
+ ],
260
+ [
261
+ ["time"],
262
+ [PgTime.new(0, 0, 0), PgTime.new(23, 59, 59), nil]
263
+ ],
264
+ [
265
+ ["time[]"],
266
+ [[PgTime.new(0, 0, 0), PgTime.new(23, 59, 59)], nil]
267
+ ],
268
+ [
269
+ ["time with time zone"],
270
+ [
271
+ PgTimeWithTimeZone.new(0, 0, 0, 0, 0),
272
+ PgTimeWithTimeZone.new(12, 0, 0, 0, 30),
273
+ PgTimeWithTimeZone.new(12, 0, 0, -8, 0),
274
+ PgTimeWithTimeZone.new(23, 59, 59, +8, 0),
275
+ nil
276
+ ]
277
+ ],
278
+ [
279
+ ["time with time zone[]"],
280
+ [
281
+ [
282
+ PgTimeWithTimeZone.new(0, 0, 0, 0, 0),
283
+ PgTimeWithTimeZone.new(23, 59, 59, +8, 0),
284
+ ],
285
+ nil
286
+ ]
287
+ ],
288
+ [
289
+ ["boolean"],
290
+ [false, true, nil],
291
+ ],
292
+ [
293
+ ["boolean[]"],
294
+ [
295
+ [false, true],
296
+ [[false, false], [false, true], [true, false], [true, true]],
297
+ nil,
298
+ ]
299
+ ],
300
+ [
301
+ ["point"],
302
+ [
303
+ PgPoint.new(0, 0),
304
+ PgPoint.new(1.2, -3),
305
+ PgPoint.new(1e20, -1e20),
306
+ nil,
307
+ ],
308
+ ],
309
+ [
310
+ ["point[]"],
311
+ [
312
+ [PgPoint.new(0, 0), PgPoint.new(1.2, -3), PgPoint.new(1e20, -1e20)],
313
+ nil,
314
+ ],
315
+ ],
316
+ [
317
+ ["lseg"],
318
+ [
319
+ PgLineSegment.new(0, 0, 0, 0),
320
+ PgLineSegment.new(1.2, -2, 1e10, -1e10),
321
+ nil
322
+ ]
323
+ ],
324
+ [
325
+ ["lseg[]"],
326
+ [
327
+ [
328
+ PgLineSegment.new(0, 0, 0, 0),
329
+ PgLineSegment.new(1.2, -2, 1e10, -1e10),
330
+ ],
331
+ nil
332
+ ]
333
+ ],
334
+ [
335
+ ["box"],
336
+ [
337
+ PgBox.new(0, 0, 0, 0),
338
+ PgBox.new(1e10, -2, 1.2, -1e10),
339
+ nil
340
+ ]
341
+ ],
342
+ # Can't get this to work, but we don't use box arrays anyhow.
343
+ # [
344
+ # ["box[]"],
345
+ # [
346
+ # [
347
+ # PgBox.new(0, 0, 0, 0),
348
+ # PgBox.new(1.2, -2, 1e10, -1e10),
349
+ # ],
350
+ # nil
351
+ # ]
352
+ # ],
353
+ [
354
+ ["path"],
355
+ [
356
+ PgPath.new(false, PgPoint.new(1, 2)),
357
+ PgPath.new(true, PgPoint.new(1, 2), PgPoint.new(3, 4)),
358
+ nil,
359
+ ]
360
+ ],
361
+ [
362
+ ["path[]"],
363
+ [
364
+ [
365
+ PgPath.new(false, PgPoint.new(1, 2)),
366
+ PgPath.new(true, PgPoint.new(1, 2), PgPoint.new(3, 4)),
367
+ ],
368
+ nil
369
+ ]
370
+ ],
371
+ [
372
+ ["polygon"],
373
+ [
374
+ PgPolygon.new(PgPoint.new(1, 2)),
375
+ PgPolygon.new(PgPoint.new(1, 2), PgPoint.new(3, 4)),
376
+ nil,
377
+ ]
378
+ ],
379
+ [
380
+ ["polygon[]"],
381
+ [
382
+ [
383
+ PgPolygon.new(PgPoint.new(1, 2)),
384
+ PgPolygon.new(PgPoint.new(1, 2), PgPoint.new(3, 4)),
385
+ ],
386
+ nil
387
+ ]
388
+ ],
389
+ [
390
+ ["circle"],
391
+ [
392
+ PgCircle.new(0, 0, 0),
393
+ PgCircle.new(1, 2, 3),
394
+ nil,
395
+ ]
396
+ ],
397
+ [
398
+ ["circle[]"],
399
+ [
400
+ [
401
+ PgCircle.new(0, 0, 0),
402
+ PgCircle.new(1, 2, 3),
403
+ ],
404
+ nil,
405
+ ]
406
+ ],
407
+ [
408
+ ["bit varying", "bit varying(6)"],
409
+ [
410
+ PgBit.new,
411
+ PgBit.new("0"),
412
+ PgBit.new("010101"),
413
+ nil
414
+ ]
415
+ ],
416
+ [
417
+ ["bit varying[]", "bit varying(6)[]"],
418
+ [
419
+ [
420
+ PgBit.new,
421
+ PgBit.new("0"),
422
+ PgBit.new("010101"),
423
+ ],
424
+ nil
425
+ ]
426
+ ],
427
+ [
428
+ ["bit(1)", "bit"],
429
+ [
430
+ PgBit.new("1"),
431
+ PgBit.new("0"),
432
+ nil
433
+ ]
434
+ ],
435
+ [
436
+ ["bit(1)[]", "bit[]"],
437
+ [
438
+ [
439
+ PgBit.new("1"),
440
+ PgBit.new("0"),
441
+ ],
442
+ nil
443
+ ]
444
+ ],
445
+ [
446
+ ["inet"],
447
+ [
448
+ PgInet.new("0.0.0.0/0"),
449
+ {
450
+ 'in'=>PgInet.new("255.255.255.255/32"),
451
+ 'out'=>PgInet.new("255.255.255.255"),
452
+ },
453
+ PgInet.new("255.255.255.255"),
454
+ PgInet.new("1.2.0.0/16"),
455
+ nil
456
+ ],
457
+ ],
458
+ [
459
+ ["inet[]"],
460
+ [
461
+ [
462
+ PgInet.new("255.255.255.255"),
463
+ PgInet.new("1.2.0.0/16")
464
+ ],
465
+ nil,
466
+ ],
467
+ ],
468
+ [
469
+ ["cidr"],
470
+ [
471
+ PgCidr.new("0.0.0.0/0"),
472
+ PgCidr.new("255.255.255.255/32"),
473
+ PgCidr.new("1.2.0.0/16"),
474
+ nil,
475
+ ],
476
+ ],
477
+ [
478
+ ["cidr[]"],
479
+ [
480
+ [
481
+ PgCidr.new("0.0.0.0/0"),
482
+ PgCidr.new("255.255.255.255/32")
483
+ ],
484
+ nil,
485
+ ],
486
+ ],
487
+ [
488
+ ["macaddr"],
489
+ [
490
+ PgMacAddr.new("08:00:2b:01:02:03"),
491
+ PgMacAddr.new("00:00:00:00:00:00"),
492
+ nil,
493
+ ]
494
+ ],
495
+ [
496
+ ["macaddr[]"],
497
+ [
498
+ [
499
+ PgMacAddr.new("08:00:2b:01:02:03"),
500
+ PgMacAddr.new("00:00:00:00:00:00"),
501
+ ],
502
+ nil,
503
+ ]
504
+ ],
505
+ ]
506
+
507
+ end
508
+
509
+ test_connections.each do |test_context, test_connection|
510
+
511
+ context test_context do
512
+
513
+ testCases.each do |columnTypes, values|
514
+
515
+ columnTypes.each do |columnType|
516
+
517
+ context "column type: #{columnType.inspect}" do
518
+
519
+ def self.table
520
+ 'round_trip_tests'
521
+ end
522
+
523
+ let(:table) {self.class.table}
524
+
525
+ let(:connection) do
526
+ test_connection
527
+ end
528
+
529
+ include_context('temporary table',
530
+ :table_name => table,
531
+ :columns => ["v #{columnType}"])
532
+
533
+ values.each do |value|
534
+
535
+ context "value: #{value.inspect}" do
536
+
537
+ it do
538
+ if value.is_a?(Hash)
539
+ value_in = value['in']
540
+ value_out = value['out']
541
+ else
542
+ value_in = value
543
+ value_out = value
544
+ end
545
+ insert = Insert.new(table, connection)
546
+ case columnType
547
+ when 'bytea[]'
548
+ insert.insert_bytea_array('v', value_in)
549
+ when /\[\]/
550
+ insert.insert_array('v', value_in)
551
+ when '"char"'
552
+ insert.insert_qchar('v', value_in)
553
+ when 'bytea'
554
+ insert.insert_bytea('v', value_in)
555
+ else
556
+ insert.insert('v', value_in)
557
+ end
558
+ insert.exec
559
+ select = Select.new(connection)
560
+ select.select('v')
561
+ select.from(table)
562
+ result = select.exec[0]['v']
563
+ result.should == value_out
564
+
565
+ end
566
+ end
567
+ end
568
+
569
+ end
570
+
571
+ end
572
+
573
+ end
574
+
575
+ end
576
+
577
+ end
578
+
579
+ end
580
+
581
+ end
582
+