swift 0.8.0 → 0.8.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/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 < Result
46
+ Statement
44
47
  .new #=> Statement
45
- #execute #=> Statement
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.4.0 (http://github.com/deepfryed/dbicpp)
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 user total real rss
221
- ar #create 0.790000 8.290000 9.08000 11.679886 405.07m
222
- ar #select 0.040000 0.310000 0.35000 0.383573 40.56m
223
- ar #update 0.720000 9.890000 10.6100 13.765735 503.48m
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.310000 3.300000 3.61000 4.593075 211.01m
226
- dm #select 0.040000 1.720000 1.76000 1.776852 114.51m
227
- dm #update 0.450000 7.600000 8.05000 9.610320 531.26m
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.670000 4.670000 5.34000 7.991811 235.39m
230
- sequel #select 0.000000 0.130000 0.13000 0.178447 12.76m
231
- sequel #update 0.790000 4.540000 5.33000 7.854936 229.70m
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.100000 0.710000 0.81000 1.562289 85.84m
234
- swift #select 0.000000 0.120000 0.12000 0.145567 8.96m
235
- swift #update 0.190000 0.690000 0.88000 1.628918 59.50m
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.010000 0.100000 0.11000 0.180514 14.80m
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.0
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
- dbi::FieldSet write_fields;
201
- for (int i = 0; i < RARRAY_LEN(fields); i++) {
202
- VALUE field = TO_S(rb_ary_entry(fields, i));
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), 0);
232
- rb_define_method(cSwiftAdapter, "close", RUBY_METHOD_FUNC(adapter_close), 0);
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), 0);
235
- rb_define_method(cSwiftAdapter, "escape", RUBY_METHOD_FUNC(adapter_escape), 1);
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), 1);
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.2'
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 = e.what();
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 = e.what();
29
+ snprintf(query->error, 8192, "%s", e.what());
30
30
  return Qfalse;
31
31
  }
32
32
  }
data/ext/query.h CHANGED
@@ -8,7 +8,7 @@ struct Query {
8
8
  dbi::Handle *handle;
9
9
  dbi::AbstractStatement *statement;
10
10
  std::vector<dbi::Param> bind;
11
- const char *error;
11
+ char error[8192];
12
12
  };
13
13
 
14
14
  VALUE query_execute(Query*);
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
- // Based on github.com/jeremyevans/sequel_pg. atoll & pow seem to be tad faster than sscanf %Lf
148
- // NOTE: Reading subsec as string means malformed subsec > 32 digits could break this.
149
- if (strchr(data, '.')) {
150
- sscanf(data, "%04d-%02d-%02d %02d:%02d:%02d.%s%c%02d:%02d",
151
- &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec, subsec,
152
- &tzsign, &tzhour, &tzmin);
153
- usec = atoll(subsec)*(uint64_t)pow(10, 6 - strlen(subsec));
154
- }
155
- else {
156
- sscanf(data, "%04d-%02d-%02d %02d:%02d:%02d%c%02d:%02d",
157
- &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec,
158
- &tzsign, &tzhour, &tzmin);
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.first(User, apple, benny)
86
+ # Swift.db.create(User, apple, benny)
87
87
  # @example Coerce multiple relations.
88
- # Swift.db.first(User, {name: 'Apple Arthurton', age: 32}, {name: 'Benny Arthurton', age: 30})
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
- if statement.execute(*relation.tuple.values_at(*scheme.header.insertable)) && scheme.header.serial
99
- relation.tuple[scheme.header.serial] = statement.insert_id
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
- statement.execute(*relation.tuple.values_at(*scheme.header.updatable, *scheme.header.keys))
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
- if result = statement.execute(*relation.tuple.values_at(*scheme.header.keys))
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.0"
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-05}
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
- assert_kind_of Fixnum, @db.prepare(sql).execute('Connie Arthurton').insert_id
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
- data = "1\tSally Arthurton\tsally@local\t2010-01-01 00:00:00\n"
120
- assert_equal 1, @db.write('users', [], data)
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
@@ -3,7 +3,7 @@ require 'date'
3
3
 
4
4
  describe 'Adapter' do
5
5
  supported_by Swift::DB::Postgres do
6
- %w(Australia/Melboure America/Chicago).each do |timezone|
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 if @db.kind_of?(Swift::DB::Postgres)
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
- - 0
9
- version: 0.8.0
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-05 00:00:00 +11:00
18
+ date: 2011-01-19 00:00:00 +11:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency