db_mod 0.0.1 → 0.0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f148df036e59a1e23b2faa43b407b9493d54671a
4
- data.tar.gz: c0ab239586891d8b91a5a82d79a17f4e19777f48
3
+ metadata.gz: 5547dcc1f21c6ca964d25c097abb813e77713161
4
+ data.tar.gz: 2214d888e4d39fb545e65e2c8539fdeadc48b145
5
5
  SHA512:
6
- metadata.gz: 199028216fcaf755e20a67d607ad5f7ac3399c0c26ea3cee37f151dc5786c3e87b57245a9c4d42bbe5807bb6e3a1e6814e2ae9495ed15030e6d94c85f9071ea1
7
- data.tar.gz: 7930c834d9705cfdb2e57556e9a478db09c0967ac16339d5728893561178431d09520fb98f7dc688ee7d331b683ffe8014ccfe9e25c7efaa7348427afe5d0158
6
+ metadata.gz: 6e5bd968a9b47e6d55972444b55bb7bf0434938711c71d0c6955b6d6d048c25a7bfb0e78bffec87bc70dbe3c58aec5766513530e63104c24a2a1089ba99a91c0
7
+ data.tar.gz: 28d48191ba234d83a0dc52dc5c9224923712834d8b8411e4e67d081bc36ab45f062f5476e7e0d17f2eb0222cb89065bdb5f657d84230c765bc2f1208ce26a0dc
data/README.md CHANGED
@@ -8,6 +8,12 @@ The `db_mod` gem is a simple framework that helps you organise your
8
8
  database access functions into modular libraries that can be included
9
9
  in your projects to give them selective access to facets of your data.
10
10
 
11
+ For the moment `db_mod` only supports PostgreSQL databases via the
12
+ `pg` gem. This gem is still in the early stages of development and no
13
+ guarantees will be made about backwards compatibility until v0.1.0.
14
+
15
+ Issues, pull requests, comments and feedback all welcomed.
16
+
11
17
  ## Usage
12
18
 
13
19
  ### The database connection
@@ -53,7 +59,7 @@ get_stuff.each do |thing|
53
59
  end
54
60
  ```
55
61
 
56
- #### `create`: Module instances
62
+ #### Module instances: `DbMod.create`
57
63
 
58
64
  Each module also comes with its own `create` function,
59
65
  which instantiates an object exposing all of the module's functions.
@@ -69,7 +75,7 @@ db = MyFunctions.create PGconn.connect # ...
69
75
  db.get_stuff
70
76
  ```
71
77
 
72
- #### `@conn`: The connection object
78
+ #### The connection object: `@conn`
73
79
 
74
80
  The connection created by `db_connect` or `create` will be stored
75
81
  in the instance variable `@conn`. This instance variable may be
@@ -104,7 +110,9 @@ db = DbAccess.create db: 'mydb'
104
110
  db.things_n_stuff
105
111
  ```
106
112
 
107
- ### `def_prepared`: Declaring SQL statements
113
+ ### Declaring SQL statements
114
+
115
+ #### Prepared statement methods: `DbMod.def_prepared`
108
116
 
109
117
  Modules which include `DbMod` can declare prepared statements
110
118
  using the module function `def_prepared`. These statements will
@@ -168,3 +176,10 @@ modules on the given connection.
168
176
  db = Db::ComplicatedStuff.create my_conn
169
177
  Db::ComplicatedStuff.prepare_all_statements my_conn
170
178
  ```
179
+
180
+ #### Saved statement methods: `DbMod.def_statement`
181
+
182
+ `def_statement` works in just the same way as `def_prepared`, except that
183
+ the SQL queries are saved in memory rather than being sent to the database
184
+ at connection time. This is useful for queries that will only be run once
185
+ or twice during a program's execution.
data/db_mod.gemspec CHANGED
@@ -5,14 +5,16 @@ Gem::Specification.new do |s|
5
5
  s.name = 'db_mod'
6
6
  s.version = DbMod::VERSION
7
7
  s.platform = Gem::Platform::RUBY
8
- s.authors = ['Doug Hammond']
8
+ s.author = 'Doug Hammond'
9
9
  s.email = ['d.lakehammond@gmail.com']
