oldmoe-mysqlplus 0.1.0 → 0.1.1

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/README CHANGED
@@ -20,6 +20,14 @@ An enhanced MySQL database driver. With support for async operations and threade
20
20
  --with-mysql-dir=/usr/local/mysql \
21
21
  --with-mysql-lib=/usr/local/mysql/lib \
22
22
  --with-mysql-include=/usr/local/mysql/include
23
+ == Using
24
+ to use within rails
25
+ add require 'mysqlplus' to the top of environment.rb
26
+ this instantiates the Mysql class that you can use.
27
+ and it will automagically use async_query instead of query, so it's a drop in replacement.
28
+
29
+ Same with other scripts that want to use it--just require 'mysqlplus' BEFORE you require 'mysql' and it will
30
+ load the asynchronous version, then ignore the sequent require 'mysql' call.
23
31
 
24
32
  === Credits
25
33
 
data/TODO_LIST ADDED
@@ -0,0 +1,13 @@
1
+ TODO list:
2
+
3
+ Is there a quick, cheap, easy way to test for writability so we don't have to use select on the way in? Does it take long anyway?
4
+
5
+ Docs for how to use with rails, etc. [there is mysqlplus_adapter, so maybe we're good there].
6
+
7
+ Merge in lourens' branch -- I like the double check for not using send_query twice in a row! [rdp]
8
+
9
+ look into http://coderrr.wordpress.com/2009/01/11/ruby-and-mysqlplus-select-deadlock/
10
+
11
+ Some of the test/* anticipate a certain database existing--todo create it first, then drop it [?]
12
+
13
+ critical todo list:
data/ext/extconf.rb CHANGED
@@ -1,10 +1,24 @@
1
1
  require 'mkmf'
2
2
 
3
+ dirs = ENV['PATH'].split(':') + %w[
4
+ /opt
5
+ /opt/local
6
+ /opt/local/mysql
7
+ /opt/local/lib/mysql5
8
+ /usr
9
+ /usr/local
10
+ /usr/local/mysql
11
+ /usr/local/mysql-*
12
+ /usr/local/lib/mysql5
13
+ ].map{|dir| "#{dir}/bin" }
14
+
15
+ GLOB = "{#{dirs.join(',')}}/{mysql_config,mysql_config5}"
16
+
3
17
  if /mswin32/ =~ RUBY_PLATFORM
4
18
  inc, lib = dir_config('mysql')
5
19
  exit 1 unless have_library("libmysql")
6
- elsif mc = with_config('mysql-config') then
7
- mc = 'mysql_config' if mc == true
20
+ elsif mc = (with_config('mysql-config') || Dir[GLOB].first) then
21
+ mc = Dir[GLOB].first if mc == true
8
22
  cflags = `#{mc} --cflags`.chomp
9
23
  exit 1 if $? != 0
10
24
  libs = `#{mc} --libs`.chomp
@@ -31,8 +45,8 @@ else
31
45
  exit 1
32
46
  end
33
47
 
34
- if have_func('rb_thread_blocking_region') and have_macro('RB_UBF_DFL', 'ruby.h')
35
- flags << "-DHAVE_TBR"
48
+ if have_func('rb_thread_blocking_region') and have_macro('RUBY_UBF_IO', 'ruby.h')
49
+ $CPPFLAGS << " -DHAVE_TBR"
36
50
  end
37
51
 
38
52
  # make mysql constant
data/ext/mysql.c CHANGED
@@ -190,8 +190,10 @@ static VALUE mysqlres2obj(MYSQL_RES* res)
190
190
  resp->res = res;
191
191
  resp->freed = Qfalse;
192
192
  rb_obj_call_init(obj, 0, NULL);
193
+ /* disabled until it can be reviewed further--rely on the normal GC for now.
193
194
  if (++store_result_count > GC_STORE_RESULT_LIMIT)
194
195
  rb_gc();
196
+ */
195
197
  return obj;
196
198
  }
