Skip to content

Commit

Permalink
Use Builder class to manipulate args into docs formatted for driver API
Browse files Browse the repository at this point in the history
  • Loading branch information
estolfo committed Feb 6, 2018
1 parent 0525854 commit 261e341
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 10 deletions.
1 change: 1 addition & 0 deletions lib/rom/mongo.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'mongo'
require 'rom/core'

require 'rom/mongo/version'
Expand Down
32 changes: 32 additions & 0 deletions lib/rom/mongo/builder.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
module ROM
module Mongo
module Builder

SORT_DIRECTION_MAP = {
asc: ::Mongo::Index::ASCENDING,
desc: ::Mongo::Index::DESCENDING,
}

extend self

def to_projection(fields)
fields.inject({}) do |doc, f|
doc.merge!(f => 1)
end
end


def to_sort_doc(doc)
doc.inject({}) do |sort_doc, (key, value)|
if SORT_DIRECTION_MAP.values.include?(value)
sort_doc.merge!(key => value)
elsif direction = SORT_DIRECTION_MAP[value]
sort_doc.merge!(key => direction)
else
sort_doc
end
end
end
end
end
end
9 changes: 4 additions & 5 deletions lib/rom/mongo/dataset.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require 'rom/mongo/builder'

module ROM
module Mongo
class Dataset
Expand Down Expand Up @@ -46,10 +48,7 @@ def where(doc)
end

def only(fields)
projection_doc = fields.inject({}) do |doc, f|
doc.merge!(f => 1)
end
dataset(criteria.projection(projection_doc))
dataset(criteria.projection(Builder.to_projection(fields)))
end

def without(fields)
Expand All @@ -65,7 +64,7 @@ def skip(value)
end

def sort(value)
dataset(criteria.sort(value))
dataset(criteria.sort(Builder.to_sort_doc(value)))
end
alias :order :sort

Expand Down
1 change: 0 additions & 1 deletion lib/rom/mongo/gateway.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
require 'mongo'
require 'uri'

require 'rom/gateway'
Expand Down
55 changes: 55 additions & 0 deletions spec/unit/builder_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
require 'spec_helper'

RSpec.describe ROM::Mongo::Builder do

describe '#to_projection' do

let(:result) do
described_class.to_projection([:name, :address])
end

it 'converts the fields into a document with 1 values' do
expect(result).to eq({ name: 1, address: 1})
end
end

describe '#to_sort_doc' do

let(:result) do
described_class.to_sort_doc(arg)
end

context 'when symbols are used as the direction' do

let(:arg) do
{name: :asc, address: :desc}
end

it 'converts the fields into a document with 1 values' do
expect(result).to eq({ name: 1, address: -1 })
end
end

context 'when integers are used as the direction' do

let(:arg) do
{name: 1, address: -1}
end

it 'converts the fields into a document with 1 values' do
expect(result).to eq({ name: 1, address: -1 })
end
end

context 'when the direction is invalid' do

let(:arg) do
{name: 1, address: :invalid}
end

it 'ignores the invalid direction' do
expect(result).to eq({ name: 1 })
end
end
end
end
8 changes: 4 additions & 4 deletions spec/unit/relation_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,18 @@

describe '#order' do
it 'sorts documents' do
expect(users.order(name: Mongo::Index::ASCENDING).only(:name).without(:_id).to_a.map(&:to_h)).
expect(users.order(name: :asc).only(:name).without(:_id).to_a.map(&:to_h)).
to eql([{name: 'Jane',}, {name: 'Joe'}])

expect(users.order(name: Mongo::Index::DESCENDING).only(:name).without(:_id).to_a.map(&:to_h)).
expect(users.order(name: :desc).only(:name).without(:_id).to_a.map(&:to_h)).
to eql([{name: 'Joe'}, {name: 'Jane'}])
end

it 'supports mutli-field sorting' do
expect(users.order(name: Mongo::Index::ASCENDING, email: Mongo::Index::ASCENDING).only(:name).without(:_id).to_a.map(&:to_h)).
expect(users.order(name: :asc, email: :asc).only(:name).without(:_id).to_a.map(&:to_h)).
to eql([{name: 'Jane',}, {name: 'Joe'}])

expect(users.order(email: Mongo::Index::ASCENDING, name: Mongo::Index::ASCENDING).only(:name).without(:_id).to_a.map(&:to_h)).
expect(users.order(email: :asc, name: :asc).only(:name).without(:_id).to_a.map(&:to_h)).
to eql([{name: 'Joe',}, {name: 'Jane'}])
end
end
Expand Down

0 comments on commit 261e341

Please sign in to comment.