10
- s.summary = 'Ruby framework for building modular db-access libs.'
11
- s.description = 'Organize your database-intensive batch scripts with db_mod.'
10
+ s.homepage = 'https://github.com/dslh/db_mod'
11
+ s.summary = 'Declarative, modular database library framework.'
12
+ s.description = 'Framework for building modular database libraries.'
12
13
  s.license = 'MIT'
13
14
 
15
+ s.required_ruby_version = '>= 1.9.3'
16
+
14
17
  s.add_runtime_dependency 'pg'
15
- s.add_runtime_dependency 'docile'
16
18
 
17
19
  s.add_development_dependency 'simplecov'
18
20
  s.add_development_dependency 'rspec'
data/lib/db_mod.rb CHANGED
@@ -17,7 +17,7 @@ module DbMod
17
17
  # class-level functions specific to the module.
18
18
  def self.included(mod)
19
19
  DbMod::Create.setup(mod)
20
- DbMod::Statements::Prepared.setup(mod)
20
+ DbMod::Statements.setup(mod)
21
21
  end
22
22
 
23
23
  protected
@@ -9,5 +9,11 @@ module DbMod
9
9
  # See {DbMod::Statements::Statement} for details on +def_statement+
10
10
  # and {DbMod::Statements::Prepared} for details on +def_prepared+.
11
11
  module Statements
12
+ # Called when a module includes {DbMod},
13
+ # defines module-level +def_statement+ and +def_prepared+ dsl methods.
14
+ def self.setup(mod)
15
+ DbMod::Statements::Prepared.setup(mod)
16
+ DbMod::Statements::Statement.setup(mod)
17
+ end
12
18
  end
13
19
  end
@@ -2,36 +2,41 @@ module DbMod
2
2
  module Statements
3
3
  # Parsing and validation of query parameters
4
4
  # for prepared SQL statements
5
- module Params
5
+ module Parameters
6
+ # Called when a {DbMod} dynamically defined method is called.
6
7
  # Assert that the named arguments given for the prepared statement
7
- # with the given name satisfy expectations.
8
+ # with the given name satisfy expectations. Returns a parameter array
9
+ # as per {Parameters.parameter_array}.
8
10
  #
9
11
  # @param expected [Array<Symbol>] the parameters expected to be present
10
- # @param args [Hash] given parameters
12
+ # @param args [Array<Hash<Symbol>>] arguments given to the method being
13
+ # executed. The method should only be called with an options hash that
14
+ # contains exactly the parameter names given when the method was
15
+ # defined.
11
16
  # @return [Array] values to be passed to the prepared statement
12
17
  def self.valid_named_args!(expected, args)
13
- unless args.is_a? Hash
14
- fail ArgumentError, "invalid argument: #{args.inspect}"
15
- end
18
+ wrapped_hash! args
16
19
 
20
+ args = args.first
17
21
  if args.size != expected.size
18
22
  fail ArgumentError, "#{args.size} args given, #{expected.size} needed"
19
23
  end
20
24
 
21
- expected.map do |arg|
22
- args[arg] || fail(ArgumentError, "missing arg #{arg}")
23
- end
25
+ parameter_array(expected, args)
24
26
  end
25
27
 
26
- # Regex matching a numbered parameter
27
- NUMBERED_PARAM = /\$\d+/
28
-
29
- # Regex matching a named parameter
30
- NAMED_PARAM = /\$[a-z]+(?:_[a-z]+)*/
31
-
32
- # For validation, named or numbered parameter
33
- NAMED_OR_NUMBERED = /^\$(?:\d+|[a-z]+(?:_[a-z]+)*)$/
28
+ # Called when a {DbMod} dynamically defined method is called.
29
+ # Assert that the correct number of arguments has been provided.
30
+ #
31
+ # @param count [Fixnum] arity of the method being called.
32
+ # @param args [Array] list of arguments given.
33
+ def self.valid_fixed_args!(count, args)
34
+ unless args.size == count
35
+ fail ArgumentError, "#{args.size} args given, #{count} expected"
36
+ end
37
+ end
34
38
 
