mysql2wrapper 0.0.1 → 0.0.2
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.
- data/.gitignore +2 -0
- data/Gemfile.lock +1 -5
- data/README.md +5 -1
- data/example/sample.rb +32 -18
- data/example/sample_table_information.rb +40 -0
- data/lib/mysql2wrapper.rb +1 -0
- data/lib/mysql2wrapper/client.rb +136 -21
- data/lib/mysql2wrapper/core_ext.rb +17 -0
- data/lib/mysql2wrapper/version.rb +1 -1
- data/test/sample_datas/image.jpeg +0 -0
- data/test/test.rb +268 -20
- metadata +6 -2
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,17 +1,13 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
mysql2wrapper (0.0.
|
5
|
-
batchbase (= 0.0.2)
|
4
|
+
mysql2wrapper (0.0.2)
|
6
5
|
mysql2 (= 0.3.11)
|
7
6
|
|
8
7
|
GEM
|
9
8
|
remote: http://rubygems.org/
|
10
9
|
specs:
|
11
|
-
batchbase (0.0.2)
|
12
|
-
sys-proctable (= 0.9.1)
|
13
10
|
mysql2 (0.3.11)
|
14
|
-
sys-proctable (0.9.1)
|
15
11
|
|
16
12
|
PLATFORMS
|
17
13
|
ruby
|
data/README.md
CHANGED
data/example/sample.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'mysql2wrapper'
|
3
3
|
require 'logger'
|
4
|
+
require 'pp'
|
4
5
|
|
5
6
|
#
|
6
7
|
# HACKME サンプルをちょっとはマシに書く、、、、
|
@@ -21,10 +22,19 @@ client = Mysql2wrapper::Client.new(db_config,logger)
|
|
21
22
|
#client = Mysql2wrapper::Client.new(db_config,nil)
|
22
23
|
|
23
24
|
query = '
|
24
|
-
DROP TABLE IF EXISTS `
|
25
|
+
DROP TABLE IF EXISTS `test01`'
|
25
26
|
client.query query
|
26
27
|
query = '
|
27
|
-
CREATE TABLE IF NOT EXISTS `
|
28
|
+
CREATE TABLE IF NOT EXISTS `test01` (
|
29
|
+
`id` int(11) NOT NULL auto_increment,
|
30
|
+
`value1` int(11) NOT NULL,
|
31
|
+
`created_at` datetime NOT NULL,
|
32
|
+
`updated_at` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
|
33
|
+
PRIMARY KEY (`id`)
|
34
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8;'
|
35
|
+
client.query query
|
36
|
+
query = '
|
37
|
+
CREATE TABLE IF NOT EXISTS `test02` (
|
28
38
|
`id` int(11) NOT NULL auto_increment,
|
29
39
|
`value1` int(11) NOT NULL,
|
30
40
|
`created_at` datetime NOT NULL,
|
@@ -33,22 +43,24 @@ CREATE TABLE IF NOT EXISTS `hoges` (
|
|
33
43
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;'
|
34
44
|
client.query query
|
35
45
|
|
36
|
-
|
37
|
-
|
38
|
-
logger.info "
|
46
|
+
p client.tables
|
47
|
+
|
48
|
+
logger.info "test01 has #{client.count 'test01'}rows"
|
49
|
+
client.query "INSERT INTO test01 (value1,created_at)VALUES(#{Time.now.to_i},NOW())"
|
50
|
+
logger.info "test01 has #{client.count 'test01'}rows"
|
39
51
|
|
40
52
|
begin
|
41
53
|
# トランザクションはブロックを渡す(ARと同じく)
|
42
54
|
client.transaction do
|
43
|
-
logger.info "
|
44
|
-
client.query "INSERT INTO
|
55
|
+
logger.info "test01 has #{client.count 'test01'}rows"
|
56
|
+
client.query "INSERT INTO test01 (value1,created_at)VALUES(#{Time.now.to_i},NOW())"
|
45
57
|
client.query query
|
46
|
-
logger.info "
|
58
|
+
logger.info "test01 has #{client.count 'test01'}rows"
|
47
59
|
raise 'error' # call ROLLBACK
|
48
60
|
end
|
49
61
|
rescue
|
50
62
|
end
|
51
|
-
logger.info "
|
63
|
+
logger.info "test01 has #{client.count 'test01'}rows"
|
52
64
|
|
53
65
|
# ハッシュを引数にしたインサートの発行
|
54
66
|
@i = 0
|
@@ -56,22 +68,24 @@ hash = {
|
|
56
68
|
:value1=>proc{@i+=1}, # procを引数にもできる
|
57
69
|
:created_at=>'now()'.to_func
|
58
70
|
}
|
59
|
-
client.insert('
|
71
|
+
client.insert('test01',hash)
|
60
72
|
logger.info "affected_rows:#{client.affected_rows}"
|
61
|
-
logger.info "
|
73
|
+
logger.info "test01 has #{client.count 'test01'}rows"
|
62
74
|
|
63
75
|
# 配列を引数にしたインサートの発行
|
64
76
|
ar = []
|
65
77
|
20.times{ar << hash}
|
66
|
-
client.insert('
|
78
|
+
client.insert('test01',ar)
|
67
79
|
logger.info "affected_rows:#{client.affected_rows}" # Client#affected_rowsでマルチプルインサートのトータルインサート数が取れる
|
68
|
-
logger.info "
|
80
|
+
logger.info "test01 has #{client.count 'test01'}rows"
|
69
81
|
|
70
82
|
# ハッシュを引数にしたアップデート
|
71
|
-
client.update '
|
72
|
-
logger.info "
|
83
|
+
client.update 'test01',{:value1=>3},'id = 1'
|
84
|
+
logger.info "test01 has #{client.count 'test01'}rows"
|
73
85
|
# 全行アップデートをしたなら第三引数でMysql2wrapper::Client::UpdateAllClassを引数にしないとダメ
|
74
|
-
client.update '
|
86
|
+
client.update 'test01',{:value1=>3},Mysql2wrapper::Client::UpdateAllClass
|
75
87
|
# clientインスタンスにショートカットあり
|
76
|
-
client.update '
|
77
|
-
logger.info "
|
88
|
+
client.update 'test01',{:value1=>4},client.update_all_flag
|
89
|
+
logger.info "test01 has #{client.count 'test01'}rows"
|
90
|
+
|
91
|
+
pp client.table_informations
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'mysql2wrapper'
|
3
|
+
require 'logger'
|
4
|
+
require 'pp'
|
5
|
+
|
6
|
+
#
|
7
|
+
# データベース内のテーブル情報を所定の書式で出力サンプル
|
8
|
+
#
|
9
|
+
|
10
|
+
logger = Logger.new(STDOUT)
|
11
|
+
# フォーマッターを変える
|
12
|
+
#logger.formatter = Kanamei::LogFormatter.formatter
|
13
|
+
db_yml_path = File::dirname(__FILE__) + '/../config/database.yml'
|
14
|
+
logger.info db_yml_path
|
15
|
+
|
16
|
+
# 第3引数は複数DB接続が無いならば指定不要
|
17
|
+
db_config = Mysql2wrapper::Client.config_from_yml(db_yml_path,'test')
|
18
|
+
|
19
|
+
client = Mysql2wrapper::Client.new(db_config,logger)
|
20
|
+
# ログ出力しないなら第二引数をnilで
|
21
|
+
#client = Mysql2wrapper::Client.new(db_config,nil)
|
22
|
+
|
23
|
+
client.table_informations.each do |table|
|
24
|
+
puts "/*"
|
25
|
+
puts "[table]"
|
26
|
+
puts table['TABLE_NAME']
|
27
|
+
puts table['TABLE_COMMENT']
|
28
|
+
puts "[columns]"
|
29
|
+
table['COLUMNS'].each do |col|
|
30
|
+
puts "#{col['COLUMN_NAME']}:#{col['COLUMN_COMMENT']}"
|
31
|
+
end
|
32
|
+
puts "[indexes]"
|
33
|
+
table['INDEXES'].each do |col|
|
34
|
+
puts "#{col['INDEX_NAME']}:#{col['INDEX_COMMENT']}"
|
35
|
+
end
|
36
|
+
puts "[history]"
|
37
|
+
puts "*/"
|
38
|
+
puts table['CREATE TABLE']
|
39
|
+
end
|
40
|
+
|
data/lib/mysql2wrapper.rb
CHANGED
data/lib/mysql2wrapper/client.rb
CHANGED
@@ -4,7 +4,7 @@ require 'yaml'
|
|
4
4
|
require 'mysql2'
|
5
5
|
|
6
6
|
class Mysql2wrapper::Client
|
7
|
-
attr_accessor :config, :client, :logger
|
7
|
+
attr_accessor :config, :client, :logger, :last_query
|
8
8
|
attr_reader :affected_rows
|
9
9
|
|
10
10
|
# 全行更新用のフラグ表現クラス
|
@@ -19,7 +19,12 @@ class Mysql2wrapper::Client
|
|
19
19
|
def initialize(config,_logger=Logger.new(STDOUT))
|
20
20
|
self.logger = _logger
|
21
21
|
if self.logger
|
22
|
-
|
22
|
+
# TODO パスワードの隠し
|
23
|
+
config_c = config.clone
|
24
|
+
if config_c[:password].present?
|
25
|
+
config_c[:password] = '****'
|
26
|
+
end
|
27
|
+
self.logger.info "mysql2 client created with #{config_c.inspect}"
|
23
28
|
end
|
24
29
|
self.client = Mysql2::Client.new(config)
|
25
30
|
self.config = config
|
@@ -52,15 +57,36 @@ class Mysql2wrapper::Client
|
|
52
57
|
"#{self.config.inspect}\n#{self.client.pretty_inspect}"
|
53
58
|
end
|
54
59
|
|
55
|
-
def query(
|
56
|
-
|
60
|
+
def query(str_query,color=QUERY_BASE_COLOR)
|
61
|
+
begin
|
62
|
+
case str_query
|
63
|
+
when /^SET /,'COMMIT','ROLLBACK'
|
64
|
+
else
|
65
|
+
self.last_query = str_query
|
66
|
+
end
|
67
|
+
rescue ArgumentError => e
|
68
|
+
# バイナリが絡むとstr_queryに正規表現とかかけられない
|
69
|
+
# invalid sequence エラーになる
|
70
|
+
self.last_query = str_query
|
71
|
+
end
|
72
|
+
res = self.class.query(self.client,str_query,self.logger,color)
|
57
73
|
@affected_rows = self.client.affected_rows
|
58
74
|
res
|
59
75
|
end
|
60
76
|
|
77
|
+
# HACKME
|
78
|
+
# トランザクションのネストをどう考えるか
|
79
|
+
# このライブラリを使うシチュエーションってのは
|
80
|
+
# トランザクションのネストを許さない場合ってな気がするので
|
81
|
+
# 一応エラーを上げるようにしてますが、、、、
|
61
82
|
def transaction(&proc)
|
62
83
|
raise ArgumentError, "No block was given" unless block_given?
|
63
84
|
#query "SET AUTOCOMMIT=0;",QUERY_SPECIAL_COLOR
|
85
|
+
if @__inside_transaction
|
86
|
+
# HACHME エラーの種別の検討
|
87
|
+
raise StandardError, 'can not nest transaction!!!!'
|
88
|
+
end
|
89
|
+
@__inside_transaction = true
|
64
90
|
query "BEGIN",QUERY_SPECIAL_COLOR
|
65
91
|
begin
|
66
92
|
yield
|
@@ -68,6 +94,8 @@ class Mysql2wrapper::Client
|
|
68
94
|
rescue => e
|
69
95
|
query "ROLLBACK",QUERY_SPECIAL_COLOR
|
70
96
|
raise e
|
97
|
+
ensure
|
98
|
+
@__inside_transaction = false
|
71
99
|
end
|
72
100
|
end
|
73
101
|
|
@@ -79,8 +107,12 @@ class Mysql2wrapper::Client
|
|
79
107
|
config = new_config
|
80
108
|
end
|
81
109
|
|
82
|
-
def count(table_name,key_name='*')
|
83
|
-
query
|
110
|
+
def count(table_name,where=nil,key_name='*')
|
111
|
+
query = "SELECT COUNT(#{escape(key_name)}) AS cnt FROM #{escape(table_name)}"
|
112
|
+
if where
|
113
|
+
query = "#{query} #{parse_where where}"
|
114
|
+
end
|
115
|
+
query(query).first['cnt']
|
84
116
|
end
|
85
117
|
|
86
118
|
def close
|
@@ -104,10 +136,11 @@ class Mysql2wrapper::Client
|
|
104
136
|
#
|
105
137
|
def update(table_name,hash,where)
|
106
138
|
case where
|
107
|
-
when
|
108
|
-
where
|
139
|
+
when '',nil
|
140
|
+
raise ArgumentError, 'can not set blank or nil on where with update(you shoule use UpdateAllClass with where)'
|
109
141
|
when UpdateAllClass.class
|
110
|
-
where =
|
142
|
+
where = nil
|
143
|
+
when String,Hash
|
111
144
|
else
|
112
145
|
raise ArgumentError, "where must be String or UpdateAll"
|
113
146
|
end
|
@@ -115,10 +148,50 @@ class Mysql2wrapper::Client
|
|
115
148
|
hash.map do |key,value|
|
116
149
|
"`#{escape(key.to_s)}` = #{proceed_value(value)}"
|
117
150
|
end.join(',')
|
118
|
-
}"
|
151
|
+
}"
|
152
|
+
if where
|
153
|
+
query = "#{query} #{parse_where where}"
|
154
|
+
end
|
119
155
|
self.query(query)
|
120
156
|
end
|
121
157
|
|
158
|
+
def select(table_name,select,where=nil)
|
159
|
+
query = "SELECT #{select} FROM `#{escape table_name}`"
|
160
|
+
if where
|
161
|
+
query = "#{query} #{parse_where(where)}"
|
162
|
+
end
|
163
|
+
query query
|
164
|
+
end
|
165
|
+
|
166
|
+
def parse_where(v)
|
167
|
+
case v
|
168
|
+
when String
|
169
|
+
if v.size > 0
|
170
|
+
"WHERE #{v}"
|
171
|
+
else
|
172
|
+
''
|
173
|
+
end
|
174
|
+
when Hash
|
175
|
+
"WHERE #{
|
176
|
+
v.map do |key,value|
|
177
|
+
case value
|
178
|
+
when nil
|
179
|
+
"`#{escape(key.to_s)}` IS NULL"
|
180
|
+
when Array
|
181
|
+
# ここ、、、自動で条件を抜くってのもできるけど、、、、まぁそれで意図しない結果になるより
|
182
|
+
# エラーを上げるほうが妥当だろうて
|
183
|
+
raise "at least one value needs for #{key.to_s} (can not call in statement with no value)" if value.size == 0
|
184
|
+
"`#{escape(key.to_s)}` in (#{value.map{|o|proceed_value(o)}.join(',')})"
|
185
|
+
else
|
186
|
+
"`#{escape(key.to_s)}` = #{proceed_value(value)}"
|
187
|
+
end
|
188
|
+
end.join(' AND ')
|
189
|
+
}"
|
190
|
+
else
|
191
|
+
raise 'can set String or Hash on where'
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
122
195
|
def update_all_flag
|
123
196
|
self.class::UPDATE_ALL
|
124
197
|
end
|
@@ -139,19 +212,21 @@ class Mysql2wrapper::Client
|
|
139
212
|
"'#{value.strftime("%Y-%m-%d %H:%M:%S")}'"
|
140
213
|
when Date
|
141
214
|
"'#{value.strftime("%Y-%m-%d")}'"
|
142
|
-
|
143
|
-
|
144
|
-
s = s.to_s unless s.kind_of?(String)
|
145
|
-
if s.respond_to?(:function_sql?) && s.function_sql?
|
215
|
+
when String
|
216
|
+
if value.respond_to?(:function_sql?) && value.function_sql?
|
146
217
|
"#{value.to_s}"
|
147
218
|
else
|
148
|
-
|
219
|
+
value = escape(value)
|
220
|
+
#value = value.encode('utf-8', {:invalid => :replace, :undef => :replace})
|
221
|
+
"'#{value}'"
|
149
222
|
end
|
223
|
+
else
|
224
|
+
"'#{escape(value.to_s)}'"
|
150
225
|
end
|
151
226
|
end
|
152
227
|
|
153
228
|
def insert(table_name,data,multiple_insert_by=MULTIPLE_INSERT_DEFAULT)
|
154
|
-
@affected_rows = 0 #
|
229
|
+
@affected_rows = 0 # 一応リセット
|
155
230
|
affected_rows_total = 0
|
156
231
|
query = "INSERT INTO `#{escape(table_name)}`"
|
157
232
|
_datas = data.clone
|
@@ -166,7 +241,6 @@ class Mysql2wrapper::Client
|
|
166
241
|
|
167
242
|
return nil if _datas.size == 0
|
168
243
|
|
169
|
-
# TODO affected_rows by multiple
|
170
244
|
_datas.each_slice(multiple_insert_by).each do |rows|
|
171
245
|
query = <<"EOS"
|
172
246
|
INSERT INTO `#{escape(table_name)}`
|
@@ -182,6 +256,7 @@ VALUES
|
|
182
256
|
end.join(',')
|
183
257
|
}
|
184
258
|
EOS
|
259
|
+
|
185
260
|
self.query(query.chomp)
|
186
261
|
affected_rows_total += self.client.affected_rows
|
187
262
|
end
|
@@ -192,12 +267,52 @@ EOS
|
|
192
267
|
# db_server_nameはDB名そのもの(複数DB対応)
|
193
268
|
#
|
194
269
|
def self.config_from_yml(yml_path,environment,db_server_name=nil)
|
270
|
+
raise "yaml not found(#{yml_path})" unless File.exists?(yml_path)
|
195
271
|
db_config = YAML.load_file(yml_path)[environment]
|
196
272
|
if db_server_name
|
197
|
-
db_config =
|
198
|
-
|
199
|
-
|
273
|
+
db_config = db_config[db_server_name]
|
274
|
+
end
|
275
|
+
unless db_config
|
276
|
+
raise "can not get db_config with env:#{environment}#{db_server_name ? "/db_server:#{db_server_name}":''}"
|
277
|
+
end
|
278
|
+
self.make_config_key_symbol(db_config)
|
279
|
+
end
|
280
|
+
|
281
|
+
def tables
|
282
|
+
table_informations.map{|o|o['TABLE_NAME']}
|
283
|
+
end
|
284
|
+
|
285
|
+
def table_names
|
286
|
+
table_informations.map{|o|o['TABLE_NAME']}
|
287
|
+
end
|
288
|
+
|
289
|
+
def databases
|
290
|
+
query = 'show databases'
|
291
|
+
self.client.query(query).map{|ar|ar['Database']}
|
292
|
+
end
|
293
|
+
|
294
|
+
def table_informations
|
295
|
+
query = "select * from INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '#{escape(self.config[:database])}' AND TABLE_TYPE = 'BASE TABLE'"
|
296
|
+
tables = self.client.query(query).to_a
|
297
|
+
tables.each do |table|
|
298
|
+
table['COLUMNS'] = table_information_schema('COLUMNS',table['TABLE_NAME'])
|
299
|
+
table['INDEXES'] = table_information_schema('STATISTICS',table['TABLE_NAME'])
|
300
|
+
query = "SHOW CREATE TABLE `#{escape(table['TABLE_NAME'])}`"
|
301
|
+
table['CREATE TABLE'] = self.client.query(query).first['Create Table']
|
200
302
|
end
|
201
|
-
|
303
|
+
tables
|
304
|
+
end
|
305
|
+
|
306
|
+
def table_information_schema(type,table_name)
|
307
|
+
query = "
|
308
|
+
SELECT
|
309
|
+
*
|
310
|
+
FROM
|
311
|
+
INFORMATION_SCHEMA.#{type}
|
312
|
+
WHERE
|
313
|
+
table_name = '#{escape(table_name)}' AND
|
314
|
+
table_schema = '#{escape(self.config[:database])}'
|
315
|
+
"
|
316
|
+
query(query).to_a
|
202
317
|
end
|
203
318
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
|
2
|
+
class Array
|
3
|
+
def select_one_must(&proc)
|
4
|
+
result = self.select(&proc)
|
5
|
+
raise StandardError, 'no data selected' if result.size == 0
|
6
|
+
raise StandardError, "multiple data selected(#{result.size} datas)" if result.size > 1
|
7
|
+
result.first
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module Mysql2
|
12
|
+
class Result
|
13
|
+
def select_one_must(&proc)
|
14
|
+
self.to_a.select_one_must(&proc)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
Binary file
|
data/test/test.rb
CHANGED
@@ -6,6 +6,7 @@ require 'test/unit'
|
|
6
6
|
require 'Fileutils'
|
7
7
|
require 'logger'
|
8
8
|
|
9
|
+
TEST_IMAGE = File.expand_path(File.dirname(__FILE__))+ '/sample_datas/image.jpeg'
|
9
10
|
#
|
10
11
|
# localhostに以下のデータベースを作成しrootのパスワード無しでアクセスできるようにしておいてください
|
11
12
|
#
|
@@ -31,7 +32,7 @@ class TestMysql2wrapper < Test::Unit::TestCase
|
|
31
32
|
query = '
|
32
33
|
CREATE TABLE IF NOT EXISTS `test02` (
|
33
34
|
`id` int(11) NOT NULL auto_increment,
|
34
|
-
`v_int1` int(11) NOT NULL,
|
35
|
+
`v_int1` int(11) NOT NULL COMMENT \'v_int1だよん\',
|
35
36
|
`v_int2` int(11) NOT NULL,
|
36
37
|
`v_int3` int(11),
|
37
38
|
`v_int4` int(11),
|
@@ -52,13 +53,14 @@ CREATE TABLE IF NOT EXISTS `test02` (
|
|
52
53
|
`v_time1` datetime NOT NULL,
|
53
54
|
`v_time2` datetime,
|
54
55
|
`v_time3` datetime,
|
56
|
+
`v_blob1` mediumblob,
|
55
57
|
`created_at` datetime NOT NULL,
|
56
58
|
`updated_at` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
|
57
|
-
PRIMARY KEY (`id`)
|
59
|
+
PRIMARY KEY (`id`),
|
60
|
+
KEY `idx_01` (`v_int1`) USING BTREE COMMENT \'idx_01 ダヨン\'
|
58
61
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
59
62
|
'
|
60
63
|
client.query query
|
61
|
-
|
62
64
|
client.close
|
63
65
|
end
|
64
66
|
|
@@ -112,16 +114,40 @@ CREATE TABLE IF NOT EXISTS `#{table}` (
|
|
112
114
|
|
113
115
|
def test_count
|
114
116
|
client = get_client
|
115
|
-
assert_equal 0,client.count('test01','id')
|
116
|
-
|
117
|
-
client.
|
118
|
-
assert_equal 1,client.count('test01'
|
119
|
-
|
120
|
-
client.
|
121
|
-
assert_equal 2,client.count('test01','
|
117
|
+
assert_equal 0,client.count('test01',nil,'id')
|
118
|
+
assert_equal 0,client.count('test01')
|
119
|
+
client.insert('test01',{:v_int1=>11,:created_at=>'NOW()'.to_func})
|
120
|
+
assert_equal 1,client.count('test01')
|
121
|
+
client.insert('test01',{:v_int1=>11,:created_at=>'NOW()'.to_func})
|
122
|
+
assert_equal 2,client.count('test01',nil,'id')
|
123
|
+
assert_equal 2,client.count('test01',nil,'*')
|
124
|
+
assert_equal 2,client.count('test01')
|
125
|
+
client.insert('test01',{:v_int1=>11,:v_int2=>22,:created_at=>'NOW()'.to_func})
|
126
|
+
assert_equal 3,client.count('test01',{:v_int1=>11},'id')
|
127
|
+
assert_equal 3,client.count('test01',"v_int1 = 11",'id')
|
128
|
+
assert_equal 1,client.count('test01',{:v_int2=>22},'id')
|
129
|
+
assert_equal 1,client.count('test01',{:v_int1=>11,:v_int2=>22},'id')
|
130
|
+
assert_equal 1,client.count('test01',{:v_int1=>11,:v_int2=>22})
|
131
|
+
assert_equal 1,client.count('test01',"v_int1 = 11 AND v_int2 = 22",'id')
|
122
132
|
client.close
|
123
133
|
end
|
124
134
|
|
135
|
+
def test_last_query
|
136
|
+
client = get_client
|
137
|
+
query = "INSERT INTO test01 (v_int1,created_at)VALUES(123,NOW())"
|
138
|
+
client.query query
|
139
|
+
assert_equal query,client.last_query
|
140
|
+
begin
|
141
|
+
client.transaction do
|
142
|
+
client.query query
|
143
|
+
assert_equal query,client.last_query
|
144
|
+
raise 'hoho'
|
145
|
+
end
|
146
|
+
rescue => e
|
147
|
+
assert_equal query,client.last_query
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
125
151
|
def test_select
|
126
152
|
client = get_client
|
127
153
|
assert_equal 0,client.count('test01','id')
|
@@ -135,8 +161,38 @@ CREATE TABLE IF NOT EXISTS `#{table}` (
|
|
135
161
|
client.query query
|
136
162
|
res = client.query "SELECT * FROM test01 WHERE id = 1"
|
137
163
|
assert_equal 1, client.affected_rows
|
164
|
+
res = client.select "test01",'*',{:id=>1}
|
165
|
+
assert_equal 1, client.affected_rows
|
138
166
|
res = client.query "SELECT * FROM test01"
|
139
167
|
assert_equal 2, client.affected_rows
|
168
|
+
|
169
|
+
query = "INSERT INTO test01 (v_int1,v_int2,created_at)VALUES(123,234,NOW())"
|
170
|
+
client.query query
|
171
|
+
res = client.select "test01",'id',{:v_int1=>123,:v_int2=>234}
|
172
|
+
assert_equal 1, client.affected_rows
|
173
|
+
assert_equal 1, res.size
|
174
|
+
res = client.select "test01",'*',"v_int1 =123 AND v_int2 = 234"
|
175
|
+
assert_equal 1, client.affected_rows
|
176
|
+
assert_equal 1, res.size
|
177
|
+
res = client.select "test01",'id',{:v_int1=>123,:v_int2=>nil}
|
178
|
+
assert_equal 2, client.affected_rows
|
179
|
+
res = client.select "test01",'*',"v_int1=123 AND v_int2 IS NULL"
|
180
|
+
assert_equal 2, client.affected_rows
|
181
|
+
|
182
|
+
|
183
|
+
res = client.select "test01",'*',{:id=>[1]}
|
184
|
+
assert_equal 1, client.affected_rows
|
185
|
+
res = client.select "test01",'*',{:id=>[1,2]}
|
186
|
+
assert_equal 2, client.affected_rows
|
187
|
+
res = client.select "test01",'*',{:id=>[1,2,999]}
|
188
|
+
assert_equal 2, client.affected_rows
|
189
|
+
res = client.select "test01",'*',{:id=>[1,2,nil]}
|
190
|
+
assert_equal 2, client.affected_rows
|
191
|
+
res = client.select "test01",'*',{:id=>[1,2,'NOW()'.to_func]}
|
192
|
+
assert_equal 2, client.affected_rows
|
193
|
+
res = client.select "test01",'*',{:id=>[1,2,Time.now]}
|
194
|
+
assert_equal 2, client.affected_rows
|
195
|
+
|
140
196
|
client.close
|
141
197
|
end
|
142
198
|
|
@@ -147,16 +203,8 @@ CREATE TABLE IF NOT EXISTS `#{table}` (
|
|
147
203
|
client.query query
|
148
204
|
client.query query
|
149
205
|
|
150
|
-
res = client.query "SELECT * FROM test01 WHERE id = 1"
|
151
|
-
assert_equal 1, res.first['v_int1']
|
152
|
-
assert_equal nil, res.first['v_int2']
|
153
|
-
res = client.query "SELECT * FROM test01 WHERE id = 2"
|
154
|
-
assert_equal 1, res.first['v_int1']
|
155
|
-
assert_equal nil, res.first['v_int2']
|
156
|
-
|
157
206
|
client.update 'test01',{:v_int1=>2},'id = 1'
|
158
207
|
assert_equal 1, client.affected_rows
|
159
|
-
|
160
208
|
res = client.query "SELECT * FROM test01 WHERE id = 1"
|
161
209
|
assert_equal 2, res.first['v_int1']
|
162
210
|
assert_equal nil, res.first['v_int2']
|
@@ -164,6 +212,8 @@ CREATE TABLE IF NOT EXISTS `#{table}` (
|
|
164
212
|
assert_equal 1, res.first['v_int1']
|
165
213
|
assert_equal nil, res.first['v_int2']
|
166
214
|
|
215
|
+
client.update 'test01',{:v_int2=>3},{:id=>3}
|
216
|
+
assert_equal 1, client.affected_rows
|
167
217
|
client.update 'test01',{:v_int1=>3}, client.update_all_flag
|
168
218
|
|
169
219
|
assert_equal 3, client.affected_rows
|
@@ -174,8 +224,19 @@ CREATE TABLE IF NOT EXISTS `#{table}` (
|
|
174
224
|
assert_equal 3, res.first['v_int1']
|
175
225
|
assert_equal nil, res.first['v_int2']
|
176
226
|
client.update 'test01',{:v_int1=>3},Mysql2wrapper::Client::UPDATE_ALL
|
227
|
+
assert_equal 0, client.affected_rows # 更新行が無いので
|
228
|
+
|
229
|
+
client.update 'test01',{:v_int1=>4},{:v_int1=>2,:v_int2=>nil}
|
177
230
|
assert_equal 0, client.affected_rows
|
178
|
-
client.update 'test01',{:v_int1=>4},
|
231
|
+
client.update 'test01',{:v_int1=>4},{:v_int1=>3,:v_int2=>nil}
|
232
|
+
assert_equal 2, client.affected_rows
|
233
|
+
client.update 'test01',{:v_int1=>4},{:v_int1=>3,:v_int2=>3}
|
234
|
+
assert_equal 1, client.affected_rows
|
235
|
+
|
236
|
+
client.update 'test01',{:v_int1=>5},{:v_int1=>[1,2,3,4],:v_int2=>3}
|
237
|
+
assert_equal 1, client.affected_rows
|
238
|
+
|
239
|
+
client.update 'test01',{:v_int1=>6},client.update_all_flag
|
179
240
|
assert_equal 3, client.affected_rows
|
180
241
|
|
181
242
|
client.close
|
@@ -189,9 +250,12 @@ CREATE TABLE IF NOT EXISTS `#{table}` (
|
|
189
250
|
assert_raise(ArgumentError){
|
190
251
|
client.update 'test01',{:v_int1=>3},nil
|
191
252
|
}
|
253
|
+
assert_raise(ArgumentError){
|
254
|
+
client.update 'test01',{:v_int1=>3},''
|
255
|
+
}
|
192
256
|
|
193
257
|
assert_raise(Mysql2::Error){
|
194
|
-
client.update 'test01',{:
|
258
|
+
client.update 'test01',{:v_int5=>3},Mysql2wrapper::Client::UPDATE_ALL
|
195
259
|
}
|
196
260
|
end
|
197
261
|
|
@@ -206,6 +270,7 @@ CREATE TABLE IF NOT EXISTS `#{table}` (
|
|
206
270
|
client.close
|
207
271
|
end
|
208
272
|
|
273
|
+
|
209
274
|
def test_tranasction_simple
|
210
275
|
client = get_client
|
211
276
|
insert(client)
|
@@ -270,6 +335,44 @@ CREATE TABLE IF NOT EXISTS `#{table}` (
|
|
270
335
|
client2.close
|
271
336
|
end
|
272
337
|
|
338
|
+
def test_tranasction_nest
|
339
|
+
client = get_client
|
340
|
+
assert_raise(StandardError) do
|
341
|
+
client.transaction do
|
342
|
+
client.transaction do
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
def test_blob
|
349
|
+
client = get_client
|
350
|
+
f = File.binread(TEST_IMAGE)
|
351
|
+
@i = 0
|
352
|
+
hash = {
|
353
|
+
:v_int1 => proc{ @i+=1 },
|
354
|
+
:v_int2 => 246,
|
355
|
+
:v_int3 => nil,
|
356
|
+
:v_str1=>"te'st日本語",
|
357
|
+
:v_str2=>"CONCAT('My','S','QL')".to_func,
|
358
|
+
:v_str3 => nil,
|
359
|
+
:v_bool1 => true,
|
360
|
+
:v_bool2 => false,
|
361
|
+
:v_bool3 => nil,
|
362
|
+
:v_date1 => Date.new(2000,1,2),
|
363
|
+
:v_date2 => nil,
|
364
|
+
:v_datetime1 => DateTime.new(2000,1,2,3,4,5),
|
365
|
+
:v_datetime2 => nil,
|
366
|
+
:v_time1 => Time.mktime(2000,1,2,3,4,5),
|
367
|
+
:v_time2 => nil,
|
368
|
+
:v_blob1 => f,
|
369
|
+
:created_at => 'NOW()'.to_func,
|
370
|
+
}
|
371
|
+
client.insert('test02',hash)
|
372
|
+
row = client.select('test02','*').first
|
373
|
+
assert_equal f, row['v_blob1']
|
374
|
+
end
|
375
|
+
|
273
376
|
def test_insert
|
274
377
|
client = get_client
|
275
378
|
@i = 0
|
@@ -379,4 +482,149 @@ CREATE TABLE IF NOT EXISTS `#{table}` (
|
|
379
482
|
assert_equal 2,client_master.count('tbl_master')
|
380
483
|
assert_equal 1,client_slave.count('tbl_slave')
|
381
484
|
end
|
485
|
+
|
486
|
+
def test_tables
|
487
|
+
client = get_client
|
488
|
+
assert_equal 2, client.tables.size
|
489
|
+
client.tables.each do |table_name|
|
490
|
+
assert %w|test01 test02|.include?(table_name)
|
491
|
+
end
|
492
|
+
end
|
493
|
+
|
494
|
+
def test_table_names
|
495
|
+
client = get_client
|
496
|
+
assert_equal 2, client.tables.size
|
497
|
+
client.tables.each do |table_name|
|
498
|
+
assert %w|test01 test02|.include?(table_name)
|
499
|
+
end
|
500
|
+
end
|
501
|
+
|
502
|
+
def test_config_from_yml
|
503
|
+
end
|
504
|
+
|
505
|
+
def test_table_informations
|
506
|
+
client = get_client
|
507
|
+
table_informations = client.table_informations
|
508
|
+
assert_equal 2, table_informations.size
|
509
|
+
table_informations.each do |hash|
|
510
|
+
assert %w|test01 test02|.include?(hash['TABLE_NAME'])
|
511
|
+
assert_not_nil hash['COLUMNS']
|
512
|
+
assert_not_nil hash['INDEXES']
|
513
|
+
assert_not_nil hash['CREATE TABLE']
|
514
|
+
case hash['TABLE_NAME']
|
515
|
+
when 'test02'
|
516
|
+
assert_equal 25, hash['COLUMNS'].size
|
517
|
+
assert_equal 2, hash['INDEXES'].size
|
518
|
+
end
|
519
|
+
end
|
520
|
+
end
|
521
|
+
|
522
|
+
def test_databases
|
523
|
+
client = get_client
|
524
|
+
databases = client.databases
|
525
|
+
assert_equal true, databases.include?('information_schema')
|
526
|
+
assert_equal false,databases.include?('tbl_master')
|
527
|
+
assert_equal true, databases.include?('mysql2wrapper_test')
|
528
|
+
assert_equal true, databases.include?('mysql2wrapper_test_master')
|
529
|
+
assert_equal true, databases.include?('mysql2wrapper_test_slave')
|
530
|
+
end
|
531
|
+
|
532
|
+
def test_array_select_one_must
|
533
|
+
ar = [1,2,2,3]
|
534
|
+
assert_equal 1,ar.select_one_must{|o|o == 1}
|
535
|
+
assert_equal 3,ar.select_one_must{|o|o == 3}
|
536
|
+
assert_raise StandardError do
|
537
|
+
ar.select_one_must{|o|o == 2}
|
538
|
+
end
|
539
|
+
assert_raise StandardError do
|
540
|
+
ar.select_one_must{|o|o == 4}
|
541
|
+
end
|
542
|
+
|
543
|
+
ar = [{:id=>1,:i=>1},{:id=>2,:i=>2}]
|
544
|
+
assert_equal ({:id=>1,:i=>1}),ar.select_one_must{|o|o[:id] == 1}
|
545
|
+
end
|
546
|
+
|
547
|
+
def test_mysql2_result_select_one_must
|
548
|
+
client = get_client
|
549
|
+
client.insert('test01',{:id=>1,:v_int1=>1,:created_at=>'NOW()'.to_func})
|
550
|
+
client.insert('test01',{:id=>2,:v_int1=>2,:created_at=>'NOW()'.to_func})
|
551
|
+
client.insert('test01',{:id=>3,:v_int1=>2,:created_at=>'NOW()'.to_func})
|
552
|
+
client.insert('test01',{:id=>4,:v_int1=>3,:created_at=>'NOW()'.to_func})
|
553
|
+
rows = client.query('select * from test01')
|
554
|
+
assert_equal 1, rows.select_one_must{|o|o['id'] == 1}['v_int1']
|
555
|
+
assert_equal 2, rows.select_one_must{|o|o['id'] == 3}['v_int1']
|
556
|
+
assert_raise StandardError do
|
557
|
+
rows.select_one_must{|o|o['v_int1'] == 2}
|
558
|
+
end
|
559
|
+
assert_raise StandardError do
|
560
|
+
rows.select_one_must{|o|o['v_int1'] == 4}
|
561
|
+
end
|
562
|
+
end
|
563
|
+
|
564
|
+
|
565
|
+
#
|
566
|
+
# http://info.dwango.co.jp/rd/2010/01/mysql.html
|
567
|
+
#
|
568
|
+
def test_queue
|
569
|
+
sample_row_size = 1000
|
570
|
+
client = get_client
|
571
|
+
ar = []
|
572
|
+
sample_row_size.times do
|
573
|
+
ar << {:v_int1=>1,:created_at=>'NOW()'.to_func}
|
574
|
+
end
|
575
|
+
client.insert('test01',ar)
|
576
|
+
|
577
|
+
assert_equal sample_row_size, client.count('test01')
|
578
|
+
|
579
|
+
cnt = 0
|
580
|
+
12.times do
|
581
|
+
threads = []
|
582
|
+
(sample_row_size / 10).times do
|
583
|
+
threads << Thread.new do
|
584
|
+
Thread.pass
|
585
|
+
th_client = get_client
|
586
|
+
query = '
|
587
|
+
UPDATE
|
588
|
+
test01
|
589
|
+
SET
|
590
|
+
id = LAST_INSERT_ID(id),
|
591
|
+
v_int1 = 2
|
592
|
+
WHERE
|
593
|
+
v_int1 = 1
|
594
|
+
ORDER BY id
|
595
|
+
LIMIT 1
|
596
|
+
'
|
597
|
+
th_client.query(query)
|
598
|
+
query = 'SELECT LAST_INSERT_ID() as last_id'
|
599
|
+
processing_id = th_client.query(query).first['last_id']
|
600
|
+
#puts processing_id
|
601
|
+
if processing_id != 0
|
602
|
+
begin
|
603
|
+
th_client.transaction do
|
604
|
+
query = "UPDATE test01 SET v_int2 = v_int2 + 1 WHERE id = #{processing_id}"
|
605
|
+
th_client.query(query)
|
606
|
+
end
|
607
|
+
rescue
|
608
|
+
end
|
609
|
+
begin
|
610
|
+
th_client.transaction do
|
611
|
+
query = "UPDATE test01 SET v_int2 = v_int2 + 1 WHERE id = #{processing_id}"
|
612
|
+
th_client.query(query)
|
613
|
+
raise 'koko'
|
614
|
+
end
|
615
|
+
rescue
|
616
|
+
end
|
617
|
+
query = "UPDATE test01 SET v_int2 = v_int2 + 1 WHERE id = #{processing_id}"
|
618
|
+
th_client.query(query)
|
619
|
+
cnt += 1
|
620
|
+
end
|
621
|
+
th_client.close
|
622
|
+
end
|
623
|
+
end
|
624
|
+
threads.each do |th|
|
625
|
+
th.join
|
626
|
+
end
|
627
|
+
end
|
628
|
+
assert_equal sample_row_size, cnt
|
629
|
+
end
|
382
630
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mysql2wrapper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-12-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: mysql2
|
@@ -42,11 +42,14 @@ files:
|
|
42
42
|
- config/database.yml
|
43
43
|
- config/database_multiple.yml
|
44
44
|
- example/sample.rb
|
45
|
+
- example/sample_table_information.rb
|
45
46
|
- lib/mysql2wrapper.rb
|
46
47
|
- lib/mysql2wrapper/client.rb
|
48
|
+
- lib/mysql2wrapper/core_ext.rb
|
47
49
|
- lib/mysql2wrapper/version.rb
|
48
50
|
- mysql2wrapper.gemspec
|
49
51
|
- test/by_hand.rb
|
52
|
+
- test/sample_datas/image.jpeg
|
50
53
|
- test/test.rb
|
51
54
|
- test/test_helper.rb
|
52
55
|
homepage: ''
|
@@ -75,6 +78,7 @@ specification_version: 3
|
|
75
78
|
summary: oreore mysql2 wrapper class
|
76
79
|
test_files:
|
77
80
|
- test/by_hand.rb
|
81
|
+
- test/sample_datas/image.jpeg
|
78
82
|
- test/test.rb
|
79
83
|
- test/test_helper.rb
|
80
84
|
has_rdoc:
|