Skip to content
This repository has been archived by the owner on Apr 18, 2018. It is now read-only.

Commit

Permalink
Add a mapping API to the repository.
Browse files Browse the repository at this point in the history
  • Loading branch information
pgr0ss committed Apr 13, 2012
1 parent 38de9af commit 0012233
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 2 deletions.
1 change: 1 addition & 0 deletions lib/curator.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require 'rubygems'

require 'curator/mapper'
require 'curator/migration'
require 'curator/migrator'
require 'curator/model'
Expand Down
27 changes: 27 additions & 0 deletions lib/curator/mapper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module Curator
class Mapper
def initialize(field_name, options)
@field_name = field_name
@serialize_function = options[:serialize]
@deserialize_function = options[:deserialize]
end

def deserialize(attributes)
_map(attributes, @deserialize_function)
end

def serialize(attributes)
_map(attributes, @serialize_function)
end

def _map(attributes, mapping_function)
current_value = attributes[@field_name]
if current_value && mapping_function
mapped_value = mapping_function.call(current_value)
attributes.merge(@field_name => mapped_value)
else
attributes
end
end
end
end
14 changes: 12 additions & 2 deletions lib/curator/repository.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,14 @@ def klass
name.to_s.gsub("Repository", "").constantize
end

def map(field_name, options)
_mappers << Mapper.new(field_name, options)
end

def _mappers
@mappers ||= []
end

def migrator
@migrator ||= Curator::Migrator.new(collection_name)
end
Expand Down Expand Up @@ -82,7 +90,8 @@ def save_without_timestamps(object)
end

def serialize(object)
object.instance_values
attributes = object.instance_values.with_indifferent_access
_mappers.inject(attributes) { |attrs, mapper| mapper.serialize(attrs) }
end

def _build_finder_methods(field_name)
Expand All @@ -106,7 +115,8 @@ def _find_by_index(collection_name, field_name, value)
end

def deserialize(attributes)
klass.new(attributes)
mapped_attributes = _mappers.inject(attributes) { |attrs, mapper| mapper.deserialize(attrs) }
klass.new(mapped_attributes)
end

def _deserialize(id, data)
Expand Down
37 changes: 37 additions & 0 deletions spec/curator/mapper_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
require 'spec_helper'

describe Curator::Mapper do
describe "serialize" do
it "serializes a field" do
mapper = Curator::Mapper.new(:foo, :serialize => lambda { |v| v + 1 })
mapper.serialize(:foo => 1).should == {:foo => 2}
end

it "ignores other fields" do
mapper = Curator::Mapper.new(:foo, :serialize => lambda { |v| v + 1 })
mapper.serialize(:bar => 1).should == {:bar => 1}
end

it "leaves fields alone if there is no option" do
mapper = Curator::Mapper.new(:foo, {})
mapper.serialize(:foo => 1).should == {:foo => 1}
end
end

describe "deserialize" do
it "deserializes a field" do
mapper = Curator::Mapper.new(:foo, :deserialize => lambda { |v| v + 1 })
mapper.deserialize(:foo => 1).should == {:foo => 2}
end

it "ignores other fields" do
mapper = Curator::Mapper.new(:foo, :deserialize => lambda { |v| v + 1 })
mapper.deserialize(:bar => 1).should == {:bar => 1}
end

it "leaves fields alone if there is no option" do
mapper = Curator::Mapper.new(:foo, {})
mapper.deserialize(:foo => 1).should == {:foo => 1}
end
end
end
38 changes: 38 additions & 0 deletions spec/curator/repository_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -306,4 +306,42 @@ def migrate(hash)
repository.save_without_timestamps(model).should == model
end
end

describe "mapping" do
it "runs serialize and deserialize" do
repository = test_repository do
map :some_field, :serialize => lambda { |i| (i + 1).to_s }, :deserialize => lambda { |str| "5#{str}".to_i }
end

model = TestModel.new(:some_field => 3)
repository.save(model)

found_model = repository.find_by_id(model.id)
found_model.some_field.should == 54
end

it "does not change value when no serialize is specified" do
repository = test_repository do
map :some_field, :deserialize => lambda { |str| Date.parse(str) }
end

model = TestModel.new(:some_field => Date.today)
repository.save(model)

found_model = repository.find_by_id(model.id)
found_model.some_field.should == Date.today
end

it "leaves value as is when no deserialize is specified" do
repository = test_repository do
map :some_field, :serialize => lambda { |date| date.year }
end

model = TestModel.new(:some_field => Date.today)
repository.save(model)

found_model = repository.find_by_id(model.id)
found_model.some_field.should == Date.today.year
end
end
end

0 comments on commit 0012233

Please sign in to comment.