zentradi 0.0.0 → 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +1 -1
- data/Rakefile +0 -1
- data/VERSION +1 -1
- data/lib/zentradi.rb +14 -9
- data/lib/zentradi/collection.rb +56 -0
- data/lib/zentradi/delegate.rb +32 -0
- data/lib/zentradi/document_wrapper.rb +38 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/zentradi/document_spec.rb +13 -19
- data/spec/zentradi/indexes_spec.rb +1 -0
- data/zentradi.gemspec +72 -0
- metadata +8 -25
- data/lib/zentradi/class_helpers.rb +0 -46
- data/lib/zentradi/connection.rb +0 -48
- data/lib/zentradi/document.rb +0 -83
- data/lib/zentradi/identity_map.rb +0 -75
- data/lib/zentradi/instantiators.rb +0 -36
- data/spec/zentradi/identity_map_spec.rb +0 -26
- data/spec/zentradi_spec.rb +0 -7
data/README.rdoc
CHANGED
@@ -61,7 +61,7 @@ In particular, I want:
|
|
61
61
|
[
|
62
62
|
"magic",
|
63
63
|
"ruby hooks overrides",
|
64
|
-
"additions to the mongo
|
64
|
+
"additions to the mongo driver API",
|
65
65
|
"plugins paraphernalia",
|
66
66
|
"use and abuse of generated methods -- find_by_blah_blah anyone? -- ",
|
67
67
|
"features of ActiveRecord, Datamapper, [INSERT ORM HERE]"
|
data/Rakefile
CHANGED
@@ -22,7 +22,6 @@ begin
|
|
22
22
|
gem.add_development_dependency "rake"
|
23
23
|
gem.add_dependency "mongo"
|
24
24
|
gem.add_dependency "mongo_ext"
|
25
|
-
gem.add_dependency "weak_hash"
|
26
25
|
gem.add_dependency "hashie"
|
27
26
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
28
27
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.1
|
data/lib/zentradi.rb
CHANGED
@@ -1,13 +1,18 @@
|
|
1
1
|
require 'hashie'
|
2
|
-
require 'weak_hash'
|
3
2
|
require 'mongo'
|
4
3
|
|
5
|
-
module
|
6
|
-
autoload :
|
7
|
-
autoload :
|
8
|
-
autoload :
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
4
|
+
module Zdi
|
5
|
+
autoload :Delegate , 'zentradi/delegate'
|
6
|
+
autoload :DocumentWrapper , 'zentradi/document_wrapper'
|
7
|
+
autoload :Collection , 'zentradi/collection'
|
8
|
+
|
9
|
+
class << self
|
10
|
+
attr_accessor :default_database
|
11
|
+
|
12
|
+
def Collection(collection, database = Zdi.default_database)
|
13
|
+
Class.new(Zdi::Collection) do
|
14
|
+
instance_variable_set("@collection", database[collection])
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
13
18
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Zdi
|
2
|
+
class Collection
|
3
|
+
class << self
|
4
|
+
extend Zdi::Delegate
|
5
|
+
delegate *(Mongo::Collection.public_instance_methods - public_instance_methods), :to => :collection
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
attr_accessor :collection
|
10
|
+
|
11
|
+
def inherited(base)
|
12
|
+
base.collection = self.collection
|
13
|
+
end
|
14
|
+
|
15
|
+
def ensure_collection
|
16
|
+
database.create_collection(collection.name)
|
17
|
+
end
|
18
|
+
|
19
|
+
def drop_collection
|
20
|
+
collection.drop
|
21
|
+
end
|
22
|
+
|
23
|
+
def recreate_collection
|
24
|
+
drop_collection; ensure_collection
|
25
|
+
end
|
26
|
+
|
27
|
+
def build(attributes = {})
|
28
|
+
DocumentWrapper.new(self, attributes)
|
29
|
+
end
|
30
|
+
|
31
|
+
def create(attributes = {})
|
32
|
+
doc = build(attributes)
|
33
|
+
doc.save
|
34
|
+
doc
|
35
|
+
end
|
36
|
+
|
37
|
+
def find_or_build(attributes)
|
38
|
+
find_one(attributes) || build(attributes)
|
39
|
+
end
|
40
|
+
|
41
|
+
def find_or_create(attributes)
|
42
|
+
update(attributes, attributes, :upsert => true)
|
43
|
+
end
|
44
|
+
|
45
|
+
def all
|
46
|
+
find
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
extend ClassMethods
|
51
|
+
|
52
|
+
class << self
|
53
|
+
alias_method :first, :find_one
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Zdi
|
2
|
+
module Delegate
|
3
|
+
def delegate(*methods)
|
4
|
+
include Wrapper unless ancestors.include?(Wrapper)
|
5
|
+
to = methods.pop[:to]
|
6
|
+
methods.each do |name|
|
7
|
+
module_eval(<<-EOMETHOD, __FILE__, __LINE__ + 1)
|
8
|
+
def #{ name }(*args, &block)
|
9
|
+
new_args = args.map { |a| a.is_a?(DocumentWrapper) ? a.to_hash : a }
|
10
|
+
|
11
|
+
result = #{to}.send :#{name}, *new_args, &block
|
12
|
+
|
13
|
+
return wrap_if_document(result)
|
14
|
+
end
|
15
|
+
EOMETHOD
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module Wrapper
|
20
|
+
def wrap_if_document(object)
|
21
|
+
if object.is_a?(OrderedHash)
|
22
|
+
DocumentWrapper.new(self, object)
|
23
|
+
elsif object.respond_to?(:map)
|
24
|
+
object.map { |e| wrap_if_document(e) }
|
25
|
+
else
|
26
|
+
return object
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Zdi
|
2
|
+
class DocumentWrapper < Hashie::Mash
|
3
|
+
|
4
|
+
attr_reader :collection
|
5
|
+
|
6
|
+
def initialize(collection, hash = {})
|
7
|
+
super(hash)
|
8
|
+
@collection = collection
|
9
|
+
end
|
10
|
+
|
11
|
+
def id
|
12
|
+
super || _id
|
13
|
+
end
|
14
|
+
|
15
|
+
def new?
|
16
|
+
id.nil? || @collection.find("_id" => id).count == 0
|
17
|
+
end
|
18
|
+
|
19
|
+
def save
|
20
|
+
if id.nil?
|
21
|
+
self.id = @collection.save(self)
|
22
|
+
else
|
23
|
+
@collection.update({"_id" => id}, self)
|
24
|
+
end
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
def update(attributes)
|
29
|
+
super(attributes)
|
30
|
+
save
|
31
|
+
end
|
32
|
+
|
33
|
+
def destroy
|
34
|
+
@collection.remove("_id" => id)
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,19 +1,14 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
mongo :collection => "post", :database => "zentradi"
|
3
|
+
Post = Zdi::Collection("posts")
|
5
4
|
|
6
|
-
|
7
|
-
end
|
8
|
-
|
9
|
-
describe Zentradi::Document do
|
5
|
+
describe Zdi::Collection do
|
10
6
|
before do
|
11
7
|
Post.remove
|
12
8
|
end
|
13
9
|
|
14
10
|
it "creates a document" do
|
15
|
-
post = Post.
|
16
|
-
post.id.should be_nil
|
11
|
+
post = Post.build
|
17
12
|
post.should be_new
|
18
13
|
|
19
14
|
post.save
|
@@ -22,18 +17,14 @@ describe Zentradi::Document do
|
|
22
17
|
post.should_not be_new
|
23
18
|
end
|
24
19
|
|
25
|
-
it "finds a document through the identity map" do
|
26
|
-
@post = Post.create(:title => "Hola Mundo", :body => "Hi.")
|
27
|
-
Post.first("_id" => @post.id).should be_an_instance_of(Post)
|
28
|
-
end
|
29
20
|
|
30
21
|
it "finds or initializes a document" do
|
31
22
|
@post = Post.create(:title => "Test")
|
32
23
|
|
33
|
-
found = Post.
|
24
|
+
found = Post.find_or_build(:title => "Test")
|
34
25
|
found.title.should == "Test"
|
35
26
|
|
36
|
-
found = Post.
|
27
|
+
found = Post.find_or_build(:title => "Test 2")
|
37
28
|
found.title.should == "Test 2"
|
38
29
|
found.should be_new
|
39
30
|
found.save
|
@@ -43,11 +34,14 @@ describe Zentradi::Document do
|
|
43
34
|
end
|
44
35
|
|
45
36
|
it "updates a document" do
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
37
|
+
post = Post.create(:title => "Hola Mundo", :body => "Hi.")
|
38
|
+
post.title = "ABC"
|
39
|
+
post.save
|
40
|
+
|
41
|
+
post.update(:title => post.title + " DEF")
|
42
|
+
|
43
|
+
from_db = Post.first("_id" => post.id)
|
44
|
+
from_db.title.should == "ABC DEF"
|
51
45
|
end
|
52
46
|
|
53
47
|
it "destroys a document" do
|
data/zentradi.gemspec
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{zentradi}
|
8
|
+
s.version = "0.0.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Emmanuel Oga"]
|
12
|
+
s.date = %q{2010-03-29}
|
13
|
+
s.description = %q{minimalistic tools for accessing mongodb}
|
14
|
+
s.email = %q{EmmanuelOga@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
"Gemfile",
|
23
|
+
"LICENSE",
|
24
|
+
"README.rdoc",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION",
|
27
|
+
"lib/zentradi.rb",
|
28
|
+
"lib/zentradi/collection.rb",
|
29
|
+
"lib/zentradi/delegate.rb",
|
30
|
+
"lib/zentradi/document_wrapper.rb",
|
31
|
+
"spec/spec_helper.rb",
|
32
|
+
"spec/zentradi/document_spec.rb",
|
33
|
+
"spec/zentradi/indexes_spec.rb",
|
34
|
+
"zentradi.gemspec"
|
35
|
+
]
|
36
|
+
s.homepage = %q{http://github.com/EmmanuelOga/zentradi}
|
37
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
38
|
+
s.require_paths = ["lib"]
|
39
|
+
s.rubygems_version = %q{1.3.6}
|
40
|
+
s.summary = %q{minimalistic tools for accessing mongodb}
|
41
|
+
s.test_files = [
|
42
|
+
"spec/zentradi/document_spec.rb",
|
43
|
+
"spec/zentradi/indexes_spec.rb",
|
44
|
+
"spec/spec_helper.rb"
|
45
|
+
]
|
46
|
+
|
47
|
+
if s.respond_to? :specification_version then
|
48
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
49
|
+
s.specification_version = 3
|
50
|
+
|
51
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
52
|
+
s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
|
53
|
+
s.add_development_dependency(%q<rake>, [">= 0"])
|
54
|
+
s.add_runtime_dependency(%q<mongo>, [">= 0"])
|
55
|
+
s.add_runtime_dependency(%q<mongo_ext>, [">= 0"])
|
56
|
+
s.add_runtime_dependency(%q<hashie>, [">= 0"])
|
57
|
+
else
|
58
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
59
|
+
s.add_dependency(%q<rake>, [">= 0"])
|
60
|
+
s.add_dependency(%q<mongo>, [">= 0"])
|
61
|
+
s.add_dependency(%q<mongo_ext>, [">= 0"])
|
62
|
+
s.add_dependency(%q<hashie>, [">= 0"])
|
63
|
+
end
|
64
|
+
else
|
65
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
66
|
+
s.add_dependency(%q<rake>, [">= 0"])
|
67
|
+
s.add_dependency(%q<mongo>, [">= 0"])
|
68
|
+
s.add_dependency(%q<mongo_ext>, [">= 0"])
|
69
|
+
s.add_dependency(%q<hashie>, [">= 0"])
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Emmanuel Oga
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-03-
|
17
|
+
date: 2010-03-29 00:00:00 -03:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -68,7 +68,7 @@ dependencies:
|
|
68
68
|
type: :runtime
|
69
69
|
version_requirements: *id004
|
70
70
|
- !ruby/object:Gem::Dependency
|
71
|
-
name:
|
71
|
+
name: hashie
|
72
72
|
prerelease: false
|
73
73
|
requirement: &id005 !ruby/object:Gem::Requirement
|
74
74
|
requirements:
|
@@ -79,18 +79,6 @@ dependencies:
|
|
79
79
|
version: "0"
|
80
80
|
type: :runtime
|
81
81
|
version_requirements: *id005
|
82
|
-
- !ruby/object:Gem::Dependency
|
83
|
-
name: hashie
|
84
|
-
prerelease: false
|
85
|
-
requirement: &id006 !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - ">="
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
segments:
|
90
|
-
- 0
|
91
|
-
version: "0"
|
92
|
-
type: :runtime
|
93
|
-
version_requirements: *id006
|
94
82
|
description: minimalistic tools for accessing mongodb
|
95
83
|
email: EmmanuelOga@gmail.com
|
96
84
|
executables: []
|
@@ -109,16 +97,13 @@ files:
|
|
109
97
|
- Rakefile
|
110
98
|
- VERSION
|
111
99
|
- lib/zentradi.rb
|
112
|
-
- lib/zentradi/
|
113
|
-
- lib/zentradi/
|
114
|
-
- lib/zentradi/
|
115
|
-
- lib/zentradi/identity_map.rb
|
116
|
-
- lib/zentradi/instantiators.rb
|
100
|
+
- lib/zentradi/collection.rb
|
101
|
+
- lib/zentradi/delegate.rb
|
102
|
+
- lib/zentradi/document_wrapper.rb
|
117
103
|
- spec/spec_helper.rb
|
118
104
|
- spec/zentradi/document_spec.rb
|
119
|
-
- spec/zentradi/identity_map_spec.rb
|
120
105
|
- spec/zentradi/indexes_spec.rb
|
121
|
-
-
|
106
|
+
- zentradi.gemspec
|
122
107
|
has_rdoc: true
|
123
108
|
homepage: http://github.com/EmmanuelOga/zentradi
|
124
109
|
licenses: []
|
@@ -150,8 +135,6 @@ signing_key:
|
|
150
135
|
specification_version: 3
|
151
136
|
summary: minimalistic tools for accessing mongodb
|
152
137
|
test_files:
|
153
|
-
- spec/zentradi_spec.rb
|
154
138
|
- spec/zentradi/document_spec.rb
|
155
|
-
- spec/zentradi/identity_map_spec.rb
|
156
139
|
- spec/zentradi/indexes_spec.rb
|
157
140
|
- spec/spec_helper.rb
|
@@ -1,46 +0,0 @@
|
|
1
|
-
module Zentradi
|
2
|
-
# Some random helpers to be used at class level.
|
3
|
-
module ClassHelpers
|
4
|
-
|
5
|
-
def instance_access_to_class_methods(*names)
|
6
|
-
names.each do |name|
|
7
|
-
module_eval(<<-EOMETHOD, __FILE__, __LINE__ + 1)
|
8
|
-
def #{ name }(*args, &block)
|
9
|
-
self.class.#{ name }(*args, &block)
|
10
|
-
end
|
11
|
-
EOMETHOD
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
# creates a shortcut for accessing keys
|
16
|
-
# on the mongo document.
|
17
|
-
# Not really needed but seems like after
|
18
|
-
# ActiveRecord nobody can live without this
|
19
|
-
# (including me? :-)
|
20
|
-
def mongo_accessor(*keys)
|
21
|
-
keys.each do |key|
|
22
|
-
module_eval(<<-EOMETHOD, __FILE__, __LINE__ + 1)
|
23
|
-
def #{ key }
|
24
|
-
document[#{key.inspect}]
|
25
|
-
end
|
26
|
-
|
27
|
-
def #{ key }=(val)
|
28
|
-
document[#{key.inspect}] = val
|
29
|
-
end
|
30
|
-
EOMETHOD
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def delegate(*methods)
|
35
|
-
to = methods.pop[:to]
|
36
|
-
methods.each do |name|
|
37
|
-
module_eval(<<-EOMETHOD, __FILE__, __LINE__ + 1)
|
38
|
-
def #{ name }(*args, &block)
|
39
|
-
#{to}.#{name}(*args, &block)
|
40
|
-
end
|
41
|
-
EOMETHOD
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
end
|
46
|
-
end
|
data/lib/zentradi/connection.rb
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
module Zentradi
|
2
|
-
# methods to manage the mongo driver communication artefacts
|
3
|
-
module Connection
|
4
|
-
|
5
|
-
def connection(*args)
|
6
|
-
@_connection = nil unless args.empty?
|
7
|
-
@_connection ||= Mongo::Connection.new(*args)
|
8
|
-
end
|
9
|
-
|
10
|
-
def database(database_name = nil)
|
11
|
-
@_database = nil unless database_name.nil?
|
12
|
-
@_database ||= connection.db(database_name)
|
13
|
-
end
|
14
|
-
|
15
|
-
def collection(collection_name = nil)
|
16
|
-
@_collection = nil unless collection_name.nil?
|
17
|
-
@_collection ||= database[collection_name]
|
18
|
-
end
|
19
|
-
|
20
|
-
# configuration shortcut
|
21
|
-
def mongo(options)
|
22
|
-
connection *options[:connection] if options.member?(:connection)
|
23
|
-
database options[:database] if options.member?(:database)
|
24
|
-
collection options[:collection] if options.member?(:collection)
|
25
|
-
end
|
26
|
-
|
27
|
-
# -------------------------------------------------------------------------
|
28
|
-
|
29
|
-
def ensure_collection
|
30
|
-
database.create_collection(collection.name)
|
31
|
-
end
|
32
|
-
|
33
|
-
def drop_collection!
|
34
|
-
collection.drop
|
35
|
-
end
|
36
|
-
|
37
|
-
def recreate_collection!
|
38
|
-
drop_collection! and ensure_collection
|
39
|
-
end
|
40
|
-
|
41
|
-
def identity_map
|
42
|
-
raise RuntimeError, "please set the mongo database first" unless database
|
43
|
-
raise RuntimeError, "please set the mongo collection first" unless collection
|
44
|
-
Zentradi::IdentityMap[database.name, collection.name]
|
45
|
-
end
|
46
|
-
|
47
|
-
end
|
48
|
-
end
|
data/lib/zentradi/document.rb
DELETED
@@ -1,83 +0,0 @@
|
|
1
|
-
module Zentradi
|
2
|
-
class Document
|
3
|
-
|
4
|
-
extend Connection
|
5
|
-
extend ClassHelpers
|
6
|
-
extend Instantiators
|
7
|
-
|
8
|
-
attr_accessor :document
|
9
|
-
instance_access_to_class_methods :identity_map, :collection
|
10
|
-
|
11
|
-
def initialize(document = nil)
|
12
|
-
raise ArgumentError, "provide a Hash like object or no parameters" unless document.nil? || document.class.ancestors.include?(Hash)
|
13
|
-
|
14
|
-
@document = document ? Hashie::Mash.new(document) : Hashie::Mash.new
|
15
|
-
end
|
16
|
-
|
17
|
-
def update(document)
|
18
|
-
@document.update(document) and save
|
19
|
-
end
|
20
|
-
|
21
|
-
def update!(document)
|
22
|
-
@document.update(document) and save!
|
23
|
-
end
|
24
|
-
|
25
|
-
def [](key)
|
26
|
-
@document[key]
|
27
|
-
end
|
28
|
-
|
29
|
-
def []=(key, value)
|
30
|
-
@document[key] = value
|
31
|
-
end
|
32
|
-
|
33
|
-
def id
|
34
|
-
@document["_id"]
|
35
|
-
end
|
36
|
-
|
37
|
-
def new?
|
38
|
-
not saved?
|
39
|
-
end
|
40
|
-
|
41
|
-
def saved?
|
42
|
-
id && collection.find("_id" => id).count != 0
|
43
|
-
end
|
44
|
-
|
45
|
-
def save(safe = false)
|
46
|
-
if id
|
47
|
-
collection.update({"_id" => id}, @document, :safe => safe)
|
48
|
-
else
|
49
|
-
update("_id" => collection.save(@document, :safe => safe))
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def save!
|
54
|
-
save(true)
|
55
|
-
end
|
56
|
-
|
57
|
-
def destroy
|
58
|
-
if id
|
59
|
-
collection.remove("_id" => id)
|
60
|
-
@document.delete("_id")
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def reload
|
65
|
-
if _id = id
|
66
|
-
@document.clear["_id"] = _id # clear and set.
|
67
|
-
update(mongo_document)
|
68
|
-
end
|
69
|
-
|
70
|
-
self
|
71
|
-
end
|
72
|
-
|
73
|
-
private
|
74
|
-
def mongo_document
|
75
|
-
raise RuntimeError, "cannot retrieve a new document" if new?
|
76
|
-
|
77
|
-
collection.find_one("_id" => id).tap do |i|
|
78
|
-
raise RuntimeError, "nothing was retrieved while loading the mongo instance ( #{ i.inspect } )" if i.nil? || i.empty?
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
end
|
83
|
-
end
|
@@ -1,75 +0,0 @@
|
|
1
|
-
module Zentradi
|
2
|
-
# NOTE: WIP, not working yet.
|
3
|
-
#
|
4
|
-
# Stores weak references to objects to ensure only one
|
5
|
-
# instance of a ruby class is used for holding a reference
|
6
|
-
# to a specific mongo collection.
|
7
|
-
class IdentityMap
|
8
|
-
class << self
|
9
|
-
# one identity map per db/collection tuple
|
10
|
-
def [](db_name, collection_name)
|
11
|
-
@hash ||= Hash.new { |h,k| h[k] = Hash.new { |hh, kk| hh[kk] = IdentityMap.new } }
|
12
|
-
@hash[db_name][collection_name]
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def initialize
|
17
|
-
@map = WeakHash.new
|
18
|
-
end
|
19
|
-
|
20
|
-
# retrieves a document with given _id
|
21
|
-
def get(_id)
|
22
|
-
@map[_id].tap { |instance| check(_id, instance) }
|
23
|
-
end
|
24
|
-
|
25
|
-
# stores a reference to the mongo document.
|
26
|
-
def set(_id, instance)
|
27
|
-
check(_id, @map[_id] = instance)
|
28
|
-
end
|
29
|
-
|
30
|
-
private
|
31
|
-
def check(_id, instance)
|
32
|
-
raise ArgumentError, "instance must be a Zentradi::Document" unless instance.nil? || instance.is_a?(Zentradi::Document)
|
33
|
-
raise RuntimeError, "instance #{ instance.inspect } does not match _id: #{ _id }" if instance && ( instance.id != _id )
|
34
|
-
instance
|
35
|
-
end
|
36
|
-
|
37
|
-
# Some helper methods to enable / disable the identity map at a class level.
|
38
|
-
module Management
|
39
|
-
def enable_identity_map
|
40
|
-
@_identity_map = true
|
41
|
-
end
|
42
|
-
|
43
|
-
def disable_identity_map
|
44
|
-
@_identity_map = false
|
45
|
-
end
|
46
|
-
|
47
|
-
# enabled by default
|
48
|
-
def identity_map_enabled?
|
49
|
-
@_identity_map.nil? || @_identity_map
|
50
|
-
end
|
51
|
-
|
52
|
-
private
|
53
|
-
|
54
|
-
def fetch_instance(param_doc)
|
55
|
-
if param_doc.nil?
|
56
|
-
nil
|
57
|
-
elsif identity_map_enabled? && param_doc["_id"]
|
58
|
-
|
59
|
-
if instance = identity_map.get(param_doc["_id"])
|
60
|
-
instance.update(param_doc)
|
61
|
-
else
|
62
|
-
document = param_doc.is_a?(Document) ? param_doc : new(param_doc)
|
63
|
-
instance = identity_map.set(document["_id"], document)
|
64
|
-
end
|
65
|
-
|
66
|
-
instance
|
67
|
-
else
|
68
|
-
param_doc.is_a?(Document) ? param_doc : new(param_doc)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
end # end module Management
|
73
|
-
|
74
|
-
end
|
75
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
module Zentradi
|
2
|
-
module Instantiators
|
3
|
-
extend ClassHelpers
|
4
|
-
|
5
|
-
delegate :remove, :update, :to => :collection
|
6
|
-
|
7
|
-
def all(params = nil)
|
8
|
-
collection.find(params).map(&method(:instantiate))
|
9
|
-
end
|
10
|
-
|
11
|
-
def first(params = nil)
|
12
|
-
query = params.is_a?(String) || params.is_a?(Numeric) ? {"_id" => params} : params
|
13
|
-
|
14
|
-
instantiate collection.find_one(query)
|
15
|
-
end
|
16
|
-
|
17
|
-
def find_or_initialize(params)
|
18
|
-
raise RuntimeError, "cannot find a document without params" if params.nil?
|
19
|
-
|
20
|
-
first(params) || instantiate(params)
|
21
|
-
end
|
22
|
-
|
23
|
-
def create(params)
|
24
|
-
instantiate(params).tap { |n| n.save }
|
25
|
-
end
|
26
|
-
|
27
|
-
def create!(params)
|
28
|
-
instantiate(params).tap { |n| n.save! }
|
29
|
-
end
|
30
|
-
|
31
|
-
def instantiate(document)
|
32
|
-
document ? new(document) : nil
|
33
|
-
end
|
34
|
-
|
35
|
-
end
|
36
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Zentradi::IdentityMap do
|
4
|
-
before do
|
5
|
-
@oh = Zentradi::Document.new
|
6
|
-
@oh["_id"] = "123456"
|
7
|
-
|
8
|
-
@im = Zentradi::IdentityMap["a_db", "a_collection"]
|
9
|
-
|
10
|
-
GC.start # make sure @im is collected if it was overwritten (e.g. in second example run)
|
11
|
-
end
|
12
|
-
|
13
|
-
it "stores an object" do
|
14
|
-
@im.set("123456", @oh)
|
15
|
-
@im.get("123456").should == @oh
|
16
|
-
end
|
17
|
-
|
18
|
-
it "stores a weak reference" do
|
19
|
-
@im.set("123456", @oh)
|
20
|
-
@im.get("123456").should == @oh
|
21
|
-
|
22
|
-
@oh = nil; GC.start
|
23
|
-
|
24
|
-
@im.get("123456").should be_nil
|
25
|
-
end
|
26
|
-
end
|