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 CHANGED
@@ -1,5 +1,7 @@
1
+ .DS_Store
1
2
  *.gem
2
3
  *.rbc
4
+ *.lock
3
5
  .bundle
4
6
  .config
5
7
  coverage
@@ -1,17 +1,13 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mysql2wrapper (0.0.1)
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
@@ -1,6 +1,10 @@
1
- mysql2wrapper
1
+ #mysql2wrapper
2
2
  =============
3
3
 
4
4
  very simple mysql2 wrapper.
5
5
  it's ore ore library!
6
6
 
7
+ ## TODO
8
+
9
+ ActiveSupportのHashWithIndifferentAccess的なものをかませるか?
10
+
@@ -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 `hoges`'
25
+ DROP TABLE IF EXISTS `test01`'
25
26
  client.query query
26
27
  query = '
27
- CREATE TABLE IF NOT EXISTS `hoges` (
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
- logger.info "hoge has #{client.count 'hoges'}rows"
37
- client.query "INSERT INTO hoges (value1,created_at)VALUES(#{Time.now.to_i},NOW())"
38
- logger.info "hoge has #{client.count 'hoges'}rows"
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 "hoge has #{client.count 'hoges'}rows"
44
- client.query "INSERT INTO hoges (value1,created_at)VALUES(#{Time.now.to_i},NOW())"
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 "hoge has #{client.count 'hoges'}rows"
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 "hoge has #{client.count 'hoges'}rows"
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('hoges',hash)
71
+ client.insert('test01',hash)
60
72
  logger.info "affected_rows:#{client.affected_rows}"
61
- logger.info "hoge has #{client.count 'hoges'}rows"
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('hoges',ar)
78
+ client.insert('test01',ar)
67
79
  logger.info "affected_rows:#{client.affected_rows}" # Client#affected_rowsでマルチプルインサートのトータルインサート数が取れる
68
- logger.info "hoge has #{client.count 'hoges'}rows"
80
+ logger.info "test01 has #{client.count 'test01'}rows"
69
81
 
70
82
  # ハッシュを引数にしたアップデート
71
- client.update 'hoges',{:value1=>3},'id = 1'
72
- logger.info "hoge has #{client.count 'hoges'}rows"
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 'hoges',{:value1=>3},Mysql2wrapper::Client::UpdateAllClass
86
+ client.update 'test01',{:value1=>3},Mysql2wrapper::Client::UpdateAllClass
75
87
  # clientインスタンスにショートカットあり
76
- client.update 'hoges',{:value1=>4},client.update_all_flag
77
- logger.info "hoge has #{client.count 'hoges'}rows"
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
+
@@ -1,4 +1,5 @@
1
1
  require "mysql2wrapper/version"
2
+ require "mysql2wrapper/core_ext"
2
3
  require "mysql2wrapper/client"
3
4
 
4
5
  class String
@@ -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
- self.logger.info "mysql2 client created with #{config.inspect}"
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(str,color=QUERY_BASE_COLOR)
56
- res = self.class.query(self.client,str,self.logger,color)
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("SELECT COUNT(#{escape(key_name)}) AS cnt FROM #{escape(table_name)}").first['cnt']
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 String
108
- where = "WHERE #{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
- }" + where
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
- else
143
- s = value
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
- "'#{escape(value.to_s)}'"
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 = self.make_config_key_symbol(db_config[db_server_name])
198
- else
199
- db_config = self.make_config_key_symbol(db_config)
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
- db_config
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
@@ -1,3 +1,3 @@
1
1
  module Mysql2wrapper
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -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
- query = "INSERT INTO test01 (v_int1,created_at)VALUES(#{Time.now.to_i},NOW())"
117
- client.query query
118
- assert_equal 1,client.count('test01','id')
119
- query = "INSERT INTO test01 (v_int1,created_at)VALUES(#{Time.now.to_i},NOW())"
120
- client.query query
121
- assert_equal 2,client.count('test01','id')
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},client.update_all_flag
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',{:v_int1=>3},''
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.1
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-10-11 00:00:00.000000000 Z
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: