swift 0.8.0 → 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
- data/API.rdoc +5 -2
- data/README.rdoc +15 -15
- data/VERSION +1 -1
- data/ext/adapter.cc +26 -10
- data/ext/extconf.rb +1 -1
- data/ext/query.cc +2 -2
- data/ext/query.h +1 -1
- data/ext/result.cc +33 -14
- data/lib/swift/adapter.rb +29 -8
- data/lib/swift/db.rb +10 -0
- data/swift.gemspec +2 -2
- data/test/test_adapter.rb +15 -3
- data/test/test_scheme.rb +48 -0
- data/test/test_timestamps.rb +1 -1
- data/test/test_types.rb +1 -1
- metadata +3 -3
data/API.rdoc
CHANGED
@@ -25,6 +25,8 @@ Public API minus the optional stuff like Pool, IdentityMap, Migrations etc.
|
|
25
25
|
#rollback
|
26
26
|
#transaction #=> Adapter
|
27
27
|
#update #=> Result
|
28
|
+
#reconnect
|
29
|
+
#delete #=> Result
|
28
30
|
|
29
31
|
# TODO: DBI < Adapter
|
30
32
|
# returning? #=> true or false
|
@@ -33,6 +35,7 @@ Public API minus the optional stuff like Pool, IdentityMap, Migrations etc.
|
|
33
35
|
DB
|
34
36
|
Mysql < Adapter # TODO: Adapter::DBI?
|
35
37
|
Postgres < Adapter # TODO: Adapter::DBI?
|
38
|
+
Sqlite3 < Adapter # TODO: Adapter::DBI?
|
36
39
|
|
37
40
|
# Enumerable collection of Scheme or Hash tuples.
|
38
41
|
Result
|
@@ -40,9 +43,9 @@ Public API minus the optional stuff like Pool, IdentityMap, Migrations etc.
|
|
40
43
|
#insert_id #=> Numeric
|
41
44
|
#fields #=> [Symbol, ...] # Field names identical to .first.keys if rows > 0
|
42
45
|
|
43
|
-
Statement
|
46
|
+
Statement
|
44
47
|
.new #=> Statement
|
45
|
-
#execute #=>
|
48
|
+
#execute #=> Result
|
46
49
|
|
47
50
|
Scheme
|
48
51
|
.all #=> Result
|
data/README.rdoc
CHANGED
@@ -9,7 +9,7 @@ A rational rudimentary object relational mapper.
|
|
9
9
|
== Dependencies
|
10
10
|
|
11
11
|
* ruby >= 1.9.1
|
12
|
-
* dbic++ >= 0.
|
12
|
+
* dbic++ >= 0.5.3 (http://github.com/deepfryed/dbicpp)
|
13
13
|
* mysql >= 5.0.17, postgresql >= 8.4 or sqlite3 >= 3.7
|
14
14
|
|
15
15
|
== Features
|
@@ -217,25 +217,25 @@ Intel Core2Duo P8700 2.53GHz and stock PostgreSQL 8.4.1.
|
|
217
217
|
|
218
218
|
./simple.rb -n1 -r10000 -s ar -s dm -s sequel -s swift
|
219
219
|
|
220
|
-
benchmark sys
|
221
|
-
ar #create
|
222
|
-
ar #select 0.
|
223
|
-
ar #update 0.
|
220
|
+
benchmark sys user total real rss
|
221
|
+
ar #create 1.01 7.91 8.92 11.426 406.22m
|
222
|
+
ar #select 0.02 0.31 0.33 0.378 40.69m
|
223
|
+
ar #update 0.88 9.64 10.52 13.908 504.93m
|
224
224
|
|
225
|
-
dm #create 0.
|
226
|
-
dm #select 0.
|
227
|
-
dm #update 0.
|
225
|
+
dm #create 0.23 3.52 3.75 5.405 211.00m
|
226
|
+
dm #select 0.11 1.67 1.78 1.912 114.57m
|
227
|
+
dm #update 0.54 7.34 7.88 9.453 531.30m
|
228
228
|
|
229
|
-
sequel #create 0.
|
230
|
-
sequel #select 0.
|
231
|
-
sequel #update 0.
|
229
|
+
sequel #create 0.77 4.61 5.38 8.194 235.50m
|
230
|
+
sequel #select 0.01 0.13 0.14 0.180 12.73m
|
231
|
+
sequel #update 0.64 4.76 5.40 7.790 229.69m
|
232
232
|
|
233
|
-
swift #create 0.
|
234
|
-
swift #select 0.
|
235
|
-
swift #update 0.
|
233
|
+
swift #create 0.13 0.66 0.79 1.463 85.77m
|
234
|
+
swift #select 0.01 0.10 0.11 0.135 8.92m
|
235
|
+
swift #update 0.14 0.75 0.89 1.585 59.56m
|
236
236
|
|
237
237
|
-- bulk insert api --
|
238
|
-
swift #write 0.
|
238
|
+
swift #write 0.00 0.10 0.10 0.180 14.79m
|
239
239
|
|
240
240
|
|
241
241
|
==== Adapter
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.8.
|
1
|
+
0.8.1
|
data/ext/adapter.cc
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
#include "adapter.h"
|
2
2
|
|
3
|
+
// extend the default dbi::FieldSet class with some ruby love.
|
4
|
+
class Fields : public dbi::FieldSet {
|
5
|
+
public:
|
6
|
+
Fields() : dbi::FieldSet(0) {}
|
7
|
+
|
8
|
+
void operator<<(VALUE v) {
|
9
|
+
VALUE name = TO_S(v);
|
10
|
+
fields.push_back(std::string(RSTRING_PTR(name), RSTRING_LEN(name)));
|
11
|
+
}
|
12
|
+
};
|
13
|
+
|
3
14
|
static VALUE cSwiftAdapter;
|
4
15
|
|
5
16
|
static void adapter_free(dbi::Handle *handle) {
|
@@ -98,6 +109,12 @@ static VALUE adapter_execute(int argc, VALUE *argv, VALUE self) {
|
|
98
109
|
CATCH_DBI_EXCEPTIONS();
|
99
110
|
}
|
100
111
|
|
112
|
+
static VALUE adapter_reconnect(VALUE self) {
|
113
|
+
dbi::Handle *handle = adapter_handle(self);
|
114
|
+
try { handle->reconnect(); } CATCH_DBI_EXCEPTIONS();
|
115
|
+
return Qtrue;
|
116
|
+
}
|
117
|
+
|
101
118
|
static VALUE adapter_initialize(VALUE self, VALUE options) {
|
102
119
|
VALUE db = rb_hash_aref(options, ID2SYM(rb_intern("db")));
|
103
120
|
VALUE driver = rb_hash_aref(options, ID2SYM(rb_intern("driver")));
|
@@ -197,11 +214,9 @@ static VALUE adapter_write(int argc, VALUE *argv, VALUE self) {
|
|
197
214
|
rb_raise(eSwiftArgumentError, "Fields must be an Array.");
|
198
215
|
|
199
216
|
try {
|
200
|
-
|
201
|
-
for (int i = 0; i < RARRAY_LEN(fields); i++)
|
202
|
-
|
203
|
-
write_fields << std::string(RSTRING_PTR(field), RSTRING_LEN(field));
|
204
|
-
}
|
217
|
+
Fields write_fields;
|
218
|
+
for (int i = 0; i < RARRAY_LEN(fields); i++)
|
219
|
+
write_fields << rb_ary_entry(fields, i);
|
205
220
|
|
206
221
|
/*
|
207
222
|
TODO: Adapter specific code is balls.
|
@@ -228,17 +243,18 @@ void init_swift_adapter() {
|
|
228
243
|
cSwiftAdapter = rb_define_class_under(mSwift, "Adapter", rb_cObject);
|
229
244
|
|
230
245
|
rb_define_method(cSwiftAdapter, "begin", RUBY_METHOD_FUNC(adapter_begin), -1);
|
231
|
-
rb_define_method(cSwiftAdapter, "clone", RUBY_METHOD_FUNC(adapter_clone),
|
232
|
-
rb_define_method(cSwiftAdapter, "close", RUBY_METHOD_FUNC(adapter_close),
|
246
|
+
rb_define_method(cSwiftAdapter, "clone", RUBY_METHOD_FUNC(adapter_clone), 0);
|
247
|
+
rb_define_method(cSwiftAdapter, "close", RUBY_METHOD_FUNC(adapter_close), 0);
|
233
248
|
rb_define_method(cSwiftAdapter, "commit", RUBY_METHOD_FUNC(adapter_commit), -1);
|
234
|
-
rb_define_method(cSwiftAdapter, "dup", RUBY_METHOD_FUNC(adapter_dup),
|
235
|
-
rb_define_method(cSwiftAdapter, "escape", RUBY_METHOD_FUNC(adapter_escape),
|
249
|
+
rb_define_method(cSwiftAdapter, "dup", RUBY_METHOD_FUNC(adapter_dup), 0);
|
250
|
+
rb_define_method(cSwiftAdapter, "escape", RUBY_METHOD_FUNC(adapter_escape), 1);
|
236
251
|
rb_define_method(cSwiftAdapter, "execute", RUBY_METHOD_FUNC(adapter_execute), -1);
|
237
|
-
rb_define_method(cSwiftAdapter, "initialize", RUBY_METHOD_FUNC(adapter_initialize),
|
252
|
+
rb_define_method(cSwiftAdapter, "initialize", RUBY_METHOD_FUNC(adapter_initialize), 1);
|
238
253
|
rb_define_method(cSwiftAdapter, "prepare", RUBY_METHOD_FUNC(adapter_prepare), -1);
|
239
254
|
rb_define_method(cSwiftAdapter, "rollback", RUBY_METHOD_FUNC(adapter_rollback), -1);
|
240
255
|
rb_define_method(cSwiftAdapter, "transaction", RUBY_METHOD_FUNC(adapter_transaction), -1);
|
241
256
|
rb_define_method(cSwiftAdapter, "write", RUBY_METHOD_FUNC(adapter_write), -1);
|
257
|
+
rb_define_method(cSwiftAdapter, "reconnect", RUBY_METHOD_FUNC(adapter_reconnect), 0);
|
242
258
|
|
243
259
|
rb_define_alloc_func(cSwiftAdapter, adapter_alloc);
|
244
260
|
}
|
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.5.
|
58
|
+
assert_dbicpp_version '0.5.4'
|
59
59
|
|
60
60
|
create_makefile 'swift'
|
data/ext/query.cc
CHANGED
@@ -12,7 +12,7 @@ VALUE query_execute(Query *query) {
|
|
12
12
|
);
|
13
13
|
}
|
14
14
|
catch (dbi::Error &e) {
|
15
|
-
query->error
|
15
|
+
snprintf(query->error, 8192, "%s", e.what());
|
16
16
|
return Qfalse;
|
17
17
|
}
|
18
18
|
}
|
@@ -26,7 +26,7 @@ VALUE query_execute_statement(Query *query) {
|
|
26
26
|
);
|
27
27
|
}
|
28
28
|
catch (dbi::Error &e) {
|
29
|
-
query->error
|
29
|
+
snprintf(query->error, 8192, "%s", e.what());
|
30
30
|
return Qfalse;
|
31
31
|
}
|
32
32
|
}
|
data/ext/query.h
CHANGED
data/ext/result.cc
CHANGED
@@ -138,24 +138,27 @@ int64_t server_tzoffset(struct tm* tm, const char *zone) {
|
|
138
138
|
|
139
139
|
VALUE typecast_timestamp(const char *data, uint64_t len, const char *zone) {
|
140
140
|
struct tm tm;
|
141
|
-
int64_t epoch, adjust, offset;
|
142
141
|
uint64_t usec = 0;
|
142
|
+
int64_t epoch, adjust, offset;
|
143
143
|
char tzsign = 0, subsec[32];
|
144
|
-
int tzhour = 0, tzmin = 0;
|
144
|
+
int tzhour = 0, tzmin = 0, lastmatch = -1;
|
145
145
|
|
146
146
|
memset(&tm, 0, sizeof(struct tm));
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
147
|
+
sscanf(data, "%04d-%02d-%02d %02d:%02d:%02d%n",
|
148
|
+
&tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &lastmatch);
|
149
|
+
|
150
|
+
// parse millisecs if any
|
151
|
+
if (lastmatch > 0 && lastmatch < len && *(data+lastmatch) == '.') {
|
152
|
+
lastmatch++;
|
153
|
+
int idx = 0;
|
154
|
+
const char *ptr = data + lastmatch;
|
155
|
+
while (*ptr && *ptr >= '0' && *ptr <= '9' && idx < 31) {
|
156
|
+
subsec[idx++] = *ptr;
|
157
|
+
ptr++;
|
158
|
+
lastmatch++;
|
159
|
+
}
|
160
|
+
subsec[idx] = 0;
|
161
|
+
usec = atoll(subsec);
|
159
162
|
}
|
160
163
|
|
161
164
|
tm.tm_year -= 1900;
|
@@ -166,6 +169,22 @@ VALUE typecast_timestamp(const char *data, uint64_t len, const char *zone) {
|
|
166
169
|
adjust = client_tzoffset(epoch, tm.tm_isdst);
|
167
170
|
offset = adjust;
|
168
171
|
|
172
|
+
// parse timezone offsets if any - matches +HH:MM +HH MM +HHMM
|
173
|
+
if (lastmatch > 0 && lastmatch < len) {
|
174
|
+
const char *ptr = data + lastmatch;
|
175
|
+
while(*ptr && *ptr != '+' && *ptr != '-') ptr++;
|
176
|
+
tzsign = *ptr++;
|
177
|
+
if (*ptr && *ptr >= '0' && *ptr <= '9') {
|
178
|
+
tzhour = *ptr++ - '0';
|
179
|
+
if (*ptr && *ptr >= '0' && *ptr <= '9') tzhour = tzhour*10 + *ptr++ - '0';
|
180
|
+
while(*ptr && (*ptr < '0' || *ptr > '9')) ptr++;
|
181
|
+
if (*ptr && *ptr >= '0' && *ptr <= '9') {
|
182
|
+
tzmin = *ptr++ - '0';
|
183
|
+
if (*ptr && *ptr >= '0' && *ptr <= '9') tzmin = tzmin*10 + *ptr++ - '0';
|
184
|
+
}
|
185
|
+
}
|
186
|
+
}
|
187
|
+
|
169
188
|
if (tzsign) {
|
170
189
|
offset = tzsign == '+'
|
171
190
|
? (time_t)tzhour * 3600 + (time_t)tzmin * 60
|
data/lib/swift/adapter.rb
CHANGED
@@ -83,9 +83,9 @@ module Swift
|
|
83
83
|
# @example Multiple relations.
|
84
84
|
# apple = User.new(name: 'Apple Arthurton', age: 32)
|
85
85
|
# benny = User.new(name: 'Benny Arthurton', age: 30)
|
86
|
-
# Swift.db.
|
86
|
+
# Swift.db.create(User, apple, benny)
|
87
87
|
# @example Coerce multiple relations.
|
88
|
-
# Swift.db.
|
88
|
+
# Swift.db.create(User, {name: 'Apple Arthurton', age: 32}, {name: 'Benny Arthurton', age: 30})
|
89
89
|
#
|
90
90
|
# @param [Swift::Scheme] scheme Concrete scheme subclass to load.
|
91
91
|
# @param [Swift::Scheme, Hash> *relations Scheme or tuple hash. Hashes will be coerced into scheme via Swift::Scheme#new
|
@@ -95,9 +95,8 @@ module Swift
|
|
95
95
|
statement = prepare_create(scheme)
|
96
96
|
relations.map do |relation|
|
97
97
|
relation = scheme.new(relation) unless relation.kind_of?(scheme)
|
98
|
-
|
99
|
-
|
100
|
-
end
|
98
|
+
result = statement.execute(*relation.tuple.values_at(*scheme.header.insertable))
|
99
|
+
relation.tuple[scheme.header.serial] = result.insert_id if scheme.header.serial
|
101
100
|
relation
|
102
101
|
end
|
103
102
|
end
|
@@ -129,7 +128,9 @@ module Swift
|
|
129
128
|
statement = prepare_update(scheme)
|
130
129
|
relations.map do |relation|
|
131
130
|
relation = scheme.new(relation) unless relation.kind_of?(scheme)
|
132
|
-
|
131
|
+
keys = relation.tuple.values_at(*scheme.header.keys)
|
132
|
+
raise ArgumentError, "relation has incomplete key : #{relation.inspect}" unless keys.select(&:nil?).empty?
|
133
|
+
statement.execute(*relation.tuple.values_at(*scheme.header.updatable), *keys)
|
133
134
|
relation
|
134
135
|
end
|
135
136
|
end
|
@@ -160,19 +161,39 @@ module Swift
|
|
160
161
|
statement = prepare_destroy(scheme)
|
161
162
|
relations.map do |relation|
|
162
163
|
relation = scheme.new(relation) unless relation.kind_of?(scheme)
|
163
|
-
|
164
|
+
keys = relation.tuple.values_at(*scheme.header.keys)
|
165
|
+
raise ArgumentError, "relation has incomplete key : #{relation.inspect}" unless keys.select(&:nil?).empty?
|
166
|
+
if result = statement.execute(*keys)
|
164
167
|
relation.freeze
|
165
168
|
end
|
166
169
|
result
|
167
170
|
end
|
168
171
|
end
|
169
172
|
|
173
|
+
|
174
|
+
# Delete one or more rows
|
175
|
+
#
|
176
|
+
# @example All.
|
177
|
+
# Swift.db.delete(User)
|
178
|
+
# @example All with conditions and binds.
|
179
|
+
# Swift.db.delete(User, ':name = ? and :age > ?', 'Apple Arthurton', 32)
|
180
|
+
#
|
181
|
+
# @param [Swift::Scheme] scheme Concrete scheme subclass
|
182
|
+
# @param [String] conditions Optional SQL 'where' fragment.
|
183
|
+
# @param [Object, ...] *binds Optional bind values that accompany conditions SQL fragment.
|
184
|
+
# @return [Swift::Result]
|
185
|
+
def delete scheme, conditions = '', *binds
|
186
|
+
sql = "delete from #{scheme.store}"
|
187
|
+
sql += " where #{exchange_names(scheme, conditions)}" unless conditions.empty?
|
188
|
+
execute(sql, *binds)
|
189
|
+
end
|
190
|
+
|
170
191
|
def migrate! scheme
|
171
192
|
keys = scheme.header.keys
|
172
193
|
fields = scheme.header.map{|p| field_definition(p)}.join(', ')
|
173
194
|
fields += ", primary key (#{keys.join(', ')})" unless keys.empty?
|
174
195
|
|
175
|
-
execute("drop table if exists #{scheme.store}")
|
196
|
+
execute("drop table if exists #{scheme.store} cascade")
|
176
197
|
execute("create table #{scheme.store} (#{fields})")
|
177
198
|
end
|
178
199
|
|
data/lib/swift/db.rb
CHANGED
@@ -8,6 +8,16 @@ module Swift
|
|
8
8
|
def returning?
|
9
9
|
false
|
10
10
|
end
|
11
|
+
|
12
|
+
# TODO Swift::Type::Bignum ?
|
13
|
+
# serial is an alias for bigint in mysql, we want integer type to be migrated as integer
|
14
|
+
# type in the database (not bigint or smallint or shortint or whatever).
|
15
|
+
def field_type attribute
|
16
|
+
case attribute
|
17
|
+
when Type::Integer then attribute.serial ? 'integer auto_increment' : 'integer'
|
18
|
+
else super
|
19
|
+
end
|
20
|
+
end
|
11
21
|
end # Mysql
|
12
22
|
|
13
23
|
class Sqlite3 < Adapter
|
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.
|
8
|
+
s.version = "0.8.1"
|
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{2011-01-
|
12
|
+
s.date = %q{2011-01-19}
|
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"]
|
data/test/test_adapter.rb
CHANGED
@@ -20,6 +20,12 @@ describe 'Adapter' do
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
+
it 'reconnects to db' do
|
24
|
+
Swift.trace true, open('/dev/null', 'w')
|
25
|
+
assert_block { @db.reconnect }
|
26
|
+
Swift.trace false
|
27
|
+
end
|
28
|
+
|
23
29
|
describe 'execute' do
|
24
30
|
it 'executes without bind values' do
|
25
31
|
assert @db.execute %q{select count(*) from users}
|
@@ -56,7 +62,9 @@ describe 'Adapter' do
|
|
56
62
|
when Swift::DB::Postgres then %q{insert into users (name) values (?) returning id}
|
57
63
|
else %q{insert into users (name) values (?)}
|
58
64
|
end
|
59
|
-
|
65
|
+
statement = @db.prepare(sql)
|
66
|
+
assert 1, statement.execute('Connie Arthurton').insert_id
|
67
|
+
assert 1, statement.insert_id # caches insert_id, just interface compatibility with dbic++
|
60
68
|
end
|
61
69
|
end
|
62
70
|
|
@@ -116,8 +124,12 @@ describe 'Adapter' do
|
|
116
124
|
end
|
117
125
|
|
118
126
|
it 'writes with no columns specified' do
|
119
|
-
|
120
|
-
|
127
|
+
ts = DateTime.parse('2010-01-01 00:00:00').to_time
|
128
|
+
data = "1\tSally Arthurton\tsally@local\t#{ts}\n"
|
129
|
+
row = {id: 1, name: 'Sally Arthurton', email: 'sally@local', created_at: ts}
|
130
|
+
|
131
|
+
assert_equal 1, @db.write('users', [], data)
|
132
|
+
assert_equal row, @db.execute('select * from users limit 1').first
|
121
133
|
end
|
122
134
|
end
|
123
135
|
end
|
data/test/test_scheme.rb
CHANGED
@@ -50,4 +50,52 @@ describe 'scheme' do
|
|
50
50
|
assert_equal 'cary@local', user.email
|
51
51
|
end
|
52
52
|
end
|
53
|
+
|
54
|
+
supported_by Swift::DB::Postgres, Swift::DB::Mysql, Swift::DB::Sqlite3 do
|
55
|
+
describe 'adapter operations' do
|
56
|
+
before do
|
57
|
+
Swift.db.migrate! @user
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'adapter should destroy valid instance' do
|
61
|
+
user = @user.create.first
|
62
|
+
assert_equal 1, user.id
|
63
|
+
|
64
|
+
assert Swift.db.destroy @user, user
|
65
|
+
assert_nil @user.get(id: 1)
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'adapter should barf when trying to destroy invalid instance' do
|
69
|
+
assert_raises(ArgumentError) { Swift.db.destroy @user, {id: nil, name: 'foo'} }
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'adapter should delete all rows given scheme' do
|
73
|
+
user = @user.create.first
|
74
|
+
assert_equal 1, user.id
|
75
|
+
|
76
|
+
Swift.db.delete @user
|
77
|
+
assert_nil @user.get(id: 1)
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'adapter should delete only relevant rows given condition & scheme' do
|
81
|
+
Swift.db.create(@user, {name: 'dave'}, {name: 'mike'})
|
82
|
+
assert_equal 2, @user.all.rows
|
83
|
+
|
84
|
+
Swift.db.delete @user, ':name = ?', 'dave'
|
85
|
+
assert_nil @user.first ':name = ?', 'dave'
|
86
|
+
assert @user.first ':name = ?', 'mike'
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should not update without valid keys' do
|
90
|
+
user = @user.new
|
91
|
+
assert_raises(ArgumentError) { user.update(name: 'dave') }
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should update with valid keys' do
|
95
|
+
user = @user.create.first
|
96
|
+
assert user.update(name: 'dave')
|
97
|
+
assert_equal 'dave', @user.first.name
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
53
101
|
end
|
data/test/test_timestamps.rb
CHANGED
@@ -3,7 +3,7 @@ require 'date'
|
|
3
3
|
|
4
4
|
describe 'Adapter' do
|
5
5
|
supported_by Swift::DB::Postgres do
|
6
|
-
%w(
|
6
|
+
%w(America/Chicago Australia/Melbourne).each do |timezone|
|
7
7
|
describe 'time parsing in %s' % timezone do
|
8
8
|
before do
|
9
9
|
@db = Swift.db
|
data/test/test_types.rb
CHANGED
@@ -40,7 +40,7 @@ describe 'Adapter' do
|
|
40
40
|
assert_kind_of Time, result[:updated]
|
41
41
|
|
42
42
|
assert_equal dt, result[:updated].strftime('%F %T')
|
43
|
-
assert_equal 12345, result[:updated].usec
|
43
|
+
assert_equal 12345, result[:updated].usec unless @db.kind_of?(Swift::DB::Mysql)
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 8
|
8
|
-
-
|
9
|
-
version: 0.8.
|
8
|
+
- 1
|
9
|
+
version: 0.8.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Shane Hanna
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-01-
|
18
|
+
date: 2011-01-19 00:00:00 +11:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|