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 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