mem_model 0.1.0 → 0.2.0
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.
- checksums.yaml +8 -8
- data/.coveralls.yml +2 -0
- data/.gitignore +46 -0
- data/.travis.yml +6 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile.ci +8 -0
- data/Manifest.txt +10 -2
- data/README.md +16 -4
- data/Rakefile +42 -4
- data/lib/mem_model/base.rb +20 -325
- data/lib/mem_model/guid.rb +21 -0
- data/lib/mem_model/rooted_base.rb +8 -0
- data/lib/mem_model/rooted_store.rb +28 -0
- data/lib/mem_model/version.rb +1 -1
- data/lib/mem_model.rb +15 -1
- data/mem_model.gemspec +17 -14
- data/test/helper.rb +16 -2
- data/test/mem_model/{test_active_model_lint.rb → test_active_model.rb} +1 -1
- data/test/mem_model/test_base.rb +47 -2
- data/test/mem_model/test_guid.rb +16 -0
- data/test/mem_model/test_rooted_store.rb +34 -0
- metadata +41 -18
- data/test/mem_model/test_persistence.rb +0 -37
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MWY1MWQ5NzM1YmIzNDMyNzgzY2EwYmRhZDBmNDU2OWMzZTRmOWFmYg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NWQ2OWZmMDc3YTFiOTVhNTA5MTJlODM1MDlkN2YzZGE3NDZiYzQxYg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MDQ1ZjEwYTI1ZTdmN2U2NDIxMGFiYmI4ZTdiNDkwYmU0YWNhYzNkYjA1MmRh
|
10
|
+
YjEzM2FkOWQxZDhkNjY5MWIwNzNjN2U0MTkyOTBiZjAwZTg1ZjkxMDM4NTc3
|
11
|
+
YTJmNjI0NDlkZmJmOGEzOTI4YWYxN2YyOGIyZWU0MGI3ZDViMWI=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NTc1YjYzYzVhZGZmNzM5ZmNjZjU0MWFlMjM2ODUyYzNhN2U5MGM1MTUzYTdj
|
14
|
+
ZWUzNmNmMjUwOTUyMjA3ODk5YjcyYzU3MTc1YTRjZjVkNDM1ZTVjNGI2MDk4
|
15
|
+
ZmJhZTNhOGQ2MDUxOGY2YjhlNzA3YmJlYjNlZDMzN2IwMWEwZDM=
|
data/.coveralls.yml
ADDED
data/.gitignore
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
## CI Artifacts
|
2
|
+
Gemfile.ci.lock
|
3
|
+
|
4
|
+
## TEXTMATE
|
5
|
+
*.tmproj
|
6
|
+
tmtags
|
7
|
+
|
8
|
+
## EMACS
|
9
|
+
*~
|
10
|
+
\#*
|
11
|
+
.\#*
|
12
|
+
|
13
|
+
## VIM
|
14
|
+
*.swp
|
15
|
+
|
16
|
+
## PROJECT::GENERAL
|
17
|
+
.yardoc
|
18
|
+
coverage
|
19
|
+
doc
|
20
|
+
log
|
21
|
+
pkg
|
22
|
+
rdoc
|
23
|
+
|
24
|
+
## BUNDLER
|
25
|
+
*.gem
|
26
|
+
.bundle
|
27
|
+
pkg
|
28
|
+
|
29
|
+
## RBENV
|
30
|
+
.ruby-version
|
31
|
+
.rbenv*
|
32
|
+
|
33
|
+
## RCOV
|
34
|
+
coverage.data
|
35
|
+
|
36
|
+
## RUBINIUS
|
37
|
+
*.rbc
|
38
|
+
|
39
|
+
## Hoe?
|
40
|
+
.source_index
|
41
|
+
|
42
|
+
# Mac Finder files
|
43
|
+
*.DS_Store
|
44
|
+
|
45
|
+
# Node / NPM
|
46
|
+
node_modules
|
data/.travis.yml
ADDED
data/CHANGELOG.md
CHANGED
data/Gemfile.ci
ADDED
data/Manifest.txt
CHANGED
@@ -1,15 +1,23 @@
|
|
1
|
+
.coveralls.yml
|
2
|
+
.gitignore
|
3
|
+
.travis.yml
|
1
4
|
CHANGELOG.md
|
2
5
|
CONTRIBUTING.md
|
6
|
+
Gemfile.ci
|
3
7
|
LICENSE.md
|
4
8
|
Manifest.txt
|
5
9
|
README.md
|
6
10
|
Rakefile
|
7
11
|
lib/mem_model.rb
|
8
12
|
lib/mem_model/base.rb
|
13
|
+
lib/mem_model/guid.rb
|
14
|
+
lib/mem_model/rooted_base.rb
|
15
|
+
lib/mem_model/rooted_store.rb
|
9
16
|
lib/mem_model/version.rb
|
10
17
|
mem_model.gemspec
|
11
18
|
test/helper.rb
|
12
|
-
test/mem_model/
|
19
|
+
test/mem_model/test_active_model.rb
|
13
20
|
test/mem_model/test_base.rb
|
14
|
-
test/mem_model/
|
21
|
+
test/mem_model/test_guid.rb
|
22
|
+
test/mem_model/test_rooted_store.rb
|
15
23
|
test/test_version.rb
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# MemModel
|
1
|
+
# MemModel [![Ver][Ver img]][Ver] [![Bld][Bld img]][Bld] [![Cov][Cov img]][Cov]
|
2
2
|
|
3
3
|
MemModel persists Ruby objects using MagLev as a data storage engine. It is an
|
4
4
|
ActiveModel compliant implementation so it works stand-alone or in Rails 3 as a
|
@@ -36,15 +36,15 @@ class Account
|
|
36
36
|
validates_presence_of :balance
|
37
37
|
end
|
38
38
|
|
39
|
-
checking = Account.new #=> #<Account balance: nil, id:
|
39
|
+
checking = Account.new #=> #<Account balance: nil, id: 17338520>
|
40
40
|
checking.valid? #=> false
|
41
41
|
checking.balance = 100 #=> 100
|
42
42
|
checking.valid? #=> true
|
43
43
|
|
44
|
-
checking.save #=>
|
44
|
+
checking.save #=> 17338520
|
45
45
|
checking.new? #=> false
|
46
46
|
Account.size #=> 1
|
47
|
-
Account.first #=> #<Account balance: 100, id:
|
47
|
+
Account.first #=> #<Account balance: 100, id: 17338520>
|
48
48
|
```
|
49
49
|
|
50
50
|
|
@@ -87,6 +87,18 @@ If you'd like to contribute to MemModel, that's awesome. There's a guide to cont
|
|
87
87
|
|
88
88
|
To see what has changed in recent versions, see the [CHANGELOG.md](CHANGELOG.md).
|
89
89
|
|
90
|
+
|
91
|
+
<!--- ###################################################################### --->
|
92
|
+
<!--- ### URLs --->
|
93
|
+
|
94
|
+
[Ver]: https://rubygems.org/gems/mem_model
|
95
|
+
[Bld]: https://travis-ci.org/johnnyt/mem_model
|
96
|
+
[Cov]: https://coveralls.io/r/johnnyt/mem_model
|
97
|
+
|
98
|
+
[Ver img]: https://badge.fury.io/rb/mem_model.png
|
99
|
+
[Bld img]: https://travis-ci.org/johnnyt/mem_model.png
|
100
|
+
[Cov img]: https://coveralls.io/repos/johnnyt/mem_model/badge.png?branch=master
|
101
|
+
|
90
102
|
[hoe]: http://www.zenspider.com/projects/hoe.html
|
91
103
|
|
92
104
|
[tesla]: https://github.com/jc00ke/tesla
|
data/Rakefile
CHANGED
@@ -1,10 +1,43 @@
|
|
1
1
|
# -*- ruby -*-
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
require './lib/mem_model/version'
|
4
|
+
begin
|
5
|
+
require 'hoe'
|
6
|
+
rescue LoadError
|
7
|
+
end
|
8
|
+
|
9
|
+
desc 'Setup your local dev environment'
|
10
|
+
task :setup do
|
11
|
+
spec = Gem::Specification::load('mem_model.gemspec')
|
12
|
+
sh "gem install hoe-git #{spec.dependencies.map{|d| d.name}.join(' ')}"
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'Changelog'
|
16
|
+
task :changelog do
|
17
|
+
spec = Gem::Specification::load('mem_model.gemspec')
|
18
|
+
|
19
|
+
changes_io = StringIO.new
|
20
|
+
$stdout = changes_io
|
21
|
+
ENV['VERSION'] = MemModel::VERSION
|
22
|
+
Rake::Task['git:changelog'].invoke
|
23
|
+
$stdout = STDOUT
|
24
|
+
changes = changes_io.string.gsub('===', '###')
|
25
|
+
|
26
|
+
current = File.read('CHANGELOG.md')
|
27
|
+
File.write('CHANGELOG.md', [changes, current].join)
|
28
|
+
|
29
|
+
puts "Prepended these new changes:\n\n#{changes}"
|
30
|
+
end
|
31
|
+
|
32
|
+
if defined? Hoe
|
33
|
+
|
34
|
+
[ :debug, :deps, :gemcutter, :newb, :publish, :signing ].each do |plugin|
|
35
|
+
Hoe.plugins.delete plugin
|
36
|
+
end
|
5
37
|
|
6
38
|
Hoe.plugin :git
|
7
39
|
Hoe.plugin :gemspec
|
40
|
+
#Hoe.plugin :rubygems
|
8
41
|
|
9
42
|
Hoe.spec 'mem_model' do
|
10
43
|
developer 'JohnnyT', 'ubergeek3141@gmail.com'
|
@@ -25,8 +58,13 @@ Hoe.spec 'mem_model' do
|
|
25
58
|
license 'MIT'
|
26
59
|
|
27
60
|
dependency 'active_attr', '>= 0.8.2'
|
28
|
-
dependency 'activesupport', '
|
29
|
-
|
61
|
+
dependency 'activesupport', '>= 3.2.15'
|
62
|
+
|
63
|
+
dependency 'minitest', '>= 5.0.0', :development
|
64
|
+
dependency 'minitest-reporters', '>= 1.0.0', :development
|
65
|
+
dependency 'coveralls', '>= 1.0.0', :development
|
30
66
|
end
|
31
67
|
|
68
|
+
end # has_hoe
|
69
|
+
|
32
70
|
# vim: syntax=ruby
|
data/lib/mem_model/base.rb
CHANGED
@@ -22,34 +22,18 @@ module MemModel
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def generate_id
|
25
|
-
|
26
|
-
end
|
27
|
-
|
28
|
-
def guid_prefix
|
29
|
-
self.name[0...3]
|
25
|
+
object_id
|
30
26
|
end
|
31
27
|
|
32
|
-
|
33
|
-
|
28
|
+
# Find or nil
|
29
|
+
def find(id)
|
30
|
+
store.detect{ |r| r.id == id }
|
34
31
|
end
|
32
|
+
alias_method :[], :find
|
35
33
|
|
34
|
+
# Find or raise
|
36
35
|
def find_by_id(id)
|
37
|
-
|
38
|
-
end
|
39
|
-
|
40
|
-
def find_all_by_id(substring)
|
41
|
-
records = store.select{ |r| r.id.include?(substring.to_s.upcase) }
|
42
|
-
records && records.size == 1 ?
|
43
|
-
records.first :
|
44
|
-
records || raise(UnknownRecord, "Couldn't find #{self.name} with ID=#{id}")
|
45
|
-
end
|
46
|
-
|
47
|
-
def [](substring)
|
48
|
-
store.detect{ |r| r.id.include?(substring.to_s.upcase) } || raise(UnknownRecord, "Couldn't find #{self.name} with ID=~#{substring}")
|
49
|
-
end
|
50
|
-
|
51
|
-
def find(id)
|
52
|
-
store.detect{ |r| r.id == id } || raise(UnknownRecord, "Couldn't find #{self.name} with ID=#{id}")
|
36
|
+
find(id) || raise(UnknownRecord, "Couldn't find #{self.name} with ID=#{id}")
|
53
37
|
end
|
54
38
|
|
55
39
|
def exists?(id)
|
@@ -92,18 +76,7 @@ module MemModel
|
|
92
76
|
def initialize(attributes = {})
|
93
77
|
@persisted = false
|
94
78
|
self.id = self.class.generate_id
|
95
|
-
|
96
|
-
end
|
97
|
-
|
98
|
-
def load(attributes) #:nodoc:
|
99
|
-
return unless attributes
|
100
|
-
attributes.each do |(name, value)|
|
101
|
-
self.send("#{name}=".to_sym, value)
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
def to_model
|
106
|
-
return self
|
79
|
+
load_attributes(attributes)
|
107
80
|
end
|
108
81
|
|
109
82
|
def new?
|
@@ -123,317 +96,39 @@ module MemModel
|
|
123
96
|
save || raise(InvalidRecord)
|
124
97
|
end
|
125
98
|
|
126
|
-
def destroy
|
127
|
-
self.class.records.delete(self.id)
|
128
|
-
self
|
129
|
-
end
|
130
|
-
|
131
99
|
def create
|
132
100
|
self.id ||= generate_id
|
133
|
-
@persisted = true
|
134
101
|
self.class.store << self
|
102
|
+
@persisted = true
|
135
103
|
self.id
|
136
104
|
end
|
137
105
|
|
138
106
|
def update
|
139
|
-
|
140
|
-
item.load(attributes)
|
107
|
+
# no-op
|
141
108
|
true
|
142
109
|
end
|
143
|
-
end
|
144
|
-
|
145
|
-
class SuperModel
|
146
|
-
|
147
|
-
class << self
|
148
|
-
attr_accessor(:primary_key) #:nodoc:
|
149
|
-
|
150
|
-
def primary_key
|
151
|
-
@primary_key ||= 'id'
|
152
|
-
end
|
153
|
-
|
154
|
-
def collection(&block)
|
155
|
-
@collection ||= Class.new(Array)
|
156
|
-
@collection.class_eval(&block) if block_given?
|
157
|
-
@collection
|
158
|
-
end
|
159
|
-
|
160
|
-
def attributes(*attributes)
|
161
|
-
self.known_attributes |= attributes.map(&:to_s)
|
162
|
-
end
|
163
|
-
|
164
|
-
def records
|
165
|
-
@records ||= {}
|
166
|
-
end
|
167
|
-
|
168
|
-
def find_by_attribute(name, value) #:nodoc:
|
169
|
-
item = records.values.find {|r| r.send(name) == value }
|
170
|
-
item && item.dup
|
171
|
-
end
|
172
|
-
|
173
|
-
def find_all_by_attribute(name, value) #:nodoc:
|
174
|
-
items = records.values.select {|r| r.send(name) == value }
|
175
|
-
collection.new(items.deep_dup)
|
176
|
-
end
|
177
|
-
|
178
|
-
def raw_find(id) #:nodoc:
|
179
|
-
records[id] || raise(UnknownRecord, "Couldn't find #{self.name} with ID=#{id}")
|
180
|
-
end
|
181
|
-
|
182
|
-
# Find record by ID, or raise.
|
183
|
-
def find(id)
|
184
|
-
item = raw_find(id)
|
185
|
-
item && item.dup
|
186
|
-
end
|
187
|
-
alias :[] :find
|
188
|
-
|
189
|
-
def first
|
190
|
-
item = records.values[0]
|
191
|
-
item && item.dup
|
192
|
-
end
|
193
|
-
|
194
|
-
def last
|
195
|
-
item = records.values[-1]
|
196
|
-
item && item.dup
|
197
|
-
end
|
198
|
-
|
199
|
-
def where(options)
|
200
|
-
items = records.values.select do |r|
|
201
|
-
options.all? do |k, v|
|
202
|
-
if v.is_a?(Enumerable)
|
203
|
-
v.include?(r.send(k))
|
204
|
-
else
|
205
|
-
r.send(k) == v
|
206
|
-
end
|
207
|
-
end
|
208
|
-
end
|
209
|
-
collection.new(items.deep_dup)
|
210
|
-
end
|
211
|
-
|
212
|
-
def exists?(id)
|
213
|
-
records.has_key?(id)
|
214
|
-
end
|
215
|
-
|
216
|
-
def count
|
217
|
-
records.length
|
218
|
-
end
|
219
|
-
|
220
|
-
def all
|
221
|
-
collection.new(records.values.deep_dup)
|
222
|
-
end
|
223
|
-
|
224
|
-
def select(&block)
|
225
|
-
collection.new(records.values.select(&block).deep_dup)
|
226
|
-
end
|
227
|
-
|
228
|
-
def update(id, atts)
|
229
|
-
find(id).update_attributes(atts)
|
230
|
-
end
|
231
|
-
|
232
|
-
def destroy(id)
|
233
|
-
find(id).destroy
|
234
|
-
end
|
235
|
-
|
236
|
-
# Removes all records and executes
|
237
|
-
# destroy callbacks.
|
238
|
-
def destroy_all
|
239
|
-
all.each {|r| r.destroy }
|
240
|
-
end
|
241
|
-
|
242
|
-
# Removes all records without executing
|
243
|
-
# destroy callbacks.
|
244
|
-
def delete_all
|
245
|
-
records.clear
|
246
|
-
end
|
247
|
-
|
248
|
-
# Create a new record.
|
249
|
-
# Example:
|
250
|
-
# create(:name => "foo", :id => 1)
|
251
|
-
def create(atts = {})
|
252
|
-
rec = self.new(atts)
|
253
|
-
rec.save && rec
|
254
|
-
end
|
255
|
-
|
256
|
-
def create!(*args)
|
257
|
-
create(*args) || raise(InvalidRecord)
|
258
|
-
end
|
259
|
-
|
260
|
-
def method_missing(method_symbol, *args) #:nodoc:
|
261
|
-
method_name = method_symbol.to_s
|
262
|
-
|
263
|
-
if method_name =~ /^find_by_(\w+)!/
|
264
|
-
send("find_by_#{$1}", *args) || raise(UnknownRecord)
|
265
|
-
elsif method_name =~ /^find_by_(\w+)/
|
266
|
-
find_by_attribute($1, args.first)
|
267
|
-
elsif method_name =~ /^find_or_create_by_(\w+)/
|
268
|
-
send("find_by_#{$1}", *args) || create($1 => args.first)
|
269
|
-
elsif method_name =~ /^find_all_by_(\w+)/
|
270
|
-
find_all_by_attribute($1, args.first)
|
271
|
-
else
|
272
|
-
super
|
273
|
-
end
|
274
|
-
end
|
275
|
-
end
|
276
|
-
|
277
|
-
attr_accessor :attributes
|
278
|
-
attr_writer :new_record
|
279
|
-
|
280
|
-
def known_attributes
|
281
|
-
self.class.known_attributes | self.attributes.keys.map(&:to_s)
|
282
|
-
end
|
283
|
-
|
284
|
-
def initialize(attributes = {})
|
285
|
-
@new_record = true
|
286
|
-
@attributes = {}.with_indifferent_access
|
287
|
-
@attributes.merge!(known_attributes.inject({}) {|h, n| h[n] = nil; h })
|
288
|
-
@changed_attributes = {}
|
289
|
-
load(attributes)
|
290
|
-
end
|
291
|
-
|
292
|
-
def clone
|
293
|
-
cloned = attributes.reject {|k,v| k == self.class.primary_key }
|
294
|
-
cloned = cloned.inject({}) do |attrs, (k, v)|
|
295
|
-
attrs[k] = v.clone
|
296
|
-
attrs
|
297
|
-
end
|
298
|
-
self.class.new(cloned)
|
299
|
-
end
|
300
110
|
|
301
|
-
def
|
302
|
-
|
303
|
-
|
304
|
-
alias :new_record? :new?
|
305
|
-
|
306
|
-
# Gets the <tt>\id</tt> attribute of the item.
|
307
|
-
def id
|
308
|
-
attributes[self.class.primary_key]
|
309
|
-
end
|
310
|
-
|
311
|
-
# Sets the <tt>\id</tt> attribute of the item.
|
312
|
-
def id=(id)
|
313
|
-
attributes[self.class.primary_key] = id
|
314
|
-
end
|
315
|
-
|
316
|
-
def ==(other)
|
317
|
-
other.equal?(self) || (other.instance_of?(self.class) && other.id == id)
|
318
|
-
end
|
319
|
-
|
320
|
-
# Tests for equality (delegates to ==).
|
321
|
-
def eql?(other)
|
322
|
-
self == other
|
323
|
-
end
|
324
|
-
|
325
|
-
def hash
|
326
|
-
id.hash
|
327
|
-
end
|
328
|
-
|
329
|
-
def dup
|
330
|
-
self.class.new.tap do |base|
|
331
|
-
base.attributes = attributes
|
332
|
-
base.new_record = new_record?
|
333
|
-
end
|
111
|
+
def update_attributes(attributes)
|
112
|
+
load_attributes(attributes)
|
113
|
+
save
|
334
114
|
end
|
335
115
|
|
336
|
-
def
|
337
|
-
|
116
|
+
def destroy
|
117
|
+
self.class.records.delete(self.id)
|
118
|
+
self
|
338
119
|
end
|
339
120
|
|
340
|
-
def
|
341
|
-
|
121
|
+
def to_model
|
122
|
+
return self
|
342
123
|
end
|
343
124
|
|
344
|
-
|
345
|
-
!new?
|
346
|
-
end
|
347
|
-
alias_method :persisted?, :exists?
|
125
|
+
private
|
348
126
|
|
349
|
-
def
|
127
|
+
def load_attributes(attributes)
|
350
128
|
return unless attributes
|
351
129
|
attributes.each do |(name, value)|
|
352
130
|
self.send("#{name}=".to_sym, value)
|
353
131
|
end
|
354
132
|
end
|
355
|
-
|
356
|
-
def reload
|
357
|
-
return self if new?
|
358
|
-
item = self.class.find(id)
|
359
|
-
load(item.attributes)
|
360
|
-
return self
|
361
|
-
end
|
362
|
-
|
363
|
-
def update_attribute(name, value)
|
364
|
-
self.send("#{name}=".to_sym, value)
|
365
|
-
self.save
|
366
|
-
end
|
367
|
-
|
368
|
-
def update_attributes(attributes)
|
369
|
-
load(attributes) && save
|
370
|
-
end
|
371
|
-
|
372
|
-
def update_attributes!(attributes)
|
373
|
-
update_attributes(attributes) || raise(InvalidRecord)
|
374
|
-
end
|
375
|
-
|
376
|
-
def has_attribute?(name)
|
377
|
-
@attributes.has_key?(name)
|
378
|
-
end
|
379
|
-
|
380
|
-
alias_method :respond_to_without_attributes?, :respond_to?
|
381
|
-
|
382
|
-
def respond_to?(method, include_priv = false)
|
383
|
-
method_name = method.to_s
|
384
|
-
if attributes.nil?
|
385
|
-
super
|
386
|
-
elsif known_attributes.include?(method_name)
|
387
|
-
true
|
388
|
-
elsif method_name =~ /(?:=|\?)$/ && attributes.include?($`)
|
389
|
-
true
|
390
|
-
else
|
391
|
-
super
|
392
|
-
end
|
393
|
-
end
|
394
|
-
|
395
|
-
def destroy
|
396
|
-
raw_destroy
|
397
|
-
self
|
398
|
-
end
|
399
|
-
|
400
|
-
protected
|
401
|
-
def read_attribute(name)
|
402
|
-
@attributes[name]
|
403
|
-
end
|
404
|
-
|
405
|
-
def write_attribute(name, value)
|
406
|
-
@attributes[name] = value
|
407
|
-
end
|
408
|
-
|
409
|
-
def generate_id
|
410
|
-
object_id
|
411
|
-
end
|
412
|
-
|
413
|
-
def raw_destroy
|
414
|
-
self.class.records.delete(self.id)
|
415
|
-
end
|
416
|
-
|
417
|
-
def raw_create
|
418
|
-
self.class.records[self.id] = self.dup
|
419
|
-
end
|
420
|
-
|
421
|
-
def create
|
422
|
-
self.id ||= generate_id
|
423
|
-
self.new_record = false
|
424
|
-
raw_create
|
425
|
-
self.id
|
426
|
-
end
|
427
|
-
|
428
|
-
def raw_update
|
429
|
-
item = self.class.raw_find(id)
|
430
|
-
item.load(attributes)
|
431
|
-
end
|
432
|
-
|
433
|
-
def update
|
434
|
-
raw_update
|
435
|
-
true
|
436
|
-
end
|
437
|
-
|
438
133
|
end
|
439
134
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module MemModel
|
2
|
+
module Guid
|
3
|
+
def self.included(base)
|
4
|
+
base.send :extend, MemModel::Guid::ClassMethods
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def generate_id
|
9
|
+
[guid_prefix, '-', SecureRandom.uuid].join.upcase
|
10
|
+
end
|
11
|
+
|
12
|
+
def guid_prefix
|
13
|
+
name[0...3]
|
14
|
+
end
|
15
|
+
|
16
|
+
def find_all_matching(substring)
|
17
|
+
store.select{ |r| r.id.include?(substring.to_s.upcase) }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module MemModel
|
2
|
+
PERSISTENT_ROOT = {} if !MemModel.maglev?
|
3
|
+
|
4
|
+
module RootedStore
|
5
|
+
def self.included(base)
|
6
|
+
base.send :extend, ClassMethods
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def store_class
|
11
|
+
MemModel.maglev? ? IdentitySet : Set
|
12
|
+
end
|
13
|
+
|
14
|
+
def root_container
|
15
|
+
MemModel.maglev? ? Maglev : MemModel
|
16
|
+
end
|
17
|
+
|
18
|
+
def store
|
19
|
+
root[:MemModel] ||= {}
|
20
|
+
root[:MemModel][name] ||= store_class.new
|
21
|
+
end
|
22
|
+
|
23
|
+
def root
|
24
|
+
@root ||= root_container::PERSISTENT_ROOT
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/mem_model/version.rb
CHANGED
data/lib/mem_model.rb
CHANGED
@@ -1,10 +1,24 @@
|
|
1
|
+
lib_dir = File.dirname(__FILE__)
|
2
|
+
$LOAD_PATH << lib_dir unless $LOAD_PATH.include? lib_dir
|
3
|
+
|
1
4
|
require 'active_attr'
|
2
5
|
require 'securerandom'
|
3
6
|
require 'forwardable'
|
4
7
|
require 'set'
|
8
|
+
require 'active_support/dependencies/autoload'
|
5
9
|
|
6
10
|
module MemModel
|
11
|
+
def maglev?
|
12
|
+
!defined?(Maglev).nil?
|
13
|
+
end
|
14
|
+
module_function :maglev?
|
15
|
+
|
16
|
+
extend ActiveSupport::Autoload
|
17
|
+
|
18
|
+
autoload :Base
|
19
|
+
autoload :Guid
|
20
|
+
autoload :RootedBase
|
21
|
+
autoload :RootedStore
|
7
22
|
end
|
8
23
|
|
9
|
-
require 'mem_model/base'
|
10
24
|
require 'mem_model/version'
|
data/mem_model.gemspec
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
# stub: mem_model 0.
|
2
|
+
# stub: mem_model 0.2.0.20131223123844 ruby lib
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "mem_model"
|
6
|
-
s.version = "0.
|
6
|
+
s.version = "0.2.0.20131223123844"
|
7
7
|
|
8
8
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
9
9
|
s.authors = ["JohnnyT"]
|
10
|
-
s.date = "2013-12-
|
10
|
+
s.date = "2013-12-23"
|
11
11
|
s.description = "MemModel persists Ruby objects using MagLev as a data storage engine. It's an ActiveModel implementation so it works stand-alone or in Rails 3 as a drop-in replacement for ActiveRecord or DataMapper. If MemModel is used in non-MagLev platforms, objects will be persisted to in-memory sets."
|
12
12
|
s.email = ["ubergeek3141@gmail.com"]
|
13
13
|
s.extra_rdoc_files = ["CHANGELOG.md", "CONTRIBUTING.md", "LICENSE.md", "Manifest.txt", "README.md"]
|
14
|
-
s.files = ["CHANGELOG.md", "CONTRIBUTING.md", "LICENSE.md", "Manifest.txt", "README.md", "Rakefile", "lib/mem_model.rb", "lib/mem_model/base.rb", "lib/mem_model/version.rb", "mem_model.gemspec", "test/helper.rb", "test/mem_model/
|
14
|
+
s.files = [".coveralls.yml", ".gitignore", ".travis.yml", "CHANGELOG.md", "CONTRIBUTING.md", "Gemfile.ci", "LICENSE.md", "Manifest.txt", "README.md", "Rakefile", "lib/mem_model.rb", "lib/mem_model/base.rb", "lib/mem_model/guid.rb", "lib/mem_model/rooted_base.rb", "lib/mem_model/rooted_store.rb", "lib/mem_model/version.rb", "mem_model.gemspec", "test/helper.rb", "test/mem_model/test_active_model.rb", "test/mem_model/test_base.rb", "test/mem_model/test_guid.rb", "test/mem_model/test_rooted_store.rb", "test/test_version.rb", ".gemtest"]
|
15
15
|
s.homepage = "https://github.com/johnnyt/mem_model"
|
16
16
|
s.licenses = ["MIT"]
|
17
17
|
s.rdoc_options = ["--main", "README.md"]
|
@@ -19,29 +19,32 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.rubyforge_project = "mem_model"
|
20
20
|
s.rubygems_version = "2.1.11"
|
21
21
|
s.summary = "ActiveModel-compliant MagLev persistence"
|
22
|
-
s.test_files = ["test/mem_model/
|
22
|
+
s.test_files = ["test/mem_model/test_guid.rb", "test/mem_model/test_base.rb", "test/mem_model/test_rooted_store.rb", "test/mem_model/test_active_model.rb", "test/test_version.rb"]
|
23
23
|
|
24
24
|
if s.respond_to? :specification_version then
|
25
25
|
s.specification_version = 4
|
26
26
|
|
27
27
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
28
28
|
s.add_runtime_dependency(%q<active_attr>, [">= 0.8.2"])
|
29
|
-
s.add_runtime_dependency(%q<activesupport>, ["
|
30
|
-
s.add_development_dependency(%q<
|
31
|
-
s.add_development_dependency(%q<minitest>, ["
|
29
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 3.2.15"])
|
30
|
+
s.add_development_dependency(%q<minitest>, [">= 5.0.0"])
|
31
|
+
s.add_development_dependency(%q<minitest-reporters>, [">= 1.0.0"])
|
32
|
+
s.add_development_dependency(%q<coveralls>, [">= 1.0.0"])
|
32
33
|
s.add_development_dependency(%q<hoe>, ["~> 3.7"])
|
33
34
|
else
|
34
35
|
s.add_dependency(%q<active_attr>, [">= 0.8.2"])
|
35
|
-
s.add_dependency(%q<activesupport>, ["
|
36
|
-
s.add_dependency(%q<
|
37
|
-
s.add_dependency(%q<minitest>, ["
|
36
|
+
s.add_dependency(%q<activesupport>, [">= 3.2.15"])
|
37
|
+
s.add_dependency(%q<minitest>, [">= 5.0.0"])
|
38
|
+
s.add_dependency(%q<minitest-reporters>, [">= 1.0.0"])
|
39
|
+
s.add_dependency(%q<coveralls>, [">= 1.0.0"])
|
38
40
|
s.add_dependency(%q<hoe>, ["~> 3.7"])
|
39
41
|
end
|
40
42
|
else
|
41
43
|
s.add_dependency(%q<active_attr>, [">= 0.8.2"])
|
42
|
-
s.add_dependency(%q<activesupport>, ["
|
43
|
-
s.add_dependency(%q<
|
44
|
-
s.add_dependency(%q<minitest>, ["
|
44
|
+
s.add_dependency(%q<activesupport>, [">= 3.2.15"])
|
45
|
+
s.add_dependency(%q<minitest>, [">= 5.0.0"])
|
46
|
+
s.add_dependency(%q<minitest-reporters>, [">= 1.0.0"])
|
47
|
+
s.add_dependency(%q<coveralls>, [">= 1.0.0"])
|
45
48
|
s.add_dependency(%q<hoe>, ["~> 3.7"])
|
46
49
|
end
|
47
50
|
end
|
data/test/helper.rb
CHANGED
@@ -1,7 +1,21 @@
|
|
1
1
|
require 'rubygems'
|
2
|
+
|
3
|
+
# Disable warning message
|
4
|
+
require 'i18n'
|
5
|
+
I18n.enforce_available_locales = false
|
6
|
+
|
7
|
+
# Only run coverage in MRI
|
8
|
+
unless defined? Maglev
|
9
|
+
if ENV['CI']
|
10
|
+
require 'coveralls'
|
11
|
+
Coveralls.wear!
|
12
|
+
else
|
13
|
+
require 'simplecov'
|
14
|
+
SimpleCov.start
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
2
18
|
require File.expand_path('lib/mem_model')
|
3
19
|
require 'active_model/lint'
|
4
20
|
gem 'minitest', '5.2.0'
|
5
21
|
require 'minitest/autorun'
|
6
|
-
require 'minitest/reporters'
|
7
|
-
Minitest::Reporters.use!
|
data/test/mem_model/test_base.rb
CHANGED
@@ -3,9 +3,54 @@ require File.expand_path('../../helper', __FILE__)
|
|
3
3
|
class TestBase < Minitest::Test
|
4
4
|
class Account
|
5
5
|
include MemModel::Base
|
6
|
+
attribute :balance
|
6
7
|
end
|
7
8
|
|
8
|
-
def
|
9
|
-
|
9
|
+
def setup
|
10
|
+
@account = Account.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def teardown
|
14
|
+
@account = nil
|
15
|
+
Account.delete_all
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_not_exists
|
19
|
+
refute Account.exists? 314159
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_exists
|
23
|
+
refute Account.exists? @account.id
|
24
|
+
@account.save
|
25
|
+
assert Account.exists? @account.id
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_update
|
29
|
+
@account.save
|
30
|
+
new_balance = 314
|
31
|
+
refute_equal new_balance, @account.balance
|
32
|
+
|
33
|
+
Account.update @account.id, :balance => new_balance
|
34
|
+
assert_equal new_balance, @account.balance
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_new_model_is_new_record
|
38
|
+
assert @account.new_record?
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_saved_model_is_persisted
|
42
|
+
@account.save
|
43
|
+
refute @account.new_record?
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_find_nonexistent_record
|
47
|
+
assert_raises(MemModel::UnknownRecord) do
|
48
|
+
Account.find_by_id 'wat'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_find
|
53
|
+
@account.save
|
54
|
+
assert_equal @account, Account.find(@account.id)
|
10
55
|
end
|
11
56
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.expand_path('../../helper', __FILE__)
|
2
|
+
|
3
|
+
class TestGuid < Minitest::Test
|
4
|
+
class Account
|
5
|
+
include MemModel::Base
|
6
|
+
include MemModel::Guid
|
7
|
+
end
|
8
|
+
|
9
|
+
def guid_regexp
|
10
|
+
/^\w{3}-\w{8}-\w{4}-\w{4}-\w{4}-\w{12}$/
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_new_guid_uniqueness
|
14
|
+
assert_match guid_regexp, Account.generate_id
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.expand_path('../../helper', __FILE__)
|
2
|
+
|
3
|
+
class TestRootedStore < Minitest::Test
|
4
|
+
class Account
|
5
|
+
include MemModel::RootedBase
|
6
|
+
end
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@account = Account.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def teardown
|
13
|
+
@account = nil
|
14
|
+
Account.delete_all
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_not_exists
|
18
|
+
refute Account.exists? 314159
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_exists
|
22
|
+
refute Account.exists? @account.id
|
23
|
+
@account.save
|
24
|
+
assert Account.exists? @account.id
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_root_container
|
28
|
+
if defined?(Maglev)
|
29
|
+
assert_equal Maglev, Account.root_container
|
30
|
+
else
|
31
|
+
assert_equal MemModel, Account.root_container
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mem_model
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- JohnnyT
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-12-
|
11
|
+
date: 2013-12-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: active_attr
|
@@ -28,44 +28,58 @@ dependencies:
|
|
28
28
|
name: activesupport
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - '
|
31
|
+
- - ! '>='
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: 3.2.15
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - '
|
38
|
+
- - ! '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 3.2.15
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: minitest
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ! '>='
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 5.0.0
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ! '>='
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 5.0.0
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name: minitest
|
56
|
+
name: minitest-reporters
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - '
|
59
|
+
- - ! '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 1.0.0
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - '
|
66
|
+
- - ! '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 1.0.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: coveralls
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ! '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.0.0
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ! '>='
|
67
81
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
82
|
+
version: 1.0.0
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: hoe
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -95,20 +109,28 @@ extra_rdoc_files:
|
|
95
109
|
- Manifest.txt
|
96
110
|
- README.md
|
97
111
|
files:
|
112
|
+
- .coveralls.yml
|
113
|
+
- .gitignore
|
114
|
+
- .travis.yml
|
98
115
|
- CHANGELOG.md
|
99
116
|
- CONTRIBUTING.md
|
117
|
+
- Gemfile.ci
|
100
118
|
- LICENSE.md
|
101
119
|
- Manifest.txt
|
102
120
|
- README.md
|
103
121
|
- Rakefile
|
104
122
|
- lib/mem_model.rb
|
105
123
|
- lib/mem_model/base.rb
|
124
|
+
- lib/mem_model/guid.rb
|
125
|
+
- lib/mem_model/rooted_base.rb
|
126
|
+
- lib/mem_model/rooted_store.rb
|
106
127
|
- lib/mem_model/version.rb
|
107
128
|
- mem_model.gemspec
|
108
129
|
- test/helper.rb
|
109
|
-
- test/mem_model/
|
130
|
+
- test/mem_model/test_active_model.rb
|
110
131
|
- test/mem_model/test_base.rb
|
111
|
-
- test/mem_model/
|
132
|
+
- test/mem_model/test_guid.rb
|
133
|
+
- test/mem_model/test_rooted_store.rb
|
112
134
|
- test/test_version.rb
|
113
135
|
- .gemtest
|
114
136
|
homepage: https://github.com/johnnyt/mem_model
|
@@ -138,7 +160,8 @@ signing_key:
|
|
138
160
|
specification_version: 4
|
139
161
|
summary: ActiveModel-compliant MagLev persistence
|
140
162
|
test_files:
|
141
|
-
- test/mem_model/
|
163
|
+
- test/mem_model/test_guid.rb
|
142
164
|
- test/mem_model/test_base.rb
|
143
|
-
- test/mem_model/
|
165
|
+
- test/mem_model/test_rooted_store.rb
|
166
|
+
- test/mem_model/test_active_model.rb
|
144
167
|
- test/test_version.rb
|
@@ -1,37 +0,0 @@
|
|
1
|
-
require File.expand_path('../../helper', __FILE__)
|
2
|
-
|
3
|
-
class TestPersistence < Minitest::Test
|
4
|
-
class Account
|
5
|
-
include MemModel::Base
|
6
|
-
attribute :balance
|
7
|
-
end
|
8
|
-
|
9
|
-
def setup
|
10
|
-
@account = Account.new
|
11
|
-
end
|
12
|
-
|
13
|
-
def teardown
|
14
|
-
@account = nil
|
15
|
-
Account.delete_all
|
16
|
-
end
|
17
|
-
|
18
|
-
def test_new_model_is_new_record
|
19
|
-
assert @account.new_record?
|
20
|
-
end
|
21
|
-
|
22
|
-
def test_saved_model_is_persisted
|
23
|
-
@account.save
|
24
|
-
refute @account.new_record?
|
25
|
-
end
|
26
|
-
|
27
|
-
def test_find_nonexistent_record
|
28
|
-
assert_raises(MemModel::UnknownRecord) do
|
29
|
-
Account.find 'wat'
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def test_find
|
34
|
-
@account.save
|
35
|
-
assert_equal @account, Account.find(@account.id)
|
36
|
-
end
|
37
|
-
end
|