39
+ # Called when a {DbMod} dynamically defined method is declared.
35
40
  # Parses parameters, named or numbered, from an SQL
36
41
  # statement. See the {Prepared} module documentation
37
42
  # for more. This method may modify the sql statement
@@ -47,15 +52,56 @@ module DbMod
47
52
  # @return [Fixnum,Array<Symbol>] description of
48
53
  # prepared statement's parameters
49
54
  def self.parse_params!(sql)
50
- Params.valid_sql_params! sql
55
+ Parameters.valid_sql_params! sql
51
56
  numbered = sql.scan NUMBERED_PARAM
52
57
  named = sql.scan NAMED_PARAM
53
58
 
54
59
  if numbered.any?
55
60
  fail ArgumentError, 'mixed named and numbered params' if named.any?
56
- Params.parse_numbered_params! numbered
61
+ Parameters.parse_numbered_params! numbered
57
62
  else
58
- Params.parse_named_params! sql, named
63
+ Parameters.parse_named_params! sql, named
64
+ end
65
+ end
66
+
67
+ # Regex matching a numbered parameter
68
+ NUMBERED_PARAM = /\$\d+/
69
+
70
+ # Regex matching a named parameter
71
+ NAMED_PARAM = /\$[a-z]+(?:_[a-z]+)*/
72
+
73
+ # For validation, named or numbered parameter
74
+ NAMED_OR_NUMBERED = /^\$(?:\d+|[a-z]+(?:_[a-z]+)*)$/
75
+
76
+ private
77
+
78
+ # Assert that the given parameter list is an array
79
+ # containing a single hash of named parameter values.
80
+ #
81
+ # Raises {ArgumentError} otherwise.
82
+ #
83
+ # @param args [Array<Hash<Symbol>>] method arguments being validated
84
+ def self.wrapped_hash!(args)
85
+ unless args.size == 1
86
+ fail ArgumentError, "unexpected arguments: #{args.inspect}"
87
+ end
88
+
89
+ unless args.first.is_a? Hash
90
+ fail ArgumentError, "invalid argument: #{args.first.inspect}"
91
+ end
92
+ end
93
+
94
+ # Convert the given named parameter hash into
95
+ # an array containing the parameter values in
96
+ # the order required to be supplied to the
97
+ # SQL statement being executed.
98
+ #
99
+ # @param expected [Array<Symbol>] the parameters expected to be present
100
+ # @param args [Hash] given parameters
101
+ # @return [Array] values to be passed to the prepared statement
102
+ def self.parameter_array(expected, args)
103
+ expected.map do |arg|
104
+ args[arg] || fail(ArgumentError, "missing arg #{arg}")
59
105
  end
60
106
  end
61
107
 
@@ -63,7 +109,7 @@ module DbMod
63
109
  # in the expected format. They must either be
64
110
  # lower_case_a_to_z or digits only.
65
111
  def self.valid_sql_params!(sql)
66
- sql.scan(/\$\S+/) do |param|
112
+ sql.scan(/\$[A-Za-z0-9_]+/) do |param|
67
113
  unless param =~ NAMED_OR_NUMBERED
68
114
  fail ArgumentError, "Invalid parameter #{param}"
69
115
  end
@@ -1,4 +1,4 @@
1
- require_relative 'params'
1
+ require_relative 'parameters'
2
2
 
3
3
  module DbMod
4
4
  module Statements
@@ -48,8 +48,6 @@ module DbMod
48
48
  # my_prepared(1,2)
49
49
  # my_named_prepared(a: 1, b: 2)
50
50
  module Prepared
51
- include Params
52
-
53
51
  # Defines a module-specific +def_prepared+ function
54
52
  # for a module that has just had {DbMod} included.
55
53
  #
@@ -63,24 +61,6 @@ module DbMod
63
61
 
64
62
  private
65
63
 
