dohmysql 0.2.24 → 0.2.25

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1490c3c56af4f3950d52ae3401ac2c08f4f41c16
4
+ data.tar.gz: 29eaa21516dbcc06f66d9a0802761a634bda31d3
5
+ SHA512:
6
+ metadata.gz: 27c4010a82bc5cfc5b7fcb8e67ab5ade62cf70744df5d8a79c237de58ce194dee279801ce83f61f504144e16992944c7b76c8b434269b942f02bf6fbc37df61e
7
+ data.tar.gz: 35ee860c5f4d64a5aa4fe93c4c472ee74c763671f2ab171bb744678b17d326755bad23f3e8ce52595bd7f39d358079d2253c8ee1cee90d727af7dce65192200d
@@ -11,7 +11,7 @@ def self.today
11
11
  end
12
12
 
13
13
  def self.now
14
- retval = DateTime.zow
14
+ retval = DateTime.now
15
15
  def retval.to_sql
16
16
  'NOW()'
17
17
  end
@@ -8,6 +8,8 @@ require 'dohmysql/hash_row'
8
8
  require 'dohmysql/smart_row'
9
9
  require 'dohmysql/to_sql'
10
10
  Mysql2::Client.default_query_options[:cast_booleans] = true
11
+ Mysql2::Client.default_query_options[:database_timezone] = :local
12
+ Mysql2::Client.default_query_options[:application_timezone] = :local
11
13
 
12
14
  module DohDb
13
15
 
@@ -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
@@ -52,8 +52,14 @@ class Test_Handle < DohTest::TestGroup
52
52
  dbh = get_dbh
53
53
  dbh.query("CREATE TEMPORARY TABLE #{tbl} (value INT KEY)")
54
54
  hash1 = {'value' => 1}
55
+ hash2 = {'value' => 2}
56
+ hash3 = {'value' => 3}
57
+ hash4 = {'value' => 4}
55
58
  assert_equal(0, dbh.insert_hash(hash1, tbl))
56
59
  assert_equal(0, dbh.insert_ignore_hash(hash1, tbl))
60
+ assert_equal(1, dbh.select_field("SELECT COUNT(*) from #{tbl}"))
61
+ assert_equal(0, dbh.insert_hashes([hash2, hash3, hash4], tbl))
62
+ assert_equal(4, dbh.select_field("SELECT COUNT(*) from #{tbl}"))
57
63
  assert_raises(Mysql2::Error) { dbh.insert_hash(hash1, tbl) }
58
64
  end
59
65
 
@@ -1,13 +1,11 @@
1
1
  require_relative 'helpers'
2
2
  require 'mysql2'
3
+ require 'dohutil/core_ext/date'
3
4
 
4
5
  module DohDb
5
6
 
6
7
  class Test_typecasting < DohTest::TestGroup
7
8
  def test_stuff
8
- Mysql2::Client.default_query_options[:database_timezone] = :utc
9
- Mysql2::Client.default_query_options[:application_timezone] = :utc
10
-
11
9
  dbh = get_dbh
12
10
  dbh.query("CREATE TEMPORARY TABLE #{tbl} (char_field CHAR(1) NOT NULL, int_field INT, bool_field TINYINT(1), date_field DATE, datetime_field DATETIME, decimal_field DECIMAL(7,2))")
13
11
  dbh.insert("INSERT INTO #{tbl} SET char_field = 'c', int_field = 5, bool_field = 1, date_field = '2012-02-20', datetime_field = '2012-02-20 21:06:00', decimal_field = 54.12")
@@ -16,7 +14,7 @@ class Test_typecasting < DohTest::TestGroup
16
14
  assert_equal(5, row['int_field'])
17
15
  assert_equal(true, row['bool_field'])
18
16
  assert_equal(Date.new(2012,2,20), row['date_field'])
19
- assert_equal(DateTime.new(2012,2,20, 21, 6, 0), row['datetime_field'])
17
+ assert_equal(DateTime.local(2012,2,20, 21, 6, 0), row['datetime_field'])
20
18
  assert_equal(BigDecimal('54.12'), row['decimal_field'])
21
19
  end
22
20
  end
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dohmysql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.24
5
- prerelease:
4
+ version: 0.2.25
6
5
  platform: ruby
7
6
  authors:
8
7
  - Makani Mason
@@ -10,102 +9,90 @@ authors:
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2013-05-22 00:00:00.000000000 Z
12
+ date: 2013-06-12 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: dohroot
17
16
  requirement: !ruby/object:Gem::Requirement
18
- none: false
19
17
  requirements:
20
- - - ! '>='
18
+ - - '>='
21
19
  - !ruby/object:Gem::Version
22
20
  version: 0.1.2
23
21
  type: :runtime
24
22
  prerelease: false
25
23
  version_requirements: !ruby/object:Gem::Requirement
26
- none: false
27
24
  requirements:
28
- - - ! '>='
25
+ - - '>='
29
26
  - !ruby/object:Gem::Version
30
27
  version: 0.1.2
31
28
  - !ruby/object:Gem::Dependency
32
29
  name: dohutil
33
30
  requirement: !ruby/object:Gem::Requirement
34
- none: false
35
31
  requirements:
36
- - - ! '>='
32
+ - - '>='
37
33
  - !ruby/object:Gem::Version
38
34
  version: 0.2.11
