db_mod 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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