jdbc-helper 0.3.2 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +33 -4
- data/lib/jdbc-helper/connection.rb +1 -0
- data/lib/jdbc-helper/sql.rb +32 -25
- data/lib/jdbc-helper/wrapper/object_wrapper.rb +0 -1
- data/lib/jdbc-helper/wrapper/table_wrapper.rb +140 -28
- data/test/database.yml +5 -5
- data/test/test_object_wrapper.rb +99 -13
- data/test/test_sql.rb +32 -23
- metadata +2 -2
data/README.rdoc
CHANGED
@@ -115,17 +115,46 @@ Add JDBC driver of the DBMS you're willing to use to your CLASSPATH
|
|
115
115
|
=== Using table wrappers (since 0.2.0)
|
116
116
|
# For more complex examples, refer to test/test_object_wrapper.rb
|
117
117
|
|
118
|
+
# Creates a table wrapper
|
118
119
|
table = conn.table('test.data')
|
120
|
+
|
121
|
+
# Counting the records in the table
|
119
122
|
table.count
|
123
|
+
table.count(:a => 10)
|
124
|
+
table.where(:a => 10).count
|
125
|
+
|
120
126
|
table.empty?
|
121
|
-
table.
|
122
|
-
|
127
|
+
table.where(:a => 10).empty?
|
128
|
+
|
129
|
+
# Selects the table by combining select, where, and order methods
|
130
|
+
table.select('a apple', :b).where(:c => (1..10)).order('b desc', 'a asc') do |row|
|
131
|
+
puts row.apple
|
123
132
|
end
|
124
|
-
|
125
|
-
|
133
|
+
|
134
|
+
# Build select SQL
|
135
|
+
sql = table.select('a apple', :b).where(:c => (1..10)).order('b desc', 'a asc').sql
|
136
|
+
|
137
|
+
# Updates with conditions
|
138
|
+
table.update(:a => 'hello', :b => JDBCHelper::SQL('now()'), :where => { :c => 3 })
|
139
|
+
# Or equivalently,
|
140
|
+
table.where(:c => 3).update(:a => 'hello', :b => JDBCHelper::SQL('now()'))
|
141
|
+
|
142
|
+
# Insert into the table
|
143
|
+
table.insert(:a => 10, :b => 20, :c => JDBCHelper::SQL('10 + 20'))
|
126
144
|
table.insert_ignore(:a => 10, :b => 20, :c => 30)
|
127
145
|
table.replace(:a => 10, :b => 20, :c => 30)
|
146
|
+
|
147
|
+
# Batch updates with batch method
|
148
|
+
table.batch.insert(:a => 10, :b => 20, :c => JDBCHelper::SQL('10 + 20'))
|
149
|
+
table.batch.insert_ignore(:a => 10, :b => 20, :c => 30)
|
150
|
+
conn.execute_batch
|
151
|
+
|
152
|
+
# Delete with conditions
|
128
153
|
table.delete(:c => 3)
|
154
|
+
# Or equivalently,
|
155
|
+
table.where(:c => 3).delete
|
156
|
+
|
157
|
+
# Truncate or drop table (Cannot be undone)
|
129
158
|
table.truncate_table!
|
130
159
|
table.drop_table!
|
131
160
|
|
@@ -11,6 +11,7 @@ require 'jdbc-helper/connection/row'
|
|
11
11
|
|
12
12
|
require 'jdbc-helper/wrapper/object_wrapper'
|
13
13
|
require 'jdbc-helper/wrapper/table_wrapper'
|
14
|
+
require 'jdbc-helper/wrapper/table_wrapper'
|
14
15
|
require 'jdbc-helper/wrapper/function_wrapper'
|
15
16
|
require 'jdbc-helper/wrapper/procedure_wrapper'
|
16
17
|
|
data/lib/jdbc-helper/sql.rb
CHANGED
@@ -2,16 +2,24 @@
|
|
2
2
|
# Junegunn Choi (junegunn.c@gmail.com)
|
3
3
|
|
4
4
|
module JDBCHelper
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
|
6
|
+
# Generate SQL snippet, prevents the string from being quoted.
|
7
|
+
# @param [String] SQL snippet
|
8
|
+
# @return [JDBCHelper::SQL]
|
9
|
+
def self.SQL str
|
10
|
+
JDBCHelper::SQL.new str
|
11
|
+
end
|
12
|
+
|
13
|
+
# Class representing an SQL snippet. Also has many SQL generator class methods.
|
14
|
+
class SQL
|
11
15
|
# Returns NotNilClass singleton object
|
16
|
+
# @return [JDBCHelper::SQL::NotNilClass]
|
12
17
|
def self.not_nil
|
13
18
|
NotNilClass.singleton
|
14
19
|
end
|
20
|
+
class << self
|
21
|
+
alias not_null not_nil
|
22
|
+
end
|
15
23
|
|
16
24
|
# Formats the given data so that it can be injected into SQL
|
17
25
|
def self.value data
|
@@ -20,7 +28,7 @@ module SQL
|
|
20
28
|
'null'
|
21
29
|
when Fixnum, Bignum, Float
|
22
30
|
data
|
23
|
-
when JDBCHelper::SQL
|
31
|
+
when JDBCHelper::SQL
|
24
32
|
data.to_s
|
25
33
|
when String
|
26
34
|
"'#{esc data}'"
|
@@ -37,7 +45,7 @@ module SQL
|
|
37
45
|
end
|
38
46
|
|
39
47
|
# Generates SQL order by cluase with the given conditions.
|
40
|
-
def self.
|
48
|
+
def self.order *criteria
|
41
49
|
str = criteria.map(&:to_s).reject(&:empty?).join(', ')
|
42
50
|
str.empty? ? str : check('order by ' + str)
|
43
51
|
end
|
@@ -62,18 +70,19 @@ module SQL
|
|
62
70
|
|
63
71
|
# Generates update SQL with hash.
|
64
72
|
# :where element of the given hash is taken out to generate where clause.
|
65
|
-
def self.update table, data_hash
|
66
|
-
where_clause = where_internal
|
73
|
+
def self.update table, data_hash, where
|
74
|
+
where_clause = where_internal where
|
67
75
|
updates = data_hash.map { |k, v| "#{k} = #{value v}" }.join(', ')
|
68
76
|
check "update #{table} set #{updates} #{where_clause}".strip
|
69
77
|
end
|
70
78
|
|
71
|
-
# Generates select
|
72
|
-
def self.select table,
|
79
|
+
# Generates select SQL with the given conditions
|
80
|
+
def self.select table, opts = {}
|
81
|
+
opts = opts.reject { |k, v| v.nil? }
|
73
82
|
check [
|
74
|
-
"select * from #{table}",
|
75
|
-
where_internal(
|
76
|
-
|
83
|
+
"select #{opts.fetch(:select, ['*']).join(', ')} from #{table}",
|
84
|
+
where_internal(opts.fetch(:where, {})),
|
85
|
+
order(opts.fetch(:order, []).join(', '))
|
77
86
|
].reject(&:empty?).join(' ')
|
78
87
|
end
|
79
88
|
|
@@ -106,6 +115,10 @@ module SQL
|
|
106
115
|
return expr
|
107
116
|
end
|
108
117
|
|
118
|
+
def to_s
|
119
|
+
@expr
|
120
|
+
end
|
121
|
+
|
109
122
|
private
|
110
123
|
def self.esc str
|
111
124
|
str.gsub("'", "''")
|
@@ -127,7 +140,7 @@ private
|
|
127
140
|
"is null"
|
128
141
|
when NotNilClass
|
129
142
|
"is not null"
|
130
|
-
when Fixnum, Bignum, Float, JDBCHelper::SQL
|
143
|
+
when Fixnum, Bignum, Float, JDBCHelper::SQL
|
131
144
|
"= #{v}"
|
132
145
|
when Range
|
133
146
|
">= #{v.first} and #{k} <#{'=' unless v.exclude_end?} #{v.last}"
|
@@ -157,16 +170,10 @@ private
|
|
157
170
|
check "#{cmd} into #{table} (#{cols.join ', '}) values (#{cols.map{|c|value data_hash[c]}.join ', '})"
|
158
171
|
end
|
159
172
|
|
160
|
-
|
161
|
-
|
162
|
-
@expr = str
|
163
|
-
end
|
164
|
-
|
165
|
-
def to_s
|
166
|
-
@expr
|
167
|
-
end
|
173
|
+
def initialize str
|
174
|
+
@expr = JDBCHelper::SQL.check str
|
168
175
|
end
|
169
|
-
|
176
|
+
|
170
177
|
# Class to represent "(IS) NOT NULL" expression in SQL
|
171
178
|
class NotNilClass
|
172
179
|
# Returns the singleton object of NotNilClass
|
@@ -5,7 +5,6 @@ module JDBCHelper
|
|
5
5
|
# Abstract base class for wrappers for various database objects.
|
6
6
|
# @abstract
|
7
7
|
# @since 0.2.0
|
8
|
-
# @todo Procedure wrapper with input & output params
|
9
8
|
class ObjectWrapper
|
10
9
|
# Underlying JDBCHelper::Connection object
|
11
10
|
# @return [JDBCHelper::Connection]
|
@@ -7,48 +7,64 @@ module JDBCHelper
|
|
7
7
|
# @example Usage
|
8
8
|
# # For more complex examples, refer to test/test_object_wrapper.rb
|
9
9
|
#
|
10
|
-
#
|
11
|
-
# conn.table('test.data')
|
12
|
-
#
|
13
|
-
#
|
10
|
+
# # Creates a table wrapper
|
11
|
+
# table = conn.table('test.data')
|
12
|
+
#
|
13
|
+
# # Counting the records in the table
|
14
|
+
# table.count
|
15
|
+
# table.count(:a => 10)
|
16
|
+
# table.where(:a => 10).count
|
17
|
+
#
|
18
|
+
# table.empty?
|
19
|
+
# table.where(:a => 10).empty?
|
20
|
+
#
|
21
|
+
# # Selects the table by combining select, where, and order methods
|
22
|
+
# table.select('a apple', :b).where(:c => (1..10)).order('b desc', 'a asc') do |row|
|
23
|
+
# puts row.apple
|
14
24
|
# end
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
25
|
+
#
|
26
|
+
# # Updates with conditions
|
27
|
+
# table.update(:a => 'hello', :b => JDBCHelper::SQL('now()'), :where => { :c => 3 })
|
28
|
+
# # Or equivalently,
|
29
|
+
# table.where(:c => 3).update(:a => 'hello', :b => JDBCHelper::SQL('now()'))
|
30
|
+
#
|
31
|
+
# # Insert into the table
|
32
|
+
# table.insert(:a => 10, :b => 20, :c => JDBCHelper::SQL('10 + 20'))
|
33
|
+
# table.insert_ignore(:a => 10, :b => 20, :c => 30)
|
34
|
+
# table.replace(:a => 10, :b => 20, :c => 30)
|
35
|
+
#
|
36
|
+
# # Delete with conditions
|
37
|
+
# table.delete(:c => 3)
|
38
|
+
# # Or equivalently,
|
39
|
+
# table.where(:c => 3).delete
|
40
|
+
#
|
41
|
+
# # Truncate or drop table (Cannot be undone)
|
42
|
+
# table.truncate_table!
|
43
|
+
# table.drop_table!
|
22
44
|
class TableWrapper < ObjectWrapper
|
23
45
|
# Returns the name of the table
|
24
46
|
# @return [String]
|
25
47
|
alias to_s name
|
26
48
|
|
27
49
|
# Retrieves the count of the table
|
50
|
+
# @param [Hash/String] Filter conditions
|
28
51
|
# @return [Fixnum] Count of the records.
|
29
|
-
def count
|
30
|
-
@connection.query(JDBCHelper::SQL.count name, where)[0][0].to_i
|
52
|
+
def count where = nil
|
53
|
+
@connection.query(JDBCHelper::SQL.count name, where || @query_where)[0][0].to_i
|
31
54
|
end
|
32
55
|
|
33
56
|
# Sees if the table is empty
|
57
|
+
# @param [Hash/String] Filter conditions
|
34
58
|
# @return [boolean]
|
35
|
-
def empty?
|
36
|
-
count == 0
|
37
|
-
end
|
38
|
-
|
39
|
-
# Select * with optional conditions
|
40
|
-
# @param [Hash/String] where Select filters
|
41
|
-
# @return [Array] Array is returned if block is not given
|
42
|
-
# @yield [JDBCHelper::Connection::Row]
|
43
|
-
def select where = nil, &block
|
44
|
-
@connection.query(JDBCHelper::SQL.select(name, where), &block)
|
59
|
+
def empty? where = nil
|
60
|
+
count(where) == 0
|
45
61
|
end
|
46
62
|
|
47
63
|
# Inserts a record into the table with the given hash
|
48
64
|
# @param [Hash] data_hash Column values in Hash
|
49
65
|
# @return [Fixnum] Number of affected records
|
50
66
|
def insert data_hash
|
51
|
-
@connection.
|
67
|
+
@connection.send @update_method, JDBCHelper::SQL.insert(name, data_hash)
|
52
68
|
end
|
53
69
|
|
54
70
|
# Inserts a record into the table with the given hash.
|
@@ -57,7 +73,7 @@ class TableWrapper < ObjectWrapper
|
|
57
73
|
# @param [Hash] data_hash Column values in Hash
|
58
74
|
# @return [Fixnum] Number of affected records
|
59
75
|
def insert_ignore data_hash
|
60
|
-
@connection.
|
76
|
+
@connection.send @update_method, JDBCHelper::SQL.insert_ignore(name, data_hash)
|
61
77
|
end
|
62
78
|
|
63
79
|
# Replaces a record in the table with the new one with the same unique key.
|
@@ -65,7 +81,7 @@ class TableWrapper < ObjectWrapper
|
|
65
81
|
# @param [Hash] data_hash Column values in Hash
|
66
82
|
# @return [Fixnum] Number of affected records
|
67
83
|
def replace data_hash
|
68
|
-
@connection.
|
84
|
+
@connection.send @update_method, JDBCHelper::SQL.replace(name, data_hash)
|
69
85
|
end
|
70
86
|
|
71
87
|
# Executes update with the given hash.
|
@@ -74,14 +90,15 @@ class TableWrapper < ObjectWrapper
|
|
74
90
|
# :where element of the given hash can (usually should) point to another Hash representing update filters.
|
75
91
|
# @return [Fixnum] Number of affected records
|
76
92
|
def update data_hash_with_where
|
77
|
-
|
93
|
+
where = data_hash_with_where.delete(:where) || @query_where
|
94
|
+
@connection.send @update_method, JDBCHelper::SQL.update(name, data_hash_with_where, where)
|
78
95
|
end
|
79
96
|
|
80
97
|
# Deletes records matching given condtion
|
81
98
|
# @param [Hash] where Delete filters
|
82
99
|
# @return [Fixnum] Number of affected records
|
83
100
|
def delete where = nil
|
84
|
-
@connection.
|
101
|
+
@connection.send @update_method, JDBCHelper::SQL.delete(name, where || @query_where)
|
85
102
|
end
|
86
103
|
|
87
104
|
# Empties the table.
|
@@ -97,6 +114,101 @@ class TableWrapper < ObjectWrapper
|
|
97
114
|
def drop_table!
|
98
115
|
@connection.update(JDBCHelper::SQL.check "drop table #{name}")
|
99
116
|
end
|
117
|
+
|
118
|
+
# Select SQL wrapper
|
119
|
+
include Enumerable
|
120
|
+
|
121
|
+
# Returns a new TableWrapper object which can be used to execute a select
|
122
|
+
# statement for the table selecting only the specified fields.
|
123
|
+
# If a block is given, executes the select statement and yields each row to the block.
|
124
|
+
# @return [*String/*Symbol] List of fields to select
|
125
|
+
# @return [JDBCHelper::TableWrapper]
|
126
|
+
# @since 0.4.0
|
127
|
+
def select *fields, &block
|
128
|
+
obj = self.dup
|
129
|
+
obj.instance_variable_set :@query_select, fields unless fields.empty?
|
130
|
+
ret obj, &block
|
131
|
+
end
|
132
|
+
|
133
|
+
# Returns a new TableWrapper object which can be used to execute a select
|
134
|
+
# statement for the table with the specified filter conditions.
|
135
|
+
# If a block is given, executes the select statement and yields each row to the block.
|
136
|
+
# @param [Hash/String] Filter conditions
|
137
|
+
# @return [JDBCHelper::TableWrapper]
|
138
|
+
# @since 0.4.0
|
139
|
+
def where conditions, &block
|
140
|
+
obj = self.dup
|
141
|
+
obj.instance_variable_set :@query_where, conditions
|
142
|
+
ret obj, &block
|
143
|
+
end
|
144
|
+
|
145
|
+
# Returns a new TableWrapper object which can be used to execute a select
|
146
|
+
# statement for the table with the given sorting criteria.
|
147
|
+
# If a block is given, executes the select statement and yields each row to the block.
|
148
|
+
# @param [*String/*Symbol] Sorting criteria
|
149
|
+
# @return [JDBCHelper::TableWrapper]
|
150
|
+
# @since 0.4.0
|
151
|
+
def order *criteria, &block
|
152
|
+
raise ArgumentError.new("Wrong number of arguments") if criteria.empty?
|
153
|
+
obj = self.dup
|
154
|
+
obj.instance_variable_set :@query_order, criteria
|
155
|
+
ret obj, &block
|
156
|
+
end
|
157
|
+
|
158
|
+
# Executes a select SQL for the table and returns an Enumerable object,
|
159
|
+
# or yields each row if block is given.
|
160
|
+
# @return [JDBCHelper::Connection::ResultSetEnumerator]
|
161
|
+
# @since 0.4.0
|
162
|
+
def each &block
|
163
|
+
@connection.enumerate sql, &block
|
164
|
+
end
|
165
|
+
|
166
|
+
# Returns a new TableWrapper object whose subsequent inserts, updates,
|
167
|
+
# and deletes are added to batch for JDBC batch-execution. The actual execution
|
168
|
+
# is deferred until JDBCHelper::Connection#execute_batch method is called.
|
169
|
+
# Self is returned when batch is called more than once.
|
170
|
+
# @return [JDBCHelper::Connection::ResultSetEnumerator]
|
171
|
+
# @since 0.4.0
|
172
|
+
def batch
|
173
|
+
if batch?
|
174
|
+
self
|
175
|
+
else
|
176
|
+
obj = self.dup
|
177
|
+
obj.instance_variable_set :@update_method, :add_batch
|
178
|
+
obj
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
# Returns if the subsequent updates for this wrapper will be batched
|
183
|
+
# @return [Boolean]
|
184
|
+
# @since 0.4.0
|
185
|
+
def batch?
|
186
|
+
@update_method == :add_batch
|
187
|
+
end
|
188
|
+
|
189
|
+
# Returns the select SQL for this wrapper object
|
190
|
+
# @return [String] Select SQL
|
191
|
+
# @since 0.4.0
|
192
|
+
def sql
|
193
|
+
JDBCHelper::SQL.select(
|
194
|
+
name,
|
195
|
+
:select => @query_select,
|
196
|
+
:where => @query_where,
|
197
|
+
:order => @query_order)
|
198
|
+
end
|
199
|
+
|
200
|
+
def initialize connection, table_name
|
201
|
+
super connection, table_name
|
202
|
+
@update_method = :update
|
203
|
+
end
|
204
|
+
private
|
205
|
+
def ret obj, &block
|
206
|
+
if block_given?
|
207
|
+
obj.each &block
|
208
|
+
else
|
209
|
+
obj
|
210
|
+
end
|
211
|
+
end
|
100
212
|
end#TableWrapper
|
101
213
|
end#JDBCHelper
|
102
214
|
|
data/test/database.yml
CHANGED
@@ -5,9 +5,9 @@ mysql:
|
|
5
5
|
user: root
|
6
6
|
password:
|
7
7
|
|
8
|
-
oracle:
|
9
|
-
driver: oracle.jdbc.driver.OracleDriver
|
10
|
-
url: jdbc:oracle:thin:@localhost/test
|
11
|
-
user: testuser
|
12
|
-
password: testpassword
|
8
|
+
#oracle:
|
9
|
+
#driver: oracle.jdbc.driver.OracleDriver
|
10
|
+
#url: jdbc:oracle:thin:@localhost/test
|
11
|
+
#user: testuser
|
12
|
+
#password: testpassword
|
13
13
|
|
data/test/test_object_wrapper.rb
CHANGED
@@ -70,15 +70,15 @@ class TestObjectWrapper < Test::Unit::TestCase
|
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
|
-
def insert table
|
73
|
+
def insert table, cnt = 100
|
74
74
|
params = {
|
75
75
|
:alpha => 100,
|
76
|
-
:beta => JDBCHelper::SQL
|
76
|
+
:beta => JDBCHelper::SQL('0.1 + 0.2'),
|
77
77
|
:gamma => 'hello world' }
|
78
78
|
|
79
|
-
(1..
|
79
|
+
(1..cnt).each do |pk|
|
80
80
|
icnt = table.insert(params.merge(:id => pk))
|
81
|
-
assert_equal
|
81
|
+
assert_equal 1, icnt unless table.batch?
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
@@ -133,10 +133,22 @@ class TestObjectWrapper < Test::Unit::TestCase
|
|
133
133
|
# Insert
|
134
134
|
insert table
|
135
135
|
|
136
|
+
# Empty?
|
137
|
+
assert_equal false, table.empty?
|
138
|
+
assert_equal true, table.empty?(:alpha => 999)
|
139
|
+
assert_equal true, table.where(:alpha => 999).empty?
|
140
|
+
|
136
141
|
# Count
|
137
142
|
assert_equal 100, table.count
|
138
143
|
assert_equal 100, table.count(:alpha => 100)
|
139
144
|
assert_equal 0, table.count(:beta => nil)
|
145
|
+
|
146
|
+
assert_equal 100, table.where(:alpha => 100).count
|
147
|
+
assert_equal 0, table.where(:beta => nil).count
|
148
|
+
assert_equal 0, table.where(:alpha => 100).count(:beta => nil)
|
149
|
+
|
150
|
+
assert_equal true, table.empty?(:beta => nil)
|
151
|
+
assert_equal true, table.where(:beta => nil).empty?
|
140
152
|
end
|
141
153
|
end
|
142
154
|
|
@@ -149,7 +161,7 @@ class TestObjectWrapper < Test::Unit::TestCase
|
|
149
161
|
params = {
|
150
162
|
:id => 1,
|
151
163
|
:alpha => 100,
|
152
|
-
:beta => JDBCHelper::SQL
|
164
|
+
:beta => JDBCHelper::SQL('0.1 + 0.2'),
|
153
165
|
:gamma => 'hello world' }
|
154
166
|
|
155
167
|
100.times do
|
@@ -168,7 +180,7 @@ class TestObjectWrapper < Test::Unit::TestCase
|
|
168
180
|
table = conn.table(@table_name)
|
169
181
|
params = {
|
170
182
|
:id => 1,
|
171
|
-
:beta => JDBCHelper::SQL
|
183
|
+
:beta => JDBCHelper::SQL('0.1 + 0.2'),
|
172
184
|
:gamma => 'hello world' }
|
173
185
|
|
174
186
|
100.times do |i|
|
@@ -187,21 +199,60 @@ class TestObjectWrapper < Test::Unit::TestCase
|
|
187
199
|
insert table
|
188
200
|
assert_equal 100, table.count
|
189
201
|
|
202
|
+
def check_row row
|
203
|
+
assert_equal 100, row.alpha
|
204
|
+
assert_equal 'hello world', row.gamma
|
205
|
+
end
|
206
|
+
|
190
207
|
cnt = 0
|
191
208
|
table.select do |row|
|
192
209
|
cnt += 1
|
193
|
-
|
194
|
-
assert_equal 'hello world', row.gamma
|
210
|
+
check_row row
|
195
211
|
end
|
196
212
|
assert_equal 100, cnt
|
197
213
|
|
198
214
|
cnt = 0
|
199
|
-
table.
|
215
|
+
table.each do |row|
|
200
216
|
cnt += 1
|
201
|
-
|
202
|
-
|
217
|
+
check_row row
|
218
|
+
end
|
219
|
+
assert_equal 100, cnt
|
220
|
+
|
221
|
+
cnt = 0
|
222
|
+
table.each_slice(10) do |rows|
|
223
|
+
cnt += rows.length
|
224
|
+
end
|
225
|
+
assert_equal 100, cnt
|
226
|
+
|
227
|
+
cnt = 0
|
228
|
+
table.select('alpha omega') do |row|
|
229
|
+
cnt += 1
|
230
|
+
assert_equal 100, row.omega
|
231
|
+
assert_equal ['omega'], row.labels.map(&:downcase)
|
232
|
+
end
|
233
|
+
assert_equal 100, cnt
|
234
|
+
|
235
|
+
cnt = 0
|
236
|
+
prev_id = 100
|
237
|
+
table.where(:id => 11..20).order('id desc') do |row|
|
238
|
+
cnt += 1
|
239
|
+
check_row row
|
240
|
+
|
241
|
+
assert row.id.to_i < prev_id
|
242
|
+
prev_id = row.id.to_i
|
203
243
|
end
|
204
244
|
assert_equal 10, cnt
|
245
|
+
|
246
|
+
assert_equal "select a, b, c cc from tmp_jdbc_helper " +
|
247
|
+
"where id >= 11 and id <= 20 order by id desc, name asc",
|
248
|
+
table.where(:id => 11..20).
|
249
|
+
select(:a, :b, 'c cc').
|
250
|
+
order('id desc', 'name asc').sql
|
251
|
+
|
252
|
+
assert_raise(ArgumentError) { table.order }
|
253
|
+
assert_raise(ArgumentError) { table.order.where }
|
254
|
+
assert_raise(ArgumentError) { table.where.order }
|
255
|
+
assert_raise(ArgumentError) { table.select.order }
|
205
256
|
end
|
206
257
|
end
|
207
258
|
|
@@ -220,9 +271,10 @@ class TestObjectWrapper < Test::Unit::TestCase
|
|
220
271
|
assert_equal 1, table.delete(:id => 21)
|
221
272
|
assert_equal 4, table.delete(:id => [22, 23, 24, 25])
|
222
273
|
assert_equal 5, table.delete("id <= 30")
|
274
|
+
assert_equal 10, table.where("id <= 40").delete
|
223
275
|
|
224
276
|
# Could be dangerous (XXX)
|
225
|
-
assert_equal
|
277
|
+
assert_equal 60, table.delete
|
226
278
|
|
227
279
|
# Count
|
228
280
|
assert_equal 0, table.count
|
@@ -236,8 +288,42 @@ class TestObjectWrapper < Test::Unit::TestCase
|
|
236
288
|
insert table
|
237
289
|
|
238
290
|
assert_equal 10, table.update(:beta => 0, :where => { :id => (1..10) })
|
239
|
-
assert_equal 10, table.
|
291
|
+
assert_equal 10, table.where(:id => (11..20)).update(:beta => 0)
|
292
|
+
assert_equal 20, table.count(:beta => 0)
|
293
|
+
assert_equal 100, table.update(:beta => 1)
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
def test_batch
|
298
|
+
each_connection do |conn|
|
299
|
+
# Initialize test table
|
300
|
+
create_table conn
|
301
|
+
table = conn.table(@table_name)
|
302
|
+
insert table
|
303
|
+
|
304
|
+
# Duplicated calls are idempotent
|
305
|
+
btable = table.batch
|
306
|
+
assert_equal btable, btable.batch
|
307
|
+
|
308
|
+
# Batch updates
|
309
|
+
table.batch.delete
|
310
|
+
assert_equal 100, table.count
|
311
|
+
|
312
|
+
insert table.batch, 50
|
313
|
+
assert_equal 100, table.count
|
314
|
+
|
315
|
+
table.batch.update(:alpha => JDBCHelper::SQL('alpha * 2'))
|
316
|
+
assert_equal 100, table.select(:alpha).to_a.first.alpha.to_i
|
317
|
+
|
318
|
+
# Independent update inbetween
|
319
|
+
table.delete(:id => 1..10)
|
320
|
+
assert_equal 90, table.count
|
321
|
+
|
322
|
+
# Finally
|
323
|
+
conn.execute_batch
|
240
324
|
|
325
|
+
assert_equal 50, table.count
|
326
|
+
assert_equal 200, table.select(:alpha).to_a.first.alpha.to_i
|
241
327
|
end
|
242
328
|
end
|
243
329
|
|
data/test/test_sql.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'helper'
|
2
2
|
include JDBCHelper
|
3
3
|
|
4
|
+
# WARNING: tests assumes ordered hash
|
4
5
|
class TestSQL < Test::Unit::TestCase
|
5
6
|
def setup
|
6
7
|
end
|
@@ -14,22 +15,22 @@ class TestSQL < Test::Unit::TestCase
|
|
14
15
|
assert_equal 9999999999999999999, SQL.value(9999999999999999999)
|
15
16
|
assert_equal "'sysdate'", SQL.value('sysdate')
|
16
17
|
assert_equal "'A''s'", SQL.value("A's")
|
17
|
-
assert_equal "sysdate", SQL.value(SQL
|
18
|
+
assert_equal "sysdate", SQL.value(JDBCHelper::SQL('sysdate'))
|
18
19
|
|
19
20
|
end
|
20
21
|
|
21
|
-
def
|
22
|
-
assert_equal "", SQL.
|
23
|
-
assert_equal "", SQL.
|
24
|
-
assert_equal "", SQL.
|
25
|
-
assert_equal "order by a", SQL.
|
26
|
-
assert_equal "order by a", SQL.
|
27
|
-
assert_equal "order by a desc", SQL.
|
28
|
-
assert_equal "order by a asc", SQL.
|
29
|
-
assert_equal "order by a, b asc, c desc", SQL.
|
30
|
-
|
31
|
-
assert_raise(ArgumentError) { SQL.
|
32
|
-
assert_raise(ArgumentError) { SQL.
|
22
|
+
def test_order
|
23
|
+
assert_equal "", SQL.order()
|
24
|
+
assert_equal "", SQL.order(nil)
|
25
|
+
assert_equal "", SQL.order(nil, nil)
|
26
|
+
assert_equal "order by a", SQL.order(:a)
|
27
|
+
assert_equal "order by a", SQL.order('a')
|
28
|
+
assert_equal "order by a desc", SQL.order('a desc')
|
29
|
+
assert_equal "order by a asc", SQL.order('a asc')
|
30
|
+
assert_equal "order by a, b asc, c desc", SQL.order(:a, 'b asc', 'c desc')
|
31
|
+
|
32
|
+
assert_raise(ArgumentError) { SQL.order(" -- ") }
|
33
|
+
assert_raise(ArgumentError) { SQL.order(:a, :b, "c 'd") }
|
33
34
|
end
|
34
35
|
|
35
36
|
def test_where
|
@@ -41,8 +42,9 @@ class TestSQL < Test::Unit::TestCase
|
|
41
42
|
assert_equal "where a = 'A''s'", SQL.where(:a => "A's")
|
42
43
|
assert_equal "where a is null", SQL.where(:a => nil)
|
43
44
|
assert_equal "where a is not null", SQL.where(:a => SQL.not_nil)
|
44
|
-
assert_equal "where a
|
45
|
-
assert_equal "where
|
45
|
+
assert_equal "where a is not null", SQL.where(:a => SQL.not_null)
|
46
|
+
assert_equal "where a = sysdate", SQL.where(:a => JDBCHelper::SQL('sysdate'))
|
47
|
+
assert_equal "where sysdate = sysdate", SQL.where(JDBCHelper::SQL('sysdate') => JDBCHelper::SQL('sysdate'))
|
46
48
|
assert_equal "where a in ('aa', 'bb', 'cc')", SQL.where(:a => %w[aa bb cc])
|
47
49
|
assert_equal "where a = 1 and b = 'A''s'", SQL.where(:a => 1, :b => "A's")
|
48
50
|
assert_equal "where a = 1 or b = 1", SQL.where("a = 1 or b = 1")
|
@@ -53,16 +55,23 @@ class TestSQL < Test::Unit::TestCase
|
|
53
55
|
assert_raise(NotImplementedError) { SQL.where(:a => Time.now) }
|
54
56
|
|
55
57
|
# Invalid SQL detection
|
56
|
-
assert_raise(ArgumentError) { SQL.where(:a => SQL
|
57
|
-
assert_raise(ArgumentError) { SQL.where(:a => SQL
|
58
|
-
assert_raise(ArgumentError) { SQL.where(:a => SQL
|
59
|
-
assert_raise(ArgumentError) { SQL.where(:a => SQL
|
60
|
-
assert_raise(ArgumentError) { SQL.where(:a => SQL
|
58
|
+
assert_raise(ArgumentError) { SQL.where(:a => JDBCHelper::SQL(" 'a--b' -- cde")) }
|
59
|
+
assert_raise(ArgumentError) { SQL.where(:a => JDBCHelper::SQL(" 'aabbb''dd")) }
|
60
|
+
assert_raise(ArgumentError) { SQL.where(:a => JDBCHelper::SQL(" 'aabbb''dd' /* aaa */")) }
|
61
|
+
assert_raise(ArgumentError) { SQL.where(:a => JDBCHelper::SQL(' aabbb""" ')) }
|
62
|
+
assert_raise(ArgumentError) { SQL.where(:a => JDBCHelper::SQL(' aab`bb`` ')) }
|
61
63
|
end
|
62
64
|
|
63
65
|
def test_select
|
64
66
|
assert_equal "select * from a.b", SQL.select('a.b')
|
65
|
-
assert_equal "select
|
67
|
+
assert_equal "select aa, bb from a.b where a is not null",
|
68
|
+
SQL.select('a.b', :select => %w[aa bb], :where => {:a => SQL.not_nil})
|
69
|
+
assert_equal "select aa, bb from a.b where a is not null and b >= 1 and b <= 10 order by cc, dd",
|
70
|
+
SQL.select('a.b',
|
71
|
+
:select => %w[aa bb],
|
72
|
+
:where => {:a => SQL.not_null, :b => (1..10)},
|
73
|
+
:order => %w[cc dd]
|
74
|
+
)
|
66
75
|
end
|
67
76
|
|
68
77
|
def test_count
|
@@ -77,10 +86,10 @@ class TestSQL < Test::Unit::TestCase
|
|
77
86
|
|
78
87
|
def test_update
|
79
88
|
assert_equal "update a.b set a = 1, b = 'A''s', c = now()",
|
80
|
-
SQL.update('a.b', :a => 1, :b => "A's", :c => SQL
|
89
|
+
SQL.update('a.b', {:a => 1, :b => "A's", :c => JDBCHelper::SQL('now()')}, {})
|
81
90
|
|
82
91
|
assert_equal "update a.b set a = 1, b = 'A''s', c = now() where a is not null",
|
83
|
-
SQL.update('a.b', :a => 1, :b => "A's", :c => SQL
|
92
|
+
SQL.update('a.b', {:a => 1, :b => "A's", :c => JDBCHelper::SQL('now()')}, { :a => SQL.not_nil })
|
84
93
|
end
|
85
94
|
|
86
95
|
def test_insert
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: jdbc-helper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: 0.4.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Junegunn Choi
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-05-
|
13
|
+
date: 2011-05-31 00:00:00 +09:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|