66
- # Merge the prepared statements from a module
67
- # into a given hash. Fails if there are any
68
- # duplicates.
69
- #
70
- # @param statements [Hash] named list of prepared statements
71
- # @param klass [Class,Module] ancestor (hopefully a DbMod module)
72
- # to collect prepared statements from
73
- def self.merge_statements(statements, klass)
74
- return unless klass.respond_to? :prepared_statements
75
- return if klass.prepared_statements.nil?
76
-
77
- klass.prepared_statements.each do |name, sql|
78
- fail DbMod::Exceptions::DuplicateStatementName if statements.key? name
79
-
80
- statements[name] = sql
81
- end
82
- end
83
-
84
64
  # Add a +def_prepared+ method definition to a module.
85
65
  # This method allows modules to declare named SQL statements
86
66
  # that will be prepared when the database connection is
@@ -94,7 +74,7 @@ module DbMod
94
74
  sql = sql.dup
95
75
  name = name.to_sym
96
76
 
97
- params = Params.parse_params! sql
77
+ params = Parameters.parse_params! sql
98
78
  prepared_statements[name] = sql
99
79
  Prepared.define_prepared_method(mod, name, params)
100
80
  end
@@ -117,18 +97,34 @@ module DbMod
117
97
  end
118
98
  end
119
99
 
120
- # Define a method in the module with the given name
100
+ # Merge the prepared statements from a module
101
+ # into a given hash. Fails if there are any
102
+ # duplicates.
103
+ #
104
+ # @param statements [Hash] named list of prepared statements
105
+ # @param klass [Class,Module] ancestor (hopefully a DbMod module)
106
+ # to collect prepared statements from
107
+ def self.merge_statements(statements, klass)
108
+ return unless klass.respond_to? :prepared_statements
109
+ return if klass.prepared_statements.nil?
110
+
111
+ klass.prepared_statements.each do |name, sql|
112
+ fail DbMod::Exceptions::DuplicateStatementName if statements.key? name
113
+
114
+ statements[name] = sql
115
+ end
116
+ end
117
+
118
+ # Define a method in the given module with the given name
121
119
  # and parameters, that will call the prepared statement
122
120
  # with the same name.
123
121
  #
124
- # @param mod [Module] module declaring the metho
122
+ # @param mod [Module] module declaring the method
125
123
  # @param name [Symbol] method name
126
124
  # @param params [Fixnum,Array<Symbol>]
127
125
  # expected parameter count, or a list of argument names.
128
126
  # An empty array produces a no-argument method.
129
127
  def self.define_prepared_method(mod, name, params)
130
- mod.expected_prepared_statement_parameters[name] = params
131
-
132
128
  if params.is_a?(Array)
133
129
  if params.empty?
134
130
  define_no_args_prepared_method(mod, name)
@@ -165,10 +161,7 @@ module DbMod
165
161
  # @param params [Array<Symbol>] list of parameter names
166
162
  def self.define_named_args_prepared_method(mod, name, params)
167
163
  method = lambda do |*args|
168
- unless args.size == 1
169
- fail ArgumentError, "unexpected arguments: #{args.inspect}"
170
- end
171
- args = Params.valid_named_args! params, args.first
164
+ args = Parameters.valid_named_args! params, args
172
165
  conn.exec_prepared(name.to_s, args)
173
166
  end
174
167
 
@@ -188,9 +181,7 @@ module DbMod
188
181
  # requires
189
182
  def self.define_fixed_args_prepared_method(mod, name, count)
190
183
  method = lambda do |*args|
191
- unless args.size == count
192
- fail ArgumentError, "#{args.size} args given, #{count} expected"
193
- end
184
+ Parameters.valid_fixed_args!(count, args)
194
185
 
195
186
  conn.exec_prepared(name.to_s, args)
196
187
  end
@@ -208,10 +199,6 @@ module DbMod
208
199
  define_method(:prepared_statements) do
209
200
  @prepared_statements ||= {}
210
201
  end
211
-
212
- define_method(:expected_prepared_statement_parameters) do
213
- @expected_prepared_statement_parameters ||= {}
214
- end
215
202
  end
216
203
  end
217
204
 
@@ -1,3 +1,5 @@
1
+ require_relative 'parameters'
2
+
1
3
  module DbMod
2
4
  module Statements
3
5
  # Provides the +def_statement+ function which allows
@@ -23,7 +25,102 @@ module DbMod
23
25
  # can then be passed parameters that will be used to fill
24
26
  # in the statement before execution.
