dohmysql 0.2.24 → 0.2.25

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