db_mod 0.0.4 → 0.0.5

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 (28) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -0
  3. data/README.md +46 -14
  4. data/lib/db_mod/exceptions/no_results.rb +2 -1
  5. data/lib/db_mod/exceptions/too_many_results.rb +2 -1
  6. data/lib/db_mod/statements/configuration.rb +95 -24
  7. data/lib/db_mod/statements/configuration/as.rb +9 -16
  8. data/lib/db_mod/statements/configuration/as/csv.rb +4 -7
  9. data/lib/db_mod/statements/configuration/as/json.rb +8 -10
  10. data/lib/db_mod/statements/configuration/defaults.rb +140 -0
  11. data/lib/db_mod/statements/configuration/method_configuration.rb +109 -0
  12. data/lib/db_mod/statements/configuration/single.rb +16 -22
  13. data/lib/db_mod/statements/configuration/single/column.rb +1 -1
  14. data/lib/db_mod/statements/configuration/single/required_row.rb +1 -1
  15. data/lib/db_mod/statements/configuration/single/required_value.rb +1 -1
  16. data/lib/db_mod/statements/configuration/single/row.rb +1 -1
  17. data/lib/db_mod/statements/configuration/single/value.rb +1 -1
  18. data/lib/db_mod/statements/parameters.rb +3 -1
  19. data/lib/db_mod/statements/prepared.rb +18 -46
  20. data/lib/db_mod/statements/statement.rb +9 -56
  21. data/lib/db_mod/version.rb +1 -1
  22. data/spec/db_mod/statements/configuration/as/csv_spec.rb +2 -2
  23. data/spec/db_mod/statements/configuration/as/json_spec.rb +29 -2
  24. data/spec/db_mod/statements/configuration/as_spec.rb +2 -2
  25. data/spec/db_mod/statements/configuration/defaults_spec.rb +203 -0
  26. data/spec/db_mod/statements/configuration/single_spec.rb +7 -7
  27. metadata +6 -3
  28. data/lib/db_mod/statements/configuration/configurable_method.rb +0 -78
@@ -7,7 +7,7 @@ describe DbMod::Statements::Configuration::As do
7
7
  Module.new do
8
8
  include DbMod
9
9
 
10
- def_statement(:foo, 'SELECT 1').as(:lolwut)
10
+ def_statement(:foo, 'SELECT 1') { as(:lolwut) }
11
11
  end
12
12
  end.to raise_exception ArgumentError
13
13
  end
@@ -17,7 +17,7 @@ describe DbMod::Statements::Configuration::As do
17
17
  Module.new do
18
18
  include DbMod
19
19
 
20
- def_statement(:foo, 'SELECT 1').as(:json).as(:csv)
20
+ def_statement(:foo, 'SELECT 1') { as(:json).as(:csv) }
21
21
  end
22
22
  end.to raise_exception DbMod::Exceptions::BadMethodConfiguration
23
23
  end
