dohmysql 0.2.28 → 0.2.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ff75b9b6da2ff030b07b3d8572c1ebfaf82f2010
4
- data.tar.gz: 912527e0df0cd7814fe0ba443c90a29a06f0ff72
3
+ metadata.gz: 71dbf50aa43b65aab550b4d8489a072bc82df2cd
4
+ data.tar.gz: 1c736a76d25785dd5cd1851168f1bd39a869ff6f
5
5
  SHA512:
6
- metadata.gz: 228017615931e6e7b369703efc3b293cf6d62b3e6b0a129770b84a8616a7d7bf33939797a57ebc270c1c7e5c924bffdb1def2f726b5be89ac7432c3ec84e900f
7
- data.tar.gz: b38882a1b7ddf5e3b576ed349f76e6090dba122f7f3fd89c973485aa633b319223ec61fdab2e95e6a8a7240b82784acfcdccf94b662c20619476ffe770298e09
6
+ metadata.gz: 16ae0b567882ff00279319a515f0e6bb565b91ab8945611b4a44623f0422dc66185d3db33ab37e90df3866f6375d0d6a45634c2c576f8425c3a8653dc2c928f8
7
+ data.tar.gz: 8cd83b4d1d917e9202f653d4e98181b6fd3cd06ec11542b251e82206012528a141cb5f22539669dc6462e6dad9f2327f7a491abf97aa444609a830c9069f0b3b
@@ -19,12 +19,9 @@ class Handle
19
19
  def initialize(config)
20
20
  @config = config
21
21
  @testing_rollback = false
22
- log_config = @config.dup
23
22
  @config[:reconnect] = true if !@config.keys.include?(:reconnect)
24
- log_config.delete(:password)
25
- DohDb.logger.call('connection', "creating connection with config: #{log_config}")
26
- @mysqlh = Mysql2::Client.new(@config)
27
- DohDb.logger.call('connection', "new connection created: id #{@mysqlh.thread_id}")
23
+ @mysqlh = nil
24
+ reopen
28
25
  end
29
26
 
30
27
  def close
@@ -200,7 +197,7 @@ private
200
197
  @mysqlh.query(sqlstr)
201
198
  rescue Exception => excpt
202
199
  DohDb.logger.call('error', "caught exception #{excpt.message} during query: #{sqlstr}")
203
- close
200
+ reopen
204
201
  raise
205
202
  end
206
203
 
@@ -237,7 +234,6 @@ private
237
234
  insert("#{keyword} INTO #{table} #{keystr} VALUES #{valuestrs.join(",")}")
238
235
  end
239
236
 
240
-
241
237
  def get_row_builder(row_builder = nil)
242
238
  if row_builder.nil?
243
239
  TypedRowBuilder.new
@@ -255,6 +251,15 @@ private
255
251
  TypedRowBuilder.new(row_builder)
256
252
  end
257
253
  end
254
+
255
+ def reopen
256
+ close if !closed?
257
+ log_config = @config.dup
258
+ log_config.delete(:password)
259
+ DohDb.logger.call('connection', "creating connection with config: #{log_config}")
260
+ @mysqlh = Mysql2::Client.new(@config)
261
+ DohDb.logger.call('connection', "new connection created: id #{@mysqlh.thread_id}")
262
+ end
258
263
  end
259
264
 
260
265
  end
@@ -0,0 +1,257 @@
1
+ require 'mysql2'
2
+ require 'dohutil/array_to_hash'
3
+ require 'dohmysql/logger'
4
+ require 'dohmysql/error'
5
+ require 'dohmysql/typed_row_builder'
6
+ require 'dohmysql/writable_row'
7
+ require 'dohmysql/hash_row'
8
+ require 'dohmysql/smart_row'
9
+ require 'dohmysql/to_sql'
10
+ Mysql2::Client.default_query_options[:cast_booleans] = true
11
+
12
+ module DohDb
13
+
14
+ class Handle
15
+ attr_reader :config, :mysqlh
16
+
17
+ def initialize(config)
18
+ @config = config
19
+ @testing_rollback = false
20
+ log_config = @config.dup
21
+ @config[:reconnect] = true if !@config.keys.include?(:reconnect)
22
+ log_config.delete(:password)
23
+ DohDb.logger.call('connection', "creating connection with config: #{log_config}")
24
+ @mysqlh = Mysql2::Client.new(@config)
25
+ DohDb.logger.call('connection', "new connection created: id #{@mysqlh.thread_id}")
26
+ end
27
+
28
+ def close
29
+ unless closed?
30
+ begin
31
+ DohDb.logger.call('connection', "closing connection: id #{@mysqlh.thread_id}")
32
+ @mysqlh.close
33
+ ensure
34
+ @mysqlh = nil
35
+ end
36
+ end
37
+ end
38
+
39
+ def closed?
40
+ @mysqlh.nil?
41
+ end
42
+
43
+ def query(statement)
44
+ generic_query(statement)
45
+ retval = @mysqlh.affected_rows
46
+ DohDb.logger.call('result', "affected #{retval} rows")
47
+ retval
48
+ end
49
+
50
+ def update(statement)
51
+ generic_query(statement)
52
+ retval = @mysqlh.affected_rows
53
+ DohDb.logger.call('result', "updated #{retval} rows")
54
+ retval
55
+ end
56
+
57
+ def update_row(statement)
58
+ retval = update(statement)
59
+ raise UnexpectedQueryResult, "updated #{retval} rows; expected 1" unless retval == 1
60
+ retval
61
+ end
62
+
63
+ def update_hash(hash, table, primary_key_value, primary_key_name)
64
+ items = hash.keys.collect {|key| key + ' = ' + hash[key].to_sql}
65
+ query("UPDATE #{table} SET #{items.join(', ')} WHERE #{primary_key_name} = #{primary_key_value.to_sql}")
66
+ end
67
+
68
+ def insert(statement)
69
+ generic_query(statement)
70
+ retval = @mysqlh.last_id
71
+ DohDb.logger.call('result', "insert_id was #{retval}")
72
+ retval
73
+ end
74
+
75
+ def insert_hash(hash, table, quote_strings = true)
76
+ insert_hash_helper(hash, table, 'INSERT', quote_strings)
77
+ end
78
+
79
+ def insert_hashes(hashes, table, quote_strings = true)
80
+ insert_hashes_helper(hashes, table, 'INSERT', quote_strings)
81
+ end
82
+
83
+ def insert_ignore_hash(hash, table, quote_strings = true)
84
+ insert_hash_helper(hash, table, 'INSERT IGNORE', quote_strings)
85
+ end
86
+
87
+ def insert_ignore_hashes(hash, table, quote_strings = true)
88
+ insert_hashes_helper(hash, table, 'INSERT IGNORE', quote_strings)
89
+ end
90
+
91
+ def replace_hash(hash, table, quote_strings = true)
92
+ insert_hash_helper(hash, table, 'REPLACE', quote_strings)
93
+ end
94
+
95
+ # The most generic form of select.
96
+ # It calls to_s on the statement object to facilitate the use of sql builder objects.
97
+ def select(statement, row_builder = nil)
98
+ result_set = generic_query(statement)
99
+ DohDb.logger.call('result', "selected #{result_set.size} rows")
100
+ rows = get_row_builder(row_builder).build_rows(result_set)
101
+ rows
102
+ end
103
+
104
+ # Simple convenience wrapper around the generic select call.
105
+ # Throws an exception unless the result set is a single row.
106
+ # Returns the row selected.
107
+ def select_row(statement, row_builder = nil)
108
+ rows = select(statement, row_builder)
109
+ raise UnexpectedQueryResult, "selected #{rows.size} rows; expected 1" unless rows.size == 1
110
+ rows[0]
111
+ end
112
+
113
+ # Simple convenience wrapper around the generic select call.
114
+ # Throws an exception unless the result set is empty or a single row.
115
+ # Returns nil if the result set is empty, or the row selected.
116
+ def select_optional_row(statement, row_builder = nil)
117
+ rows = select(statement, row_builder)
118
+ raise UnexpectedQueryResult, "selected #{rows.size} rows; expected 0 or 1" if rows.size > 1
119
+ if rows.empty? then nil else rows[0] end
120
+ end
121
+
122
+ # Simple convenience wrapper around select_row.
123
+ # Returns the first (and typically, the only) field from the selected row.
124
+ def select_field(statement, row_builder = nil)
125
+ select_row(statement, row_builder).at(0)
126
+ end
127
+
128
+ # Simple convenience wrapper around select_optional_row.
129
+ # Returns the first (and typically, the only) field from the selected row, if any, or nil.
130
+ def select_optional_field(statement, row_builder = nil)
131
+ row = select_optional_row(statement, row_builder)
132
+ row && row.at(0)
133
+ end
134
+
135
+ # Rows in the result set must have 2 or more fields.
136
+ # If there are 2 fields, returns a hash where each key is the first field in the result set, and the value is the second field.
137
+ # If there are more than 2 fields, returns a hash where each key is the first field in the result set,
138
+ # and the value is the row itself, as a Hash, and without the field used as a key.
139
+ def select_transpose(statement, row_builder = nil)
140
+ rows = select(statement, row_builder)
141
+ return {} if rows.empty?
142
+ field_count = rows.first.size
143
+ if field_count < 2
144
+ raise UnexpectedQueryResult, "must select at least 2 fields in order to transpose"
145
+ elsif field_count == 2
146
+ Doh.array_to_hash(rows) { |row| [row.at(0), row.at(1)] }
147
+ else
148
+ key_field = rows.first.keys.first
149
+ Doh.array_to_hash(rows) do |row|
150
+ value = row.to_h
151
+ value.delete(key_field)
152
+ [row.at(0), value]
153
+ end
154
+ end
155
+ end
156
+
157
+ # Returns an array of arrays, where the individual arrays contain just the values from each database row -- they lack field names.
158
+ def select_values(statement, row_builder = nil)
159
+ select(statement, row_builder).collect { |row| row.values }
160
+ end
161
+
162
+ # Returns an array of the first (and typically, the only) field of every row in the result set.
163
+ def select_list(statement, row_builder = nil)
164
+ select(statement, row_builder).collect { |row| row.at(0) }
165
+ end
166
+
167
+ def transaction
168
+ query("START TRANSACTION")
169
+ need_rollback = true
170
+ begin
171
+ retval = yield(self)
172
+ if !@testing_rollback
173
+ query("COMMIT")
174
+ need_rollback = false
175
+ end
176
+ ensure
177
+ query("ROLLBACK") if need_rollback
178
+ end
179
+ retval
180
+ end
181
+
182
+ def test_transaction_rollback
183
+ begin
184
+ @testing_rollback = true
185
+ yield(self)
186
+ ensure
187
+ @testing_rollback = false
188
+ end
189
+ end
190
+ private
191
+ def generic_query(statement)
192
+ sqlstr = statement.to_s
193
+ DohDb.logger.call('query', sqlstr)
194
+ @mysqlh.query(sqlstr)
195
+ rescue Exception => excpt
196
+ DohDb.logger.call('error', "caught exception #{excpt.message} during query: #{sqlstr}")
197
+ close
198
+ raise
199
+ end
200
+
201
+ def get_key_insert_str(keys)
202
+ "(`#{keys.join('`,`')}`)"
203
+ end
204
+
205
+ def insert_hash_helper(hash, table, keyword, quote_strings)
206
+ names = []
207
+ values = []
208
+ hash.each_pair do |key, value|
209
+ names.push(key)
210
+ values.push(if quote_strings || !value.is_a?(String) then value.to_sql else value end)
211
+ end
212
+
213
+ insert("#{keyword} INTO #{table} (`#{names.join('`,`')}`) VALUES (#{values.join(',')})")
214
+ end
215
+
216
+ def insert_hashes_helper(hashes, table, keyword, quote_strings)
217
+ <<<<<<< HEAD:lib/dohmysql/handle.rb
218
+ return if hashes.empty?
219
+
220
+ =======
221
+ >>>>>>> implement insert_hashes, mostly not-sharing with insert_hash for speed (3% or so decrease on unit test speeds when I had them shared):lib/doh/mysql/handle.rb
222
+ valuestrs = []
223
+ keys = hashes[0].keys
224
+ keystr = get_key_insert_str(keys)
225
+ hashes.each do |hash|
226
+ values = []
227
+ keys.each do |key|
228
+ value = hash[key]
229
+ values.push(if quote_strings || !value.is_a?(String) then value.to_sql else value end)
230
+ end
231
+ valuestrs.push("(#{values.join(',')})")
232
+ end
233
+
234
+ insert("#{keyword} INTO #{table} #{keystr} VALUES #{valuestrs.join(",")}")
235
+ end
236
+
237
+
238
+ def get_row_builder(row_builder = nil)
239
+ if row_builder.nil?
240
+ TypedRowBuilder.new
241
+ elsif row_builder == :read
242
+ TypedRowBuilder.new(ReadOnlyRow)
243
+ elsif row_builder == :hash
244
+ TypedRowBuilder.new(HashRow)
245
+ elsif row_builder == :write
246
+ TypedRowBuilder.new(WritableRow)
247
+ elsif row_builder == :smart
248
+ TypedRowBuilder.new(SmartRow)
249
+ elsif row_builder.respond_to?('build_rows')
250
+ row_builder
251
+ else
252
+ TypedRowBuilder.new(row_builder)
253
+ end
254
+ end
255
+ end
256
+
257
+ end
data/test/handle.dt.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require_relative 'helpers'
2
2
  require 'dohmysql/handle'