39
35
  type: :runtime
40
36
  prerelease: false
41
37
  version_requirements: !ruby/object:Gem::Requirement
42
- none: false
43
38
  requirements:
44
- - - ! '>='
39
+ - - '>='
45
40
  - !ruby/object:Gem::Version
46
41
  version: 0.2.11
47
42
  - !ruby/object:Gem::Dependency
48
43
  name: dohlog
49
44
  requirement: !ruby/object:Gem::Requirement
50
- none: false
51
45
  requirements:
52
- - - ! '>='
46
+ - - '>='
53
47
  - !ruby/object:Gem::Version
54
48
  version: 0.2.1
55
49
  type: :runtime
56
50
  prerelease: false
57
51
  version_requirements: !ruby/object:Gem::Requirement
58
- none: false
59
52
  requirements:
60
- - - ! '>='
53
+ - - '>='
61
54
  - !ruby/object:Gem::Version
62
55
  version: 0.2.1
63
56
  - !ruby/object:Gem::Dependency
64
57
  name: mysql2
65
58
  requirement: !ruby/object:Gem::Requirement
66
- none: false
67
59
  requirements:
68
- - - ! '>='
60
+ - - '>='
69
61
  - !ruby/object:Gem::Version
70
62
  version: 0.3.11
71
63
  type: :runtime
72
64
  prerelease: false
73
65
  version_requirements: !ruby/object:Gem::Requirement
74
- none: false
75
66
  requirements:
76
- - - ! '>='
67
+ - - '>='
77
68
  - !ruby/object:Gem::Version
78
69
  version: 0.3.11
79
70
  - !ruby/object:Gem::Dependency
80
71
  name: sqlstmt
81
72
  requirement: !ruby/object:Gem::Requirement
82
- none: false
83
73
  requirements:
84
- - - ! '>='
74
+ - - '>='
85
75
  - !ruby/object:Gem::Version
86
76
  version: 0.1.11
87
77
  type: :runtime
88
78
  prerelease: false
89
79
  version_requirements: !ruby/object:Gem::Requirement
90
- none: false
91
80
  requirements:
92
- - - ! '>='
81
+ - - '>='
93
82
  - !ruby/object:Gem::Version
94
83
  version: 0.1.11
95
84
  - !ruby/object:Gem::Dependency
96
85
  name: dohtest
97
86
  requirement: !ruby/object:Gem::Requirement
98
- none: false
99
87
  requirements:
100
- - - ! '>='
88
+ - - '>='
101
89
  - !ruby/object:Gem::Version
102
90
  version: 0.1.19
103
91
  type: :development
104
92
  prerelease: false
105
93
  version_requirements: !ruby/object:Gem::Requirement
106
- none: false
107
94
  requirements:
108
- - - ! '>='
95
+ - - '>='
109
96
  - !ruby/object:Gem::Version
110
97
  version: 0.1.19
111
98
  description: wrapper classes around low level mysql gem to provide a better interface
@@ -120,6 +107,7 @@ extra_rdoc_files:
120
107
  files:
121
108
  - bin/makedb
122
109
  - bin/migrate
110
+ - lib/dohmysql.rb
123
111
  - lib/dohmysql/abstract_row.rb
124
112
  - lib/dohmysql/cache_connector.rb
125
113
  - lib/dohmysql/connector_instance.rb
@@ -130,6 +118,7 @@ files:
130
118
  - lib/dohmysql/error.rb
131
119
  - lib/dohmysql/file_util.rb
132
120
  - lib/dohmysql/handle.rb
121
+ - lib/dohmysql/handle.rb.orig
133
122
  - lib/dohmysql/hash_row.rb
134
123
  - lib/dohmysql/load_sql.rb
135
124
  - lib/dohmysql/logger.rb
@@ -143,7 +132,6 @@ files:
143
132
  - lib/dohmysql/to_sql.rb
144
133
  - lib/dohmysql/typed_row_builder.rb
145
134
  - lib/dohmysql/writable_row.rb
146
- - lib/dohmysql.rb
147
135
  - test/cache_connector.dt.rb
148
136
  - test/connector_instance.dt.rb
149
137
  - test/db_date.dt.rb
@@ -158,27 +146,26 @@ files:
158
146
  homepage: https://github.com/atpsoft/dohmysql
159
147
  licenses:
160
148
  - MIT
149
+ metadata: {}
161
150
  post_install_message:
162
151
  rdoc_options: []
163
152
  require_paths:
164
153
  - lib
165
154
  required_ruby_version: !ruby/object:Gem::Requirement
166
- none: false
167
155
  requirements:
168
- - - ! '>='
156
+ - - '>='
169
157
  - !ruby/object:Gem::Version
170
158
  version: 1.9.3
171
159
  required_rubygems_version: !ruby/object:Gem::Requirement
172
- none: false
173
160
  requirements:
174
- - - ! '>='
161
+ - - '>='
175
162
  - !ruby/object:Gem::Version
176
163
  version: '0'
177
164
  requirements: []
178
165
  rubyforge_project:
179
- rubygems_version: 1.8.25
166
+ rubygems_version: 2.0.2
180
167
  signing_key:
181
- specification_version: 3
168
+ specification_version: 4
182
169
  summary: friendly mysql client interface
183
170
  test_files:
184
171
  - test/cache_connector.dt.rb