@@ -0,0 +1,203 @@
1
+ require 'spec_helper'
2
+
3
+ describe DbMod::Statements::Configuration::Defaults do
4
+ before do
5
+ @conn = instance_double 'PGconn'
6
+ allow(@conn).to receive(:prepare)
7
+ allow(PGconn).to receive(:connect).and_return(@conn)
8
+ end
9
+
10
+ context 'named arguments' do
11
+ subject do
12
+ Module.new do
13
+ include DbMod
14
+
15
+ def_statement(:a, %(
16
+ SELECT *
17
+ FROM foo
18
+ WHERE id = $id
19
+ AND x > $min
20
+ )) { defaults min: 10 }
21
+
22
+ def_prepared(:b, %(
23
+ INSERT INTO foo
24
+ (x, name)
25
+ VALUES
26
+ ($x, $name)
27
+ )) { single(:value!).defaults x: 100, name: 'dunno' }
28
+ end.create db: 'testdb'
29
+ end
30
+
31
+ it 'defines default method arguments' do
32
+ expect(@conn).to receive(:exec_params) do |_, params|
33
+ expect(params).to eq([1, 10])
34
+ end
35
+ subject.a id: 1
36
+
37
+ expect(@conn).to(
38
+ receive(:exec_prepared).with('b', [100, 'dunno']).and_return(
39
+ [{ 'id' => '1' }]
40
+ )
41
+ )
42
+ expect(subject.b).to eq('1')
43
+ end
44
+
45
+ it 'defers to provided values' do
46
+ expect(@conn).to receive(:exec_params) do |_, params|
47
+ expect(params).to eq([2, 20])
48
+ end
49
+ subject.a id: 2, min: 20
50
+
51
+ expect(@conn).to(
52
+ receive(:exec_prepared).with('b', [200, 'name']).and_return(
53
+ [{ 'id' => '7' }]
54
+ )
55
+ )
56
+ subject.b name: 'name', x: 200
57
+ end
58
+
59
+ it 'allows explicit nil' do
60
+ expect(@conn).to(
61
+ receive(:exec_prepared).with('b', [nil, 'dunno']).and_return(
62
+ [{ 'id' => '8' }]
63
+ )
64
+ )
65
+ subject.b x: nil
66
+ end
67
+
68
+ it 'requires parameters without defaults' do
69
+ expect(@conn).not_to receive(:exec_params)
70
+ expect { subject.a }.to raise_exception ArgumentError
71
+ end
72
+ end
73
+
74
+ context 'indexed arguments' do
75
+ subject do
76
+ Module.new do
77
+ include DbMod
78
+
79
+ def_statement(:a, %(
80
+ SELECT *
81
+ FROM foo
82
+ WHERE id = $1
83
+ AND x > $2
84
+ )) { defaults 10 }
85
+
86
+ def_prepared(:b, %(
87
+ INSERT INTO foo
88
+ (x, name)
89
+ VALUES
90
+ ($1, $2)
91
+ RETURNING id
92
+ )) { defaults(100, 'huh?').single(:row!).as(:json) }
93
+ end.create db: 'testdb'
94
+ end
95
+
96
+ it 'defines default method arguments' do
97
+ expect(@conn).to(
98
+ receive(:exec_prepared).with('b', [100, 'huh?']).and_return(
99
+ [{ 'id' => '2' }]
100
+ )
101
+ )
102
+ expect(subject.b).to eq('{"id":"2"}')
103
+ end
104
+
105
+ it 'fills in arguments from the right hand side' do
106
+ expect(@conn).to receive(:exec_params) do |_, params|
107
+ expect(params).to eq([4, 10])
108
+ end
109
+ subject.a 4
110
+
111
+ expect(@conn).to(
112
+ receive(:exec_prepared).with('b', [102, 'huh?']).and_return(
113
+ [{ 'id' => '5' }]
114
+ )
115
+ )
116
+ subject.b 102
117
+ end
118
+
119
+ it 'defers to provided values' do
120
+ expect(@conn).to receive(:exec_params) do |_, params|
121
+ expect(params).to eq([5, 11])
122
+ end
123
+ subject.a 5, 11
124
+
125
+ expect(@conn).to(
126
+ receive(:exec_prepared).with('b', [101, 'nom']).and_return(
127
+ [{ 'id' => '6' }]
128
+ )
129
+ )
130
+ subject.b 101, 'nom'
131
+ end
132
+
133
+ it 'asserts correct parameter count' do
134
+ expect { subject.a }.to raise_exception ArgumentError
135
+ expect { subject.b 1, 2, 3 }.to raise_exception ArgumentError
136
+ end
137
+ end
138
+
139
+ context 'definition-time validation' do
140
+ it 'must use named or indexed parameters appropriately' do
141
+ expect do
142
+ Module.new do
143
+ include DbMod
144
+
145
+ def_statement(:a, 'SELECT * FROM foo WHERE x = $1') do
146
+ defaults id: 1
147
+ end
148
+ end
149
+ end.to raise_exception ArgumentError
150
+
151
+ expect do
152
+ Module.new do
153
+ include DbMod
154
+
155
+ def_prepared(:a, 'SELECT * FROM foo WHERE id = $id') { defaults 1 }
156
+ end
157
+ end.to raise_exception ArgumentError
158
+ end
159
+
160
+ it 'asserts that mixed default types are not given' do
161
+ expect do
162
+ Module.new do
163
+ include DbMod
164
+
165
+ def_statement(:a, 'SELECT * FROM foo WHERE id = $id') do
166
+ defaults 1, id: 2
167
+ end
168
+ end
169
+ end.to raise_exception ArgumentError
170
+ end
171
+
172
+ it 'may not be specified more than once' do
173
+ expect do
174
+ Module.new do
175
+ include DbMod
176
+
177
+ def_statement(:a, 'SELECT * FROM foo WHERE x = $1') do
178
+ defaults 1
179
+ defaults 2
180
+ end
181
+ end
182
+ end.to raise_exception DbMod::Exceptions::BadMethodConfiguration
183
+ end
184
+
185
+ it 'disallows too many defaults' do
186
+ expect do
187
+ Module.new do
188
+ include DbMod
189
+
190
+ def_statement(:a, 'SELECT * FROM foo WHERE x=$1') { defaults 1, 2 }
191
+ end
192
+ end.to raise_exception ArgumentError
193
+
194
+ expect do
195
+ Module.new do
196
+ include DbMod
197
+
198
+ def_statement(:a, 'SELECT 1') { defaults 10 }
199
+ end
200
+ end.to raise_exception ArgumentError
201
+ end
202
+ end
203
+ end
@@ -5,13 +5,13 @@ describe DbMod::Statements::Configuration::Single do
5
5
  Module.new do
