swift 0.13.0 → 0.14.0
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/API.rdoc +16 -12
- data/{README.rdoc → README.md} +120 -66
- data/Rakefile +0 -1
- data/VERSION +1 -1
- data/ext/adapter.cc +84 -5
- data/ext/datetime.cc +96 -0
- data/ext/datetime.h +12 -0
- data/ext/extconf.rb +5 -4
- data/ext/query.cc +42 -18
- data/ext/query.h +2 -1
- data/ext/result.cc +65 -148
- data/ext/result.h +1 -1
- data/ext/statement.cc +1 -1
- data/ext/swift.cc +1 -2
- data/ext/swift.h +4 -2
- data/lib/swift/adapter/sql.rb +11 -1
- data/lib/swift/db.rb +14 -1
- data/lib/swift/type.rb +9 -2
- data/lib/swift.rb +9 -1
- data/swift.gemspec +8 -13
- data/test/test_adapter.rb +18 -4
- data/test/test_async.rb +28 -0
- data/test/test_datetime_parser.rb +12 -0
- data/test/test_error.rb +23 -0
- data/test/test_scheme.rb +1 -1
- data/test/test_timestamps.rb +22 -12
- data/test/test_types.rb +2 -2
- metadata +10 -23
- data/ext/pool.cc +0 -96
- data/ext/pool.h +0 -8
- data/ext/request.cc +0 -44
- data/ext/request.h +0 -10
- data/lib/swift/pool.rb +0 -76
- data/test/test_pool.rb +0 -38
data/test/test_async.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
|
3
|
+
describe 'Adapter' do
|
4
|
+
supported_by Swift::DB::Postgres do
|
5
|
+
describe 'async operations' do
|
6
|
+
it 'can runs queries async' do
|
7
|
+
rows = []
|
8
|
+
pool = 3.times.map.with_index {|n| Swift.setup n, Swift::DB::Postgres, db: 'swift' }
|
9
|
+
|
10
|
+
Thread.new do
|
11
|
+
pool[0].async_execute('select pg_sleep(0.3), 1 as query_id') {|row| rows << row[:query_id]}
|
12
|
+
end
|
13
|
+
|
14
|
+
Thread.new do
|
15
|
+
pool[1].async_execute('select pg_sleep(0.2), 2 as query_id') {|row| rows << row[:query_id]}
|
16
|
+
end
|
17
|
+
|
18
|
+
Thread.new do
|
19
|
+
pool[2].async_execute('select pg_sleep(0.1), 3 as query_id') {|row| rows << row[:query_id]}
|
20
|
+
end
|
21
|
+
|
22
|
+
Thread.list.reject {|thread| Thread.current == thread}.each(&:join)
|
23
|
+
|
24
|
+
assert_equal [3, 2, 1], rows
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
|
3
|
+
describe 'DateTimeParser' do
|
4
|
+
it 'should handle ymd style values' do
|
5
|
+
text = "2011-12-31 09:01:02.80300899 +1100"
|
6
|
+
time = DateTime.parse(text)
|
7
|
+
result = Swift::DateTime.parse(text)
|
8
|
+
|
9
|
+
assert_equal time.strftime('%F %T %z'), result.strftime('%F %T %z')
|
10
|
+
assert_equal time.second_fraction.to_f.round(8), result.second_fraction.to_f.round(8)
|
11
|
+
end
|
12
|
+
end
|
data/test/test_error.rb
CHANGED
@@ -23,4 +23,27 @@ describe 'Error' do
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
26
|
+
|
27
|
+
supported_by Swift::DB::Postgres do
|
28
|
+
describe 'execute' do
|
29
|
+
before do
|
30
|
+
Swift.db do |db|
|
31
|
+
db.execute %q{drop table if exists users}
|
32
|
+
db.execute %q{create table users(id integer, name text, primary key(id))}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'throws connection error on connection failures' do
|
37
|
+
select1 = Swift.db.prepare("select * from users")
|
38
|
+
select2 = Swift.db.prepare("select * from users where id > ?")
|
39
|
+
|
40
|
+
Swift.db.close
|
41
|
+
|
42
|
+
assert_raises(SwiftConnectionError) { select1.execute }
|
43
|
+
assert_raises(SwiftConnectionError) { select2.execute(1) }
|
44
|
+
assert_raises(SwiftConnectionError) { Swift.db.execute("select * from users") }
|
45
|
+
assert_raises(SwiftConnectionError) { Swift.db.execute("select * from users where id > ?", 1) }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
26
49
|
end
|
data/test/test_scheme.rb
CHANGED
@@ -10,7 +10,7 @@ describe 'scheme' do
|
|
10
10
|
attribute :height, Swift::Type::Float, default: 172.25
|
11
11
|
attribute :email, Swift::Type::String
|
12
12
|
attribute :verified, Swift::Type::Boolean, default: false
|
13
|
-
attribute :created_at, Swift::Type::
|
13
|
+
attribute :created_at, Swift::Type::DateTime, default: proc { Time.now }
|
14
14
|
|
15
15
|
migrations do |db|
|
16
16
|
db.execute %q{
|
data/test/test_timestamps.rb
CHANGED
@@ -1,13 +1,18 @@
|
|
1
1
|
require_relative 'helper'
|
2
|
-
require 'date'
|
3
2
|
|
4
3
|
describe 'Adapter' do
|
5
4
|
supported_by Swift::DB::Postgres do
|
6
5
|
%w(America/Chicago Australia/Melbourne).each do |timezone|
|
7
6
|
describe 'time parsing in %s' % timezone do
|
8
7
|
before do
|
9
|
-
@db = Swift.db
|
10
8
|
ENV['TZ'] = ":#{timezone}"
|
9
|
+
@db = Swift.db
|
10
|
+
@db.execute 'create table datetime_test(id serial, ts timestamp with time zone)'
|
11
|
+
@db.execute "set time zone '#{timezone}'"
|
12
|
+
end
|
13
|
+
|
14
|
+
after do
|
15
|
+
@db.execute 'drop table datetime_test'
|
11
16
|
end
|
12
17
|
|
13
18
|
it 'should parse timestamps and do conversion accordingly' do
|
@@ -25,14 +30,19 @@ describe 'Adapter' do
|
|
25
30
|
assert_timestamp_like time, fetch_timestamp_at(time), 'DST off'
|
26
31
|
end
|
27
32
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
it 'should store fractional seconds' do
|
34
|
+
time = Time.now
|
35
|
+
datetime = time.to_datetime
|
36
|
+
|
37
|
+
@db.execute 'insert into datetime_test(ts) values (?), (?)', time, datetime
|
38
|
+
values = @db.execute('select ts from datetime_test').map(&:values).flatten
|
39
|
+
|
40
|
+
assert_equal 2, values.size
|
41
|
+
|
42
|
+
# postgres resolution is microsecond.
|
43
|
+
values.each do |value|
|
44
|
+
assert_equal datetime.strftime('%F %T %z'), value.strftime('%F %T %z')
|
45
|
+
assert_equal datetime.second_fraction.to_f.round(6), value.second_fraction.to_f.round(6)
|
36
46
|
end
|
37
47
|
end
|
38
48
|
|
@@ -49,8 +59,8 @@ describe 'Adapter' do
|
|
49
59
|
|
50
60
|
def assert_timestamp_like expect, given, comment
|
51
61
|
match = Regexp.new expect.to_time.strftime('%F %T')
|
52
|
-
assert_kind_of
|
53
|
-
assert_match match, given.strftime('%F %T'), comment
|
62
|
+
assert_kind_of DateTime, given
|
63
|
+
assert_match match, given.to_time.strftime('%F %T'), comment
|
54
64
|
end
|
55
65
|
end
|
56
66
|
end
|
data/test/test_types.rb
CHANGED
@@ -37,10 +37,10 @@ describe 'Adapter' do
|
|
37
37
|
assert_kind_of TrueClass, result[:hacker]
|
38
38
|
assert_kind_of FalseClass, result[:slacker]
|
39
39
|
assert_kind_of Date, result[:created]
|
40
|
-
assert_kind_of
|
40
|
+
assert_kind_of DateTime, result[:updated]
|
41
41
|
|
42
42
|
assert_equal dt, result[:updated].strftime('%F %T')
|
43
|
-
assert_equal 65000, result[:updated].usec unless @db.kind_of?(Swift::DB::Mysql)
|
43
|
+
assert_equal 65000, result[:updated].to_time.usec unless @db.kind_of?(Swift::DB::Mysql)
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: swift
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.14.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,11 +10,11 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2012-03-21 00:00:00.000000000Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: minitest
|
17
|
-
requirement: &
|
17
|
+
requirement: &10639060 !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ! '>='
|
@@ -22,18 +22,7 @@ dependencies:
|
|
22
22
|
version: 1.7.0
|
23
23
|
type: :development
|
24
24
|
prerelease: false
|
25
|
-
version_requirements: *
|
26
|
-
- !ruby/object:Gem::Dependency
|
27
|
-
name: eventmachine
|
28
|
-
requirement: &6951140 !ruby/object:Gem::Requirement
|
29
|
-
none: false
|
30
|
-
requirements:
|
31
|
-
- - ! '>='
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: *6951140
|
25
|
+
version_requirements: *10639060
|
37
26
|
description: A rational rudimentary database abstraction.
|
38
27
|
email:
|
39
28
|
- shane.hanna@gmail.com
|
@@ -43,11 +32,11 @@ extensions:
|
|
43
32
|
- ext/extconf.rb
|
44
33
|
extra_rdoc_files:
|
45
34
|
- LICENSE
|
46
|
-
- README.
|
35
|
+
- README.md
|
47
36
|
files:
|
48
37
|
- API.rdoc
|
49
38
|
- LICENSE
|
50
|
-
- README.
|
39
|
+
- README.md
|
51
40
|
- Rakefile
|
52
41
|
- VERSION
|
53
42
|
- ext/adapter.cc
|
@@ -56,13 +45,11 @@ files:
|
|
56
45
|
- ext/adapter_io.h
|
57
46
|
- ext/attribute.cc
|
58
47
|
- ext/attribute.h
|
48
|
+
- ext/datetime.cc
|
49
|
+
- ext/datetime.h
|
59
50
|
- ext/extconf.rb
|
60
|
-
- ext/pool.cc
|
61
|
-
- ext/pool.h
|
62
51
|
- ext/query.cc
|
63
52
|
- ext/query.h
|
64
|
-
- ext/request.cc
|
65
|
-
- ext/request.h
|
66
53
|
- ext/result.cc
|
67
54
|
- ext/result.h
|
68
55
|
- ext/statement.cc
|
@@ -77,7 +64,6 @@ files:
|
|
77
64
|
- lib/swift/header.rb
|
78
65
|
- lib/swift/identity_map.rb
|
79
66
|
- lib/swift/migrations.rb
|
80
|
-
- lib/swift/pool.rb
|
81
67
|
- lib/swift/scheme.rb
|
82
68
|
- lib/swift/type.rb
|
83
69
|
- lib/swift/validations.rb
|
@@ -86,11 +72,12 @@ files:
|
|
86
72
|
- test/house-explode.jpg
|
87
73
|
- test/minitest_teardown_hack.rb
|
88
74
|
- test/test_adapter.rb
|
75
|
+
- test/test_async.rb
|
76
|
+
- test/test_datetime_parser.rb
|
89
77
|
- test/test_encoding.rb
|
90
78
|
- test/test_error.rb
|
91
79
|
- test/test_identity_map.rb
|
92
80
|
- test/test_io.rb
|
93
|
-
- test/test_pool.rb
|
94
81
|
- test/test_scheme.rb
|
95
82
|
- test/test_swift.rb
|
96
83
|
- test/test_timestamps.rb
|
data/ext/pool.cc
DELETED
@@ -1,96 +0,0 @@
|
|
1
|
-
#include "pool.h"
|
2
|
-
|
3
|
-
VALUE cSwiftPool;
|
4
|
-
|
5
|
-
static void pool_free(dbi::ConnectionPool *self) {
|
6
|
-
if (self) delete self;
|
7
|
-
}
|
8
|
-
|
9
|
-
VALUE pool_alloc(VALUE klass) {
|
10
|
-
dbi::ConnectionPool *pool = 0;
|
11
|
-
return Data_Wrap_Struct(klass, 0, pool_free, pool);
|
12
|
-
}
|
13
|
-
|
14
|
-
static dbi::ConnectionPool* pool_handle(VALUE self) {
|
15
|
-
dbi::ConnectionPool *pool;
|
16
|
-
Data_Get_Struct(self, dbi::ConnectionPool, pool);
|
17
|
-
if (!pool) rb_raise(eSwiftRuntimeError, "Invalid object, did you forget to call #super ?");
|
18
|
-
return pool;
|
19
|
-
}
|
20
|
-
|
21
|
-
VALUE pool_init(VALUE self, VALUE n, VALUE options) {
|
22
|
-
VALUE db = rb_hash_aref(options, ID2SYM(rb_intern("db")));
|
23
|
-
VALUE user = rb_hash_aref(options, ID2SYM(rb_intern("user")));
|
24
|
-
VALUE driver = rb_hash_aref(options, ID2SYM(rb_intern("driver")));
|
25
|
-
|
26
|
-
if (NIL_P(db)) rb_raise(eSwiftArgumentError, "Pool#new called without :db");
|
27
|
-
if (NIL_P(driver)) rb_raise(eSwiftArgumentError, "#new called without :driver");
|
28
|
-
|
29
|
-
user = NIL_P(user) ? current_user() : user;
|
30
|
-
if (NUM2INT(n) < 1) rb_raise(eSwiftArgumentError, "Pool#new called with invalid pool size.");
|
31
|
-
|
32
|
-
try {
|
33
|
-
DATA_PTR(self) = new dbi::ConnectionPool(
|
34
|
-
NUM2INT(n),
|
35
|
-
CSTRING(driver),
|
36
|
-
CSTRING(user),
|
37
|
-
CSTRING(rb_hash_aref(options, ID2SYM(rb_intern("password")))),
|
38
|
-
CSTRING(db),
|
39
|
-
CSTRING(rb_hash_aref(options, ID2SYM(rb_intern("host")))),
|
40
|
-
CSTRING(rb_hash_aref(options, ID2SYM(rb_intern("port"))))
|
41
|
-
);
|
42
|
-
|
43
|
-
rb_iv_set(self, "@timezone", rb_hash_aref(options, ID2SYM(rb_intern("timezone"))));
|
44
|
-
}
|
45
|
-
CATCH_DBI_EXCEPTIONS();
|
46
|
-
|
47
|
-
return Qnil;
|
48
|
-
}
|
49
|
-
|
50
|
-
void pool_callback(dbi::AbstractResult *result) {
|
51
|
-
VALUE callback = (VALUE)result->context;
|
52
|
-
|
53
|
-
// NOTE: C Result object will be deallocated in dbic++
|
54
|
-
if (!NIL_P(callback)) {
|
55
|
-
VALUE obj = result_wrap_handle(cSwiftResult, 0, result, false);
|
56
|
-
rb_iv_set(obj, "@timezone", rb_iv_get(callback, "@timezone"));
|
57
|
-
rb_proc_call(callback, rb_ary_new3(1, obj));
|
58
|
-
}
|
59
|
-
}
|
60
|
-
|
61
|
-
VALUE pool_execute(int argc, VALUE *argv, VALUE self) {
|
62
|
-
int n;
|
63
|
-
VALUE sql;
|
64
|
-
VALUE bind_values;
|
65
|
-
VALUE callback;
|
66
|
-
VALUE request = Qnil;
|
67
|
-
|
68
|
-
dbi::ConnectionPool *pool = pool_handle(self);
|
69
|
-
rb_scan_args(argc, argv, "1*&", &sql, &bind_values, &callback);
|
70
|
-
|
71
|
-
// The only way to pass timezone to the C callback routine.
|
72
|
-
if (NIL_P(callback))
|
73
|
-
rb_raise(eSwiftArgumentError, "No block given in Pool#execute");
|
74
|
-
else
|
75
|
-
rb_iv_set(callback, "@timezone", rb_iv_get(self, "@timezone"));
|
76
|
-
|
77
|
-
try {
|
78
|
-
Query query;
|
79
|
-
query_bind_values(&query, bind_values);
|
80
|
-
request = request_alloc(cSwiftRequest);
|
81
|
-
DATA_PTR(request) = pool->execute(CSTRING(sql), query.bind, pool_callback, (void*)callback);
|
82
|
-
return request;
|
83
|
-
}
|
84
|
-
CATCH_DBI_EXCEPTIONS();
|
85
|
-
}
|
86
|
-
|
87
|
-
void init_swift_pool() {
|
88
|
-
VALUE mSwift = rb_define_module("Swift");
|
89
|
-
VALUE mDB = rb_define_module_under(mSwift, "DB");
|
90
|
-
cSwiftPool = rb_define_class_under(mDB, "Pool", rb_cObject);
|
91
|
-
|
92
|
-
rb_define_alloc_func(cSwiftPool, pool_alloc);
|
93
|
-
|
94
|
-
rb_define_method(cSwiftPool, "initialize", RUBY_METHOD_FUNC(pool_init), 2);
|
95
|
-
rb_define_method(cSwiftPool, "execute", RUBY_METHOD_FUNC(pool_execute), -1);
|
96
|
-
}
|
data/ext/pool.h
DELETED
data/ext/request.cc
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
#include "request.h"
|
2
|
-
|
3
|
-
VALUE cSwiftRequest;
|
4
|
-
|
5
|
-
static void request_free(dbi::Request *request) {
|
6
|
-
if(request) delete request;
|
7
|
-
}
|
8
|
-
|
9
|
-
VALUE request_alloc(VALUE klass) {
|
10
|
-
dbi::Request *request = 0;
|
11
|
-
return Data_Wrap_Struct(klass, 0, request_free, request);
|
12
|
-
}
|
13
|
-
|
14
|
-
static dbi::Request* request_handle(VALUE self) {
|
15
|
-
dbi::Request *request;
|
16
|
-
Data_Get_Struct(self, dbi::Request, request);
|
17
|
-
if (!request) rb_raise(eSwiftRuntimeError, "Invalid object, did you forget to call #super ?");
|
18
|
-
return request;
|
19
|
-
}
|
20
|
-
|
21
|
-
VALUE request_socket(VALUE self) {
|
22
|
-
dbi::Request *request = request_handle(self);
|
23
|
-
try {
|
24
|
-
return INT2NUM(request->socket());
|
25
|
-
}
|
26
|
-
CATCH_DBI_EXCEPTIONS();
|
27
|
-
}
|
28
|
-
|
29
|
-
VALUE request_process(VALUE self) {
|
30
|
-
dbi::Request *request = request_handle(self);
|
31
|
-
try {
|
32
|
-
return request->process() ? Qtrue : Qfalse;
|
33
|
-
}
|
34
|
-
CATCH_DBI_EXCEPTIONS();
|
35
|
-
}
|
36
|
-
|
37
|
-
void init_swift_request() {
|
38
|
-
VALUE mSwift = rb_define_module("Swift");
|
39
|
-
cSwiftRequest = rb_define_class_under(mSwift, "Request", rb_cObject);
|
40
|
-
|
41
|
-
rb_define_alloc_func(cSwiftRequest, request_alloc);
|
42
|
-
rb_define_method(cSwiftRequest, "socket", RUBY_METHOD_FUNC(request_socket), 0);
|
43
|
-
rb_define_method(cSwiftRequest, "process", RUBY_METHOD_FUNC(request_process), 0);
|
44
|
-
}
|
data/ext/request.h
DELETED
data/lib/swift/pool.rb
DELETED
@@ -1,76 +0,0 @@
|
|
1
|
-
require 'eventmachine'
|
2
|
-
|
3
|
-
module Swift
|
4
|
-
class Pool
|
5
|
-
module Handler
|
6
|
-
def initialize request, pool
|
7
|
-
@request, @pool = request, pool
|
8
|
-
end
|
9
|
-
|
10
|
-
def socket
|
11
|
-
@request.socket
|
12
|
-
end
|
13
|
-
|
14
|
-
def notify_readable
|
15
|
-
if @request.process
|
16
|
-
detach
|
17
|
-
@pool.detach self
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def notify_writable
|
22
|
-
notify_readable
|
23
|
-
end
|
24
|
-
end # Handler
|
25
|
-
|
26
|
-
|
27
|
-
def initialize size, options
|
28
|
-
@pool = Swift::DB::Pool.new size, options
|
29
|
-
|
30
|
-
# used to be used for db2
|
31
|
-
@writable = false
|
32
|
-
@pending = {}
|
33
|
-
@queue = []
|
34
|
-
end
|
35
|
-
|
36
|
-
def attach c
|
37
|
-
@pending[c] = true
|
38
|
-
end
|
39
|
-
|
40
|
-
def detach c
|
41
|
-
@pending.delete(c)
|
42
|
-
unless @queue.empty?
|
43
|
-
sql, bind, callback = @queue.shift
|
44
|
-
execute(sql, *bind, &callback)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def attached? fd
|
49
|
-
@pending.keys.select{|c| c.socket == fd}.length > 0
|
50
|
-
end
|
51
|
-
|
52
|
-
def execute sql, *bind, &callback
|
53
|
-
request = @pool.execute sql, *bind, &callback
|
54
|
-
# NOTE EM segfaults if we try to attach same fd twice.
|
55
|
-
if request && !attached?(request.socket)
|
56
|
-
EM.watch(request.socket, Handler, request, self) do |c|
|
57
|
-
attach c
|
58
|
-
c.notify_writable = @writable
|
59
|
-
c.notify_readable = true
|
60
|
-
end
|
61
|
-
else
|
62
|
-
@queue << [ sql, bind, callback ]
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def run &block
|
67
|
-
EM.run{ yield self }
|
68
|
-
end
|
69
|
-
end # Pool
|
70
|
-
|
71
|
-
def self.pool size, name = :default, &block
|
72
|
-
pool = Pool.new(size, Swift.db(name).options)
|
73
|
-
pool.run(&block) if block_given?
|
74
|
-
pool
|
75
|
-
end
|
76
|
-
end # Swift
|
data/test/test_pool.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
require_relative 'helper'
|
2
|
-
require 'swift/pool'
|
3
|
-
|
4
|
-
describe 'Adapter' do
|
5
|
-
supported_by Swift::DB::Postgres, Swift::DB::Mysql do
|
6
|
-
describe 'Asynchronous connection pool' do
|
7
|
-
before do
|
8
|
-
Swift.db do |db|
|
9
|
-
db.execute %q{drop table if exists users}
|
10
|
-
db.execute %Q{create table users(name varchar(64))}
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
it 'creates connection pool and runs queries' do
|
15
|
-
rows = []
|
16
|
-
Swift.pool(5) do |pool|
|
17
|
-
assert pool
|
18
|
-
assert Swift.db.write('users', %w{name}, StringIO.new("user1\nuser2\nuser3\n"))
|
19
|
-
pool.execute('select * from users') do |rs|
|
20
|
-
rows += rs.to_a
|
21
|
-
Thread.new do
|
22
|
-
sleep 0.25
|
23
|
-
pool.execute('select * from users order by name desc') {|rs| rows += rs.to_a; EM.stop }
|
24
|
-
end
|
25
|
-
end
|
26
|
-
pool.execute('select * from users') do |rs|
|
27
|
-
rows += rs.to_a
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
data = %w(user1 user2 user3)
|
32
|
-
|
33
|
-
assert_equal 9, rows.length
|
34
|
-
assert_equal data*2 + data.reverse, rows.map {|r| r[:name] }
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|