25
27
  module Statement
26
- # Not yet implemented.
28
+ # Defines a module-specific +def_statement+ function
29
+ # for a module that has just had {DbMod} included.
30
+ #
31
+ # @param mod [Module]
32
+ def self.setup(mod)
33
+ Statement.define_def_statement(mod)
34
+ end
35
+
36
+ private
37
+
38
+ # Add a +def_statement+ method definition to a module.
39
+ # This method allows modules to declare SQL statements
40
+ # that can be accessed via an instance method with
41
+ # arbitrary name.
42
+ #
43
+ # @param mod [Module] a module with {DbMod} included
44
+ def self.define_def_statement(mod)
45
+ mod.class.instance_eval do
46
+ define_method(:def_statement) do |name, sql|
47
+ sql = sql.dup
48
+ name = name.to_sym
49
+
50
+ params = Parameters.parse_params! sql
51
+ Statement.define_statement_method(mod, name, params, sql)
52
+ end
53
+ end
54
+ end
55
+
56
+ # Define a method in the given module with the given name
57
+ # and parameters, that will call the given sql statement
58
+ # and return the results.
59
+ #
60
+ # @param mod [Module] module declaring the method
61
+ # @param name [Symbol] method name
62
+ # @param params [Fixnum,Array<Symbol>]
63
+ # expected parameter count, or a list of argument names.
64
+ # An empty array produces a no-argument method.
65
+ def self.define_statement_method(mod, name, params, sql)
66
+ if params.is_a?(Array)
67
+ if params.empty?
68
+ define_no_args_statement_method(mod, name, sql)
69
+ else
70
+ define_named_args_statement_method(mod, name, params, sql)
71
+ end
72
+ else
73
+ define_fixed_args_statement_method(mod, name, params, sql)
74
+ end
75
+ end
76
+
77
+ # Define a no-argument method with the given name
78
+ # that will execute the given sql statement and return
79
+ # the result.
80
+ #
81
+ # @param mod [Module] {DbMod} enabled module
82
+ # where the method will be defined
83
+ # @param name [Symbol] name of the method to be defined
84
+ # @param sql [String] parameterless SQL statement to execute
85
+ def self.define_no_args_statement_method(mod, name, sql)
86
+ mod.instance_eval do
87
+ define_method name, ->() { query(sql) }
88
+ end
89
+ end
90
+
91
+ # Define a method with the given name, that accepts the
92
+ # given set of named parameters that will be used to execute
93
+ # the given SQL query.
94
+ #
95
+ # @param mod [Module] {DbMod} enabled module
96
+ # @param name [Symbol] name of the method to be defined
97
+ # @param params [Array<Symbol>] parameter names and order
98
+ def self.define_named_args_statement_method(mod, name, params, sql)
99
+ method = lambda do |*args|
100
+ args = Parameters.valid_named_args! params, args
101
+ conn.exec_params(sql, args)
102
+ end
103
+
104
+ mod.instance_eval { define_method(name, method) }
105
+ end
106
+
107
+ # Define a method with the given name that accepts a fixed number
108
+ # of arguments, that will be used to execute the given SQL query.
109
+ #
110
+ # @param mod [Module] {DbMod} enabled module where the method
111
+ # will be defined
112
+ # @param name [Symbol] name of the method to be defined
113
+ # @param count [Fixnum] arity of the defined method,
114
+ # the number of parameters that the SQL statement requires
115
+ def self.define_fixed_args_statement_method(mod, name, count, sql)
116
+ method = lambda do |*args|
117
+ Parameters.valid_fixed_args!(count, args)
118
+
119
+ conn.exec_params(sql, args)
120
+ end
121
+
122
+ mod.instance_eval { define_method(name, method) }
123
+ end
27
124
  end
28
125
  end
29
126
  end
@@ -1,5 +1,5 @@
1
1
  # Version information
2
2
  module DbMod
3
3
  # The current version of db_mod.
4
- VERSION = '0.0.1'
4
+ VERSION = '0.0.2'
5
5
  end
@@ -108,6 +108,29 @@ describe DbMod::Statements::Prepared do
108
108
  end.not_to raise_exception
109
109
  end
110
110
 