6
6
  include DbMod
7
7
 
8
- def_statement(:v, 'SELECT a FROM foo').single(:value)
9
- def_prepared(:v!, 'SELECT c FROM d WHERE e = $f').single(:value!)
8
+ def_statement(:v, 'SELECT a FROM foo') { single(:value) }
9
+ def_prepared(:v!, 'SELECT c FROM d WHERE e = $f') { single(:value!) }
10
10
 
11
- def_prepared(:r, 'SELECT a, b FROM foo WHERE c = $1').single(:row)
12
- def_statement(:r!, 'SELECT a, b FROM foo').single(:row!)
11
+ def_prepared(:r, 'SELECT a, b FROM foo WHERE c = $1') { single(:row) }
12
+ def_statement(:r!, 'SELECT a, b FROM foo') { single(:row!) }
13
13
 
14
- def_statement(:c, 'SELECT a FROM foo WHERE c > $min').single(:column)
14
+ def_statement(:c, 'SELECT a FROM foo WHERE c > $min') { single(:column) }
15
15
  end.create(db: 'testdb')
16
16
  end
17
17
 
@@ -89,7 +89,7 @@ describe DbMod::Statements::Configuration::Single do
89
89
  Module.new do
90
90
  include DbMod
91
91
 
92
- def_statement(:a, 'SELECT 1').single(:lolwut)
92
+ def_statement(:a, 'SELECT 1') { single(:lolwut) }
93
93
  end
94
94
  end.to raise_exception ArgumentError
95
95
  end
@@ -99,7 +99,7 @@ describe DbMod::Statements::Configuration::Single do
99
99
  Module.new do
100
100
  include DbMod
101
101
 
102
- def_statement(:a, 'SELECT 1').single(:row).single(:value)
102
+ def_statement(:a, 'SELECT 1') { single(:row).single(:value) }
103
103
  end
104
104
  end.to raise_exception DbMod::Exceptions::BadMethodConfiguration
105
105
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: db_mod
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Doug Hammond
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-15 00:00:00.000000000 Z
11
+ date: 2015-10-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pg
@@ -129,7 +129,8 @@ files:
129
129
  - lib/db_mod/statements/configuration/as.rb
130
130
  - lib/db_mod/statements/configuration/as/csv.rb
131
131
  - lib/db_mod/statements/configuration/as/json.rb
