motion-prime 0.1.0 → 0.1.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/.gitignore +2 -1
- data/.travis.yml +6 -0
- data/Gemfile +5 -10
- data/Gemfile.lock +10 -7
- data/README.md +15 -7
- data/Rakefile +3 -2
- data/files/Gemfile +8 -1
- data/files/Rakefile +2 -0
- data/files/app/app_delegate.rb +10 -0
- data/files/app/config/base.rb +6 -0
- data/files/app/models/.gitkeep +0 -0
- data/files/app/screens/application_screen.rb +4 -0
- data/files/app/screens/help_screen.rb +5 -0
- data/files/app/screens/home_screen.rb +5 -0
- data/files/app/screens/sidebar_screen.rb +14 -0
- data/files/app/sections/sidebar/action.rb +5 -0
- data/files/app/sections/sidebar/table.rb +20 -0
- data/files/app/styles/sidebar.rb +38 -0
- data/files/resources/images/navigation/bg.png +0 -0
- data/files/resources/images/navigation/bg@2x.png +0 -0
- data/files/resources/images/navigation/button.png +0 -0
- data/files/resources/images/navigation/button@2x.png +0 -0
- data/lib/motion-prime.rb +1 -1
- data/motion-prime.gemspec +3 -0
- data/motion-prime/config/base.rb +8 -0
- data/motion-prime/config/config.rb +49 -0
- data/motion-prime/elements/draw/label.rb +1 -1
- data/motion-prime/models/association.rb +115 -0
- data/motion-prime/models/bag.rb +129 -0
- data/motion-prime/models/base.rb +15 -65
- data/motion-prime/models/errors.rb +3 -0
- data/motion-prime/models/finder.rb +189 -0
- data/motion-prime/models/json.rb +45 -0
- data/motion-prime/models/model.rb +118 -0
- data/motion-prime/models/store.rb +53 -0
- data/motion-prime/models/store_extension.rb +159 -0
- data/motion-prime/styles/{forms.rb → base.rb} +4 -0
- data/motion-prime/support/dm_view_controller.rb +1 -1
- data/motion-prime/version.rb +1 -1
- data/spec/config/store_spec.rb +73 -0
- data/spec/delegate/base_delegate_spec.rb +12 -0
- data/spec/helpers/base_delegate.rb +5 -0
- data/spec/helpers/base_screen.rb +9 -0
- data/spec/helpers/models.rb +53 -0
- data/spec/models/association_spec.rb +49 -0
- data/spec/models/bag_spec.rb +92 -0
- data/spec/models/base_model_spec.rb +158 -0
- data/spec/models/finder_spec.rb +183 -0
- data/spec/models/store_extension_spec.rb +120 -0
- data/spec/models/store_spec.rb +51 -0
- data/spec/screens/base_screen_spec.rb +77 -0
- metadata +84 -8
- data/lib/view_styler.rb +0 -141
- data/spec/main_spec.rb +0 -9
@@ -0,0 +1,118 @@
|
|
1
|
+
module MotionPrime
|
2
|
+
module ModelMethods
|
3
|
+
def save
|
4
|
+
raise StoreError, 'No store provided' unless self.store
|
5
|
+
|
6
|
+
error_ptr = Pointer.new(:id)
|
7
|
+
self.store.addObject(self, error: error_ptr)
|
8
|
+
raise StoreError, error_ptr[0].description if error_ptr[0]
|
9
|
+
self
|
10
|
+
end
|
11
|
+
|
12
|
+
def delete
|
13
|
+
raise StoreError, 'No store provided' unless self.store
|
14
|
+
|
15
|
+
error_ptr = Pointer.new(:id)
|
16
|
+
self.store.removeObject(self, error: error_ptr)
|
17
|
+
raise StoreError, error_ptr[0].description if error_ptr[0]
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
def store
|
22
|
+
super || self.class.store
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module ModelClassMethods
|
27
|
+
# Initialize a new object
|
28
|
+
#
|
29
|
+
# Examples:
|
30
|
+
# User.new(name: "Bob", age: 10)
|
31
|
+
#
|
32
|
+
# @return MotionPrime::BaseModel unsaved model
|
33
|
+
def new(data = {})
|
34
|
+
data.keys.each { |k|
|
35
|
+
unless self.attributes.member? k.to_sym
|
36
|
+
raise StoreError, "'#{k}' is not a defined attribute for this model"
|
37
|
+
end
|
38
|
+
}
|
39
|
+
|
40
|
+
object = self.nanoObjectWithDictionary(data)
|
41
|
+
object
|
42
|
+
end
|
43
|
+
|
44
|
+
# Initialize a new object and save it
|
45
|
+
#
|
46
|
+
# Examples:
|
47
|
+
# User.create(name: "Bob", age: 10)
|
48
|
+
#
|
49
|
+
# @return MotionPrime::BaseModel saved model
|
50
|
+
def create(data = {})
|
51
|
+
object = self.new(data)
|
52
|
+
object.save
|
53
|
+
end
|
54
|
+
|
55
|
+
# Define model attribute
|
56
|
+
#
|
57
|
+
# Examples:
|
58
|
+
# class User < MotionPrime::BaseModel
|
59
|
+
# attribute :name
|
60
|
+
# attribute :age
|
61
|
+
# end
|
62
|
+
#
|
63
|
+
# @return Nil
|
64
|
+
def attribute(name)
|
65
|
+
attributes << name
|
66
|
+
|
67
|
+
define_method(name) do |*args, &block|
|
68
|
+
self.info[name]
|
69
|
+
end
|
70
|
+
|
71
|
+
define_method((name + "=").to_sym) do |*args, &block|
|
72
|
+
self.info[name] = args[0]
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Return all model attribute names
|
77
|
+
#
|
78
|
+
# @return Array array of attribute names
|
79
|
+
def attributes(*attrs)
|
80
|
+
if attrs.size > 0
|
81
|
+
attrs.each{|attr| attribute attr}
|
82
|
+
else
|
83
|
+
@attributes ||= []
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Return store associated with model class, or shared store by default
|
88
|
+
#
|
89
|
+
# @return MotionPrime::Store store
|
90
|
+
def store
|
91
|
+
@store ||= MotionPrime::Store.shared_store
|
92
|
+
end
|
93
|
+
|
94
|
+
# Define store associated with model class
|
95
|
+
#
|
96
|
+
# @param MotionPrime::Store store
|
97
|
+
# @return MotionPrime::Store store
|
98
|
+
def store=(store)
|
99
|
+
@store = store
|
100
|
+
end
|
101
|
+
|
102
|
+
# Count of models
|
103
|
+
#
|
104
|
+
# @return Fixnum count
|
105
|
+
def count
|
106
|
+
self.store.count(self)
|
107
|
+
end
|
108
|
+
|
109
|
+
# Delete objects from store
|
110
|
+
#
|
111
|
+
# @param [Array, MotionPrime::BaseModel] objects to delete
|
112
|
+
# @return [Array] result
|
113
|
+
def delete(*args)
|
114
|
+
keys = find_keys(*args)
|
115
|
+
self.store.delete_keys(keys)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
motion_require '../config/base.rb'
|
2
|
+
module MotionPrime
|
3
|
+
class Store
|
4
|
+
def self.create(type = nil, path = nil)
|
5
|
+
error_ptr = Pointer.new(:id)
|
6
|
+
case type || MotionPrime::Config.model.store_type.to_sym
|
7
|
+
when :memory
|
8
|
+
store = NSFNanoStore.createAndOpenStoreWithType(NSFMemoryStoreType, path: nil, error: error_ptr)
|
9
|
+
when :temporary, :temp
|
10
|
+
store = NSFNanoStore.createAndOpenStoreWithType(NSFTemporaryStoreType, path: nil, error: error_ptr)
|
11
|
+
when :persistent, :file
|
12
|
+
path ||= begin
|
13
|
+
documents_path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true)[0]
|
14
|
+
documents_path + "/nano.db"
|
15
|
+
end
|
16
|
+
store = NSFNanoStore.createAndOpenStoreWithType(NSFPersistentStoreType, path: path, error: error_ptr)
|
17
|
+
else
|
18
|
+
raise StoreError.new("unexpected store type (#{type}), must be one of: :memory, :temporary or :persistent")
|
19
|
+
end
|
20
|
+
|
21
|
+
raise StoreError, error_ptr[0].description if error_ptr[0]
|
22
|
+
store
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.connect!(type = nil)
|
26
|
+
self.shared_store = create(type)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.connect(type = nil)
|
30
|
+
connect!(type) unless connected?
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.connected?
|
34
|
+
!!shared_store
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.disconnect
|
38
|
+
self.shared_store = nil
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.shared_store
|
42
|
+
@shared_store
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.shared_store=(store)
|
46
|
+
@shared_store = store
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.debug=(debug)
|
50
|
+
NSFSetIsDebugOn(debug)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
class NSFNanoStore
|
2
|
+
def engine
|
3
|
+
self.nanoStoreEngine
|
4
|
+
end
|
5
|
+
|
6
|
+
def changed?
|
7
|
+
self.hasUnsavedChanges
|
8
|
+
end
|
9
|
+
|
10
|
+
def save_interval=(interval)
|
11
|
+
self.setSaveInterval(interval)
|
12
|
+
end
|
13
|
+
|
14
|
+
## Open and Close store
|
15
|
+
|
16
|
+
def close
|
17
|
+
error_ptr = Pointer.new(:id)
|
18
|
+
closed = self.closeWithError(error_ptr)
|
19
|
+
raise MotionPrime::StoreError, error_ptr[0].description if error_ptr[0]
|
20
|
+
closed
|
21
|
+
end
|
22
|
+
|
23
|
+
def open
|
24
|
+
error_ptr = Pointer.new(:id)
|
25
|
+
opened = self.openWithError(error_ptr)
|
26
|
+
raise MotionPrime::StoreError, error_ptr[0].description if error_ptr[0]
|
27
|
+
opened
|
28
|
+
end
|
29
|
+
|
30
|
+
def closed?
|
31
|
+
self.isClosed
|
32
|
+
end
|
33
|
+
|
34
|
+
## Adding and Removing Objects
|
35
|
+
|
36
|
+
def <<(objects)
|
37
|
+
error_ptr = Pointer.new(:id)
|
38
|
+
if objects.is_a?(Array)
|
39
|
+
self.addObjectsFromArray(objects, error:error_ptr)
|
40
|
+
else
|
41
|
+
self.addObject(objects, error:error_ptr)
|
42
|
+
end
|
43
|
+
raise MotionPrime::StoreError, error_ptr[0].description if error_ptr[0]
|
44
|
+
self
|
45
|
+
end
|
46
|
+
|
47
|
+
def +(object)
|
48
|
+
error_ptr = Pointer.new(:id)
|
49
|
+
self.addObject(object, error:error_ptr)
|
50
|
+
raise MotionPrime::StoreError, error_ptr[0].description if error_ptr[0]
|
51
|
+
self
|
52
|
+
end
|
53
|
+
|
54
|
+
# delete a object or array of objects from the array
|
55
|
+
def delete(objects)
|
56
|
+
error_ptr = Pointer.new(:id)
|
57
|
+
if objects.is_a?(Array)
|
58
|
+
result = self.removeObjectsInArray(objects, error:error_ptr)
|
59
|
+
else
|
60
|
+
result = self.removeObject(objects, error:error_ptr)
|
61
|
+
end
|
62
|
+
raise MotionPrime::StoreError, error_ptr[0].description if error_ptr[0]
|
63
|
+
result
|
64
|
+
end
|
65
|
+
|
66
|
+
# Delete objects by keys
|
67
|
+
def delete_keys(keys)
|
68
|
+
error_ptr = Pointer.new(:id)
|
69
|
+
success = self.store.removeObjectsWithKeysInArray(keys, error: error_ptr)
|
70
|
+
raise MotionPrime::StoreError, error_ptr[0].description if error_ptr[0]
|
71
|
+
result
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
# delete all objects from store
|
76
|
+
def clear
|
77
|
+
error_ptr = Pointer.new(:id)
|
78
|
+
result = self.removeAllObjectsFromStoreAndReturnError(error_ptr)
|
79
|
+
raise MotionPrime::StoreError, error_ptr[0].description if error_ptr[0]
|
80
|
+
result
|
81
|
+
end
|
82
|
+
|
83
|
+
# delete object with keys
|
84
|
+
# param: keys - array of key
|
85
|
+
def delete_keys(keys)
|
86
|
+
error_ptr = Pointer.new(:id)
|
87
|
+
result = self.removeObjectsWithKeysInArray(keys, error:error_ptr)
|
88
|
+
raise MotionPrime::StoreError, error_ptr[0].description if error_ptr[0]
|
89
|
+
result
|
90
|
+
end
|
91
|
+
|
92
|
+
## Save and Maintenance
|
93
|
+
|
94
|
+
# Saves the uncommitted changes to the document store.
|
95
|
+
def save
|
96
|
+
error_ptr = Pointer.new(:id)
|
97
|
+
result = saveStoreAndReturnError(error_ptr)
|
98
|
+
raise MotionPrime::StoreError, error_ptr[0].description if error_ptr[0]
|
99
|
+
result
|
100
|
+
end
|
101
|
+
|
102
|
+
# Discards the uncommitted changes that were added to the document store.
|
103
|
+
alias_method :discard, :discardUnsavedChanges
|
104
|
+
|
105
|
+
# Compact the database file size.
|
106
|
+
def compact
|
107
|
+
error_ptr = Pointer.new(:id)
|
108
|
+
result = self.compactStoreAndReturnError(error_ptr)
|
109
|
+
raise MotionPrime::StoreError, error_ptr[0].description if error_ptr[0]
|
110
|
+
result
|
111
|
+
end
|
112
|
+
|
113
|
+
# Remove all indexes from the document store.
|
114
|
+
def clear_index
|
115
|
+
error_ptr = Pointer.new(:id)
|
116
|
+
result = self.clearIndexesAndReturnError(error_ptr)
|
117
|
+
raise MotionPrime::StoreError, error_ptr[0].description if error_ptr[0]
|
118
|
+
result
|
119
|
+
end
|
120
|
+
|
121
|
+
# Recreate all indexes from the document store.
|
122
|
+
def rebuild_index
|
123
|
+
error_ptr = Pointer.new(:id)
|
124
|
+
result = self.rebuildIndexesAndReturnError(error_ptr)
|
125
|
+
raise MotionPrime::StoreError, error_ptr[0].description if error_ptr[0]
|
126
|
+
result
|
127
|
+
end
|
128
|
+
|
129
|
+
# Makes a copy of the document store to a different location and optionally compacts it to its minimum size.
|
130
|
+
def save_store(path, compact=true)
|
131
|
+
error_ptr = Pointer.new(:id)
|
132
|
+
result = self.saveStoreToDirectoryAtPath(path, compactDatabase:compact, error:error_ptr)
|
133
|
+
raise MotionPrime::StoreError, error_ptr[0].description if error_ptr[0]
|
134
|
+
result
|
135
|
+
end
|
136
|
+
|
137
|
+
# Count number of this class objects in store
|
138
|
+
def count(clazz)
|
139
|
+
self.countOfObjectsOfClassNamed(clazz.bare_class_name)
|
140
|
+
end
|
141
|
+
|
142
|
+
# Create a transaction
|
143
|
+
def transaction
|
144
|
+
error_ptr = Pointer.new(:id)
|
145
|
+
beginTransactionAndReturnError(error_ptr)
|
146
|
+
raise MotionPrime::StoreError, error_ptr[0].description if error_ptr[0]
|
147
|
+
|
148
|
+
begin
|
149
|
+
yield self
|
150
|
+
rescue StandardError => e
|
151
|
+
rollbackTransactionAndReturnError(error_ptr)
|
152
|
+
raise e
|
153
|
+
end
|
154
|
+
success = commitTransactionAndReturnError(error_ptr)
|
155
|
+
raise MotionPrime::StoreError, error_ptr[0].description if error_ptr[0]
|
156
|
+
success
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|
data/motion-prime/version.rb
CHANGED
@@ -0,0 +1,73 @@
|
|
1
|
+
describe MotionPrime::Config do
|
2
|
+
before { @config = MotionPrime::Config.new }
|
3
|
+
|
4
|
+
describe "[]" do
|
5
|
+
before { @config = MotionPrime::Config.new(foo: "bar") }
|
6
|
+
|
7
|
+
it "returns the value if there is one" do
|
8
|
+
@config[:foo].should == "bar"
|
9
|
+
@config["foo"].should == "bar"
|
10
|
+
end
|
11
|
+
|
12
|
+
it "returns a new Configatron::Store object if there is no value" do
|
13
|
+
@config[:unknown].is_a?(MotionPrime::Config).should == true
|
14
|
+
@config["unknown"].is_a?(MotionPrime::Config).should == true
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "[]=" do
|
19
|
+
it "sets the value" do
|
20
|
+
@config[:foo] = "bar"
|
21
|
+
@config[:foo].should == "bar"
|
22
|
+
@config["foo"].should == "bar"
|
23
|
+
|
24
|
+
@config[:baz] = "bazzy"
|
25
|
+
@config[:baz].should == "bazzy"
|
26
|
+
@config["baz"].should == "bazzy"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "nil?" do
|
31
|
+
it "returns true if there is no value set" do
|
32
|
+
@config.foo.nil?.should == true
|
33
|
+
@config.foo = "bar"
|
34
|
+
@config.foo.nil?.should == false
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "class methods" do
|
39
|
+
it "should allow to set value for class" do
|
40
|
+
MotionPrime::Config.foo.nil?.should == true
|
41
|
+
MotionPrime::Config.foo = "bar"
|
42
|
+
MotionPrime::Config.foo.should == "bar"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "has_key?" do
|
47
|
+
it "returns true if there is a key" do
|
48
|
+
@config.has_key?(:foo).should == false
|
49
|
+
@config.foo = "bar"
|
50
|
+
@config.has_key?(:foo).should == true
|
51
|
+
end
|
52
|
+
|
53
|
+
it "returns false if the key is a MotionPrime::Config" do
|
54
|
+
@config.has_key?(:foo).should == false
|
55
|
+
@config.foo = MotionPrime::Config.new
|
56
|
+
@config.has_key?(:foo).should == false
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "configuring with a block" do
|
61
|
+
before do
|
62
|
+
@config.a.b = 'B'
|
63
|
+
end
|
64
|
+
|
65
|
+
it "yields the store to configure" do
|
66
|
+
@config.a do |a|
|
67
|
+
a.c = 'C'
|
68
|
+
end
|
69
|
+
@config.a.b.should == 'B'
|
70
|
+
@config.a.c.should == 'C'
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
describe "base delegate" do
|
2
|
+
|
3
|
+
before { @subject = BaseDelegate.new }
|
4
|
+
|
5
|
+
it 'should call on_load on launch' do
|
6
|
+
@subject.mock!(:on_load) do |app, options|
|
7
|
+
app.should.be.kind_of(UIApplication)
|
8
|
+
end
|
9
|
+
|
10
|
+
@subject.application(UIApplication.sharedApplication, didFinishLaunchingWithOptions: {})
|
11
|
+
end
|
12
|
+
end
|