Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implements in memory data store #20

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 1 addition & 2 deletions lib/perpetuity.rb
@@ -1,14 +1,13 @@
require "perpetuity/version"
require "perpetuity/retrieval"
require "perpetuity/mongodb"
require "perpetuity/config"
require "perpetuity/mapper"

module Perpetuity
def self.configure &block
configuration.instance_exec(&block)
end

def self.configuration
@configuration ||= Configuration.new
end
Expand Down
4 changes: 4 additions & 0 deletions lib/perpetuity/mapper_registry.rb
Expand Up @@ -13,5 +13,9 @@ def self.[] klass
def self.[]= klass, mapper
@mappers[klass] = mapper
end

def self.clear
@mappers.clear
end
end
end
100 changes: 100 additions & 0 deletions lib/perpetuity/memory.rb
@@ -0,0 +1,100 @@
require 'securerandom'

module Perpetuity
class Memory
def initialize options = {}
@cache = Hash.new
@indexes = Hash.new { |hash, key| hash[key] = active_indexes(key) }
end

def insert klass, attributes
unless attributes.has_key? :id
attributes[:id] = SecureRandom.uuid
end

# make keys indifferent
attributes.default_proc = proc do |h, k|
case k
when String then sym = k.to_sym; h[sym] if h.key?(sym)
when Symbol then str = k.to_s; h[str] if h.key?(str)
end
end

collection(klass) << attributes
attributes[:id]
end

def count klass
collection(klass).size
end

def delete_all klass
collection(klass).clear
end

def first klass
collection(klass).first
end

def retrieve klass, criteria, options = {}
collection(klass).find_all do |r|
criteria.all? do |field, value|
r[field] === value
end
end
end

def all klass
retrieve klass, {}, {}
end

def delete object, klass=nil
klass ||= object.class
id = object.class == String || !object.respond_to?(:id) ? object : object.id

collection(klass).each_with_index do |record, index|
if record[:id] === id
collection(klass).delete_at index
end
end
end

def update klass, id, new_data
collection(klass).each_with_index do |record, index|
if record[:id] == id
collection(klass)[index] = record.merge(new_data)
end
end
end

def can_serialize? value
true
end

def index klass, attribute, options={}
@indexes[klass] ||= Set.new
end

def indexes klass
@indexes[klass]
end

def active_indexes klass
Set.new
end

def activate_index! klass
true
end

def remove_index index
end

protected

def collection klass
@cache[klass] = Array.new unless @cache.key? klass
@cache[klass]
end
end
end
14 changes: 14 additions & 0 deletions spec/integration/memory_spec.rb
@@ -0,0 +1,14 @@
require 'perpetuity'
require 'perpetuity/memory'
require 'perpetuity_shared'

describe Perpetuity::Memory do
before(:all) do
Perpetuity.configure { data_source Perpetuity::Memory.new }
end

it_behaves_like "mappable"
it_behaves_like "persistable"
it_behaves_like "crud"
it_behaves_like "pagination"
end
18 changes: 18 additions & 0 deletions spec/integration/mongodb_spec.rb
@@ -0,0 +1,18 @@
require 'perpetuity'
require "perpetuity/mongodb"
require 'perpetuity_shared'

describe Perpetuity::MongoDB do
before(:all) do
Perpetuity.configure { data_source Perpetuity::MongoDB.new db: 'perpetuity_gem_test' }
end

it_behaves_like "mappable"
it_behaves_like "persistable"
it_behaves_like "crud"
it_behaves_like "pagination"
it_behaves_like "associations"
it_behaves_like "validation"
it_behaves_like "scopable"
it_behaves_like "indexable"
end
70 changes: 70 additions & 0 deletions spec/perpetuity/memory_spec.rb
@@ -0,0 +1,70 @@
require 'perpetuity/memory'
require 'date'

module Perpetuity
describe Memory do
let(:store) { Memory.new }
let(:klass) { String }
subject { store }

describe 'initialization params' do
end

it 'removes all documents from a collection' do
store.insert klass, {}
store.delete_all klass
store.count(klass).should == 0
end

it 'counts the documents in a collection' do
store.delete_all klass
3.times do
store.insert klass, {}
end
store.count(klass).should == 3
end

it 'gets the first document in a collection' do
value = {value: 1}
store.insert klass, value
store.first(klass)[:value].should == value['value']
end

it 'gets all of the documents in a collection' do
values = [{value: 1}, {value: 2}]
values.each do |value|
store.insert klass, value
end

store.all(klass).should == values
end

it 'retrieves by id' do
time = Time.now.utc
id = store.insert klass, {"inserted" => time}

objects = store.retrieve(klass, id: id).to_a
objects.map{|i| i["inserted"].to_f}.first.should be_within(0.001).of time.to_f
end

it 'updates by id' do
time = Time.now.utc

id = store.insert klass, {"modified_at" => time - 8600}
store.update klass, id, {"modified_at" => time}

objects = store.retrieve(klass, id: id).to_a
objects.map{|i| i["modified_at"].to_f}.first.should be_within(0.001).of time.to_f
end

it 'deletes by id' do
time = Time.now.utc
id = store.insert klass, {"modified_at" => time}

store.count(klass).should == 1
store.delete id, klass
store.count(klass).should == 0
end
end
end