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

Commit

Permalink
Support boolean source '$exists foo.bar.baz'
Browse files Browse the repository at this point in the history
The seemingly unrelated test change is to prevent an exception in
BSON.serialize.
  • Loading branch information
glasser committed Nov 3, 2014
1 parent 3c287e7 commit 5fb534f
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 4 deletions.
1 change: 1 addition & 0 deletions Gemfile.lock
Expand Up @@ -2,6 +2,7 @@ PATH
remote: .
specs:
mosql (0.4.0)
bson (~> 1.10.2)
bson_ext
json
log4r
Expand Down
19 changes: 17 additions & 2 deletions lib/mosql/schema.rb
Expand Up @@ -159,10 +159,24 @@ def fetch_and_delete_dotted(obj, dotted)
val
end

def fetch_special_source(obj, source)
def fetch_exists(obj, dotted)
pieces = dotted.split(".")
while pieces.length > 1
key = pieces.shift
obj = obj[key]
return false unless obj.is_a?(Hash)
end
obj.has_key?(pieces.first)
end

def fetch_special_source(obj, source, original)
case source
when "$timestamp"
Sequel.function(:now)
when /^\$exists (.+)/
# We need to look in the cloned original object, not in the version that
# has had some fields deleted.
fetch_exists(original, $1)
else
raise SchemaError.new("Unknown source: #{source}")
end
Expand All @@ -189,14 +203,15 @@ def transform(ns, obj, schema=nil)
schema ||= find_ns!(ns)

obj = obj.dup
original = BSON.deserialize(BSON.serialize(obj))
row = []
schema[:columns].each do |col|

source = col[:source]
type = col[:type]

if source.start_with?("$")
v = fetch_special_source(obj, source)
v = fetch_special_source(obj, source, original)
else
v = fetch_and_delete_dotted(obj, source)
case v
Expand Down
1 change: 1 addition & 0 deletions mosql.gemspec
Expand Up @@ -19,6 +19,7 @@ Gem::Specification.new do |gem|
%w[sequel pg mongo bson_ext rake log4r json
].each { |dep| gem.add_runtime_dependency(dep) }
gem.add_runtime_dependency "mongoriver", "0.4"
gem.add_runtime_dependency "bson", "~> 1.10.2"

gem.add_development_dependency "minitest"
gem.add_development_dependency "mocha"
Expand Down
4 changes: 2 additions & 2 deletions test/functional/streamer.rb
Expand Up @@ -262,7 +262,7 @@ def build_streamer
@streamer.handle_op({ 'ns' => 'mosql_test.collection',
'op' => 'u',
'o2' => { '_id' => 'a' },
'o' => { 'var' => 1 << 70 },
'o' => { 'var' => 1 << 62 },
})
end
end
Expand All @@ -272,7 +272,7 @@ def build_streamer
@streamer.handle_op({ 'ns' => 'mosql_test.collection',
'op' => 'u',
'o2' => { '_id' => 'a' },
'o' => { 'var' => 1 << 70 },
'o' => { 'var' => 1 << 62 },
})
assert_equal(0, sequel[:sqltable].where(:_id => 'a').count)
end
Expand Down
42 changes: 42 additions & 0 deletions test/unit/lib/mosql/schema.rb
Expand Up @@ -343,6 +343,26 @@ def check(orig, path, expect, result)
- mosql_created:
:source: $timestamp
:type: timestamp
existence:
:meta:
:table: b_table
:columns:
- _id: TEXT
- has_foo:
:source: $exists foo
:type: BOOLEAN
- has_foo_bar:
:source: $exists foo.bar
:type: BOOLEAN
exists_and_value:
:meta:
:table: c_table
:columns:
- _id: TEXT
- foo: TEXT
- has_foo:
:source: $exists foo
:type: BOOLEAN
invalid:
:meta:
:table: invalid
Expand All @@ -362,6 +382,28 @@ def check(orig, path, expect, result)
assert_equal(['a', Sequel.function(:now)], r)
end

it 'translates $exists' do
r = @othermap.transform('db.existence', { '_id' => 'a' })
assert_equal(['a', false, false], r)
r = @othermap.transform('db.existence', { '_id' => 'a', 'foo' => nil })
assert_equal(['a', true, false], r)
r = @othermap.transform('db.existence', { '_id' => 'a', 'foo' => {} })
assert_equal(['a', true, false], r)
r = @othermap.transform('db.existence', { '_id' => 'a', 'foo' => {'bar' => nil} })
assert_equal(['a', true, true], r)
r = @othermap.transform('db.existence', { '_id' => 'a', 'foo' => {'bar' => 42} })
assert_equal(['a', true, true], r)
end

it 'can get $exists and value' do
r = @othermap.transform('db.exists_and_value', { '_id' => 'a' })
assert_equal(['a', nil, false], r)
r = @othermap.transform('db.exists_and_value', { '_id' => 'a', 'foo' => nil })
assert_equal(['a', nil, true], r)
r = @othermap.transform('db.exists_and_value', { '_id' => 'a', 'foo' => 'xxx' })
assert_equal(['a', 'xxx', true], r)
end

it 'rejects unknown specials' do
assert_raises(MoSQL::SchemaError) do
r = @othermap.transform('db.invalid', { '_id' => 'a' })
Expand Down

0 comments on commit 5fb534f

Please sign in to comment.