197
199
 
@@ -719,18 +721,43 @@ static VALUE use_result(VALUE obj)
719
721
  }
720
722
 
721
723
  static VALUE res_free(VALUE);
724
+
725
+ typedef struct {
726
+ MYSQL *m;
727
+ const char *data;
728
+ unsigned long len;
729
+ } QueryArgs;
730
+
731
+ static VALUE blocking_query(void *data)
732
+ {
733
+ QueryArgs *args = (QueryArgs *) data;
734
+ return (VALUE) mysql_real_query(args->m, args->data, args->len);
735
+ }
736
+
722
737
  /* query(sql) */
723
738
  static VALUE query(VALUE obj, VALUE sql)
724
739
  {
725
740
  int loop = 0;
726
741
  MYSQL* m = GetHandler(obj);
742
+ QueryArgs args;
743
+ int result;
744
+
727
745
  Check_Type(sql, T_STRING);
728
746
  if (GetMysqlStruct(obj)->connection == Qfalse) {
729
747
  rb_raise(eMysql, "query: not connected");
730
748
  }
731
749
  if (rb_block_given_p()) {
732
- if (mysql_real_query(m, RSTRING_PTR(sql), RSTRING_LEN(sql)) != 0)
750
+ #ifdef RUBY_VM
751
+ args.m = m;
752
+ args.data = RSTRING_PTR(sql);
753
+ args.len = RSTRING_LEN(sql);
754
+ result = (int) rb_thread_blocking_region(blocking_query, &args, RUBY_UBF_PROCESS, 0);
755
+ #else
756
+ result = mysql_real_query(m, RSTRING_PTR(sql), RSTRING_LEN(sql));
757
+ #endif
758
+ if (result != 0)
733
759
  mysql_raise(m);
760
+
734
761
  do {
735
762
  MYSQL_RES* res = mysql_store_result(m);
736
763
  if (res == NULL) {
@@ -749,7 +776,16 @@ static VALUE query(VALUE obj, VALUE sql)
749
776
  #endif
750
777
  return obj;
751
778
  }
752
- if (mysql_real_query(m, RSTRING_PTR(sql), RSTRING_LEN(sql)) != 0)
779
+
780
+ #ifdef RUBY_VM
781
+ args.m = m;
782
+ args.data = RSTRING_PTR(sql);
783
+ args.len = RSTRING_LEN(sql);
784
+ result = (int) rb_thread_blocking_region(blocking_query, &args, RUBY_UBF_PROCESS, 0);
785
+ #else
786
+ result = mysql_real_query(m, RSTRING_PTR(sql), RSTRING_LEN(sql));
787
+ #endif
788
+ if (result != 0)
753
789
  mysql_raise(m);
754
790
  if (GetMysqlStruct(obj)->query_with_result == Qfalse)
755
791
  return obj;
@@ -764,13 +800,12 @@ static VALUE socket(VALUE obj)
764
800
  MYSQL* m = GetHandler(obj);
765
801
  return INT2NUM(m->net.fd);
766
802
  }
767
-
768
803
  /* socket_type */
769
804
  static VALUE socket_type(VALUE obj)
770
805
  {
771
806
  MYSQL* m = GetHandler(obj);
772
807
  VALUE description = vio_description( m->net.vio );
773
- return NILorSTRING( description );
808
+ return (VALUE) NILorSTRING( description );
774
809
  }
775
810
 
776
811
  /* blocking */
@@ -824,42 +859,33 @@ static VALUE get_result(VALUE obj)
824
859
  return store_result(obj);
825
860
  }
826
861
 
827
- /* async_query(sql,timeout=nil) */
828
- static VALUE async_query(int argc, VALUE* argv, VALUE obj)
862
+ static void schedule(VALUE obj, VALUE timeout)
829
863
  {
830
- MYSQL* m = GetHandler(obj);
831
- VALUE sql, timeout;
832
- fd_set read;
833
- int ret;
864
+ MYSQL* m = GetHandler(obj);
865
+ fd_set read;
834
866
 
835
- rb_scan_args(argc, argv, "11", &sql, &timeout);
867
+ timeout = ( NIL_P(timeout) ? m->net.read_timeout : INT2NUM(timeout) );
836
868
 
837
- send_query(obj,sql);
869
+ struct timeval tv = { tv_sec: timeout, tv_usec: 0 };
838
870
 
839
- timeout = ( NIL_P(timeout) ? m->net.read_timeout : INT2NUM(timeout) );
871
+ FD_ZERO(&read);
872
+ FD_SET(m->net.fd, &read);
840
873
 
841
- VALUE args[1];
842
- args[0] = timeout;
874
+ if (rb_thread_select(m->net.fd + 1, &read, NULL, NULL, &tv) < 0) {
875
+ rb_raise(eMysql, "query: timeout");
876
+ }
877
+ }
843
878
 
844
- struct timeval tv = { tv_sec: timeout, tv_usec: 0 };
879
+ /* async_query(sql,timeout=nil) */
880
+ static VALUE async_query(int argc, VALUE* argv, VALUE obj)
881
+ {
882
+ VALUE sql, timeout;
845
883
 
846
- FD_ZERO(&read);
847
- FD_SET(m->net.fd, &read);
884
+ rb_scan_args(argc, argv, "11", &sql, &timeout);
848
885
 
849
- for(;;) {
850
- ret = rb_thread_select(m->net.fd + 1, &read, NULL, NULL, &tv);
851
- if (ret < 0) {
852
- rb_raise(eMysql, "query: timeout");
853
- }
854
-
855
- if (ret == 0) {
856
- continue;
857
- }
886
+ send_query(obj,sql);
858
887
 
859
- if ( vio_poll_read( m->net.vio, INT2NUM(timeout) ) == 0 ) {
860
- break;
861
- }
862
- }
888
+ schedule(obj, timeout);
863
889
 
864
890
  return get_result(obj);
865
891
  }
@@ -1136,7 +1162,7 @@ static VALUE process_all_hashes(VALUE obj, VALUE with_table, int build_array, in
1136
1162
  {
1137
1163
  MYSQL_RES* res = GetMysqlRes(obj);
1138
1164
  unsigned int n = mysql_num_fields(res);
1139
- VALUE ary;
1165
+ VALUE ary = Qnil;
1140
1166
  if(build_array)
1141
1167
  ary = rb_ary_new();
1142
1168
  MYSQL_ROW row = mysql_fetch_row(res); // grab one off the top, to determine the rows
@@ -1203,6 +1229,8 @@ static VALUE process_all_hashes(VALUE obj, VALUE with_table, int build_array, in
1203
1229
 
1204
1230
  if(yield)
1205
1231
  return obj;
1232
+
1233
+ return Qnil; /* we should never get here -- this takes out a compiler warning */
1206
1234
  }
1207
1235
 
1208
1236
  /* fetch_hash2 (internal) */
@@ -1586,12 +1614,12 @@ static VALUE stmt_execute(int argc, VALUE *argv, VALUE obj)
1586
1614
  s->param.bind[i].buffer = &(s->param.buffer[i]);
1587
1615
  t.second_part = 0;
1588
1616
  t.neg = 0;
1589
- t.second = FIX2INT(RARRAY(a)->ptr[0]);
1590
- t.minute = FIX2INT(RARRAY(a)->ptr[1]);
1591
- t.hour = FIX2INT(RARRAY(a)->ptr[2]);
1592
- t.day = FIX2INT(RARRAY(a)->ptr[3]);
1593
- t.month = FIX2INT(RARRAY(a)->ptr[4]);
1594
- t.year = FIX2INT(RARRAY(a)->ptr[5]);
1617
+ t.second = FIX2INT(rb_ary_entry(a, 0));
1618
+ t.minute = FIX2INT(rb_ary_entry(a, 1));
1619
+ t.hour = FIX2INT(rb_ary_entry(a, 2));
1620
+ t.day = FIX2INT(rb_ary_entry(a, 3));
1621
+ t.month = FIX2INT(rb_ary_entry(a, 4));
1622
+ t.year = FIX2INT(rb_ary_entry(a, 5));
1595
1623
  *(MYSQL_TIME*)&(s->param.buffer[i]) = t;
1596
1624
  } else if (CLASS_OF(argv[i]) == cMysqlTime) {
1597
1625
  MYSQL_TIME t;
data/lib/mysqlplus.rb CHANGED
@@ -1,19 +1,21 @@
1
- require 'mysql'
1
+ require 'mysql' # this should load the mysqlplus version of mysql.so, as we assume the user has installed mysql as a gem and have not done any previous "require 'mysql'" to have loaded the other
2
2
 
3
+ #
4
+ # Mysqlplus library gives you a [slightly modified] version of the Mysql class
5
+ # See http://www.kitebird.com/articles/ruby-mysql.html for details, as well as the test directory within the library
6
+ #
3
7
  class Mysql
4
8
 
5
- def async_query(sql, timeout = nil)
9
+ def ruby_async_query(sql, timeout = nil) # known to deadlock TODO
6
10
  send_query(sql)
7
11
  select [ (@sockets ||= {})[socket] ||= IO.new(socket) ], nil, nil, nil
8
12
  get_result
9
13
  end
10
-
11
- end
12
14
 
13
- class Mysql::Result
14
- def all_hashes
15
- rows = []
16
- each_hash { |row| rows << row }
17
- rows
15
+ begin
16
+ alias_method :async_query, :c_async_query
17
+ rescue NameError => e
18
+ raise LoadError.new "error loading mysqlplus--this may mean you ran a require 'mysql' before a require 'mysqplus', which much come first"
18
19
  end
20
+
19
21
  end
data/mysqlplus.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "mysqlplus"
3
- s.version = "0.1.0"
4
- s.date = "2008-08-13"
3
+ s.version = "0.1.1"
4
+ s.date = "2009-03-22"
5
5
  s.summary = "Enhanced Ruby MySQL driver"
6
6
  s.email = "oldmoe@gmail.com"
7
7
  s.homepage = "http://github.com/oldmoe/mysqlplus"
@@ -9,19 +9,25 @@ Gem::Specification.new do |s|
9
9
  s.has_rdoc = true
10
10
  s.authors = ["Muhammad A. Ali"]
11
11
  s.platform = Gem::Platform::RUBY
12
- s.files = [
13
- "mysqlplus.gemspec",
14
- "README",
15
- "Rakefile",
16
- "lib/mysqlplus.rb",
17
- "test/test_helper.rb",
18
- "test/native_threaded_test.rb",
19
- "test/c_threaded_test.rb",
20
- "test/evented_test.rb",
21
- "ext/error_const.h",
22
- "ext/extconf.rb",
23
- "ext/mysql.c"
24
- ]
12
+ s.files = %w[
13
+ README
14
+ Rakefile
15
+ TODO_LIST
16
+ ext/error_const.h
17
+ ext/extconf.rb
18
+ ext/mysql.c
19
+ lib/mysqlplus.rb
20
+ mysqlplus.gemspec
21
+ test/c_threaded_test.rb
22
+ test/evented_test.rb
23
+ test/native_threaded_test.rb
24
+ test/test_all_hashes.rb
25
+ test/test_failure.rb
26
+ test/test_helper.rb
27
+ test/test_many_requests.rb
28
+ test/test_parsing_while_response_is_being_read.rb
29
+ test/test_threaded_sequel.rb
30
+ ]
25
31
  s.rdoc_options = ["--main", "README"]
26
32
  s.extra_rdoc_files = ["README"]
27
33
  s.extensions << "ext/extconf.rb"
@@ -3,34 +3,34 @@ require File.dirname(__FILE__) + '/test_helper'
3
3
  ThreadedMysqlTest.new( 10, "Threaded, C, very small overhead" ) do |test|
4
4
  test.setup{ Mysql.real_connect('localhost','root') }
5
5
  test.per_query_overhead = 0.005
6
- test.c_async_query = true
6
+ test.query_with = :c_async_query
7
7
  test.run!
8
8
  end
9
9
 
10
10
  ThreadedMysqlTest.new( 10, "Threaded, C, small overhead" ) do |test|
11
11
  test.setup{ Mysql.real_connect('localhost','root') }
12
12
  test.per_query_overhead = 0.1
13
- test.c_async_query = true
13
+ test.query_with = :c_async_query
14
14
  test.run!
15
15
  end
16
16
 
17
17
  ThreadedMysqlTest.new( 10, "Threaded, C, medium overhead" ) do |test|
18
18
  test.setup{ Mysql.real_connect('localhost','root') }
19
19
  test.per_query_overhead = 1
20
- test.c_async_query = true
20
+ test.query_with = :c_async_query
21
21
  test.run!
22
22
  end
23
23
 
24
24
  ThreadedMysqlTest.new( 10, "Threaded, C, large overhead" ) do |test|
25
25
  test.setup{ Mysql.real_connect('localhost','root') }
26
26
  test.per_query_overhead = 3
27
- test.c_async_query = true
27
+ test.query_with = :c_async_query
28
28
  test.run!
29
29
  end
30
30
 
31
31
  ThreadedMysqlTest.new( 10, "Threaded, C, random overhead" ) do |test|
32
32
  test.setup{ Mysql.real_connect('localhost','root') }
33
33
  test.per_query_overhead = :random
34
- test.c_async_query = true
34
+ test.query_with = :c_async_query
35
35
  test.run!
36
36
  end
@@ -3,29 +3,34 @@ require File.dirname(__FILE__) + '/test_helper'
3
3
  ThreadedMysqlTest.new( 10, "Threaded, native Ruby, very small overhead" ) do |test|
4
4
  test.setup{ Mysql.real_connect('localhost','root') }
5
5
  test.per_query_overhead = 0.005
6
+ test.query_with = :async_query
6
7
  test.run!
7
8
  end
8
9
 
9
10
  ThreadedMysqlTest.new( 10, "Threaded, native Ruby, small overhead" ) do |test|
10
11
  test.setup{ Mysql.real_connect('localhost','root') }
11
12
  test.per_query_overhead = 0.1
13
+ test.query_with = :async_query
12
14
  test.run!
13
15
  end
14
16
 
15
17
  ThreadedMysqlTest.new( 10, "Threaded, native Ruby, medium overhead" ) do |test|
16
18
  test.setup{ Mysql.real_connect('localhost','root') }
17
19
  test.per_query_overhead = 1
20
+ test.query_with = :async_query
18
21
  test.run!
19
22
  end
20
23
 
21
24
  ThreadedMysqlTest.new( 10, "Threaded, native Ruby, large overhead" ) do |test|
22
25
  test.setup{ Mysql.real_connect('localhost','root') }
23
26
  test.per_query_overhead = 3
27
+ test.query_with = :async_query
24
28
  test.run!
25
29
  end
26
30
 
27
31
  ThreadedMysqlTest.new( 10, "Threaded, native Ruby, random overhead" ) do |test|
28
32
  test.setup{ Mysql.real_connect('localhost','root') }
29
33
  test.per_query_overhead = :random
34
+ test.query_with = :async_query
30
35
  test.run!
31
36
  end
@@ -0,0 +1,43 @@
1
+ # shows the effect of using .all_hashes instead of looping on each hash
2
+ # run it by substiting in a 'long' [many row] query for the query variable and toggling use_all_hashes here at the top
3
+ # note that we load all the rows first, then run .all_hashes on the result [to see more easily the effect of all hashes]
4
+ # on my machine and a 200_000 row table, it took 3.38s versus 3.65s
5
+ require 'rubygems'
6
+ require 'mysqlplus'
7
+
8
+ use_the_all_hashes_method = true
9
+
10
+ $count = 5
11
+
12
+ $start = Time.now
13
+
14
+ $connections = []
15
+ $count.times do
16
+ $connections << Mysql.real_connect('localhost','root', '', 'local_leadgen_dev')
17
+ end
18
+
19
+ puts 'connection pool ready'
20
+
21
+ $threads = []
22
+ $count.times do |i|
23
+ $threads << Thread.new do
24
+
25
+ query = "select * from campus_zips"
26
+ puts "sending query on connection #{i}"
27
+ conn = $connections[i]
28
+ result = conn.async_query(query)
29
+ if use_the_all_hashes_method
30
+ saved = result.all_hashes
31
+ else
32
+ saved = []
33
+ result.each_hash {|h| saved << h }
34
+ end
35
+ result.free
36
+
37
+ end
38
+ end
39
+
40
+ puts 'waiting on threads'
41
+ $threads.each{|t| t.join }
42
+
43
+ puts Time.now - $start
@@ -0,0 +1,17 @@
1
+ require 'rubygems'
2
+ require 'mysqlplus'
3
+ begin
4
+ Mysql.real_connect('fakehost','root', '', 'local_leadgen_dev')
5
+ rescue Mysql::Error
6
+ end
7
+ begin
8
+ Mysql.real_connect('localhost','root', '', 'faketable')
9
+ rescue Mysql::Error
10
+ end
11
+ begin
12
+ Mysql.real_connect('localhost', 'root', 'pass', 'db', 3307)# bad port
13
+ rescue Mysql::Error
14
+ end
15
+ print "pass"
16
+
17
+
data/test/test_helper.rb CHANGED
@@ -12,7 +12,7 @@ class MysqlTest
12
12
  :connection_signature,
13
13
  :start,
14
14
  :done,
15
- :c_async_query,
15
+ :query_with,
16
16
  :per_query_overhead,
17
17
  :timeout
18
18
 
@@ -20,7 +20,7 @@ class MysqlTest
20
20
  @queries = queries
21
21
  @context = context
22
22
  @done = []
23
- @c_async_query = false
23
+ @query_with = :async_query
24
24
  @per_query_overhead = 3
25
25
  @timeout = 20
26
26
  yield self if block_given?
@@ -78,7 +78,7 @@ class MysqlTest
78
78
  end
79
79
 
80
80
  def c_or_native_ruby_async_query
81
- if @c_async_query
81
+ if @query_with == :c_async_query
82
82
  log "** using C based async_query"
83
83
  else
84
84
  log "** using native Ruby async_query"
@@ -86,9 +86,8 @@ class MysqlTest
86
86
  yield
87
87
  end
88
88
 
89
- def c_or_native_async_query( connection, sql, timeout = nil )
90
- method = @c_async_query ? :c_async_query : :async_query
91
- connection.send( method, sql, timeout )
89
+ def dispatch_query( connection, sql, timeout = nil )
90
+ connection.send( @query_with, sql, timeout )
92
91
  end
93
92
 
94
93
  end
@@ -188,7 +187,7 @@ class ThreadedMysqlTest < MysqlTest
188
187
 
189
188
  log "sending query on connection #{conn}"
190
189
 
191
- c_or_native_async_query( @connections[conn], "select sleep(#{@per_query_overhead})", @timeout ).each do |result|
190
+ dispatch_query( @connections[conn], "select sleep(#{@per_query_overhead})", @timeout ).each do |result|
192
191
  log "connection #{conn} done"
193
192
  end
194
193
 
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+ require 'mysqlplus'
3
+ a = Mysql.real_connect('localhost','root')
4
+ 100.times { a.query("select sleep(0)") }
5
+ print "pass"
6
+
7
+
@@ -0,0 +1,48 @@
1
+ # This is an example of using Mysql::ResultSet#use_result [see docs for what that does]
2
+ # this function is useful for those who have large query results and want to be able to parse them
3
+ # as they come in, instead of having to wait for the query to finish before doing parsing
4
+ # for me, running this on a query with 200_000 lines decreases total time to create an array of results
5
+ # from .82s to .62s
6
+ # you can experiment with it by changing the query here to be a long one, and toggling the do_the_use_query_optimization variable
7
+ # this also has the interesting property of 'freeing' Ruby to do thread changes mid-query.
8
+ require 'rubygems'
9
+ require 'mysqlplus'
10
+
11
+ do_the_use_query_optimization = true
12
+
13
+ $count = 5
14
+
15
+ $start = Time.now
16
+
17
+ $connections = []
18
+ $count.times do
19
+ $connections << Mysql.real_connect('localhost','root', '', 'local_leadgen_dev')
20
+ end
21
+
22
+ puts 'connection pool ready'
23
+
24
+ $threads = []
25
+ $count.times do |i|
26
+ $threads << Thread.new do
27
+
28
+ puts "sending query on connection #{i}"
29
+ conn = $connections[i]
30
+ saved = []
31
+ query = "select * from campus_zips"
32
+ if do_the_use_query_optimization
33
+ conn.query_with_result=false
34
+ result = conn.async_query(query)
35
+ res = result.use_result
36
+ res.each_hash { |h| saved << h }
37
+ res.free
38
+ else
39
+ conn.async_query(query).each_hash {|h| saved << h }
40
+ end
41
+
42
+ end
43
+ end
44
+
45
+ puts 'waiting on threads'
46
+ $threads.each{|t| t.join }
47
+
48
+ puts Time.now - $start
@@ -0,0 +1,24 @@
1
+ require 'rubygems'
2
+ require 'sequel'
3
+
4
+ require 'mysqlplus'
5
+ class Mysql
6
+ unless method_defined? :sync_query
7
+ alias :sync_query :query
8
+ alias :query :async_query
9
+ end
10
+ end
11
+
12
+ DB = Sequel.connect('mysql://root@localhost', :max_connections => 20)
13
+
14
+ start = Time.now
15
+
16
+ (0..10).map do
17
+ Thread.new do
18
+
19
+ p DB['select sleep(2)'].all
20
+
21
+ end
22
+ end.map{|t| t.join }
23
+
24
+ p (Time.now - start)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oldmoe-mysqlplus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Muhammad A. Ali
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-08-13 00:00:00 -07:00
12
+ date: 2009-03-22 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -22,17 +22,23 @@ extensions:
22
22
  extra_rdoc_files:
23
23
  - README
24
24
  files:
25
- - mysqlplus.gemspec
26
25
  - README
27
26
  - Rakefile
28
- - lib/mysqlplus.rb
29
- - test/test_helper.rb
30
- - test/native_threaded_test.rb
31
- - test/c_threaded_test.rb
32
- - test/evented_test.rb
27
+ - TODO_LIST
33
28
  - ext/error_const.h
34
29
  - ext/extconf.rb
35
30
  - ext/mysql.c
31
+ - lib/mysqlplus.rb
32
+ - mysqlplus.gemspec
33
+ - test/c_threaded_test.rb
34
+ - test/evented_test.rb
35
+ - test/native_threaded_test.rb
36
+ - test/test_all_hashes.rb
37
+ - test/test_failure.rb
38
+ - test/test_helper.rb
39
+ - test/test_many_requests.rb
40
+ - test/test_parsing_while_response_is_being_read.rb
41
+ - test/test_threaded_sequel.rb
36
42
  has_rdoc: true
37
43
  homepage: http://github.com/oldmoe/mysqlplus
38
44
  post_install_message: