wikk_sql 0.1.2 → 0.2.1
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 +5 -5
- data/History.txt +78 -0
- data/Manifest.txt +2 -0
- data/README.md +3 -3
- data/Rakefile +15 -15
- data/lib/wikk_mysql2.rb +384 -0
- data/lib/wikk_ruby_mysql.rb +341 -0
- data/lib/wikk_sql.rb +36 -254
- metadata +17 -14
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 69f45ee6d7fb4c55391f5f0dcbb161b1abaa53a57fa6a845223e0293d356d622
|
|
4
|
+
data.tar.gz: e057cd23694695352a95f6d2b7ec72cd3216b22456c0ed73646a0d742bfa74a2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 388b183d0bf33873a8fa840a55016000a1d66d36d64dc65028dd219857e67dac0e9ec560a786bce4c0bc7d7d2d7f2561b8e3b22121ada356e91cd0761e00a8b3
|
|
7
|
+
data.tar.gz: 85e177dda64b58d5319db994f3fadb94ae2f0d3eb9ba0a6ba6aced0c2de0344311c199752614f36b0783641651a3eb9d434777c5402cda51a26bd41d4102b017
|
data/History.txt
CHANGED
|
@@ -1,3 +1,81 @@
|
|
|
1
|
+
robertburrowes Tue Jun 21 09:26:47 2022 +1200
|
|
2
|
+
bump version
|
|
3
|
+
robertburrowes Tue Jun 21 09:26:16 2022 +1200
|
|
4
|
+
add aliases, so calls without blocks read better
|
|
5
|
+
robertburrowes Sun Jun 5 14:16:58 2022 +1200
|
|
6
|
+
Split gem into a loader, and connector files
|
|
7
|
+
robertburrowes Sun Jun 5 14:00:56 2022 +1200
|
|
8
|
+
add escape()
|
|
9
|
+
robertburrowes Fri Jun 3 11:35:39 2022 +1200
|
|
10
|
+
Add self.escape
|
|
11
|
+
robertburrowes Thu Jun 2 16:29:38 2022 +1200
|
|
12
|
+
test cleanup.
|
|
13
|
+
robertburrowes Thu Jun 2 16:23:33 2022 +1200
|
|
14
|
+
Hashed_row should have been hrow
|
|
15
|
+
robertburrowes Thu Jun 2 16:13:17 2022 +1200
|
|
16
|
+
Added each_param (**kwargs) test, and changed each_sym test to not use params
|
|
17
|
+
robertburrowes Thu Jun 2 16:07:24 2022 +1200
|
|
18
|
+
Uppercased user rather than DB
|
|
19
|
+
robertburrowes Thu Jun 2 16:07:10 2022 +1200
|
|
20
|
+
add escape method
|
|
21
|
+
robertburrowes Thu Jun 2 15:47:21 2022 +1200
|
|
22
|
+
Test DB uppercase
|
|
23
|
+
robertburrowes Wed Jun 1 14:17:39 2022 +1200
|
|
24
|
+
Now need a each_param, as hash to named kargs now needs a **
|
|
25
|
+
robertburrowes Tue May 31 22:03:20 2022 +1200
|
|
26
|
+
name change
|
|
27
|
+
robertburrowes Tue May 31 22:03:08 2022 +1200
|
|
28
|
+
Wrong exception
|
|
29
|
+
robertburrowes Tue May 31 22:02:51 2022 +1200
|
|
30
|
+
Setting up test DB
|
|
31
|
+
robertburrowes Tue May 31 18:44:38 2022 +1200
|
|
32
|
+
Merge branch 'master' of github.com:wikarekare/wikk_sql
|
|
33
|
+
robertburrowes Tue May 31 17:04:27 2022 +1200
|
|
34
|
+
Working on consistency between ruby-mysql and mysql2 connectors
|
|
35
|
+
robertburrowes Tue May 31 17:03:55 2022 +1200
|
|
36
|
+
unsure we get bash
|
|
37
|
+
robertburrowes Tue May 31 17:00:43 2022 +1200
|
|
38
|
+
rubocop'd
|
|
39
|
+
robertburrowes Thu May 26 22:42:58 2022 +1200
|
|
40
|
+
Getting it to work, Slowly
|
|
41
|
+
robertburrowes Thu May 26 16:55:35 2022 +1200
|
|
42
|
+
Working towards having the gem work with either ruby-mysql or mysql2
|
|
43
|
+
robertburrowes Mon May 23 20:36:26 2022 +1200
|
|
44
|
+
rubocop'd
|
|
45
|
+
robertburrowes Sun Oct 25 21:44:30 2020 +1300
|
|
46
|
+
Yard comment tidy up
|
|
47
|
+
robertburrowes Sun Oct 25 21:15:26 2020 +1300
|
|
48
|
+
Fix doc url
|
|
49
|
+
robertburrowes Sun Oct 25 21:14:28 2020 +1300
|
|
50
|
+
mode change
|
|
51
|
+
robertburrowes Sun Oct 25 21:14:19 2020 +1300
|
|
52
|
+
Update for new Hoe
|
|
53
|
+
robertburrowes Sun Oct 25 21:13:58 2020 +1300
|
|
54
|
+
Improve dependency to remove warning
|
|
55
|
+
robertburrowes Sun Oct 25 21:13:40 2020 +1300
|
|
56
|
+
Include in repo
|
|
57
|
+
robertburrowes Sun Oct 25 21:13:26 2020 +1300
|
|
58
|
+
mv dev scripts to sbin
|
|
59
|
+
robertburrowes Thu Jun 29 10:13:40 2017 +1200
|
|
60
|
+
raise exception if not connected
|
|
61
|
+
robertburrowes Thu Jun 29 09:43:14 2017 +1200
|
|
62
|
+
result should have been @result
|
|
63
|
+
robertburrowes Wed Jan 4 16:49:28 2017 +1300
|
|
64
|
+
set @affected_rows before query :(
|
|
65
|
+
robertburrowes Tue Jun 28 22:39:37 2016 +1200
|
|
66
|
+
added auto git tagging on release
|
|
67
|
+
robertburrowes Sun Jun 19 14:58:57 2016 +1200
|
|
68
|
+
Put Wikk Configuration class into module WIKK
|
|
69
|
+
robertburrowes Sun Jun 19 14:54:48 2016 +1200
|
|
70
|
+
Acknowledge code origin
|
|
71
|
+
robertburrowes Sun Jun 19 14:50:56 2016 +1200
|
|
72
|
+
Tidied up inline documentation of class
|
|
73
|
+
robertburrowes Sun Jun 19 14:50:30 2016 +1200
|
|
74
|
+
Ensured history file generated before package is generated
|
|
75
|
+
robertburrowes Sun Jun 19 14:50:07 2016 +1200
|
|
76
|
+
Upped version
|
|
77
|
+
robertburrowes Sun Jun 19 14:49:52 2016 +1200
|
|
78
|
+
Changed WIKK_SQL to module WIKK::SQL
|
|
1
79
|
robertburrowes Sun Jun 19 14:01:08 2016 +1200
|
|
2
80
|
Encapsulation of SQL into module WIKK
|
|
3
81
|
robertburrowes Sun Jun 19 13:59:27 2016 +1200
|
data/Manifest.txt
CHANGED
data/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# wikk_sql
|
|
2
2
|
|
|
3
|
-
*
|
|
4
|
-
* Source https://github.com/wikarekare/wikk_sql
|
|
5
|
-
* Gem https://rubygems.org/gems/wikk_sql
|
|
3
|
+
* Docs :: https://wikarekare.github.io/wikk_sql/
|
|
4
|
+
* Source :: https://github.com/wikarekare/wikk_sql
|
|
5
|
+
* Gem :: https://rubygems.org/gems/wikk_sql
|
|
6
6
|
|
|
7
7
|
## DESCRIPTION:
|
|
8
8
|
|
data/Rakefile
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
# -*- ruby -*-
|
|
2
|
-
|
|
3
2
|
require 'rubygems'
|
|
4
3
|
require 'hoe'
|
|
5
4
|
Hoe.plugin :yard
|
|
6
5
|
|
|
7
|
-
Hoe.spec 'wikk_sql' do
|
|
8
|
-
self.readme_file =
|
|
9
|
-
self.developer(
|
|
6
|
+
Hoe.spec 'wikk_sql' do
|
|
7
|
+
self.readme_file = 'README.md'
|
|
8
|
+
self.developer( 'Rob Burrowes', 'r.burrowes@auckland.ac.nz')
|
|
10
9
|
remote_rdoc_dir = '' # Release to root
|
|
11
|
-
|
|
10
|
+
|
|
12
11
|
self.yard_title = 'wikk_sql'
|
|
13
|
-
self.yard_options = ['--markup', 'markdown', '--protected']
|
|
14
|
-
end
|
|
12
|
+
self.yard_options = [ '--markup', 'markdown', '--protected' ]
|
|
15
13
|
|
|
14
|
+
# self.dependency "ruby-mysql", ['~> 1.0', '>= 1.0.0']
|
|
15
|
+
end
|
|
16
16
|
|
|
17
|
-
#Validate manfest.txt
|
|
18
|
-
#rake check_manifest
|
|
17
|
+
# Validate manfest.txt
|
|
18
|
+
# rake check_manifest
|
|
19
19
|
|
|
20
|
-
#Local checking. Creates pkg/
|
|
21
|
-
#rake gem
|
|
20
|
+
# Local checking. Creates pkg/
|
|
21
|
+
# rake gem
|
|
22
22
|
|
|
23
|
-
#create doc/
|
|
24
|
-
#rake docs
|
|
23
|
+
# create doc/
|
|
24
|
+
# rake docs
|
|
25
25
|
|
|
26
|
-
#Copy up to rubygem.org
|
|
27
|
-
#rake release VERSION=1.0.1
|
|
26
|
+
# Copy up to rubygem.org
|
|
27
|
+
# rake release VERSION=1.0.1
|
data/lib/wikk_mysql2.rb
ADDED
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
require 'mysql2'
|
|
2
|
+
|
|
3
|
+
# Provides common front end, even if we change the connector library
|
|
4
|
+
# Connector is mysql2. Requires libmysql-dev or libmariadb-dev to install the gem.
|
|
5
|
+
module WIKK
|
|
6
|
+
# WIKK_SQL wrapper for ruby mysql gem.
|
|
7
|
+
# @attr_reader [Numeric] affected_rows the number of rows changed, deleted, or added.
|
|
8
|
+
# @attr_reader [Mysql::Result] result the last query's result
|
|
9
|
+
# @attr_reader [Mysql] my the DB connection descriptor
|
|
10
|
+
class SQL
|
|
11
|
+
attr_reader :affected_rows, :result, :my
|
|
12
|
+
|
|
13
|
+
# Create WIKK::SQL instance and set up the mySQL connection.
|
|
14
|
+
# @param db_config [Configuration] Configuration class, Hash, or any class with appropriate attr_readers.
|
|
15
|
+
# @yieldparam sql [WIKK_SQL] if a block is given.
|
|
16
|
+
# @return [NilClass] if block is given, and closes the mySQL connection.
|
|
17
|
+
# @return [WIKK_SQL] if no block is given, and caller must call sql.close
|
|
18
|
+
def self.connect(db_config)
|
|
19
|
+
sql = self.new
|
|
20
|
+
sql.connect(db_config)
|
|
21
|
+
if block_given?
|
|
22
|
+
yield sql
|
|
23
|
+
return sql.close
|
|
24
|
+
else
|
|
25
|
+
return sql
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Set up the mySQL connection.
|
|
30
|
+
#
|
|
31
|
+
# @param db_config [Configuration] Configuration class, Hash, or any class with appropriate attr_readers.
|
|
32
|
+
# @yieldparam [] if a block is given.
|
|
33
|
+
# @return [NilClass] if block is given, and closes the mySQL connection.
|
|
34
|
+
# @return [WIKK_SQL] if no block is given, and caller must call sql.close
|
|
35
|
+
def connect(db_config)
|
|
36
|
+
if db_config.instance_of?(Hash)
|
|
37
|
+
sym = db_config.transform_keys(& :to_sym )
|
|
38
|
+
db_config = Struct.new(*(k = sym.keys)).new(*sym.values_at(*k))
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
begin
|
|
42
|
+
@my = Mysql2::Client.new( host: db_config.host,
|
|
43
|
+
database: db_config.db,
|
|
44
|
+
username: db_config.dbuser,
|
|
45
|
+
password: db_config.key,
|
|
46
|
+
socket: db_config.respond_to?(:socket) ? db_config.socket : nil,
|
|
47
|
+
port: db_config.respond_to?(:port) ? db_config.port : nil,
|
|
48
|
+
flags: 'SESSION_TRACK',
|
|
49
|
+
init_command: 'SET @@SESSION.session_track_schema=ON'
|
|
50
|
+
)
|
|
51
|
+
rescue StandardError => e
|
|
52
|
+
@my = nil
|
|
53
|
+
raise e
|
|
54
|
+
end
|
|
55
|
+
raise Mysql2::Error, 2002 if @my.nil?
|
|
56
|
+
|
|
57
|
+
# @@my.reconnect = true
|
|
58
|
+
if block_given?
|
|
59
|
+
yield
|
|
60
|
+
return close
|
|
61
|
+
end
|
|
62
|
+
return @my
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
alias open connect
|
|
66
|
+
|
|
67
|
+
# close the mySQL connection. Call only if connect was not given a block.
|
|
68
|
+
#
|
|
69
|
+
# @return [NilClass]
|
|
70
|
+
def close
|
|
71
|
+
@my.close if @my != nil
|
|
72
|
+
return (@my = nil)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Call underlying connector's escape of the query string
|
|
76
|
+
# @param query [String] The SQL query
|
|
77
|
+
# @return [String] The SQL query, escaped to remove vulnerabilities
|
|
78
|
+
def self.escape(query)
|
|
79
|
+
Mysql2::Client.escape(query)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Call underlying connector's escape of the query string
|
|
83
|
+
# @param query [String] The SQL query
|
|
84
|
+
# @return [String] The SQL query, escaped to remove vulnerabilities
|
|
85
|
+
def escape(query)
|
|
86
|
+
@my.escape(query)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Run a query on the DB server.
|
|
90
|
+
#
|
|
91
|
+
# @param the_query [String] Sql query to send to DB server.
|
|
92
|
+
# @raise [Mysql] passes on Mysql errors, freeing the result.
|
|
93
|
+
# @yieldparam [Mysql::Result] @result and @affected_rows are also set.
|
|
94
|
+
# @return [Mysql::Result] @result and @affected_rows are also set.
|
|
95
|
+
def query(the_query, options = nil )
|
|
96
|
+
raise Mysql2::Error, 2002 if @my.nil?
|
|
97
|
+
|
|
98
|
+
# Default to returning values as an array, with no caching of previous results
|
|
99
|
+
# This is consistent with ruby-mysql
|
|
100
|
+
options ||= { as: :array, cache_rows: false }
|
|
101
|
+
begin
|
|
102
|
+
if @result != nil
|
|
103
|
+
@result.free # Free any result we had left over from previous use.
|
|
104
|
+
@result = nil
|
|
105
|
+
end
|
|
106
|
+
@affected_rows = 0 # incase this query crashes and burns, this will have a value.
|
|
107
|
+
@result = @my.query(the_query, options)
|
|
108
|
+
@affected_rows = @my.affected_rows # This is non-zero for select/insert/delete/update of rows
|
|
109
|
+
if block_given?
|
|
110
|
+
yield @result
|
|
111
|
+
else
|
|
112
|
+
return @result
|
|
113
|
+
end
|
|
114
|
+
rescue Mysql2::Error => e
|
|
115
|
+
if @result != nil
|
|
116
|
+
@result.free # Free any result we had left over from previous use.
|
|
117
|
+
@result = nil
|
|
118
|
+
end
|
|
119
|
+
raise e
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Perform a transaction in the passed block.
|
|
124
|
+
# RollBACK on error, otherwise COMMIT
|
|
125
|
+
#
|
|
126
|
+
# @yieldparam [] yields to block, where the queries are performed.
|
|
127
|
+
# @raise [Mysql] passes on Mysql errors, freeing the result.
|
|
128
|
+
def transaction
|
|
129
|
+
raise Mysql2::Error, 2002 if @my.nil?
|
|
130
|
+
|
|
131
|
+
if block_given?
|
|
132
|
+
begin
|
|
133
|
+
@my.query('START TRANSACTION WITH CONSISTENT SNAPSHOT')
|
|
134
|
+
yield # Start executing the query black.
|
|
135
|
+
@my.query('COMMIT')
|
|
136
|
+
rescue Mysql2::Error => e
|
|
137
|
+
@my.query('ROLLBACK')
|
|
138
|
+
raise e
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Yields query query results row by row, as Array
|
|
144
|
+
#
|
|
145
|
+
# @param the_query [String] Sql query to send to DB server.
|
|
146
|
+
# @raise [Mysql] passes on Mysql errors, freeing the result.
|
|
147
|
+
# @yieldparam [Array] each result row
|
|
148
|
+
# @return [Array] of rows
|
|
149
|
+
# @note @result and @affected_rows are also set via call to query().
|
|
150
|
+
def each_row(the_query, &block)
|
|
151
|
+
begin
|
|
152
|
+
query(the_query, { as: :array, cache_rows: false })
|
|
153
|
+
unless @result.nil?
|
|
154
|
+
if block_given?
|
|
155
|
+
@affected_rows = @result.count # This is non-zero is we do a select, and get results.
|
|
156
|
+
@result.each(&block)
|
|
157
|
+
else
|
|
158
|
+
result = []
|
|
159
|
+
@result.each { |row| result << row }
|
|
160
|
+
return result
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
rescue Mysql2::Error => e
|
|
164
|
+
# puts "#{e.errno}: #{e.error}"
|
|
165
|
+
raise e
|
|
166
|
+
ensure
|
|
167
|
+
if block_given? && @result != nil
|
|
168
|
+
@result.free
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
alias query_array each_row
|
|
174
|
+
|
|
175
|
+
# Yields query result row by row, as Hash, using String keys
|
|
176
|
+
#
|
|
177
|
+
# @param the_query [String] Sql query to send to DB server.
|
|
178
|
+
# @param with_table_names [Boolean] if TrueClass, then table names are included in the hash keys.
|
|
179
|
+
# @raise [Mysql] passes on Mysql errors, freeing the result.
|
|
180
|
+
# @yieldparam [Hash] each result row
|
|
181
|
+
# @return [Array] If no block is given: of rows with hash keys
|
|
182
|
+
# @note @result and @affected_rows are also set via call to query().
|
|
183
|
+
def each_hash(the_query, with_table_names = false, &block)
|
|
184
|
+
begin
|
|
185
|
+
if with_table_names
|
|
186
|
+
# We have to build the hash ourselves, if we want table names included
|
|
187
|
+
query(the_query, { as: :array, cache_rows: false })
|
|
188
|
+
if @result != nil
|
|
189
|
+
fields = @result.fields
|
|
190
|
+
tables = @result.respond_to?(:tables) ? @result.tables : [] # My addition to mysql2 results.c
|
|
191
|
+
|
|
192
|
+
result = []
|
|
193
|
+
@result.each do |row|
|
|
194
|
+
hrow = {}
|
|
195
|
+
(0...row.length).each do |i|
|
|
196
|
+
field_name = tables[i].nil? ? fields[i] : "#{tables[i]}.#{fields[i]}"
|
|
197
|
+
hrow[field_name] = row[i]
|
|
198
|
+
end
|
|
199
|
+
yield hrow
|
|
200
|
+
result << hrow
|
|
201
|
+
end
|
|
202
|
+
return result
|
|
203
|
+
end
|
|
204
|
+
else
|
|
205
|
+
query(the_query, { as: :hash, cache_rows: false })
|
|
206
|
+
if @result != nil
|
|
207
|
+
if block_given?
|
|
208
|
+
@result.each(&block)
|
|
209
|
+
else
|
|
210
|
+
return @result.to_a
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
rescue Mysql2::Error => e
|
|
215
|
+
# puts "#{e.errno}: #{e.error}"
|
|
216
|
+
raise e
|
|
217
|
+
ensure
|
|
218
|
+
if block_given? && @result != nil
|
|
219
|
+
@result.free
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
alias query_hash each_hash
|
|
225
|
+
|
|
226
|
+
# Yields query result row by row, as Hash using Symbol keys, so can't have table names included.
|
|
227
|
+
# This can be used with keyword arguments. eg. each_sym { |key1:, key2:, ..., **rest_of_args| do something }
|
|
228
|
+
#
|
|
229
|
+
# @param the_query [String] Sql query to send to DB server.
|
|
230
|
+
# @raise [Mysql] passes on Mysql errors, freeing the result.
|
|
231
|
+
# @yieldparam [Hash] each result row
|
|
232
|
+
# @return [Array] If no block is given: of hashed rows with symbol keys.
|
|
233
|
+
# @note @result and @affected_rows are also set via call to query().
|
|
234
|
+
def each_sym(the_query, &block)
|
|
235
|
+
query(the_query, { symbolize_keys: true, as: :hash, cache_rows: false })
|
|
236
|
+
if @result != nil
|
|
237
|
+
if block_given?
|
|
238
|
+
@result.each(&block)
|
|
239
|
+
else
|
|
240
|
+
return @result.to_a
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
alias query_sym each_sym
|
|
246
|
+
|
|
247
|
+
# Yields query result row by row, as **Hash using Symbol keys, so can't have table names included.
|
|
248
|
+
# This can be used with keyword arguments. eg. each_sym { |key1:, key2:, ..., **rest_of_args| do something }
|
|
249
|
+
#
|
|
250
|
+
# @param the_query [String] Sql query to send to DB server.
|
|
251
|
+
# @raise [Mysql] passes on Mysql errors, freeing the result.
|
|
252
|
+
# @yieldparam [**Hash] each result row
|
|
253
|
+
# @return [Array] If no block is given: of hashed rows with symbol keys.
|
|
254
|
+
# @note @result and @affected_rows are also set via call to query().
|
|
255
|
+
def each_param(the_query)
|
|
256
|
+
query(the_query, { symbolize_keys: true, as: :hash, cache_rows: false })
|
|
257
|
+
if @result != nil
|
|
258
|
+
if block_given?
|
|
259
|
+
@result.each { |row| yield(**row) }
|
|
260
|
+
else
|
|
261
|
+
return @result.to_a
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
# Get the database field attributes from a query result.
|
|
267
|
+
#
|
|
268
|
+
# @return [Array][Mysql::Field] Array of field records
|
|
269
|
+
# @note mySQL2 doesn't expose this structure. Only parts of it.
|
|
270
|
+
def fetch_fields
|
|
271
|
+
fields = @result.fields
|
|
272
|
+
field_types = @result.field_types
|
|
273
|
+
tables = @result.respond_to?(:tables) ? @result.tables : [] # My addition to mysql2 results.c
|
|
274
|
+
fields_arr = []
|
|
275
|
+
(0...@result.fields.length).each do |i|
|
|
276
|
+
fields_arr[i] = MySQL_FIELD.new(
|
|
277
|
+
name: fields[i],
|
|
278
|
+
table: tables[i],
|
|
279
|
+
db: databases[i],
|
|
280
|
+
type: field_types[i]
|
|
281
|
+
)
|
|
282
|
+
end
|
|
283
|
+
return fields_arr
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
# Create WIKK::SQL instance and set up the mySQL connection, and Run a query on the DB server.
|
|
287
|
+
#
|
|
288
|
+
# @param db_config [Configuration] Configuration class, Hash, or any class with appropriate attr_readers.
|
|
289
|
+
# @param the_query [String] Sql query to send to DB server.
|
|
290
|
+
# @raise [Mysql] passes on Mysql errors, freeing the result.
|
|
291
|
+
# @yieldparam [Mysql::Result] @result and @affected_rows are also set.
|
|
292
|
+
# @return [Mysql::Result] @result and @affected_rows are also set.
|
|
293
|
+
def self.query(db_config, the_query)
|
|
294
|
+
self.connect db_config do |sql|
|
|
295
|
+
result = sql.query(the_query)
|
|
296
|
+
if block_given?
|
|
297
|
+
yield result
|
|
298
|
+
return sql.affected_rows
|
|
299
|
+
else
|
|
300
|
+
return result
|
|
301
|
+
end
|
|
302
|
+
end
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
# Create WIKK::SQL instance and set up the mySQL connection, and Run a query on the DB server.
|
|
306
|
+
# Yields query query results row by row, as Array
|
|
307
|
+
#
|
|
308
|
+
# @param db_config [Configuration] Configuration class, Hash, or any class with appropriate attr_readers.
|
|
309
|
+
# @param the_query [String] Sql query to send to DB server.
|
|
310
|
+
# @raise [Mysql] passes on Mysql errors, freeing the result.
|
|
311
|
+
# @yieldparam [Array] each result row
|
|
312
|
+
# @note @result and @affected_rows are also set via call to query().
|
|
313
|
+
def self.each_row(db_config, query, &block)
|
|
314
|
+
self.connect db_config do |sql|
|
|
315
|
+
if block_given?
|
|
316
|
+
sql.each_row(query, &block)
|
|
317
|
+
return sql.affected_rows
|
|
318
|
+
else
|
|
319
|
+
return sql.each_row(query)
|
|
320
|
+
end
|
|
321
|
+
end
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
# Create WIKK::SQL instance and set up the mySQL connection, and Run a query on the DB server.
|
|
325
|
+
# Yields query result row by row, as Hash, using String keys
|
|
326
|
+
#
|
|
327
|
+
# @param db_config [Configuration] Configuration class, Hash, or any class with appropriate attr_readers.
|
|
328
|
+
# @param the_query [String] Sql query to send to DB server.
|
|
329
|
+
# @param with_table_names [Boolean] if TrueClass, then table names are included in the hash keys.
|
|
330
|
+
# @raise [Mysql] passes on Mysql errors, freeing the result.
|
|
331
|
+
# @yieldparam [Hash] each result row
|
|
332
|
+
# @note @result and @affected_rows are also set via call to query().
|
|
333
|
+
def self.each_hash(db_config, query, with_table_names = false, &block)
|
|
334
|
+
self.connect( db_config ) do |sql|
|
|
335
|
+
if block_given?
|
|
336
|
+
sql.each_hash(query, with_table_names, &block)
|
|
337
|
+
return sql.affected_rows
|
|
338
|
+
else
|
|
339
|
+
return sql.each_hash(query, with_table_names)
|
|
340
|
+
end
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
# Create WIKK::SQL instance and set up the mySQL connection, and Run a query on the DB server.
|
|
345
|
+
# Yields query result row by row, as Hash using Symbol keys, so can't have table names included.
|
|
346
|
+
#
|
|
347
|
+
# @param db_config [Configuration] Configuration class, Hash, or any class with appropriate attr_readers.
|
|
348
|
+
# This can be used with keyword arguments. eg. each_sym { |key1:, key2:, ..., **rest_of_args| do something }
|
|
349
|
+
# @param the_query [String] Sql query to send to DB server.
|
|
350
|
+
# @raise [Mysql] passes on Mysql errors, freeing the result.
|
|
351
|
+
# @yieldparam [Hash] each result row
|
|
352
|
+
# @note @result and @affected_rows are also set via call to query().
|
|
353
|
+
def self.each_sym(db_config, query, &block)
|
|
354
|
+
self.connect( db_config ) do |sql|
|
|
355
|
+
if block_given?
|
|
356
|
+
sql.each_sym(query, &block)
|
|
357
|
+
return sql # May be useful to access the affected rows
|
|
358
|
+
else
|
|
359
|
+
return sql.each_sym(query)
|
|
360
|
+
end
|
|
361
|
+
end
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
# Create WIKK::SQL instance and set up the mySQL connection, and Run a query on the DB server.
|
|
365
|
+
# Yields query result row by row, as Hash using Symbol keys, so can't have table names included.
|
|
366
|
+
#
|
|
367
|
+
# @param db_config [Configuration] Configuration class, Hash, or any class with appropriate attr_readers.
|
|
368
|
+
# This can be used with keyword arguments. eg. each_sym { |key1:, key2:, ..., **rest_of_args| do something }
|
|
369
|
+
# @param the_query [String] Sql query to send to DB server.
|
|
370
|
+
# @raise [Mysql] passes on Mysql errors, freeing the result.
|
|
371
|
+
# @yieldparam [**Hash] for each result row, which can be passed to named args in a block
|
|
372
|
+
# @note @result and @affected_rows are also set via call to query().
|
|
373
|
+
def self.each_param(db_config, query, &block)
|
|
374
|
+
self.connect( db_config ) do |sql|
|
|
375
|
+
if block_given?
|
|
376
|
+
sql.each_param(query, &block)
|
|
377
|
+
return sql # May be useful to access the affected rows
|
|
378
|
+
else
|
|
379
|
+
return sql.each_sym(query)
|
|
380
|
+
end
|
|
381
|
+
end
|
|
382
|
+
end
|
|
383
|
+
end
|
|
384
|
+
end
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
require 'mysql'
|
|
2
|
+
|
|
3
|
+
# Provides common front end, even if we change the connector library
|
|
4
|
+
# Connector is ruby-mysql native ruby gem
|
|
5
|
+
module WIKK
|
|
6
|
+
# WIKK_SQL wrapper for ruby mysql gem.
|
|
7
|
+
# @attr_reader [Numeric] affected_rows the number of rows changed, deleted, or added.
|
|
8
|
+
# @attr_reader [Mysql::Result] result the last query's result
|
|
9
|
+
# @attr_reader [Mysql] my the DB connection descriptor
|
|
10
|
+
class SQL
|
|
11
|
+
attr_reader :affected_rows, :result, :my
|
|
12
|
+
|
|
13
|
+
# Create WIKK::SQL instance and set up the mySQL connection.
|
|
14
|
+
# @param db_config [Configuration] Configuration class, Hash, or any class with appropriate attr_readers.
|
|
15
|
+
# @yieldparam sql [WIKK_SQL] if a block is given.
|
|
16
|
+
# @return [NilClass] if block is given, and closes the mySQL connection.
|
|
17
|
+
# @return [WIKK_SQL] if no block is given, and caller must call sql.close
|
|
18
|
+
def self.connect(db_config)
|
|
19
|
+
sql = self.new # Create an instance of WIKK::SQL
|
|
20
|
+
sql.connect(db_config) # Connect to the database
|
|
21
|
+
if block_given?
|
|
22
|
+
yield sql # Yield the instance, so caller can access methods
|
|
23
|
+
return sql.close # Clean up at end of the callers block
|
|
24
|
+
else
|
|
25
|
+
return sql # Return new instance of WIKK::SQL
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Set up the mySQL connection.
|
|
30
|
+
#
|
|
31
|
+
# @param db_config [Configuration] Configuration class, Hash, or any class with appropriate attr_readers.
|
|
32
|
+
# @yieldparam [] if a block is given.
|
|
33
|
+
# @return [NilClass] if block is given, and closes the mySQL connection.
|
|
34
|
+
# @return [WIKK_SQL] if no block is given, and caller must call sql.close
|
|
35
|
+
def connect(db_config)
|
|
36
|
+
if db_config.instance_of?(Hash)
|
|
37
|
+
sym = db_config.transform_keys(& :to_sym )
|
|
38
|
+
db_config = Struct.new(*(k = sym.keys)).new(*sym.values_at(*k))
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
begin
|
|
42
|
+
@my = Mysql.new(db_config.host, db_config.dbuser, db_config.key, db_config.db )
|
|
43
|
+
rescue StandardError => e
|
|
44
|
+
@my = nil
|
|
45
|
+
raise e
|
|
46
|
+
end
|
|
47
|
+
raise Mysql::Error, 'Not Connected' if @my.nil?
|
|
48
|
+
|
|
49
|
+
# @@my.reconnect = true
|
|
50
|
+
if block_given?
|
|
51
|
+
yield
|
|
52
|
+
return close
|
|
53
|
+
end
|
|
54
|
+
return @my
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
alias open connect
|
|
58
|
+
|
|
59
|
+
# close the mySQL connection. Call only if connect was not given a block.
|
|
60
|
+
#
|
|
61
|
+
# @return [NilClass]
|
|
62
|
+
def close
|
|
63
|
+
@my.close if @my != nil
|
|
64
|
+
return (@my = nil)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Call underlying connector's escape of the query string
|
|
68
|
+
# @param query [String] The SQL query
|
|
69
|
+
# @return [String] The SQL query, escaped to remove vulnerabilities
|
|
70
|
+
def self.escape(query)
|
|
71
|
+
Mysql.escape_string(query)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Call underlying connector's escape of the query string
|
|
75
|
+
# @param query [String] The SQL query
|
|
76
|
+
# @return [String] The SQL query, escaped to remove vulnerabilities
|
|
77
|
+
def self.escape(query)
|
|
78
|
+
Mysql.escape_string(query)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Run a query on the DB server.
|
|
82
|
+
#
|
|
83
|
+
# @param the_query [String] Sql query to send to DB server.
|
|
84
|
+
# @raise [Mysql] passes on Mysql errors, freeing the result.
|
|
85
|
+
# @yieldparam [Mysql::Result] @result and @affected_rows are also set.
|
|
86
|
+
# @return [Mysql::Result] @result and @affected_rows are also set.
|
|
87
|
+
def query(the_query)
|
|
88
|
+
raise Mysql::Error, 'Not Connected' if @my.nil?
|
|
89
|
+
|
|
90
|
+
begin
|
|
91
|
+
if @result != nil
|
|
92
|
+
@result.free # Free any result we had left over from previous use.
|
|
93
|
+
@result = nil
|
|
94
|
+
end
|
|
95
|
+
@affected_rows = 0 # incase this query crashes and burns, this will have a value.
|
|
96
|
+
@result = @my.query(the_query)
|
|
97
|
+
@affected_rows = @my.affected_rows # This is non-zero for insert/delete/update of rows
|
|
98
|
+
if block_given?
|
|
99
|
+
yield @result
|
|
100
|
+
else
|
|
101
|
+
return @result
|
|
102
|
+
end
|
|
103
|
+
rescue Mysql::Error => e
|
|
104
|
+
if @result != nil
|
|
105
|
+
@result.free # Free any result we had left over from previous use.
|
|
106
|
+
@result = nil
|
|
107
|
+
end
|
|
108
|
+
raise e
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Perform a transaction in the passed block.
|
|
113
|
+
# RollBACK on error, otherwise COMMIT
|
|
114
|
+
#
|
|
115
|
+
# @yieldparam [] yields to block, where the queries are performed.
|
|
116
|
+
# @raise [Mysql] passes on Mysql errors, freeing the result.
|
|
117
|
+
def transaction
|
|
118
|
+
raise Mysql::Error, 'Not Connected' if @my.nil?
|
|
119
|
+
|
|
120
|
+
if block_given?
|
|
121
|
+
begin
|
|
122
|
+
@my.query('START TRANSACTION WITH CONSISTENT SNAPSHOT')
|
|
123
|
+
yield # Start executing the query black.
|
|
124
|
+
@my.query('COMMIT')
|
|
125
|
+
rescue Mysql::Error => e
|
|
126
|
+
@my.query('ROLLBACK')
|
|
127
|
+
raise e
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Yields query query results row by row, as Array
|
|
133
|
+
#
|
|
134
|
+
# @param the_query [String] Sql query to send to DB server.
|
|
135
|
+
# @raise [Mysql] passes on Mysql errors, freeing the result.
|
|
136
|
+
# @yieldparam [Array] each result row
|
|
137
|
+
# @return [Array] Array of rows
|
|
138
|
+
# @note @result and @affected_rows are also set via call to query().
|
|
139
|
+
def each_row(the_query, &block)
|
|
140
|
+
begin
|
|
141
|
+
query(the_query)
|
|
142
|
+
unless @result.nil?
|
|
143
|
+
@affected_rows = @result.num_rows # This is non-zero is we do a select, and get results.
|
|
144
|
+
if block_given?
|
|
145
|
+
@result.each(&block)
|
|
146
|
+
else
|
|
147
|
+
result = []
|
|
148
|
+
@result.each { |row| result << row }
|
|
149
|
+
return result
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
rescue Mysql::Error => e
|
|
153
|
+
# puts "#{e.errno}: #{e.error}"
|
|
154
|
+
raise e
|
|
155
|
+
ensure
|
|
156
|
+
if block_given? && @result != nil
|
|
157
|
+
@result.free
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
alias query_array each_row
|
|
163
|
+
|
|
164
|
+
# Yields query result row by row, as Hash, using String keys
|
|
165
|
+
#
|
|
166
|
+
# @param the_query [String] Sql query to send to DB server.
|
|
167
|
+
# @param with_table_names [Boolean] if TrueClass, then table names are included in the hash keys.
|
|
168
|
+
# @raise [Mysql] passes on Mysql errors, freeing the result.
|
|
169
|
+
# @yieldparam [Hash] each result row
|
|
170
|
+
# @return [Array] all rows, if no block is given
|
|
171
|
+
# @note @result and @affected_rows are also set via call to query().
|
|
172
|
+
def each_hash(the_query, with_table_names = false, &block)
|
|
173
|
+
begin
|
|
174
|
+
query(the_query)
|
|
175
|
+
unless @result.nil?
|
|
176
|
+
@affected_rows = @result.num_rows # This is non-zero is we do a select, and get results.
|
|
177
|
+
if block_given?
|
|
178
|
+
@result.each_hash(with_table_names, &block)
|
|
179
|
+
else
|
|
180
|
+
result = []
|
|
181
|
+
@result.each_hash(with_table_names) { |row| result << row }
|
|
182
|
+
return result
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
rescue Mysql::Error => e
|
|
186
|
+
# puts "#{e.errno}: #{e.error}"
|
|
187
|
+
raise e
|
|
188
|
+
ensure
|
|
189
|
+
if block_given? && @result != nil
|
|
190
|
+
@result.free
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
alias query_hash each_hash
|
|
196
|
+
|
|
197
|
+
# Yields query result row by row, as Hash using Symbol keys, so can't have table names included.
|
|
198
|
+
# This can be used with keyword arguments. eg. each_sym { |key1:, key2:, ..., **rest_of_args| do something }
|
|
199
|
+
#
|
|
200
|
+
# @param the_query [String] Sql query to send to DB server.
|
|
201
|
+
# @raise [Mysql] passes on Mysql errors, freeing the result.
|
|
202
|
+
# @yieldparam [Hash] each result row
|
|
203
|
+
# @return [Array] if no block is given, returns an Array of Hash'd rows, with symbol as the key
|
|
204
|
+
# @note @result and @affected_rows are also set via call to query().
|
|
205
|
+
def each_sym(the_query)
|
|
206
|
+
if block_given?
|
|
207
|
+
each_hash(the_query) { |row| yield row.transform_keys(& :to_sym ) }
|
|
208
|
+
else
|
|
209
|
+
result = []
|
|
210
|
+
each_hash(the_query) { |row| result << row.transform_keys(& :to_sym ) }
|
|
211
|
+
return result
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
alias query_sym each_sym
|
|
216
|
+
|
|
217
|
+
# Yields query result row by row, as **Hash using Symbol keys, so can't have table names included.
|
|
218
|
+
# This can be used with keyword arguments. eg. each_sym { |key1:, key2:, ..., **rest_of_args| do something }
|
|
219
|
+
#
|
|
220
|
+
# @param the_query [String] Sql query to send to DB server.
|
|
221
|
+
# @raise [Mysql] passes on Mysql errors, freeing the result.
|
|
222
|
+
# @yieldparam [**Hash] each result row
|
|
223
|
+
# @return [Array] if no block is given, returns an Array of Hash'd rows, with symbol as the key
|
|
224
|
+
# @note @result and @affected_rows are also set via call to query().
|
|
225
|
+
def each_param(the_query)
|
|
226
|
+
if block_given?
|
|
227
|
+
each_hash(the_query) { |row| yield(**row.transform_keys(& :to_sym )) }
|
|
228
|
+
else
|
|
229
|
+
result = []
|
|
230
|
+
each_hash(the_query) { |row| result << row.transform_keys(& :to_sym ) }
|
|
231
|
+
return result
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
# Get the database field attributes from a query result.
|
|
236
|
+
#
|
|
237
|
+
# @return [Array][Mysql::Field] Array of field records
|
|
238
|
+
# @note fields are name (of field), table (name), def, type, length, max_length, flags,decimals
|
|
239
|
+
def fetch_fields
|
|
240
|
+
@result.fetch_fields
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
# Create WIKK::SQL instance and set up the mySQL connection, and Run a query on the DB server.
|
|
244
|
+
#
|
|
245
|
+
# @param db_config [Configuration] Configuration class, Hash, or any class with appropriate attr_readers.
|
|
246
|
+
# @param the_query [String] Sql query to send to DB server.
|
|
247
|
+
# @raise [Mysql] passes on Mysql errors, freeing the result.
|
|
248
|
+
# @yieldparam [Mysql::Result] @result and @affected_rows are also set.
|
|
249
|
+
# @return [Mysql::Result] @result and @affected_rows are also set.
|
|
250
|
+
def self.query(db_config, the_query)
|
|
251
|
+
self.connect db_config do |sql|
|
|
252
|
+
result = sql.query(the_query)
|
|
253
|
+
if block_given?
|
|
254
|
+
yield result
|
|
255
|
+
return sql.affected_rows
|
|
256
|
+
else
|
|
257
|
+
return result
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
# Create WIKK::SQL instance and set up the mySQL connection, and Run a query on the DB server.
|
|
263
|
+
# Yields query query results row by row, as Array
|
|
264
|
+
#
|
|
265
|
+
# @param db_config [Configuration] Configuration class, Hash, or any class with appropriate attr_readers.
|
|
266
|
+
# @param the_query [String] Sql query to send to DB server.
|
|
267
|
+
# @raise [Mysql] passes on Mysql errors, freeing the result.
|
|
268
|
+
# @yieldparam [Array] each result row
|
|
269
|
+
# @note @result and @affected_rows are also set via call to query().
|
|
270
|
+
def self.each_row(db_config, query, &block)
|
|
271
|
+
self.connect db_config do |sql|
|
|
272
|
+
if block_given?
|
|
273
|
+
sql.each_row(query, &block)
|
|
274
|
+
return sql.affected_rows
|
|
275
|
+
else
|
|
276
|
+
return sql.each_row(query)
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
# Create WIKK::SQL instance and set up the mySQL connection, and Run a query on the DB server.
|
|
282
|
+
# Yields query result row by row, as Hash, using String keys
|
|
283
|
+
#
|
|
284
|
+
# @param db_config [Configuration] Configuration class, Hash, or any class with appropriate attr_readers.
|
|
285
|
+
# @param the_query [String] Sql query to send to DB server.
|
|
286
|
+
# @param with_table_names [Boolean] if TrueClass, then table names are included in the hash keys.
|
|
287
|
+
# @raise [Mysql] passes on Mysql errors, freeing the result.
|
|
288
|
+
# @yieldparam [Hash] each result row
|
|
289
|
+
# @note @result and @affected_rows are also set via call to query().
|
|
290
|
+
def self.each_hash(db_config, query, with_table_names = false, &block)
|
|
291
|
+
self.connect( db_config ) do |sql|
|
|
292
|
+
if block_given?
|
|
293
|
+
sql.each_hash(query, with_table_names, &block)
|
|
294
|
+
return sql.affected_rows
|
|
295
|
+
else
|
|
296
|
+
return sql.each_hash(query, with_table_names)
|
|
297
|
+
end
|
|
298
|
+
end
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
# Create WIKK::SQL instance and set up the mySQL connection, and Run a query on the DB server.
|
|
302
|
+
# Yields query result row by row, as Hash using Symbol keys, so can't have table names included.
|
|
303
|
+
#
|
|
304
|
+
# @param db_config [Configuration] Configuration class, Hash, or any class with appropriate attr_readers.
|
|
305
|
+
# This can be used with keyword arguments. eg. each_sym { |key1:, key2:, ..., **rest_of_args| do something }
|
|
306
|
+
# @param the_query [String] Sql query to send to DB server.
|
|
307
|
+
# @raise [Mysql] passes on Mysql errors, freeing the result.
|
|
308
|
+
# @yieldparam [Hash] each result row
|
|
309
|
+
# @note @result and @affected_rows are also set via call to query().
|
|
310
|
+
def self.each_sym(db_config, query, &block)
|
|
311
|
+
self.connect( db_config ) do |sql|
|
|
312
|
+
if block_given?
|
|
313
|
+
sql.each_sym(query, &block)
|
|
314
|
+
return sql # May be useful to access the affected rows
|
|
315
|
+
else
|
|
316
|
+
return sql.each_sym(query)
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
# Create WIKK::SQL instance and set up the mySQL connection, and Run a query on the DB server.
|
|
322
|
+
# Yields query result row by row, as Hash using Symbol keys, so can't have table names included.
|
|
323
|
+
#
|
|
324
|
+
# @param db_config [Configuration] Configuration class, Hash, or any class with appropriate attr_readers.
|
|
325
|
+
# This can be used with keyword arguments. eg. each_sym { |key1:, key2:, ..., **rest_of_args| do something }
|
|
326
|
+
# @param the_query [String] Sql query to send to DB server.
|
|
327
|
+
# @raise [Mysql] passes on Mysql errors, freeing the result.
|
|
328
|
+
# @yieldparam [**Hash] for each result row, which can be passed to named args in a block
|
|
329
|
+
# @note @result and @affected_rows are also set via call to query().
|
|
330
|
+
def self.each_param(db_config, query, &block)
|
|
331
|
+
self.connect( db_config ) do |sql|
|
|
332
|
+
if block_given?
|
|
333
|
+
sql.each_param(query, &block)
|
|
334
|
+
return sql # May be useful to access the affected rows
|
|
335
|
+
else
|
|
336
|
+
return sql.each_sym(query)
|
|
337
|
+
end
|
|
338
|
+
end
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
end
|
data/lib/wikk_sql.rb
CHANGED
|
@@ -1,262 +1,44 @@
|
|
|
1
|
+
# Provides common front end, even if we change the connector library
|
|
2
|
+
# Choice of ruby-mysql or mysql2 connectors
|
|
1
3
|
module WIKK
|
|
2
|
-
require 'mysql'
|
|
3
4
|
require 'pp'
|
|
4
5
|
require 'json'
|
|
5
6
|
|
|
6
|
-
#
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if block_given?
|
|
24
|
-
yield sql
|
|
25
|
-
return sql.close
|
|
26
|
-
else
|
|
27
|
-
return sql
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
#Set up the mySQL connection.
|
|
32
|
-
# @param db_config [Configuration] Configuration class, Hash, or any class with appropriate attr_readers.
|
|
33
|
-
# @yieldparam [] if a block is given.
|
|
34
|
-
# @return [NilClass] if block is given, and closes the mySQL connection.
|
|
35
|
-
# @return [WIKK_SQL] if no block is given, and caller must call sql.close
|
|
36
|
-
def connect(db_config)
|
|
37
|
-
if db_config.class == Hash
|
|
38
|
-
sym = db_config.each_with_object({}) { |(k,v),h| h[k.to_sym] = v }
|
|
39
|
-
db_config = Struct.new(*(k = sym.keys)).new(*sym.values_at(*k))
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
@my = Mysql::new(db_config.host, db_config.dbuser, db_config.key, db_config.db )
|
|
43
|
-
#@@my.reconnect = true
|
|
44
|
-
if block_given?
|
|
45
|
-
yield
|
|
46
|
-
return close
|
|
47
|
-
end
|
|
48
|
-
return @my
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
alias open connect
|
|
52
|
-
|
|
53
|
-
#close the mySQL connection. Call only if connect was not given a block.
|
|
54
|
-
# @return [NilClass]
|
|
55
|
-
def close
|
|
56
|
-
@my.close if @my != nil
|
|
57
|
-
return (@my = nil)
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
#Run a query on the DB server.
|
|
61
|
-
# @param the_query [String] Sql query to send to DB server.
|
|
62
|
-
# @raise [Mysql] passes on Mysql errors, freeing the result.
|
|
63
|
-
# @yieldparam [Mysql::Result] @result and @affected_rows are also set.
|
|
64
|
-
# @return [Mysql::Result] @result and @affected_rows are also set.
|
|
65
|
-
def query(the_query)
|
|
66
|
-
begin
|
|
67
|
-
if result != nil
|
|
68
|
-
@result.free #Free any result we had left over from previous use.
|
|
69
|
-
@result = nil
|
|
70
|
-
end
|
|
71
|
-
@affected_rows = 0 #incase this query crashes and burns, this will have a value.
|
|
72
|
-
@result = @my.query(the_query)
|
|
73
|
-
@affected_rows = @my.affected_rows #This is non-zero for insert/delete/update of rows
|
|
74
|
-
if block_given?
|
|
75
|
-
yield @result
|
|
76
|
-
else
|
|
77
|
-
return @result
|
|
78
|
-
end
|
|
79
|
-
rescue Mysql::Error => e
|
|
80
|
-
if result != nil
|
|
81
|
-
@result.free #Free any result we had left over from previous use.
|
|
82
|
-
@result = nil
|
|
83
|
-
end
|
|
84
|
-
raise e
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
#Perform a transaction in the passed block.
|
|
89
|
-
#RollBACK on error, otherwise COMMIT
|
|
90
|
-
# @yieldparam [] yields to block, where the queries are performed.
|
|
91
|
-
# @raise [Mysql] passes on Mysql errors, freeing the result.
|
|
92
|
-
def transaction
|
|
93
|
-
puts "transaction"
|
|
94
|
-
if block_given?
|
|
95
|
-
begin
|
|
96
|
-
@my.query("START TRANSACTION WITH CONSISTENT SNAPSHOT")
|
|
97
|
-
yield #Start executing the query black.
|
|
98
|
-
@my.query("COMMIT")
|
|
99
|
-
rescue Mysql::Error => e
|
|
100
|
-
@my.query("ROLLBACK")
|
|
101
|
-
raise e
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
#Yields query query results row by row, as Array
|
|
107
|
-
# @param the_query [String] Sql query to send to DB server.
|
|
108
|
-
# @raise [Mysql] passes on Mysql errors, freeing the result.
|
|
109
|
-
# @yieldparam [Array] each result row
|
|
110
|
-
# @note @result and @affected_rows are also set via call to query().
|
|
111
|
-
def each_row(the_query)
|
|
112
|
-
begin
|
|
113
|
-
query(the_query)
|
|
114
|
-
if @result != nil && block_given?
|
|
115
|
-
@affected_rows = @result.num_rows() #This is non-zero is we do a select, and get results.
|
|
116
|
-
@result.each do |row|
|
|
117
|
-
yield row #return one row at a time to the block
|
|
118
|
-
end
|
|
119
|
-
end
|
|
120
|
-
rescue Mysql::Error => e
|
|
121
|
-
#puts "#{e.errno}: #{e.error}"
|
|
122
|
-
raise e
|
|
123
|
-
ensure
|
|
124
|
-
if block_given? && @result != nil
|
|
125
|
-
@result.free
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
#Yields query result row by row, as Hash, using String keys
|
|
131
|
-
# @param the_query [String] Sql query to send to DB server.
|
|
132
|
-
# @param with_table_names [Boolean] if TrueClass, then table names are included in the hash keys.
|
|
133
|
-
# @raise [Mysql] passes on Mysql errors, freeing the result.
|
|
134
|
-
# @yieldparam [Hash] each result row
|
|
135
|
-
# @note @result and @affected_rows are also set via call to query().
|
|
136
|
-
def each_hash(the_query, with_table_names=false)
|
|
137
|
-
begin
|
|
138
|
-
query(the_query)
|
|
139
|
-
if @result != nil && block_given?
|
|
140
|
-
@affected_rows = @result.num_rows() #This is non-zero is we do a select, and get results.
|
|
141
|
-
@result.each_hash(with_table_names) do |row|
|
|
142
|
-
yield row
|
|
143
|
-
end
|
|
144
|
-
end
|
|
145
|
-
rescue Mysql::Error => e
|
|
146
|
-
#puts "#{e.errno}: #{e.error}"
|
|
147
|
-
raise e
|
|
148
|
-
ensure
|
|
149
|
-
if block_given? && @result != nil
|
|
150
|
-
@result.free
|
|
151
|
-
end
|
|
152
|
-
end
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
#Yields query result row by row, as Hash using Symbol keys, so can't have table names included.
|
|
156
|
-
#This can be used with keyword arguments. eg. each_sym { |key1:, key2:, ..., **rest_of_args| do something }
|
|
157
|
-
# @param the_query [String] Sql query to send to DB server.
|
|
158
|
-
# @raise [Mysql] passes on Mysql errors, freeing the result.
|
|
159
|
-
# @yieldparam [Hash] each result row
|
|
160
|
-
# @note @result and @affected_rows are also set via call to query().
|
|
161
|
-
def each_sym(the_query)
|
|
162
|
-
each_hash(the_query) do |row_hash|
|
|
163
|
-
yield row_hash.each_with_object({}) { |(k,v),h| h[k.to_sym] = v }
|
|
164
|
-
end
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
#Get the database field attributes from a query result.
|
|
168
|
-
# @yieldparam [Array][Mysql::Field] Array of field records
|
|
169
|
-
# @note fields are name (of field), table (name), def, type, length, max_length, flags,decimals
|
|
170
|
-
def fetch_fields
|
|
171
|
-
@result.fetch_fields
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
#Create WIKK::SQL instance and set up the mySQL connection, and Run a query on the DB server.
|
|
175
|
-
# @param db_config [Configuration] Configuration class, Hash, or any class with appropriate attr_readers.
|
|
176
|
-
# @param the_query [String] Sql query to send to DB server.
|
|
177
|
-
# @raise [Mysql] passes on Mysql errors, freeing the result.
|
|
178
|
-
# @yieldparam [Mysql::Result] @result and @affected_rows are also set.
|
|
179
|
-
# @return [Mysql::Result] @result and @affected_rows are also set.
|
|
180
|
-
def self.query(db_config, the_query)
|
|
181
|
-
sql = self.new
|
|
182
|
-
sql.open db_config
|
|
183
|
-
begin
|
|
184
|
-
result = sql.query(the_query)
|
|
185
|
-
if block_given?
|
|
186
|
-
yield result
|
|
187
|
-
end
|
|
188
|
-
ensure
|
|
189
|
-
sql.close
|
|
190
|
-
end
|
|
191
|
-
return result
|
|
192
|
-
end
|
|
7
|
+
# From mysql.h, but mostly blank for both our connectors
|
|
8
|
+
MySQL_FIELD = Struct.new(
|
|
9
|
+
:name, # Field name. Could be an 'as' alias
|
|
10
|
+
:org_name, # Field name, not aliased (for introspection)
|
|
11
|
+
:table, # Table name. Could be an 'as' alias
|
|
12
|
+
:org_table, # Table name, not aliased (for introspection)
|
|
13
|
+
:db, # database for table (useful for multitable queries)
|
|
14
|
+
:catalog, # catalog for table
|
|
15
|
+
:def, # Default value (if code wants to revert to the default)
|
|
16
|
+
:col_width, # Width of column (length in mysql.h, but length is taken in Ruby)
|
|
17
|
+
:max_length, # Max width for selected set
|
|
18
|
+
:flags, # Div flags
|
|
19
|
+
:decimals, # Number of decimals in field
|
|
20
|
+
:charsetnr, # Character set
|
|
21
|
+
:type, # Field type
|
|
22
|
+
:extension
|
|
23
|
+
)
|
|
193
24
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
# @param the_query [String] Sql query to send to DB server.
|
|
198
|
-
# @raise [Mysql] passes on Mysql errors, freeing the result.
|
|
199
|
-
# @yieldparam [Array] each result row
|
|
200
|
-
# @note @result and @affected_rows are also set via call to query().
|
|
201
|
-
def self.each_row(db_config, query)
|
|
202
|
-
sql = self.new
|
|
203
|
-
sql.open db_config
|
|
204
|
-
begin
|
|
205
|
-
if block_given?
|
|
206
|
-
sql.each_row(query) { |y| yield y }
|
|
207
|
-
end
|
|
208
|
-
ensure
|
|
209
|
-
sql.close
|
|
210
|
-
end
|
|
211
|
-
return sql
|
|
212
|
-
end
|
|
213
|
-
|
|
214
|
-
#Create WIKK::SQL instance and set up the mySQL connection, and Run a query on the DB server.
|
|
215
|
-
#Yields query result row by row, as Hash, using String keys
|
|
216
|
-
# @param db_config [Configuration] Configuration class, Hash, or any class with appropriate attr_readers.
|
|
217
|
-
# @param the_query [String] Sql query to send to DB server.
|
|
218
|
-
# @param with_table_names [Boolean] if TrueClass, then table names are included in the hash keys.
|
|
219
|
-
# @raise [Mysql] passes on Mysql errors, freeing the result.
|
|
220
|
-
# @yieldparam [Hash] each result row
|
|
221
|
-
# @note @result and @affected_rows are also set via call to query().
|
|
222
|
-
def self.each_hash(db_config, query, with_table_names=false)
|
|
223
|
-
sql = self.new
|
|
224
|
-
sql.open db_config
|
|
225
|
-
begin
|
|
226
|
-
if block_given?
|
|
227
|
-
sql.each_hash(query, with_table_names) do |res|
|
|
228
|
-
yield res
|
|
229
|
-
end
|
|
230
|
-
end
|
|
231
|
-
ensure
|
|
232
|
-
sql.close
|
|
233
|
-
end
|
|
234
|
-
return sql
|
|
235
|
-
end
|
|
25
|
+
class SQL
|
|
26
|
+
VERSION = '0.2.1'
|
|
27
|
+
end
|
|
236
28
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
yield **res
|
|
252
|
-
end
|
|
253
|
-
end
|
|
254
|
-
ensure
|
|
255
|
-
sql.close
|
|
256
|
-
end
|
|
257
|
-
return sql
|
|
258
|
-
end
|
|
29
|
+
# Prefer mysql2 over ruby-mysql, as it is faster
|
|
30
|
+
# Downside is, mysql2 doesn't expose field table names.
|
|
31
|
+
begin
|
|
32
|
+
Gem::Specification.find_by_name('mysql2')
|
|
33
|
+
rescue Gem::MissingSpecError
|
|
34
|
+
begin
|
|
35
|
+
Gem::Specification.find_by_name('ruby-mysql')
|
|
36
|
+
rescue Gem::MissingSpecError
|
|
37
|
+
raise Gem::MissingSpecError 'Need either mysql2 or ruby-mysql gems'
|
|
38
|
+
else
|
|
39
|
+
require_relative 'wikk_ruby_mysql.rb'
|
|
40
|
+
end
|
|
41
|
+
else
|
|
42
|
+
require_relative 'wikk_mysql2.rb'
|
|
259
43
|
end
|
|
260
44
|
end
|
|
261
|
-
|
|
262
|
-
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: wikk_sql
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1
|
|
4
|
+
version: 0.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Rob Burrowes
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2022-06-20 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: hoe-yard
|
|
@@ -16,29 +16,31 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: 0.1.
|
|
19
|
+
version: 0.1.3
|
|
20
20
|
type: :development
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - ">="
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: 0.1.
|
|
26
|
+
version: 0.1.3
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: hoe
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
31
|
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '3.
|
|
33
|
+
version: '3.23'
|
|
34
34
|
type: :development
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '3.
|
|
41
|
-
description:
|
|
40
|
+
version: '3.23'
|
|
41
|
+
description: |-
|
|
42
|
+
Wrappers around mysql gem.
|
|
43
|
+
Consolidation of bits of code from many of my projects, going back 10+ years, into a gem.
|
|
42
44
|
email:
|
|
43
45
|
- r.burrowes@auckland.ac.nz
|
|
44
46
|
executables: []
|
|
@@ -52,12 +54,14 @@ files:
|
|
|
52
54
|
- Manifest.txt
|
|
53
55
|
- README.md
|
|
54
56
|
- Rakefile
|
|
57
|
+
- lib/wikk_mysql2.rb
|
|
58
|
+
- lib/wikk_ruby_mysql.rb
|
|
55
59
|
- lib/wikk_sql.rb
|
|
56
|
-
homepage:
|
|
60
|
+
homepage: https://wikarekare.github.io/wikk_sql/
|
|
57
61
|
licenses:
|
|
58
62
|
- MIT
|
|
59
63
|
metadata: {}
|
|
60
|
-
post_install_message:
|
|
64
|
+
post_install_message:
|
|
61
65
|
rdoc_options:
|
|
62
66
|
- "--markup"
|
|
63
67
|
- markdown
|
|
@@ -78,9 +82,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
78
82
|
- !ruby/object:Gem::Version
|
|
79
83
|
version: '0'
|
|
80
84
|
requirements: []
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
signing_key:
|
|
85
|
+
rubygems_version: 3.2.22
|
|
86
|
+
signing_key:
|
|
84
87
|
specification_version: 4
|
|
85
|
-
summary:
|
|
88
|
+
summary: Wrappers around mysql gem
|
|
86
89
|
test_files: []
|