julien51-em-mysql 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/em-mysql.gemspec +1 -1
- data/lib/em/mysql.rb +11 -185
- data/test.rb +1 -1
- metadata +1 -1
data/em-mysql.gemspec
CHANGED
data/lib/em/mysql.rb
CHANGED
@@ -161,9 +161,11 @@ class EventedMysql < EM::Connection
|
|
161
161
|
# IO.pipe
|
162
162
|
# EM.add_timer(0){ close_connection }
|
163
163
|
# close_connection
|
164
|
-
fd = detach
|
165
|
-
|
166
|
-
|
164
|
+
fd = detach if EM.reactor_running?
|
165
|
+
if @io
|
166
|
+
@io.close rescue nil
|
167
|
+
@io = nil
|
168
|
+
end
|
167
169
|
log 'detached fd', fd
|
168
170
|
end
|
169
171
|
|
@@ -191,11 +193,13 @@ class EventedMysql < EM::Connection
|
|
191
193
|
|
192
194
|
public
|
193
195
|
|
194
|
-
def self.connect
|
196
|
+
def self.connect *servers_opts
|
195
197
|
unless EM.respond_to?(:attach) and Mysql.method_defined?(:socket)
|
196
198
|
raise RuntimeError, 'mysqlplus and EM.attach are required for EventedMysql'
|
197
199
|
end
|
198
|
-
|
200
|
+
|
201
|
+
opts = servers_opts.pop
|
202
|
+
opts[:failover] = servers_opts
|
199
203
|
if conn = _connect(opts)
|
200
204
|
EM.attach conn.socket, self, conn, opts
|
201
205
|
else
|
@@ -254,6 +258,8 @@ class EventedMysql < EM::Connection
|
|
254
258
|
if cb = opts[:on_error]
|
255
259
|
cb.call(e)
|
256
260
|
nil
|
261
|
+
elsif opts[:failover]
|
262
|
+
connect(opts[:failover])
|
257
263
|
else
|
258
264
|
raise e
|
259
265
|
end
|
@@ -310,183 +316,3 @@ class EventedMysql
|
|
310
316
|
end
|
311
317
|
end
|
312
318
|
|
313
|
-
if __FILE__ == $0 and require 'em/spec'
|
314
|
-
|
315
|
-
EM.describe EventedMysql, 'individual connections' do
|
316
|
-
|
317
|
-
should 'create a new connection' do
|
318
|
-
@mysql = EventedMysql.connect :host => '127.0.0.1',
|
319
|
-
:port => 3306,
|
320
|
-
:database => 'test',
|
321
|
-
:logging => false
|
322
|
-
|
323
|
-
@mysql.class.should == EventedMysql
|
324
|
-
done
|
325
|
-
end
|
326
|
-
|
327
|
-
should 'execute sql' do
|
328
|
-
start = Time.now
|
329
|
-
|
330
|
-
@mysql.execute('select sleep(0.2)'){
|
331
|
-
(Time.now-start).should.be.close 0.2, 0.1
|
332
|
-
done
|
333
|
-
}
|
334
|
-
end
|
335
|
-
|
336
|
-
should 'reconnect when disconnected' do
|
337
|
-
@mysql.close
|
338
|
-
@mysql.execute('select 1+2'){
|
339
|
-
:connected.should == :connected
|
340
|
-
done
|
341
|
-
}
|
342
|
-
end
|
343
|
-
|
344
|
-
# to test, run:
|
345
|
-
# mysqladmin5 -u root kill `mysqladmin5 -u root processlist | grep "select sleep(5)+1" | cut -d'|' -f2`
|
346
|
-
#
|
347
|
-
# should 're-run query if disconnected during query' do
|
348
|
-
# @mysql.execute('select sleep(5)+1', :select){ |res|
|
349
|
-
# res.first['sleep(5)+1'].should == '1'
|
350
|
-
# done
|
351
|
-
# }
|
352
|
-
# end
|
353
|
-
|
354
|
-
should 'run select queries and return results' do
|
355
|
-
@mysql.execute('select 1+2', :select){ |res|
|
356
|
-
res.size.should == 1
|
357
|
-
res.first['1+2'].should == '3'
|
358
|
-
done
|
359
|
-
}
|
360
|
-
end
|
361
|
-
|
362
|
-
should 'queue up queries and execute them in order' do
|
363
|
-
@mysql.execute('select 1+2', :select)
|
364
|
-
@mysql.execute('select 2+3', :select)
|
365
|
-
@mysql.execute('select 3+4', :select){ |res|
|
366
|
-
res.first['3+4'].should == '7'
|
367
|
-
done
|
368
|
-
}
|
369
|
-
end
|
370
|
-
|
371
|
-
should 'continue processing queries after hitting an error' do
|
372
|
-
@mysql.settings.update :on_error => proc{|e|}
|
373
|
-
|
374
|
-
@mysql.execute('select 1+ from table'){}
|
375
|
-
@mysql.execute('select 1+1 as num', :select){ |res|
|
376
|
-
res[0]['num'].should == '2'
|
377
|
-
done
|
378
|
-
}
|
379
|
-
end
|
380
|
-
|
381
|
-
should 'have raw mode which yields the mysql object' do
|
382
|
-
@mysql.execute('select 1+2 as num', :raw){ |mysql|
|
383
|
-
mysql.should.is_a? Mysql
|
384
|
-
mysql.result.all_hashes.should == [{'num' => '3'}]
|
385
|
-
done
|
386
|
-
}
|
387
|
-
end
|
388
|
-
|
389
|
-
should 'allow custom error callbacks for each query' do
|
390
|
-
@mysql.settings.update :on_error => proc{ should.flunk('default errback invoked') }
|
391
|
-
|
392
|
-
@mysql.execute('select 1+ from table', :select, proc{
|
393
|
-
should.flunk('callback invoked')
|
394
|
-
}, proc{ |e|
|
395
|
-
done
|
396
|
-
})
|
397
|
-
end
|
398
|
-
|
399
|
-
end
|
400
|
-
|
401
|
-
EM.describe EventedMysql, 'connection pools' do
|
402
|
-
|
403
|
-
EventedMysql.settings.update :connections => 3
|
404
|
-
|
405
|
-
should 'run queries in parallel' do
|
406
|
-
n = 0
|
407
|
-
EventedMysql.select('select sleep(0.25)'){ n+=1 }
|
408
|
-
EventedMysql.select('select sleep(0.25)'){ n+=1 }
|
409
|
-
EventedMysql.select('select sleep(0.25)'){ n+=1 }
|
410
|
-
|
411
|
-
EM.add_timer(0.30){
|
412
|
-
n.should == 3
|
413
|
-
done
|
414
|
-
}
|
415
|
-
end
|
416
|
-
|
417
|
-
end
|
418
|
-
|
419
|
-
SQL = EventedMysql
|
420
|
-
def SQL(query, &blk) SQL.select(query, &blk) end
|
421
|
-
|
422
|
-
# XXX this should get cleaned up automatically after reactor stops
|
423
|
-
SQL.reset!
|
424
|
-
|
425
|
-
|
426
|
-
EM.describe SQL, 'sql api' do
|
427
|
-
|
428
|
-
should 'run a query on all connections' do
|
429
|
-
SQL.all('use test'){
|
430
|
-
:done.should == :done
|
431
|
-
done
|
432
|
-
}
|
433
|
-
end
|
434
|
-
|
435
|
-
should 'execute queries with no results' do
|
436
|
-
SQL.execute('drop table if exists evented_mysql_test'){
|
437
|
-
:table_dropped.should == :table_dropped
|
438
|
-
SQL.execute('create table evented_mysql_test (id int primary key auto_increment, num int not null)'){
|
439
|
-
:table_created.should == :table_created
|
440
|
-
done
|
441
|
-
}
|
442
|
-
}
|
443
|
-
end
|
444
|
-
|
445
|
-
should 'insert rows and return inserted id' do
|
446
|
-
SQL.insert('insert into evented_mysql_test (num) values (10),(11),(12)'){ |id|
|
447
|
-
id.should == 1
|
448
|
-
done
|
449
|
-
}
|
450
|
-
end
|
451
|
-
|
452
|
-
should 'select rows from the database' do
|
453
|
-
SQL.select('select * from evented_mysql_test'){ |res|
|
454
|
-
res.size.should == 3
|
455
|
-
res.first.should == { 'id' => '1', 'num' => '10' }
|
456
|
-
res.last.should == { 'id' => '3', 'num' => '12' }
|
457
|
-
done
|
458
|
-
}
|
459
|
-
end
|
460
|
-
|
461
|
-
should 'update rows and return affected rows' do
|
462
|
-
SQL.update('update evented_mysql_test set num = num + 10'){ |changed|
|
463
|
-
changed.should == 3
|
464
|
-
done
|
465
|
-
}
|
466
|
-
end
|
467
|
-
|
468
|
-
should 'allow access to insert_id in raw mode' do
|
469
|
-
SQL.raw('insert into evented_mysql_test (num) values (20), (21), (22)'){ |mysql|
|
470
|
-
mysql.insert_id.should == 4
|
471
|
-
done
|
472
|
-
}
|
473
|
-
end
|
474
|
-
|
475
|
-
should 'allow access to affected_rows in raw mode' do
|
476
|
-
SQL.raw('update evented_mysql_test set num = num + 10'){ |mysql|
|
477
|
-
mysql.affected_rows.should == 6
|
478
|
-
done
|
479
|
-
}
|
480
|
-
end
|
481
|
-
|
482
|
-
should 'fire error callback with exceptions' do
|
483
|
-
SQL.settings.update :on_error => proc{ |e|
|
484
|
-
e.class.should == Mysql::Error
|
485
|
-
done
|
486
|
-
}
|
487
|
-
SQL.select('select 1+ from table'){}
|
488
|
-
end
|
489
|
-
|
490
|
-
end
|
491
|
-
|
492
|
-
end
|
data/test.rb
CHANGED