swift 0.5.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +1 -1
- data/VERSION +1 -1
- data/examples/scheme.rb +3 -3
- data/ext/adapter.cc +3 -4
- data/ext/extconf.rb +1 -1
- data/ext/query.cc +28 -10
- data/ext/query.h +1 -0
- data/ext/result.cc +14 -6
- data/ext/statement.cc +2 -4
- data/ext/swift.h +10 -2
- data/lib/swift/adapter.rb +1 -1
- data/lib/swift/type.rb +2 -1
- data/swift.gemspec +6 -4
- data/test/test_scheme.rb +5 -5
- data/test/test_types.rb +29 -0
- metadata +7 -12
data/README.rdoc
CHANGED
@@ -71,7 +71,7 @@ primitive Ruby type conversion.
|
|
71
71
|
attribute :id, Swift::Type::Integer, serial: true, key: true
|
72
72
|
attribute :name, Swift::Type::String
|
73
73
|
attribute :email, Swift::Type::String
|
74
|
-
attribute :updated_at, Swift::Type::
|
74
|
+
attribute :updated_at, Swift::Type::DateTime
|
75
75
|
end # User
|
76
76
|
|
77
77
|
Swift.db do |db|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.6.0
|
data/examples/scheme.rb
CHANGED
@@ -9,12 +9,12 @@ require 'swift/validations'
|
|
9
9
|
|
10
10
|
class User < Swift::Scheme
|
11
11
|
store :users
|
12
|
-
attribute :id, Swift::Type::Integer,
|
12
|
+
attribute :id, Swift::Type::Integer, serial: true, key: true
|
13
13
|
attribute :name, Swift::Type::String
|
14
14
|
attribute :email, Swift::Type::String
|
15
15
|
attribute :active, Swift::Type::Boolean
|
16
|
-
attribute :created, Swift::Type::
|
17
|
-
attribute :optional, Swift::Type::String,
|
16
|
+
attribute :created, Swift::Type::DateTime, default: proc { Time.now }
|
17
|
+
attribute :optional, Swift::Type::String, default: 'woot'
|
18
18
|
|
19
19
|
validations do |errors|
|
20
20
|
errors << [:name, 'is blank'] if name.to_s.empty?
|
data/ext/adapter.cc
CHANGED
@@ -86,10 +86,9 @@ static VALUE adapter_execute(int argc, VALUE *argv, VALUE self) {
|
|
86
86
|
if (RARRAY_LEN(bind_values) > 0) query_bind_values(&query, bind_values);
|
87
87
|
if (dbi::_trace) dbi::logMessage(dbi::_trace_fd, dbi::formatParams(query.sql, query.bind));
|
88
88
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
rows = query_execute(&query);
|
89
|
+
if ((rows = rb_thread_blocking_region(((VALUE (*)(void*))query_execute), &query, RUBY_UBF_IO, 0)) == Qfalse)
|
90
|
+
rb_raise(eSwiftRuntimeError, "%s", query.error);
|
91
|
+
|
93
92
|
if (rb_block_given_p()) {
|
94
93
|
dbi::AbstractResultSet *result = handle->results();
|
95
94
|
return result_each(Data_Wrap_Struct(cSwiftResult, 0, result_free, result));
|
data/ext/extconf.rb
CHANGED
@@ -55,6 +55,6 @@ exit 1 unless library_installed? 'pcrecpp', apt_install_hint('libpcre3-dev')
|
|
55
55
|
exit 1 unless library_installed? 'uuid', apt_install_hint('uuid-dev')
|
56
56
|
exit 1 unless library_installed? 'dbic++', apt_install_hint('dbic++-dev')
|
57
57
|
|
58
|
-
assert_dbicpp_version '0.3.
|
58
|
+
assert_dbicpp_version '0.3.1'
|
59
59
|
|
60
60
|
create_makefile 'swift'
|
data/ext/query.cc
CHANGED
@@ -1,19 +1,31 @@
|
|
1
1
|
#include "query.h"
|
2
2
|
|
3
3
|
VALUE query_execute(Query *query) {
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
try {
|
5
|
+
return UINT2NUM(
|
6
|
+
query->bind.size() == 0
|
7
|
+
? query->handle->conn()->execute(query->sql)
|
8
|
+
: query->handle->conn()->execute(query->sql, query->bind)
|
9
|
+
);
|
10
|
+
}
|
11
|
+
catch (dbi::Error &e) {
|
12
|
+
query->error = e.what();
|
13
|
+
return Qfalse;
|
14
|
+
}
|
9
15
|
}
|
10
16
|
|
11
17
|
VALUE query_execute_statement(Query *query) {
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
18
|
+
try {
|
19
|
+
return UINT2NUM(
|
20
|
+
query->bind.size() == 0
|
21
|
+
? query->statement->execute()
|
22
|
+
: query->statement->execute(query->bind)
|
23
|
+
);
|
24
|
+
}
|
25
|
+
catch (dbi::Error &e) {
|
26
|
+
query->error = e.what();
|
27
|
+
return Qfalse;
|
28
|
+
}
|
17
29
|
}
|
18
30
|
|
19
31
|
void query_bind_values(Query *query, VALUE bind_values) {
|
@@ -23,6 +35,12 @@ void query_bind_values(Query *query, VALUE bind_values) {
|
|
23
35
|
if (bind_value == Qnil) {
|
24
36
|
query->bind.push_back(dbi::PARAM(dbi::null()));
|
25
37
|
}
|
38
|
+
else if (bind_value == Qtrue) {
|
39
|
+
query->bind.push_back(dbi::PARAM("1"));
|
40
|
+
}
|
41
|
+
else if (bind_value == Qfalse) {
|
42
|
+
query->bind.push_back(dbi::PARAM("0"));
|
43
|
+
}
|
26
44
|
else if (rb_obj_is_kind_of(bind_value, rb_cIO) == Qtrue || rb_obj_is_kind_of(bind_value, cStringIO) == Qtrue) {
|
27
45
|
bind_value = rb_funcall(bind_value, rb_intern("read"), 0);
|
28
46
|
query->bind.push_back(dbi::PARAM_BINARY((unsigned char*)RSTRING_PTR(bind_value), RSTRING_LEN(bind_value)));
|
data/ext/query.h
CHANGED
data/ext/result.cc
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
#include "result.h"
|
2
2
|
|
3
|
-
VALUE
|
3
|
+
VALUE cBigDecimal;
|
4
|
+
VALUE cDate;
|
4
5
|
VALUE cDateTime;
|
5
6
|
VALUE cStringIO;
|
6
|
-
VALUE
|
7
|
+
VALUE cSwiftResult;
|
7
8
|
|
8
9
|
VALUE fNew, fNewBang;
|
9
10
|
|
@@ -91,6 +92,7 @@ static VALUE result_finish(VALUE self) {
|
|
91
92
|
int64_t client_tzoffset(int64_t local, int isdst) {
|
92
93
|
struct tm tm;
|
93
94
|
gmtime_r((const time_t*)&local, &tm);
|
95
|
+
// TODO: This won't work in Lord Howe Island, Australia which uses half hour shift.
|
94
96
|
return (int64_t)(local + (isdst ? 3600 : 0) - mktime(&tm));
|
95
97
|
}
|
96
98
|
|
@@ -106,7 +108,7 @@ static void reduce(uint64_t *numerator, uint64_t *denominator) {
|
|
106
108
|
*denominator = *denominator / b;
|
107
109
|
}
|
108
110
|
|
109
|
-
VALUE
|
111
|
+
VALUE typecast_timestamp(VALUE klass, const char *data, uint64_t len) {
|
110
112
|
struct tm tm;
|
111
113
|
int64_t epoch, adjust, offset;
|
112
114
|
|
@@ -141,24 +143,27 @@ VALUE typecast_datetime(const char *data, uint64_t len) {
|
|
141
143
|
}
|
142
144
|
|
143
145
|
// 32bit platforms are for weenies
|
144
|
-
uint64_t ajd_n = (epoch + adjust - offset), ajd_d =
|
146
|
+
uint64_t ajd_n = (epoch + adjust - offset)*1000000 + usec*1000000, ajd_d = DAYMICROSECS;
|
145
147
|
reduce(&ajd_n, &ajd_d);
|
146
148
|
ajd_n = epoch_ajd_n*ajd_d + ajd_n*epoch_ajd_d;
|
147
149
|
ajd_d = epoch_ajd_d*ajd_d;
|
148
150
|
reduce(&ajd_n, &ajd_d);
|
149
151
|
|
150
152
|
VALUE ajd = rb_rational_new(SIZET2NUM(ajd_n), SIZET2NUM(ajd_d));
|
151
|
-
return rb_funcall(
|
153
|
+
return rb_funcall(klass, fNewBang, 3, ajd, rb_rational_new(INT2FIX(adjust), daysecs), sg);
|
152
154
|
}
|
153
155
|
|
154
156
|
// TODO: throw a warning ?
|
155
157
|
return rb_str_new(data, len);
|
156
158
|
}
|
157
159
|
|
160
|
+
#define typecast_datetime(data,len) typecast_timestamp(cDateTime, data, len)
|
161
|
+
#define typecast_date(data,len) typecast_timestamp(cDate, data, len)
|
162
|
+
|
158
163
|
VALUE typecast_field(int type, const char *data, uint64_t length) {
|
159
164
|
switch(type) {
|
160
165
|
case DBI_TYPE_BOOLEAN:
|
161
|
-
return
|
166
|
+
return (data && (data[0] =='t' || data[0] == '1')) ? Qtrue : Qfalse;
|
162
167
|
case DBI_TYPE_INT:
|
163
168
|
return rb_cstr2inum(data, 10);
|
164
169
|
case DBI_TYPE_BLOB:
|
@@ -167,6 +172,8 @@ VALUE typecast_field(int type, const char *data, uint64_t length) {
|
|
167
172
|
return rb_enc_str_new(data, length, rb_utf8_encoding());
|
168
173
|
case DBI_TYPE_TIME:
|
169
174
|
return typecast_datetime(data, length);
|
175
|
+
case DBI_TYPE_DATE:
|
176
|
+
return typecast_date(data, length);
|
170
177
|
case DBI_TYPE_NUMERIC:
|
171
178
|
return rb_funcall(cBigDecimal, fNew, 1, rb_str_new2(data));
|
172
179
|
case DBI_TYPE_FLOAT:
|
@@ -219,6 +226,7 @@ void init_swift_result() {
|
|
219
226
|
VALUE mSwift = rb_define_module("Swift");
|
220
227
|
cSwiftResult = rb_define_class_under(mSwift, "Result", rb_cObject);
|
221
228
|
cDateTime = CONST_GET(rb_mKernel, "DateTime");
|
229
|
+
cDate = CONST_GET(rb_mKernel, "Date");
|
222
230
|
cStringIO = CONST_GET(rb_mKernel, "StringIO");
|
223
231
|
cBigDecimal = CONST_GET(rb_mKernel, "BigDecimal");
|
224
232
|
|
data/ext/statement.cc
CHANGED
@@ -37,10 +37,8 @@ static VALUE statement_execute(int argc, VALUE *argv, VALUE self) {
|
|
37
37
|
if (RARRAY_LEN(bind_values) > 0) query_bind_values(&query, bind_values);
|
38
38
|
if (dbi::_trace) dbi::logMessage(dbi::_trace_fd, dbi::formatParams(statement->command(), query.bind));
|
39
39
|
|
40
|
-
|
41
|
-
|
42
|
-
// rb_thread_blocking_region(((VALUE (*)(void*))query_execute_statement), &query, RUBY_UBF_IO, 0);
|
43
|
-
query_execute_statement(&query);
|
40
|
+
if (rb_thread_blocking_region(((VALUE (*)(void*))query_execute_statement), &query, RUBY_UBF_IO, 0) == Qfalse)
|
41
|
+
rb_raise(eSwiftRuntimeError, "%s", query.error);
|
44
42
|
}
|
45
43
|
CATCH_DBI_EXCEPTIONS();
|
46
44
|
|
data/ext/swift.h
CHANGED
@@ -17,10 +17,10 @@ extern VALUE eSwiftConnectionError;
|
|
17
17
|
|
18
18
|
#define CATCH_DBI_EXCEPTIONS() \
|
19
19
|
catch (dbi::ConnectionError &error) { \
|
20
|
-
rb_raise(eSwiftConnectionError, "%s",
|
20
|
+
rb_raise(eSwiftConnectionError, "%s", error.what()); \
|
21
21
|
} \
|
22
22
|
catch (dbi::Error &error) { \
|
23
|
-
rb_raise(eSwiftRuntimeError, "%s",
|
23
|
+
rb_raise(eSwiftRuntimeError, "%s", error.what()); \
|
24
24
|
}
|
25
25
|
|
26
26
|
#include "adapter.h"
|
@@ -31,5 +31,13 @@ extern VALUE eSwiftConnectionError;
|
|
31
31
|
#include "request.h"
|
32
32
|
#include "pool.h"
|
33
33
|
|
34
|
+
#undef SIZET2NUM
|
35
|
+
#ifdef HAVE_LONG_LONG
|
36
|
+
#define SIZET2NUM(x) ULL2NUM(x)
|
37
|
+
#define DAYMICROSECS 86400000000LL
|
38
|
+
#else
|
39
|
+
#define SIZET2NUM(x) ULONG2NUM(x)
|
40
|
+
#define DAYMICROSECS 86400000000L
|
34
41
|
#endif
|
35
42
|
|
43
|
+
#endif
|
data/lib/swift/adapter.rb
CHANGED
@@ -107,7 +107,7 @@ module Swift
|
|
107
107
|
when Type::Integer then attribute.serial ? 'serial' : 'integer'
|
108
108
|
when Type::Float then 'float'
|
109
109
|
when Type::BigDecimal then 'numeric'
|
110
|
-
when Type::
|
110
|
+
when Type::DateTime then 'timestamp'
|
111
111
|
when Type::Boolean then 'boolean'
|
112
112
|
when Type::IO then 'blob'
|
113
113
|
else 'text'
|
data/lib/swift/type.rb
CHANGED
@@ -2,11 +2,12 @@ module Swift
|
|
2
2
|
module Type
|
3
3
|
class BigDecimal < Attribute; end
|
4
4
|
class Boolean < Attribute; end
|
5
|
+
class Date < Attribute; end
|
6
|
+
class DateTime < Attribute; end
|
5
7
|
class Float < Attribute; end
|
6
8
|
class Integer < Attribute; end
|
7
9
|
class IO < Attribute; end
|
8
10
|
class String < Attribute; end
|
9
|
-
class Time < Attribute; end
|
10
11
|
end # Type
|
11
12
|
end # Swift
|
12
13
|
|
data/swift.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{swift}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.6.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Shane Hanna", "Bharanee 'Barney' Rathna"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-09-02}
|
13
13
|
s.description = %q{A rational rudimentary database abstraction.}
|
14
14
|
s.email = ["shane.hanna@gmail.com", "deepfryed@gmail.com"]
|
15
15
|
s.extensions = ["ext/extconf.rb"]
|
@@ -63,12 +63,13 @@ Gem::Specification.new do |s|
|
|
63
63
|
"test/test_scheme.rb",
|
64
64
|
"test/test_timestamps.rb",
|
65
65
|
"test/test_transactions.rb",
|
66
|
+
"test/test_types.rb",
|
66
67
|
"test/test_validations.rb"
|
67
68
|
]
|
68
69
|
s.homepage = %q{http://github.com/shanna/swift}
|
69
70
|
s.rdoc_options = ["--charset=UTF-8"]
|
70
71
|
s.require_paths = ["lib"]
|
71
|
-
s.rubygems_version = %q{1.3.
|
72
|
+
s.rubygems_version = %q{1.3.6}
|
72
73
|
s.summary = %q{A rational rudimentary database abstraction.}
|
73
74
|
s.test_files = [
|
74
75
|
"test/test_pool.rb",
|
@@ -82,6 +83,7 @@ Gem::Specification.new do |s|
|
|
82
83
|
"test/test_encoding.rb",
|
83
84
|
"test/test_timestamps.rb",
|
84
85
|
"test/test_scheme.rb",
|
86
|
+
"test/test_types.rb",
|
85
87
|
"examples/scheme.rb",
|
86
88
|
"examples/async.rb",
|
87
89
|
"examples/db.rb"
|
@@ -91,7 +93,7 @@ Gem::Specification.new do |s|
|
|
91
93
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
92
94
|
s.specification_version = 3
|
93
95
|
|
94
|
-
if Gem::Version.new(Gem::
|
96
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
95
97
|
s.add_development_dependency(%q<minitest>, [">= 1.7.0"])
|
96
98
|
s.add_development_dependency(%q<eventmachine>, [">= 0"])
|
97
99
|
else
|
data/test/test_scheme.rb
CHANGED
@@ -4,12 +4,12 @@ describe 'scheme' do
|
|
4
4
|
before do
|
5
5
|
@user = Class.new(Swift::Scheme) do
|
6
6
|
store :users
|
7
|
-
attribute :id, Swift::Type::Integer,
|
8
|
-
attribute :name, Swift::Type::String,
|
9
|
-
attribute :age, Swift::Type::Integer,
|
7
|
+
attribute :id, Swift::Type::Integer, serial: true, key: true
|
8
|
+
attribute :name, Swift::Type::String, default: "dave"
|
9
|
+
attribute :age, Swift::Type::Integer, default: 18
|
10
10
|
attribute :email, Swift::Type::String
|
11
|
-
attribute :verified, Swift::Type::Boolean,
|
12
|
-
attribute :created_at, Swift::Type::
|
11
|
+
attribute :verified, Swift::Type::Boolean, default: false
|
12
|
+
attribute :created_at, Swift::Type::DateTime, default: proc { Time.now }
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
data/test/test_types.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
|
3
|
+
describe 'Adapter' do
|
4
|
+
supported_by Swift::DB::Postgres, Swift::DB::Mysql do
|
5
|
+
describe 'typecasting' do
|
6
|
+
before do
|
7
|
+
@db = Swift.db
|
8
|
+
@db.execute %q{drop table if exists users}
|
9
|
+
@db.execute %q{
|
10
|
+
create table users(id serial, name text, age integer, height float, hacker bool, slacker bool, created date)
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'query result is typecast correctly' do
|
15
|
+
bind = [ 'jim', 32, 178.71, true, false ]
|
16
|
+
@db.execute %q{insert into users(name,age,height,hacker,slacker, created) values(?, ?, ?, ?, ?, now())}, *bind
|
17
|
+
|
18
|
+
result = @db.prepare(%q{select * from users limit 1}).execute.first
|
19
|
+
assert_kind_of Integer, result[:id]
|
20
|
+
assert_kind_of String, result[:name]
|
21
|
+
assert_kind_of Integer, result[:age]
|
22
|
+
assert_kind_of Float, result[:height]
|
23
|
+
assert_kind_of TrueClass, result[:hacker]
|
24
|
+
assert_kind_of FalseClass, result[:slacker]
|
25
|
+
assert_kind_of Date, result[:created]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 6
|
8
|
+
- 0
|
9
|
+
version: 0.6.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Shane Hanna
|
@@ -15,14 +15,13 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-09-02 00:00:00 +10:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
22
|
name: minitest
|
23
23
|
prerelease: false
|
24
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
25
|
requirements:
|
27
26
|
- - ">="
|
28
27
|
- !ruby/object:Gem::Version
|
@@ -37,7 +36,6 @@ dependencies:
|
|
37
36
|
name: eventmachine
|
38
37
|
prerelease: false
|
39
38
|
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
-
none: false
|
41
39
|
requirements:
|
42
40
|
- - ">="
|
43
41
|
- !ruby/object:Gem::Version
|
@@ -103,10 +101,8 @@ files:
|
|
103
101
|
- test/test_scheme.rb
|
104
102
|
- test/test_timestamps.rb
|
105
103
|
- test/test_transactions.rb
|
104
|
+
- test/test_types.rb
|
106
105
|
- test/test_validations.rb
|
107
|
-
- examples/scheme.rb
|
108
|
-
- examples/async.rb
|
109
|
-
- examples/db.rb
|
110
106
|
has_rdoc: true
|
111
107
|
homepage: http://github.com/shanna/swift
|
112
108
|
licenses: []
|
@@ -117,7 +113,6 @@ rdoc_options:
|
|
117
113
|
require_paths:
|
118
114
|
- lib
|
119
115
|
required_ruby_version: !ruby/object:Gem::Requirement
|
120
|
-
none: false
|
121
116
|
requirements:
|
122
117
|
- - ">="
|
123
118
|
- !ruby/object:Gem::Version
|
@@ -125,7 +120,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
125
120
|
- 0
|
126
121
|
version: "0"
|
127
122
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
128
|
-
none: false
|
129
123
|
requirements:
|
130
124
|
- - ">="
|
131
125
|
- !ruby/object:Gem::Version
|
@@ -135,7 +129,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
135
129
|
requirements: []
|
136
130
|
|
137
131
|
rubyforge_project:
|
138
|
-
rubygems_version: 1.3.
|
132
|
+
rubygems_version: 1.3.6
|
139
133
|
signing_key:
|
140
134
|
specification_version: 3
|
141
135
|
summary: A rational rudimentary database abstraction.
|
@@ -151,6 +145,7 @@ test_files:
|
|
151
145
|
- test/test_encoding.rb
|
152
146
|
- test/test_timestamps.rb
|
153
147
|
- test/test_scheme.rb
|
148
|
+
- test/test_types.rb
|
154
149
|
- examples/scheme.rb
|
155
150
|
- examples/async.rb
|
156
151
|
- examples/db.rb
|