perpetuity 0.4.6 → 0.4.7
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +8 -0
- data/README.md +1 -1
- data/lib/perpetuity/identity_map.rb +8 -7
- data/lib/perpetuity/mapper.rb +1 -1
- data/lib/perpetuity/mongodb/index.rb +5 -1
- data/lib/perpetuity/mongodb.rb +6 -4
- data/lib/perpetuity/serializer.rb +17 -7
- data/lib/perpetuity/version.rb +1 -1
- data/spec/{perpetuity → integration}/mongodb_spec.rb +0 -4
- data/spec/integration/persistence_spec.rb +12 -0
- data/spec/integration/retrieval_spec.rb +15 -0
- data/spec/integration/update_spec.rb +13 -0
- data/spec/support/test_classes/crm_person.rb +5 -0
- data/spec/support/test_classes.rb +5 -1
- metadata +13 -5
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
## Version 0.4.7
|
2
|
+
|
3
|
+
- Use instance variables rather than attr_readers in IdentityMap (avoids calling methods during `load_association!`).
|
4
|
+
- Fixed a bug with MongoDB authentication.
|
5
|
+
- Use attribute names rather than a stringified attribute for MongoDB indexes.
|
6
|
+
- Fixed a bug with deserializing attributes of namespaced classes. — [Jaap Groeneveld](https://github.com/jgroeneveld)
|
7
|
+
- Fixed serialization of `Perpetuity::Reference` attributes caused by resaving an object that did not have all of its referenced associations loaded.
|
8
|
+
|
1
9
|
## Version 0.4.6
|
2
10
|
|
3
11
|
- Fix an inconsistency between `mongo` and `moped` gems. Previously, the MongoDB adapter relied on the fail-fast behavior of the `mongo` gem so we had no need to check for errors. Moped does not do that by default, which resulted in incorrect behavior of the gem when an object was not persisted.
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Perpetuity [![Build Status](https://secure.travis-ci.org/jgaskins/perpetuity.png)](http://travis-ci.org/jgaskins/perpetuity)
|
1
|
+
# Perpetuity [![Build Status](https://secure.travis-ci.org/jgaskins/perpetuity.png)](http://travis-ci.org/jgaskins/perpetuity) [![Code Climate](https://codeclimate.com/github/jgaskins/perpetuity.png)](https://codeclimate.com/github/jgaskins/perpetuity)
|
2
2
|
|
3
3
|
Perpetuity is a simple Ruby object persistence layer that attempts to follow Martin Fowler's Data Mapper pattern, allowing you to use plain-old Ruby objects in your Ruby apps in order to decouple your domain logic from the database as well as speed up your tests. There is no need for your model classes to inherit from another class or even include a mix-in.
|
4
4
|
|
@@ -2,16 +2,17 @@ module Perpetuity
|
|
2
2
|
class IdentityMap
|
3
3
|
def initialize objects, attribute, mapper_registry
|
4
4
|
@map = Hash[
|
5
|
-
objects.map(
|
5
|
+
objects.map { |object| object.instance_variable_get("@#{attribute}") }
|
6
6
|
.flatten
|
7
7
|
.group_by(&:klass)
|
8
8
|
.map { |klass, ref|
|
9
|
-
[
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
9
|
+
[
|
10
|
+
klass,
|
11
|
+
Hash[
|
12
|
+
mapper_registry[klass].select { |object|
|
13
|
+
object.id.in ref.map(&:id).uniq
|
14
|
+
}.map { |obj| [obj.id, obj] }
|
15
|
+
]
|
15
16
|
]
|
16
17
|
}
|
17
18
|
]
|
data/lib/perpetuity/mapper.rb
CHANGED
@@ -103,7 +103,7 @@ module Perpetuity
|
|
103
103
|
identity_map = IdentityMap.new(objects, attribute, mapper_registry)
|
104
104
|
|
105
105
|
objects.each do |object|
|
106
|
-
reference = object.
|
106
|
+
reference = object.instance_variable_get("@#{attribute}")
|
107
107
|
if reference.is_a? Array
|
108
108
|
refs = reference
|
109
109
|
real_objects = refs.map { |ref| identity_map[ref.klass][ref.id] }
|
@@ -40,8 +40,12 @@ module Perpetuity
|
|
40
40
|
self == other
|
41
41
|
end
|
42
42
|
|
43
|
+
def attribute_name
|
44
|
+
attribute.respond_to?(:name) ? attribute.name : attribute
|
45
|
+
end
|
46
|
+
|
43
47
|
def hash
|
44
|
-
"#{collection}/#{
|
48
|
+
"#{collection}/#{attribute_name}:#{unique?}:#{order}".hash
|
45
49
|
end
|
46
50
|
end
|
47
51
|
end
|
data/lib/perpetuity/mongodb.rb
CHANGED
@@ -17,25 +17,27 @@ module Perpetuity
|
|
17
17
|
@password = options[:password]
|
18
18
|
@session = nil
|
19
19
|
@indexes = Hash.new { |hash, key| hash[key] = active_indexes(key) }
|
20
|
+
@connected = false
|
20
21
|
end
|
21
22
|
|
22
23
|
def session
|
23
|
-
@session ||= Moped::Session.new(["#{host}:#{port}"])
|
24
|
-
@session.with(safe: true)
|
24
|
+
@session ||= Moped::Session.new(["#{host}:#{port}"]).with(safe: true)
|
25
25
|
end
|
26
26
|
|
27
27
|
def connect
|
28
28
|
session.login(@username, @password) if @username and @password
|
29
|
+
@connected = true
|
29
30
|
session
|
30
31
|
end
|
31
32
|
|
32
33
|
def connected?
|
33
|
-
!!@
|
34
|
+
!!@connected
|
34
35
|
end
|
35
36
|
|
36
37
|
def database
|
37
|
-
connect unless connected?
|
38
38
|
session.use db
|
39
|
+
connect unless connected?
|
40
|
+
session
|
39
41
|
end
|
40
42
|
|
41
43
|
def collection klass
|
@@ -20,7 +20,9 @@ module Perpetuity
|
|
20
20
|
attrs = mapper.class.attribute_set.map do |attrib|
|
21
21
|
value = attribute_for object, attrib.name
|
22
22
|
|
23
|
-
serialized_value = if value.is_a?
|
23
|
+
serialized_value = if value.is_a? Reference
|
24
|
+
serialize_reference value
|
25
|
+
elsif value.is_a? Array
|
24
26
|
serialize_array(value, attrib.embedded?)
|
25
27
|
elsif mapper.data_source.can_serialize? value
|
26
28
|
value
|
@@ -74,8 +76,11 @@ module Perpetuity
|
|
74
76
|
elsif data.is_a? Hash
|
75
77
|
metadata = data.delete('__metadata__')
|
76
78
|
if metadata
|
77
|
-
klass =
|
79
|
+
klass = metadata['class'].split('::').inject(Kernel) do |scope, const_name|
|
80
|
+
scope.const_get(const_name)
|
81
|
+
end
|
78
82
|
id = metadata['id']
|
83
|
+
|
79
84
|
if id
|
80
85
|
object = Reference.new(klass, id)
|
81
86
|
else
|
@@ -123,13 +128,18 @@ module Perpetuity
|
|
123
128
|
end
|
124
129
|
|
125
130
|
def serialize_reference value
|
126
|
-
|
127
|
-
|
131
|
+
if value.is_a? Reference
|
132
|
+
reference = value
|
133
|
+
else
|
134
|
+
unless value.is_a? PersistedObject
|
135
|
+
mapper_registry[value.class].insert value
|
136
|
+
end
|
137
|
+
reference = Reference.new(value.class.to_s, value.id)
|
128
138
|
end
|
129
139
|
{
|
130
|
-
'__metadata__' =>
|
131
|
-
'class' =>
|
132
|
-
'id'
|
140
|
+
'__metadata__' => {
|
141
|
+
'class' => reference.klass.to_s,
|
142
|
+
'id' => reference.id
|
133
143
|
}
|
134
144
|
}
|
135
145
|
end
|
data/lib/perpetuity/version.rb
CHANGED
@@ -48,10 +48,6 @@ module Perpetuity
|
|
48
48
|
its(:password) { should == password }
|
49
49
|
end
|
50
50
|
|
51
|
-
it 'uses the selected database' do
|
52
|
-
mongo.database.name.should == 'perpetuity_gem_test'
|
53
|
-
end
|
54
|
-
|
55
51
|
it 'removes all documents from a collection' do
|
56
52
|
mongo.insert klass, {}
|
57
53
|
mongo.delete_all klass
|
@@ -93,5 +93,17 @@ describe 'Persistence' do
|
|
93
93
|
Perpetuity[Book].insert book
|
94
94
|
book.id.should eq "my-title-#{noise}"
|
95
95
|
end
|
96
|
+
|
97
|
+
context 'with namespaced classes' do
|
98
|
+
let(:person) { CRM::Person.new }
|
99
|
+
let(:mapper) { Perpetuity[CRM::Person] }
|
100
|
+
|
101
|
+
before { person.name = 'Foo Bar' }
|
102
|
+
|
103
|
+
it 'persists even with colons in the names' do
|
104
|
+
mapper.insert person
|
105
|
+
person.should be_a Perpetuity::PersistedObject
|
106
|
+
end
|
107
|
+
end
|
96
108
|
end
|
97
109
|
|
@@ -111,4 +111,19 @@ describe "retrieval" do
|
|
111
111
|
ids.should_not include draft.id
|
112
112
|
end
|
113
113
|
end
|
114
|
+
|
115
|
+
context 'with namespaced classes' do
|
116
|
+
let(:article) { Article.new }
|
117
|
+
let(:person) { CRM::Person.new }
|
118
|
+
let(:mapper) { Perpetuity[Article] }
|
119
|
+
|
120
|
+
before { article.author = person }
|
121
|
+
|
122
|
+
it 'gets a CRM::Person object back' do
|
123
|
+
mapper.insert article
|
124
|
+
retrieved_article = mapper.find(article.id)
|
125
|
+
mapper.load_association! retrieved_article, :author
|
126
|
+
retrieved_article.author.should be_a CRM::Person
|
127
|
+
end
|
128
|
+
end
|
114
129
|
end
|
@@ -25,6 +25,19 @@ describe 'updating' do
|
|
25
25
|
mapper.save article
|
26
26
|
mapper.find(article.id).title.should eq new_title
|
27
27
|
end
|
28
|
+
|
29
|
+
it 'updates an object with referenced attributes' do
|
30
|
+
user = User.new
|
31
|
+
article.author = user
|
32
|
+
mapper.save article
|
33
|
+
|
34
|
+
retrieved_article = mapper.find(article.id)
|
35
|
+
retrieved_article.title = new_title
|
36
|
+
mapper.save retrieved_article
|
37
|
+
|
38
|
+
retrieved_article = mapper.find(retrieved_article.id)
|
39
|
+
retrieved_article.author.should be_a Perpetuity::Reference
|
40
|
+
end
|
28
41
|
end
|
29
42
|
|
30
43
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
%w( user article comment book message topic car ).each do |file|
|
1
|
+
%w( user article comment book message topic car crm_person).each do |file|
|
2
2
|
require "support/test_classes/#{file}"
|
3
3
|
end
|
4
4
|
|
@@ -55,3 +55,7 @@ Perpetuity.generate_mapper_for(Car) do
|
|
55
55
|
present :make
|
56
56
|
end
|
57
57
|
end
|
58
|
+
|
59
|
+
Perpetuity.generate_mapper_for CRM::Person do
|
60
|
+
attribute :name
|
61
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: perpetuity
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.7
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-03-
|
12
|
+
date: 2013-03-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -103,6 +103,7 @@ files:
|
|
103
103
|
- spec/integration/associations_spec.rb
|
104
104
|
- spec/integration/deletion_spec.rb
|
105
105
|
- spec/integration/indexing_spec.rb
|
106
|
+
- spec/integration/mongodb_spec.rb
|
106
107
|
- spec/integration/pagination_spec.rb
|
107
108
|
- spec/integration/persistence_spec.rb
|
108
109
|
- spec/integration/retrieval_spec.rb
|
@@ -121,7 +122,6 @@ files:
|
|
121
122
|
- spec/perpetuity/mongodb/query_intersection_spec.rb
|
122
123
|
- spec/perpetuity/mongodb/query_spec.rb
|
123
124
|
- spec/perpetuity/mongodb/query_union_spec.rb
|
124
|
-
- spec/perpetuity/mongodb_spec.rb
|
125
125
|
- spec/perpetuity/persisted_object_spec.rb
|
126
126
|
- spec/perpetuity/reference_spec.rb
|
127
127
|
- spec/perpetuity/retrieval_spec.rb
|
@@ -136,6 +136,7 @@ files:
|
|
136
136
|
- spec/support/test_classes/book.rb
|
137
137
|
- spec/support/test_classes/car.rb
|
138
138
|
- spec/support/test_classes/comment.rb
|
139
|
+
- spec/support/test_classes/crm_person.rb
|
139
140
|
- spec/support/test_classes/message.rb
|
140
141
|
- spec/support/test_classes/topic.rb
|
141
142
|
- spec/support/test_classes/user.rb
|
@@ -151,15 +152,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
151
152
|
- - ! '>='
|
152
153
|
- !ruby/object:Gem::Version
|
153
154
|
version: '0'
|
155
|
+
segments:
|
156
|
+
- 0
|
157
|
+
hash: 3471626582421512512
|
154
158
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
155
159
|
none: false
|
156
160
|
requirements:
|
157
161
|
- - ! '>='
|
158
162
|
- !ruby/object:Gem::Version
|
159
163
|
version: '0'
|
164
|
+
segments:
|
165
|
+
- 0
|
166
|
+
hash: 3471626582421512512
|
160
167
|
requirements: []
|
161
168
|
rubyforge_project:
|
162
|
-
rubygems_version: 1.8.
|
169
|
+
rubygems_version: 1.8.25
|
163
170
|
signing_key:
|
164
171
|
specification_version: 3
|
165
172
|
summary: Persistence library allowing serialization of Ruby objects
|
@@ -167,6 +174,7 @@ test_files:
|
|
167
174
|
- spec/integration/associations_spec.rb
|
168
175
|
- spec/integration/deletion_spec.rb
|
169
176
|
- spec/integration/indexing_spec.rb
|
177
|
+
- spec/integration/mongodb_spec.rb
|
170
178
|
- spec/integration/pagination_spec.rb
|
171
179
|
- spec/integration/persistence_spec.rb
|
172
180
|
- spec/integration/retrieval_spec.rb
|
@@ -185,7 +193,6 @@ test_files:
|
|
185
193
|
- spec/perpetuity/mongodb/query_intersection_spec.rb
|
186
194
|
- spec/perpetuity/mongodb/query_spec.rb
|
187
195
|
- spec/perpetuity/mongodb/query_union_spec.rb
|
188
|
-
- spec/perpetuity/mongodb_spec.rb
|
189
196
|
- spec/perpetuity/persisted_object_spec.rb
|
190
197
|
- spec/perpetuity/reference_spec.rb
|
191
198
|
- spec/perpetuity/retrieval_spec.rb
|
@@ -200,6 +207,7 @@ test_files:
|
|
200
207
|
- spec/support/test_classes/book.rb
|
201
208
|
- spec/support/test_classes/car.rb
|
202
209
|
- spec/support/test_classes/comment.rb
|
210
|
+
- spec/support/test_classes/crm_person.rb
|
203
211
|
- spec/support/test_classes/message.rb
|
204
212
|
- spec/support/test_classes/topic.rb
|
205
213
|
- spec/support/test_classes/user.rb
|