motion_model 0.2.1 → 0.2.2
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/CHANGELOG +10 -0
- data/README.md +7 -28
- data/Rakefile +1 -0
- data/lib/motion_model/model.rb +57 -2
- data/lib/motion_model/version.rb +1 -1
- data/spec/model_spec.rb +18 -1
- metadata +2 -2
data/CHANGELOG
CHANGED
@@ -11,3 +11,13 @@ to the column metadata.
|
|
11
11
|
if not specified in new or create.
|
12
12
|
|
13
13
|
2012-09-06: Added block-style finders. Added delete method.
|
14
|
+
|
15
|
+
2012-09-07: IMPORTANT! PLEASE READ! Two new methods were added
|
16
|
+
to MotionModel to support persistence:
|
17
|
+
|
18
|
+
Task#serialize_to_file(file_name)
|
19
|
+
Task.deserialize_from_file(file_name)
|
20
|
+
|
21
|
+
Note that serialize operates on an instance and
|
22
|
+
deserialize is a class method that creates an
|
23
|
+
instance.
|
data/README.md
CHANGED
@@ -132,44 +132,23 @@ Things That Work
|
|
132
132
|
@tasks = Task.order{|one, two| two.details <=> one.details}.all # Get tasks ordered descending by :details
|
133
133
|
```
|
134
134
|
|
135
|
-
* Serialization
|
136
|
-
in your `AppDelegate`:
|
135
|
+
* Serialization is part of MotionModel. So, in your `AppDelegate` you might do something like this:
|
137
136
|
|
138
137
|
```ruby
|
139
|
-
|
140
|
-
if File.exist? documents_file("my_fine.dat")
|
141
|
-
error_ptr = Pointer.new(:object)
|
142
|
-
|
143
|
-
data = NSData.dataWithContentsOfFile(documents_file('my_fine.dat'), options:NSDataReadingMappedIfSafe, error:error_ptr)
|
144
|
-
|
145
|
-
if data.nil?
|
146
|
-
error = error_ptr[0]
|
147
|
-
show_user_scary_warning error
|
148
|
-
else
|
149
|
-
@my_data_tree = NSKeyedUnarchiver.unarchiveObjectWithData(data)
|
150
|
-
end
|
151
|
-
else
|
152
|
-
show_user_first_time_welcome
|
153
|
-
end
|
154
|
-
end
|
138
|
+
@tasks = Task.deserialize_from_file('tasks.dat')
|
155
139
|
```
|
156
140
|
|
157
141
|
and of course on the "save" side:
|
158
142
|
|
159
143
|
```ruby
|
160
|
-
|
161
|
-
|
162
|
-
data = NSKeyedArchiver.archivedDataWithRootObject App.delegate.events
|
163
|
-
unless data.writeToFile(documents_file('my_fine.dat'), options: NSDataWritingAtomic, error: error_ptr)
|
164
|
-
error = error_ptr[0]
|
165
|
-
show_scary_message error
|
144
|
+
@tasks.serialize_to_file('tasks.dat')
|
166
145
|
end
|
167
146
|
```
|
168
147
|
|
169
|
-
Note that the
|
170
|
-
automatically handled by `NSCoder` provided you conform to the coding
|
171
|
-
protocol. When you declare your columns, `MotionModel` understands how
|
172
|
-
|
148
|
+
Note that the this serialization of any arbitrarily complex set of relations
|
149
|
+
is automatically handled by `NSCoder` provided you conform to the coding
|
150
|
+
protocol. When you declare your columns, `MotionModel` understands how to
|
151
|
+
serialize your data so you need take no further action.
|
173
152
|
|
174
153
|
* Relations, in principle work. This is a part I'm still noodling over
|
175
154
|
so it's not really safe to use them. In any case, how I expect it will
|
data/Rakefile
CHANGED
data/lib/motion_model/model.rb
CHANGED
@@ -38,6 +38,8 @@
|
|
38
38
|
#
|
39
39
|
|
40
40
|
module MotionModel
|
41
|
+
class PersistFileError < Exception; end
|
42
|
+
|
41
43
|
module Model
|
42
44
|
class Column
|
43
45
|
attr_accessor :name
|
@@ -223,6 +225,37 @@ module MotionModel
|
|
223
225
|
def each(&block)
|
224
226
|
raise ArgumentError.new("each requires a block") unless block_given?
|
225
227
|
@collection.each{|item| yield item}
|
228
|
+
end
|
229
|
+
|
230
|
+
# Returns the unarchived object if successful, otherwise false
|
231
|
+
#
|
232
|
+
# Note that subsequent calls to serialize/deserialize methods
|
233
|
+
# will remember the file name, so they may omit that argument.
|
234
|
+
#
|
235
|
+
# Raises a +MotionModel::PersistFileFailureError+ on failure.
|
236
|
+
def deserialize_from_file(file_name = nil)
|
237
|
+
@file_name ||= file_name
|
238
|
+
new_object = self.new
|
239
|
+
|
240
|
+
if File.exist? documents_file(@file_name)
|
241
|
+
error_ptr = Pointer.new(:object)
|
242
|
+
|
243
|
+
data = NSData.dataWithContentsOfFile(documents_file(file_name), options:NSDataReadingMappedIfSafe, error:error_ptr)
|
244
|
+
|
245
|
+
if data.nil?
|
246
|
+
error = error_ptr[0]
|
247
|
+
raise MotionModel::PersistFileFailureError.new "Error when reading the data: #{error}"
|
248
|
+
else
|
249
|
+
return NSKeyedUnarchiver.unarchiveObjectWithData(data)
|
250
|
+
end
|
251
|
+
else
|
252
|
+
return false
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
def documents_file(file_name)
|
257
|
+
file_path = File.join NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true), file_name
|
258
|
+
file_path
|
226
259
|
end
|
227
260
|
|
228
261
|
end
|
@@ -311,7 +344,7 @@ module MotionModel
|
|
311
344
|
|
312
345
|
def initWithCoder(coder)
|
313
346
|
self.init
|
314
|
-
|
347
|
+
columns.each do |attr|
|
315
348
|
# If a model revision has taken place, don't try to decode
|
316
349
|
# something that's not there.
|
317
350
|
new_tag_id = 1
|
@@ -330,7 +363,7 @@ module MotionModel
|
|
330
363
|
end
|
331
364
|
|
332
365
|
def encodeWithCoder(coder)
|
333
|
-
|
366
|
+
columns.each do |attr|
|
334
367
|
coder.encodeObject(self.send(attr), forKey: attr.to_s)
|
335
368
|
end
|
336
369
|
end
|
@@ -373,6 +406,28 @@ ERRORINFO
|
|
373
406
|
end
|
374
407
|
end
|
375
408
|
|
409
|
+
# Serializes data to a persistent store (file, in this
|
410
|
+
# terminology). Serialization is synchronous, so this
|
411
|
+
# will pause your run loop until complete.
|
412
|
+
#
|
413
|
+
# +file_name+ is the name of the persistent store you
|
414
|
+
# want to use. If you omit this, it will use the last
|
415
|
+
# remembered file name.
|
416
|
+
#
|
417
|
+
# Raises a +MotionModel::PersistFileFailureError+ on failure.
|
418
|
+
def serialize_to_file(file_name = nil)
|
419
|
+
@file_name ||= file_name
|
420
|
+
error_ptr = Pointer.new(:object)
|
421
|
+
|
422
|
+
data = NSKeyedArchiver.archivedDataWithRootObject self
|
423
|
+
unless data.writeToFile(self.class.documents_file(file_name), options: NSDataWritingAtomic, error: error_ptr)
|
424
|
+
# De-reference the pointer.
|
425
|
+
error = error_ptr[0]
|
426
|
+
|
427
|
+
# Now we can use the `error' object.
|
428
|
+
raise MotionModel::PersistFileFailureError.new "Error when writing data: #{error}"
|
429
|
+
end
|
430
|
+
end
|
376
431
|
end
|
377
432
|
end
|
378
433
|
|
data/lib/motion_model/version.rb
CHANGED
data/spec/model_spec.rb
CHANGED
@@ -325,5 +325,22 @@ describe "Creating a model" do
|
|
325
325
|
end
|
326
326
|
|
327
327
|
end
|
328
|
+
end
|
329
|
+
|
330
|
+
describe 'persistence' do
|
331
|
+
before do
|
332
|
+
Task.delete_all
|
333
|
+
%w(one two three).each do |task|
|
334
|
+
@tasks = Task.create(:name => "name #{task}")
|
335
|
+
end
|
336
|
+
@tasks.serialize_to_file('test.dat')
|
337
|
+
end
|
328
338
|
|
329
|
-
|
339
|
+
it 'reads persisted model data' do
|
340
|
+
tasks = Task.deserialize_from_file('test.dat')
|
341
|
+
|
342
|
+
Task.first.name.should == 'name one'
|
343
|
+
Task.last.name.should == 'name three'
|
344
|
+
Task.count.should == 3
|
345
|
+
end
|
346
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: motion_model
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
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: 2012-09-
|
12
|
+
date: 2012-09-07 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Simple model and validation mixins for RubyMotion
|
15
15
|
email:
|