3
+ require 'timeout'
3
4
 
4
5
  module DohDb
5
6
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dohmysql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.28
4
+ version: 0.2.29
5
5
  platform: ruby
6
6
  authors:
7
7
  - Makani Mason
@@ -31,28 +31,28 @@ dependencies:
31
31
  requirements:
32
32
  - - '>='
33
33
  - !ruby/object:Gem::Version
34
- version: 0.2.14
34
+ version: 0.2.15
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - '>='
40
40
  - !ruby/object:Gem::Version
41
- version: 0.2.14
41
+ version: 0.2.15
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: dohlog
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
46
  - - '>='
47
47
  - !ruby/object:Gem::Version
48
- version: 0.2.3
48
+ version: 0.2.4
49
49
  type: :runtime
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
53
  - - '>='
54
54
  - !ruby/object:Gem::Version
55
- version: 0.2.3
55
+ version: 0.2.4
56
56
  - !ruby/object:Gem::Dependency
57
57
  name: mysql2
58
58
  requirement: !ruby/object:Gem::Requirement
@@ -73,28 +73,28 @@ dependencies:
73
73
  requirements:
74
74
  - - '>='
75
75
  - !ruby/object:Gem::Version
76
- version: 0.1.13
76
+ version: 0.1.14
77
77
  type: :runtime
78
78
  prerelease: false
79
79
  version_requirements: !ruby/object:Gem::Requirement
80
80
  requirements:
81
81
  - - '>='
82
82
  - !ruby/object:Gem::Version
83
- version: 0.1.13
83
+ version: 0.1.14
84
84
  - !ruby/object:Gem::Dependency
85
85
  name: dohtest
86
86
  requirement: !ruby/object:Gem::Requirement
87
87
  requirements:
88
88
  - - '>='
89
89
  - !ruby/object:Gem::Version
90
- version: 0.1.19
90
+ version: 0.1.24
91
91
  type: :development
92
92
  prerelease: false
93
93
  version_requirements: !ruby/object:Gem::Requirement
94
94
  requirements:
95
95
  - - '>='
96
96
  - !ruby/object:Gem::Version
97
- version: 0.1.19
97
+ version: 0.1.24
98
98
  description: wrapper classes around low level mysql gem to provide a better interface
99
99
  email:
100
100
  - devinfo@atpsoft.com
@@ -118,6 +118,7 @@ files:
118
118
  - lib/dohmysql/error.rb
119
119
  - lib/dohmysql/file_util.rb
120
120
  - lib/dohmysql/handle.rb
121
+ - lib/dohmysql/handle.rb.orig
121
122
  - lib/dohmysql/hash_row.rb
122
123
  - lib/dohmysql/load_sql.rb
123
124
  - lib/dohmysql/logger.rb
@@ -162,7 +163,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
162
163
  version: '0'
163
164
  requirements: []
164
165
  rubyforge_project:
165
- rubygems_version: 2.0.3
166
+ rubygems_version: 2.0.2
166
167
  signing_key:
167
168
  specification_version: 4
168
169
  summary: friendly mysql client interface