pod4 0.7.2 → 0.8.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.
- checksums.yaml +4 -4
- data/.hgignore +1 -0
- data/.hgtags +1 -0
- data/Gemfile +3 -1
- data/Rakefile +17 -5
- data/lib/pod4/pg_interface.rb +81 -57
- data/lib/pod4/sequel_interface.rb +61 -6
- data/lib/pod4/sql_helper.rb +229 -0
- data/lib/pod4/tds_interface.rb +65 -50
- data/lib/pod4/version.rb +1 -1
- data/md/roadmap.md +81 -25
- data/spec/common/basic_model_spec.rb +5 -0
- data/spec/common/model_spec.rb +49 -7
- data/spec/common/nebulous_interface_spec.rb +2 -0
- data/spec/common/sequel_interface_pg_spec.rb +511 -0
- data/spec/common/sql_helper_spec.rb +299 -0
- data/spec/jruby/sequel_interface_jdbc_ms_spec.rb +525 -0
- data/spec/jruby/sequel_interface_jdbc_pg_spec.rb +520 -0
- data/spec/mri/pg_interface_spec.rb +140 -16
- data/spec/mri/sequel_interface_spec.rb +146 -13
- data/spec/mri/tds_interface_spec.rb +82 -12
- metadata +11 -4
- data/spec/jruby/pg_interface_spec.rb +0 -469
@@ -8,6 +8,9 @@ require_relative '../fixtures/database'
|
|
8
8
|
class TestPgInterface < PgInterface
|
9
9
|
set_table :customer
|
10
10
|
set_id_fld :id
|
11
|
+
|
12
|
+
# We open a lot of connections, unusually
|
13
|
+
def stop; close; end
|
11
14
|
end
|
12
15
|
|
13
16
|
class SchemaPgInterface < PgInterface
|
@@ -24,23 +27,33 @@ class BadPgInterface2 < PgInterface
|
|
24
27
|
set_id_fld :id
|
25
28
|
end
|
26
29
|
|
30
|
+
class ProdPgInterface < PgInterface
|
31
|
+
set_table :product
|
32
|
+
set_id_fld :code
|
33
|
+
end
|
34
|
+
|
27
35
|
|
28
36
|
describe TestPgInterface do
|
29
37
|
|
30
38
|
def db_setup(connect)
|
31
39
|
client = PG.connect(connect)
|
32
40
|
|
33
|
-
client.exec(%Q|drop table if exists customer;|)
|
34
|
-
|
35
41
|
client.exec(%Q|
|
42
|
+
drop table if exists customer;
|
43
|
+
drop table if exists product;
|
44
|
+
|
36
45
|
create table customer (
|
37
|
-
id serial,
|
46
|
+
id serial primary key,
|
38
47
|
name text,
|
39
48
|
level real null,
|
40
49
|
day date null,
|
41
50
|
timestamp timestamp null,
|
42
51
|
price money null,
|
43
|
-
qty numeric null )
|
52
|
+
qty numeric null );
|
53
|
+
|
54
|
+
create table product (
|
55
|
+
code text,
|
56
|
+
name text );| )
|
44
57
|
|
45
58
|
ensure
|
46
59
|
client.finish if client
|
@@ -52,6 +65,11 @@ describe TestPgInterface do
|
|
52
65
|
end
|
53
66
|
|
54
67
|
|
68
|
+
def fill_product_data(ifce)
|
69
|
+
ifce.create( {code: "foo", name: "bar"} )
|
70
|
+
end
|
71
|
+
|
72
|
+
|
55
73
|
before(:all) do
|
56
74
|
@connect_hash = DB[:pg]
|
57
75
|
db_setup(@connect_hash)
|
@@ -82,8 +100,16 @@ describe TestPgInterface do
|
|
82
100
|
|
83
101
|
|
84
102
|
before do
|
85
|
-
|
86
|
-
|
103
|
+
interface.execute(%Q|
|
104
|
+
truncate table customer restart identity;
|
105
|
+
truncate table product;|)
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
after do
|
111
|
+
# We open a lot of connections, unusually
|
112
|
+
interface.stop if interface
|
87
113
|
end
|
88
114
|
|
89
115
|
|
@@ -91,6 +117,10 @@ describe TestPgInterface do
|
|
91
117
|
TestPgInterface.new(@connect_hash)
|
92
118
|
end
|
93
119
|
|
120
|
+
let(:prod_interface) do
|
121
|
+
ProdPgInterface.new(@connect_hash)
|
122
|
+
end
|
123
|
+
|
94
124
|
#####
|
95
125
|
|
96
126
|
|
@@ -212,20 +242,29 @@ describe TestPgInterface do
|
|
212
242
|
expect( interface.read(id).to_h ).to include ot.to_h
|
213
243
|
end
|
214
244
|
|
215
|
-
it '
|
245
|
+
it 'shouldn\'t have a problem with record values of nil' do
|
216
246
|
record = {name: 'Ranger', price: nil}
|
217
247
|
expect{ interface.create(record) }.not_to raise_exception
|
218
248
|
id = interface.create(record)
|
219
249
|
expect( interface.read(id).to_h ).to include(record)
|
220
250
|
end
|
221
251
|
|
222
|
-
it '
|
252
|
+
it 'shouldn\'t have a problem with strings containing special characters' do
|
223
253
|
record = {name: %Q|T'Challa""|, price: nil}
|
224
254
|
expect{ interface.create(record) }.not_to raise_exception
|
225
255
|
id = interface.create(record)
|
226
256
|
expect( interface.read(id).to_h ).to include(record)
|
227
257
|
end
|
228
258
|
|
259
|
+
it 'shouldn\'t have a problem with non-integer keys' do
|
260
|
+
hash = {code: "foo", name: "bar"}
|
261
|
+
id = prod_interface.create( Octothorpe.new(hash) )
|
262
|
+
|
263
|
+
expect( id ).to eq "foo"
|
264
|
+
expect{ prod_interface.read("foo") }.not_to raise_exception
|
265
|
+
expect( prod_interface.read("foo").to_h ).to include hash
|
266
|
+
end
|
267
|
+
|
229
268
|
end
|
230
269
|
##
|
231
270
|
|
@@ -284,6 +323,14 @@ describe TestPgInterface do
|
|
284
323
|
expect( price ).to eq @data.first[:price]
|
285
324
|
end
|
286
325
|
|
326
|
+
it 'shouldn\'t have a problem with non-integer keys' do
|
327
|
+
# this is a 100% overlap with the create test above...
|
328
|
+
fill_product_data(prod_interface)
|
329
|
+
|
330
|
+
expect{ prod_interface.read("foo") }.not_to raise_exception
|
331
|
+
expect( prod_interface.read("foo").to_h ).to include(code: "foo", name: "bar")
|
332
|
+
end
|
333
|
+
|
287
334
|
end
|
288
335
|
##
|
289
336
|
|
@@ -337,8 +384,6 @@ describe TestPgInterface do
|
|
337
384
|
record = {name: 'Booboo', price: 99.99}
|
338
385
|
interface.update(id, record)
|
339
386
|
|
340
|
-
# It so happens that TinyTds returns money as BigDecimal --
|
341
|
-
# this is a really good thing, even though it screws with our test.
|
342
387
|
expect( float_price( interface.read(id).to_h ) ).to include(record)
|
343
388
|
end
|
344
389
|
|
@@ -354,26 +399,32 @@ describe TestPgInterface do
|
|
354
399
|
|
355
400
|
end
|
356
401
|
|
357
|
-
it '
|
402
|
+
it 'shouldn\'t have a problem with record values of nil' do
|
358
403
|
record = {name: 'Ranger', price: nil}
|
359
404
|
expect{ interface.update(id, record) }.not_to raise_exception
|
360
405
|
expect( interface.read(id).to_h ).to include(record)
|
361
406
|
end
|
362
407
|
|
363
|
-
it '
|
408
|
+
it 'shouldn\'t have a problem with strings containing special characters' do
|
364
409
|
record = {name: %Q|T'Challa""|, price: nil}
|
365
410
|
expect{ interface.update(id, record) }.not_to raise_exception
|
366
411
|
expect( interface.read(id).to_h ).to include(record)
|
367
412
|
end
|
368
413
|
|
414
|
+
it 'shouldn\'t have a problem with non-integer keys' do
|
415
|
+
fill_product_data(prod_interface)
|
416
|
+
expect{ prod_interface.update("foo", name: "baz") }.not_to raise_error
|
417
|
+
expect( prod_interface.read("foo").to_h[:name] ).to eq "baz"
|
418
|
+
end
|
419
|
+
|
369
420
|
end
|
370
421
|
##
|
371
422
|
|
372
423
|
|
373
424
|
describe '#delete' do
|
374
425
|
|
375
|
-
def list_contains(id)
|
376
|
-
|
426
|
+
def list_contains(ifce, id)
|
427
|
+
ifce.list.find {|x| x[ifce.id_fld] == id }
|
377
428
|
end
|
378
429
|
|
379
430
|
let(:id) { interface.list.first[:id] }
|
@@ -386,9 +437,16 @@ describe TestPgInterface do
|
|
386
437
|
end
|
387
438
|
|
388
439
|
it 'makes the record at ID go away' do
|
389
|
-
expect( list_contains(id) ).to be_truthy
|
440
|
+
expect( list_contains(interface, id) ).to be_truthy
|
390
441
|
interface.delete(id)
|
391
|
-
expect( list_contains(id) ).to be_falsy
|
442
|
+
expect( list_contains(interface, id) ).to be_falsy
|
443
|
+
end
|
444
|
+
|
445
|
+
it 'shouldn\'t have a problem with non-integer keys' do
|
446
|
+
fill_product_data(prod_interface)
|
447
|
+
expect( list_contains(prod_interface, "foo") ).to be_truthy
|
448
|
+
prod_interface.delete("foo")
|
449
|
+
expect( list_contains(prod_interface, "foo") ).to be_falsy
|
392
450
|
end
|
393
451
|
|
394
452
|
end
|
@@ -423,6 +481,34 @@ describe TestPgInterface do
|
|
423
481
|
##
|
424
482
|
|
425
483
|
|
484
|
+
describe '#executep' do
|
485
|
+
|
486
|
+
let(:sql) { 'delete from customer where cast(price as numeric) < %s and name = %s;' }
|
487
|
+
|
488
|
+
before { fill_data(interface) }
|
489
|
+
|
490
|
+
it 'requires an SQL string' do
|
491
|
+
expect{ interface.executep }.to raise_exception ArgumentError
|
492
|
+
expect{ interface.executep(nil) }.to raise_exception ArgumentError
|
493
|
+
expect{ interface.executep(14) }.to raise_exception ArgumentError
|
494
|
+
end
|
495
|
+
|
496
|
+
it 'raises some sort of Pod4 error if it runs into problems' do
|
497
|
+
expect{ interface.executep('delete from not_a_table where foo = %s', 12) }.
|
498
|
+
to raise_exception Pod4Error
|
499
|
+
|
500
|
+
end
|
501
|
+
|
502
|
+
it 'executes the string with the given parameters' do
|
503
|
+
expect{ interface.executep(sql, 12.0, 'Barney') }.not_to raise_exception
|
504
|
+
expect( interface.list.size ).to eq(@data.size - 1)
|
505
|
+
expect( interface.list.map{|r| r[:name] } ).not_to include 'Barney'
|
506
|
+
end
|
507
|
+
|
508
|
+
end
|
509
|
+
##
|
510
|
+
|
511
|
+
|
426
512
|
describe '#select' do
|
427
513
|
|
428
514
|
before { fill_data(interface) }
|
@@ -462,5 +548,43 @@ describe TestPgInterface do
|
|
462
548
|
##
|
463
549
|
|
464
550
|
|
551
|
+
describe '#selectp' do
|
552
|
+
|
553
|
+
before { fill_data(interface) }
|
554
|
+
|
555
|
+
it 'requires an SQL string' do
|
556
|
+
expect{ interface.selectp }.to raise_exception ArgumentError
|
557
|
+
expect{ interface.selectp(nil) }.to raise_exception ArgumentError
|
558
|
+
expect{ interface.selectp(14) }.to raise_exception ArgumentError
|
559
|
+
end
|
560
|
+
|
561
|
+
it 'raises some sort of Pod4 error if it runs into problems' do
|
562
|
+
expect{ interface.selectp('select * from not_a_table where thingy = %s', 12) }.
|
563
|
+
to raise_exception Pod4Error
|
564
|
+
|
565
|
+
end
|
566
|
+
|
567
|
+
it 'returns the result of the sql' do
|
568
|
+
sql = 'select name from customer where cast(price as numeric) < %s;'
|
569
|
+
|
570
|
+
expect{ interface.selectp(sql, 2.0) }.not_to raise_exception
|
571
|
+
expect( interface.selectp(sql, 2.0) ).to eq( [{name: 'Barney'}] )
|
572
|
+
expect( interface.selectp(sql, 0.0) ).to eq( [] )
|
573
|
+
end
|
574
|
+
|
575
|
+
it 'works if you pass a non-select' do
|
576
|
+
sql = 'delete from customer where cast(price as numeric) < %s;'
|
577
|
+
ret = interface.selectp(sql, 2.0)
|
578
|
+
|
579
|
+
expect( interface.list.size ).to eq(@data.size - 1)
|
580
|
+
expect( interface.list.map{|r| r[:name] } ).not_to include 'Barney'
|
581
|
+
expect( ret ).to eq( [] )
|
582
|
+
end
|
583
|
+
|
584
|
+
|
585
|
+
end
|
586
|
+
##
|
587
|
+
|
588
|
+
|
465
589
|
end
|
466
590
|
|
@@ -27,6 +27,13 @@ class BadSequelInterface2 < SequelInterface
|
|
27
27
|
set_id_fld :id
|
28
28
|
end
|
29
29
|
|
30
|
+
class ProdSequelInterface < SequelInterface
|
31
|
+
set_table :product
|
32
|
+
set_id_fld :code
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
|
30
37
|
|
31
38
|
describe TestSequelInterface do
|
32
39
|
|
@@ -63,14 +70,18 @@ describe TestSequelInterface do
|
|
63
70
|
data.each{|r| ifce.create(r) }
|
64
71
|
end
|
65
72
|
|
73
|
+
def fill_product_data(ifce)
|
74
|
+
ifce.create( {code: "foo", name: "bar"} )
|
75
|
+
end
|
76
|
+
|
77
|
+
|
66
78
|
# This is stolen almost verbatim from the Sequel Readme. We use an in-memory
|
67
79
|
# sqlite database, and we assume that Sequel is sane and behaves broadly the
|
68
80
|
# same for our limited purposes as it would when talking to TinyTDS or Pg.
|
69
|
-
#
|
70
|
-
# change this. But in any case, we are not in the business of testing Sequel:
|
71
|
-
# just our interface to it.
|
81
|
+
# We test these elsewhere...
|
72
82
|
let (:db) do
|
73
83
|
db = Sequel.sqlite
|
84
|
+
|
74
85
|
db.create_table :customer do
|
75
86
|
primary_key :id
|
76
87
|
String :name
|
@@ -79,10 +90,17 @@ describe TestSequelInterface do
|
|
79
90
|
Time :timestamp
|
80
91
|
BigDecimal :price, :size=>[10.2] # Sequel doesn't support money
|
81
92
|
end
|
93
|
+
|
94
|
+
db.create_table :product do
|
95
|
+
String :code, :primary_key => true
|
96
|
+
String :name
|
97
|
+
end
|
98
|
+
|
82
99
|
db
|
83
100
|
end
|
84
101
|
|
85
|
-
let(:interface)
|
102
|
+
let(:interface) { TestSequelInterface.new(db) }
|
103
|
+
let(:prod_interface) { ProdSequelInterface.new(db) }
|
86
104
|
|
87
105
|
before do
|
88
106
|
fill_data(interface)
|
@@ -108,8 +126,6 @@ describe TestSequelInterface do
|
|
108
126
|
end
|
109
127
|
|
110
128
|
let(:record) { {name: 'Barney', price: 1.11} }
|
111
|
-
#let(:record_id) { 'Barney' }
|
112
|
-
|
113
129
|
end
|
114
130
|
##
|
115
131
|
|
@@ -215,6 +231,7 @@ describe TestSequelInterface do
|
|
215
231
|
# kinda impossible to seperate these two tests
|
216
232
|
id = interface.create(hash)
|
217
233
|
|
234
|
+
expect( id ).not_to be_nil
|
218
235
|
expect{ interface.read(id) }.not_to raise_exception
|
219
236
|
expect( interface.read(id).to_h ).to include hash
|
220
237
|
end
|
@@ -222,6 +239,7 @@ describe TestSequelInterface do
|
|
222
239
|
it 'creates the record when given an Octothorpe' do
|
223
240
|
id = interface.create(ot)
|
224
241
|
|
242
|
+
expect( id ).not_to be_nil
|
225
243
|
expect{ interface.read(id) }.not_to raise_exception
|
226
244
|
expect( interface.read(id).to_h ).to include ot.to_h
|
227
245
|
end
|
@@ -231,20 +249,29 @@ describe TestSequelInterface do
|
|
231
249
|
expect{ interface.create(name: :Booboo) }.not_to raise_exception
|
232
250
|
end
|
233
251
|
|
234
|
-
it '
|
252
|
+
it 'shouldn\'t have a problem with record values of nil' do
|
235
253
|
record = {name: 'Ranger', price: nil}
|
236
254
|
expect{ interface.create(record) }.not_to raise_exception
|
237
255
|
id = interface.create(record)
|
238
256
|
expect( interface.read(id).to_h ).to include(record)
|
239
257
|
end
|
240
258
|
|
241
|
-
it '
|
259
|
+
it 'shouldn\'t have a problem with strings containing special characters' do
|
242
260
|
record = {name: "T'Challa[]", price: nil}
|
243
261
|
expect{ interface.create(record) }.not_to raise_exception
|
244
262
|
id = interface.create(record)
|
245
263
|
expect( interface.read(id).to_h ).to include(record)
|
246
264
|
end
|
247
265
|
|
266
|
+
it 'shouldn\'t have a problem with non-integer keys' do
|
267
|
+
hash = {code: "foo", name: "bar"}
|
268
|
+
id = prod_interface.create( Octothorpe.new(hash) )
|
269
|
+
|
270
|
+
expect( id ).to eq "foo"
|
271
|
+
expect{ prod_interface.read("foo") }.not_to raise_exception
|
272
|
+
expect( prod_interface.read("foo").to_h ).to include hash
|
273
|
+
end
|
274
|
+
|
248
275
|
end
|
249
276
|
##
|
250
277
|
|
@@ -293,6 +320,14 @@ describe TestSequelInterface do
|
|
293
320
|
expect( price ).to eq data.first[:price]
|
294
321
|
end
|
295
322
|
|
323
|
+
it 'shouldn\'t have a problem with non-integer keys' do
|
324
|
+
# this is a 100% overlap with the create test above...
|
325
|
+
fill_product_data(prod_interface)
|
326
|
+
|
327
|
+
expect{ prod_interface.read("foo") }.not_to raise_exception
|
328
|
+
expect( prod_interface.read("foo").to_h ).to include(code: "foo", name: "bar")
|
329
|
+
end
|
330
|
+
|
296
331
|
end
|
297
332
|
##
|
298
333
|
|
@@ -305,12 +340,31 @@ describe TestSequelInterface do
|
|
305
340
|
expect{ interface.list(name: 'Barney') }.not_to raise_exception
|
306
341
|
end
|
307
342
|
|
343
|
+
=begin
|
308
344
|
it 'returns an array of Octothorpes that match the records' do
|
309
345
|
# convert each OT to a hash and remove the ID key
|
310
346
|
arr = interface.list.map {|ot| x = ot.to_h; x.delete(:id); x }
|
311
347
|
|
312
348
|
expect( arr ).to match_array data
|
313
349
|
end
|
350
|
+
=end
|
351
|
+
|
352
|
+
it 'returns an array of Octothorpes that match the records' do
|
353
|
+
arr = interface.list.map {|ot| x = ot.to_h}
|
354
|
+
|
355
|
+
expect( arr.size ).to eq(data.size)
|
356
|
+
|
357
|
+
data.each do |d|
|
358
|
+
r = arr.find{|x| x[:name] == d[:name] }
|
359
|
+
expect( r ).not_to be_nil
|
360
|
+
expect( r[:level] ).to be_within(0.001).of( d[:level] )
|
361
|
+
expect( r[:day] ).to eq d[:day]
|
362
|
+
expect( r[:timestamp] ).to eq d[:timestamp]
|
363
|
+
expect( r[:qty] ).to eq d[:qty]
|
364
|
+
end
|
365
|
+
|
366
|
+
end
|
367
|
+
|
314
368
|
|
315
369
|
it 'returns a subset of records based on the selection parameter' do
|
316
370
|
expect( interface.list(name: 'Fred').size ).to eq 1
|
@@ -385,14 +439,20 @@ describe TestSequelInterface do
|
|
385
439
|
expect( interface.read(id).to_h ).to include(record)
|
386
440
|
end
|
387
441
|
|
442
|
+
it 'shouldn\'t have a problem with non-integer keys' do
|
443
|
+
fill_product_data(prod_interface)
|
444
|
+
expect{ prod_interface.update("foo", name: "baz") }.not_to raise_error
|
445
|
+
expect( prod_interface.read("foo").to_h[:name] ).to eq "baz"
|
446
|
+
end
|
447
|
+
|
388
448
|
end
|
389
449
|
##
|
390
450
|
|
391
451
|
|
392
452
|
describe '#delete' do
|
393
453
|
|
394
|
-
def list_contains(id)
|
395
|
-
|
454
|
+
def list_contains(ifce, id)
|
455
|
+
ifce.list.find {|x| x[ifce.id_fld] == id }
|
396
456
|
end
|
397
457
|
|
398
458
|
let(:id) { interface.list.first[:id] }
|
@@ -403,9 +463,16 @@ describe TestSequelInterface do
|
|
403
463
|
end
|
404
464
|
|
405
465
|
it 'makes the record at ID go away' do
|
406
|
-
expect( list_contains(id) ).to be_truthy
|
466
|
+
expect( list_contains(interface, id) ).to be_truthy
|
407
467
|
interface.delete(id)
|
408
|
-
expect( list_contains(id) ).to be_falsy
|
468
|
+
expect( list_contains(interface, id) ).to be_falsy
|
469
|
+
end
|
470
|
+
|
471
|
+
it 'shouldn\'t have a problem with non-integer keys' do
|
472
|
+
fill_product_data(prod_interface)
|
473
|
+
expect( list_contains(prod_interface, "foo") ).to be_truthy
|
474
|
+
prod_interface.delete("foo")
|
475
|
+
expect( list_contains(prod_interface, "foo") ).to be_falsy
|
409
476
|
end
|
410
477
|
|
411
478
|
end
|
@@ -471,10 +538,76 @@ describe TestSequelInterface do
|
|
471
538
|
expect( ret ).to eq( [] )
|
472
539
|
end
|
473
540
|
|
474
|
-
|
475
541
|
end
|
476
542
|
##
|
477
543
|
|
478
544
|
|
545
|
+
describe "#executep" do
|
546
|
+
# For the time being lets assume that Sequel does its job and the three modes we are calling
|
547
|
+
# actually work
|
548
|
+
|
549
|
+
let(:sql) { 'delete from customer where price < ?;' }
|
550
|
+
|
551
|
+
it 'requires an SQL string and a mode' do
|
552
|
+
expect{ interface.executep }.to raise_exception ArgumentError
|
553
|
+
expect{ interface.executep(nil) }.to raise_exception ArgumentError
|
554
|
+
expect{ interface.executep(14, :update) }.to raise_exception ArgumentError
|
555
|
+
expect{ interface.executep(14, :update, 2) }.to raise_exception ArgumentError
|
556
|
+
end
|
557
|
+
|
558
|
+
it 'requires the mode to be valid' do
|
559
|
+
expect{ interface.executep(sql, :foo, 2) }.to raise_exception ArgumentError
|
560
|
+
end
|
561
|
+
|
562
|
+
it 'raises some sort of Pod4 error if it runs into problems' do
|
563
|
+
expect{ interface.executep('delete from not_a_table where thingy = ?', :delete, 14) }.
|
564
|
+
to raise_exception Pod4Error
|
565
|
+
|
566
|
+
end
|
567
|
+
|
568
|
+
it 'executes the string' do
|
569
|
+
expect{ interface.executep(sql, :delete, 2.0) }.not_to raise_exception
|
570
|
+
expect( interface.list.size ).to eq(data.size - 1)
|
571
|
+
expect( interface.list.map{|r| r[:name] } ).not_to include 'Barney'
|
572
|
+
end
|
573
|
+
|
574
|
+
end
|
575
|
+
|
576
|
+
|
577
|
+
describe "#selectp" do
|
578
|
+
|
579
|
+
it 'requires an SQL string' do
|
580
|
+
expect{ interface.selectp }.to raise_exception ArgumentError
|
581
|
+
expect{ interface.selectp(nil) }.to raise_exception ArgumentError
|
582
|
+
expect{ interface.selectp(14) }.to raise_exception ArgumentError
|
583
|
+
end
|
584
|
+
|
585
|
+
it 'raises some sort of Pod4 error if it runs into problems' do
|
586
|
+
expect{ interface.selectp('select * from not_a_table where thingy = ?', 14) }.
|
587
|
+
to raise_exception Pod4Error
|
588
|
+
|
589
|
+
end
|
590
|
+
|
591
|
+
it 'returns the result of the sql' do
|
592
|
+
sql = 'select name from customer where price < ?;'
|
593
|
+
|
594
|
+
expect{ interface.selectp(sql, 2.0) }.not_to raise_exception
|
595
|
+
expect( interface.selectp(sql, 2.0) ).to eq( [{name: 'Barney'}] )
|
596
|
+
expect( interface.selectp(sql, 0.0) ).to eq( [] )
|
597
|
+
end
|
598
|
+
|
599
|
+
it 'works if you pass a non-select' do
|
600
|
+
# By which I mean: still executes the SQL; returns []
|
601
|
+
sql = 'delete from customer where price < ?;'
|
602
|
+
ret = interface.selectp(sql, 2.0)
|
603
|
+
|
604
|
+
expect( interface.list.size ).to eq(data.size - 1)
|
605
|
+
expect( interface.list.map{|r| r[:name] } ).not_to include 'Barney'
|
606
|
+
expect( ret ).to eq( [] )
|
607
|
+
end
|
608
|
+
|
609
|
+
end
|
610
|
+
|
611
|
+
|
479
612
|
end
|
480
613
|
|