132
- - lib/db_mod/statements/configuration/configurable_method.rb
132
+ - lib/db_mod/statements/configuration/defaults.rb
133
+ - lib/db_mod/statements/configuration/method_configuration.rb
133
134
  - lib/db_mod/statements/configuration/single.rb
134
135
  - lib/db_mod/statements/configuration/single/column.rb
135
136
  - lib/db_mod/statements/configuration/single/required_row.rb
@@ -145,6 +146,7 @@ files:
145
146
  - spec/db_mod/statements/configuration/as/csv_spec.rb
146
147
  - spec/db_mod/statements/configuration/as/json_spec.rb
147
148
  - spec/db_mod/statements/configuration/as_spec.rb
149
+ - spec/db_mod/statements/configuration/defaults_spec.rb
148
150
  - spec/db_mod/statements/configuration/single_spec.rb
149
151
  - spec/db_mod/statements/prepared_spec.rb
150
152
  - spec/db_mod/statements/statement_spec.rb
@@ -180,6 +182,7 @@ test_files:
180
182
  - spec/db_mod/statements/configuration/as/csv_spec.rb
181
183
  - spec/db_mod/statements/configuration/as/json_spec.rb
182
184
  - spec/db_mod/statements/configuration/as_spec.rb
185
+ - spec/db_mod/statements/configuration/defaults_spec.rb
183
186
  - spec/db_mod/statements/configuration/single_spec.rb
184
187
  - spec/db_mod/statements/prepared_spec.rb
185
188
  - spec/db_mod/statements/statement_spec.rb
@@ -1,78 +0,0 @@
1
- require_relative 'as'
2
- require_relative 'single'
3
-
4
- module DbMod
5
- module Statements
6
- module Configuration
7
- # Encapsulates a method that has just been defined
8
- # via the dsl exposed in {DbMod::Statements} so that
9
- # it can be extended with additional processing such
10
- # as result coercion.
11
- #
12
- # The pattern here is something similar to rack's middleware.
13
- # Calling any of the extension methods below will replace
14
- # the original method defined by +def_prepared+ or +def_statement+
15
- # with a wrapper function that may perform processing on given
16
- # arguments, pass them to the original function, then perform
17
- # additional processing on the result.
18
- class ConfigurableMethod
19
- # Encapsulate a method that has been newly defined
20
- # by a {DbMod} dsl function, for additional configuration.
21
- #
22
- # @param mod [Module] the {DbMod} enabled module
23
- # where the method was defined
24
- # @param name [Symbol] the method name
25
- def initialize(mod, name)
26
- @mod = mod
27
- @name = name
28
- @already_called = {}
29
- end
30
-
31
- # Extend the method by converting results into a given
32
- # format, using one of the coercion methods defined
33
- # under {DbMod::Statements::Configuration::As}.
34
- #
35
- # @param type [:csv,:json] output format for the method
36
- # @return [self]
37
- def as(type)
38
- called! :as
39
-
40
- Configuration::As.extend_method(@mod, @name, type)
41
-
42
- self
43
- end
44
-
45
- # Extend the method by extracting a singular part of
46
- # the result set, for queries expected to only return
47
- # one row, one column, or one row with a single value.
48
- # See {DbMod::Statements::Configuration::Single} for
49
- # more details.
50
- #
51
- # @param type [Symbol] see {SINGLE_TYPES}
52
- # @return [self]
53
- def single(type)
54
- called! :single
55
-
56
- Configuration::Single.extend_method(@mod, @name, type)
57
-
58
- self
59
- end
60
-
61
- private
62
-
63
- # Guard method which asserts that a configuration method
64
- # may not be called more than once, or else raises
65
- # {DbMod::Exceptions::BadMethodConfiguration}.
66
- #
67
- # @param method [Symbol] method being called
68
- def called!(method)
69
- if @already_called[method]
70
- fail Exceptions::BadMethodConfiguration, "#{method} already called"
71
- end
72
-
73
- @already_called[method] = true
74
- end
75
- end
76
- end
77
- end
78
- end