Skip to content
This repository has been archived by the owner on Dec 22, 2020. It is now read-only.

Commit

Permalink
Fix a bug with updates on objects with BSON::ObjectId's.
Browse files Browse the repository at this point in the history
closes #9.
  • Loading branch information
nelhage committed Feb 14, 2013
1 parent fa2ce80 commit 187fa6e
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 10 deletions.
4 changes: 2 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
mosql (0.1.0)
mosql (0.1.1)
bson_ext
json
log4r
Expand All @@ -17,7 +17,7 @@ GEM
bson (1.8.2)
bson_ext (1.8.2)
bson (~> 1.8.2)
json (1.7.6)
json (1.7.7)
log4r (1.1.10)
metaclass (0.0.1)
minitest (3.0.0)
Expand Down
3 changes: 2 additions & 1 deletion lib/mosql/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -253,11 +253,12 @@ def optail
end

def sync_object(ns, _id)
sqlid = @sql.transform_one_ns(ns, { '_id' => _id })['_id']
obj = collection_for_ns(ns).find_one({:_id => _id})
if obj
@sql.upsert_ns(ns, obj)
else
@sql.table_for_ns(ns).where(:_id => _id).delete()
@sql.table_for_ns(ns).where(:_id => sqlid).delete()
end
end

Expand Down
16 changes: 9 additions & 7 deletions lib/mosql/sql.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,24 @@ def table_for_ns(ns)
@db[@schema.table_for_ns(ns).intern]
end


def upsert_ns(ns, obj)
def transform_one_ns(ns, obj)
h = {}
cols = @schema.all_columns(@schema.find_ns(ns))
row = @schema.transform(ns, obj)
cols.zip(row).each { |k,v| h[k] = v }
h
end

def upsert_ns(ns, obj)
h = transform_one_ns(ns, obj)
upsert(table_for_ns(ns), h)
end

# obj must contain an _id field. All other fields will be ignored.
def delete_ns(ns, obj)
cols = @schema.all_columns(@schema.find_ns(ns))
row = @schema.transform(ns, obj)
sqlid = row[cols.index("_id")]
raise "No _id found in transform of #{obj}" if sqlid.nil?
table_for_ns(ns).where(:_id => sqlid).delete
h = transform_one_ns(ns, obj)
raise "No _id found in transform of #{obj.inspect}" if h['_id'].nil?
table_for_ns(ns).where(:_id => h['_id']).delete
end

def upsert(table, item)
Expand Down
17 changes: 17 additions & 0 deletions test/functional/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,21 @@ def fake_cli
})
assert_equal(0, sequel[:sqltable].where(:_id => o['_id'].to_s).count)
end

it 'handle "u" ops with $set and BSON::ObjectIDs' do
o = { '_id' => BSON::ObjectId.new, 'var' => 17 }
@adapter.upsert_ns('mosql_test.collection', o)

# $set's are currently a bit of a hack where we read the object
# from the db, so make sure the new object exists in mongo
connect_mongo['mosql_test']['collection'].insert(o.merge('var' => 100),
:w => 1)

@cli.handle_op({ 'ns' => 'mosql_test.collection',
'op' => 'u',
'o2' => { '_id' => o['_id'] },
'o' => { '$set' => { 'var' => 100 } },
})
assert_equal(100, sequel[:sqltable].where(:_id => o['_id'].to_s).select.first[:var])
end
end

0 comments on commit 187fa6e

Please sign in to comment.