111
+ it 'handles complicated parameter usage' do
112
+ mod = Module.new do
113
+ include DbMod
114
+
115
+ def_prepared(
116
+ :params_test,
117
+ 'INSERT INTO foo (a,b,c,d) VALUES ($a-1,$b::integer,$c*2,$b)'
118
+ )
119
+ end
120
+
121
+ expect(@conn).to receive(:prepare).with(
122
+ 'params_test',
123
+ 'INSERT INTO foo (a,b,c,d) VALUES ($1-1,$2::integer,$3*2,$2)'
124
+ )
125
+ db = mod.create(db: 'testdb')
126
+
127
+ expect(@conn).to receive(:exec_prepared).with(
128
+ 'params_test',
129
+ [1, 2, 3]
130
+ )
131
+ db.params_test(a: 1, b: 2, c: 3)
132
+ end
133
+
111
134
  it 'does not allow invalid parameters' do
112
135
  %w(CAPITALS numb3rs_and_l3tt3rs).each do |param|
113
136
  expect do
@@ -0,0 +1,130 @@
1
+ require 'spec_helper'
2
+
3
+ describe DbMod::Statements::Statement do
4
+ subject do
5
+ Module.new do
6
+ include DbMod
7
+
8
+ def_statement(
9
+ :one,
10
+ 'SELECT * FROM foo WHERE a = $1 AND b = $2 AND c = $1'
11
+ )
12
+
13
+ def_statement(
14
+ :two,
15
+ 'SELECT * FROM foo WHERE a = $a AND b = $b AND c = $a'
16
+ )
17
+ end.create db: 'testdb'
18
+ end
19
+
20
+ before do
21
+ @conn = instance_double 'PGconn'
22
+ allow(PGconn).to receive(:connect).and_return(@conn)
23
+ end
24
+
25
+ it 'executes statements with numbered params' do
26
+ expect(@conn).to receive(:exec_params).with(
27
+ 'SELECT * FROM foo WHERE a = $1 AND b = $2 AND c = $1',
28
+ [1, 'two']
29
+ )
30
+ subject.one(1, 'two')
31
+
32
+ expect { subject.one 'not enough args' }.to raise_exception ArgumentError
33
+
34
+ expect do
35
+ subject.one('too', 'many', 'args')
36
+ end.to raise_exception ArgumentError
37
+ end
38
+
39
+ it 'executes statements with named params' do
40
+ expect(@conn).to receive(:exec_params).with(
41
+ 'SELECT * FROM foo WHERE a = $1 AND b = $2 AND c = $1',
42
+ [1, 'two']
43
+ )
44
+ subject.two(a: 1, b: 'two')
45
+
46
+ expect do
47
+ subject.two bad: 'arg', b: 1, a: 1
48
+ end.to raise_exception ArgumentError
49
+ expect { subject.two b: 'a missing' }.to raise_exception ArgumentError
50
+ expect { subject.two 1, 2 }.to raise_exception ArgumentError
51
+ expect { subject.two 1 }.to raise_exception ArgumentError
52
+ end
53
+
54
+ it 'allows statements with no parameters' do
55
+ expect do
56
+ mod = Module.new do
57
+ include DbMod
58
+
59
+ def_statement :no_params, 'SELECT 1'
60
+ end
61
+
62
+ expect(@conn).to receive(:query).with('SELECT 1')
63
+ db = mod.create db: 'testdb'
64
+
65
+ expect { db.no_params }.not_to raise_exception
66
+ expect { db.no_params(1) }.to raise_exception ArgumentError
67
+ end.not_to raise_exception
68
+ end
69
+
70
+ it 'does not allow mixed parameter types' do
71
+ expect do
72
+ Module.new do
73
+ include DbMod
74
+
75
+ def_statement :numbers_and_names, <<-SQL
76
+ SELECT *
77
+ FROM foo
78
+ WHERE this = $1 AND wont = $work
79
+ SQL
80
+ end
81
+ end.to raise_exception ArgumentError
82
+ end
83
+
84
+ it 'handles complicated parameter usage' do
85
+ db = Module.new do
86
+ include DbMod
87
+
88
+ def_statement(
89
+ :params_test,
90
+ 'INSERT INTO foo (a,b,c,d) VALUES ($a-1,$b::integer,$c*2,$b)'
91
+ )
92
+ end.create(db: 'testdb')
93
+
94
+ expect(@conn).to receive(:exec_params).with(
95
+ 'INSERT INTO foo (a,b,c,d) VALUES ($1-1,$2::integer,$3*2,$2)',
96
+ [1, 2, 3]
97
+ )
98
+ db.params_test(a: 1, b: 2, c: 3)
99
+ end
100
+
101
+ it 'does not allow invalid parameters' do
102
+ %w(CAPITALS numb3s_and_l3tt3rs).each do |param|
103
+ expect do
104
+ Module.new do
105
+ include DbMod
106
+
107
+ def_statement :bad_params, %(
108
+ SELECT * FROM foo WHERE bad = $#{param}
109
+ )
110
+ end
111
+ end.to raise_exception ArgumentError
112
+ end
113
+ end
114
+
115
+ it 'validates numbered arguments' do
116
+ [
117
+ 'a = $1 and b = $2 and c = $2 and c = $4',
118
+ 'a = $2 and b = $2 and c = $3',
119
+ 'a = $1 and b = $2 and c = $4'
120
+ ].each do |params|
121
+ expect do
122
+ Module.new do
123
+ include DbMod
124
+
125
+ def_statement :bad_params, "SELECT * FROM foo WHERE #{params}"
126
+ end
127
+ end.to raise_exception ArgumentError
128
+ end
129
+ end
130
+ 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.1
4
+ version: 0.0.2
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-11 00:00:00.000000000 Z
11
+ date: 2015-10-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pg
@@ -24,20 +24,6 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: docile
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: simplecov
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -108,7 +94,7 @@ dependencies:
108
94
  - - ">="
109
95
  - !ruby/object:Gem::Version
110
96
  version: '0'
111
- description: Organize your database-intensive batch scripts with db_mod.
97
+ description: Framework for building modular database libraries.
112
98
  email:
113
99
  - d.lakehammond@gmail.com
114
100
  executables: []
@@ -134,17 +120,18 @@ files:
134
120
  - lib/db_mod/exceptions/connection_not_set.rb
135
121
  - lib/db_mod/exceptions/duplicate_statement_name.rb
136
122
  - lib/db_mod/statements.rb
137
- - lib/db_mod/statements/params.rb
123
+ - lib/db_mod/statements/parameters.rb
138
124
  - lib/db_mod/statements/prepared.rb
139
125
  - lib/db_mod/statements/statement.rb
140
126
  - lib/db_mod/transaction.rb
141
127
  - lib/db_mod/version.rb
142
128
  - spec/db_mod/create_spec.rb
143
129
  - spec/db_mod/statements/prepared_spec.rb
130
+ - spec/db_mod/statements/statement_spec.rb
144
131
  - spec/db_mod/transaction_spec.rb
145
132
  - spec/db_mod_spec.rb
146
133
  - spec/spec_helper.rb
147
- homepage:
134
+ homepage: https://github.com/dslh/db_mod
148
135
  licenses:
149
136
  - MIT
150
137
  metadata: {}
@@ -156,7 +143,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
156
143
  requirements:
157
144
  - - ">="
158
145
  - !ruby/object:Gem::Version
159
- version: '0'
146
+ version: 1.9.3
160
147
  required_rubygems_version: !ruby/object:Gem::Requirement
161
148
  requirements:
162
149
  - - ">="
@@ -167,10 +154,11 @@ rubyforge_project:
167
154
  rubygems_version: 2.4.8
168
155
  signing_key:
169
156
  specification_version: 4
170
- summary: Ruby framework for building modular db-access libs.
157
+ summary: Declarative, modular database library framework.
171
158
  test_files:
172
159
  - spec/db_mod/create_spec.rb
173
160
  - spec/db_mod/statements/prepared_spec.rb
161
+ - spec/db_mod/statements/statement_spec.rb
174
162
  - spec/db_mod/transaction_spec.rb
175
163
  - spec/db_mod_spec.rb
176
164
  - spec/spec_helper.rb