motion-realm 1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a15ecd791d1c966a720c45c29448c2be273cd4fc
4
+ data.tar.gz: d70a0d971061f8b6ed50a7534b54925804cde2b9
5
+ SHA512:
6
+ metadata.gz: a1130480e8fa233851ef5da1f9910a95840eb8a29d148db8ca5f2ef6d726afe7372bbde7c66fedae4be8290735b08b0e8274c709f759ecf2e56578f8f9b90625
7
+ data.tar.gz: d8d5274581d12cc6ebba30ca367b8e3842ff8e375d94dc7fd299b9a5f0347c817091a9dae980859e63adc4c53eeaa76367c31c7a0ddaff637eb5f6c12110fc8c
data/README.md ADDED
@@ -0,0 +1,264 @@
1
+ # motion-realm
2
+
3
+ `motion-realm` gem has been made to Rubyfy Realm's syntax. You will
4
+ still need to read some Realm's docs in order to understand how it works. Also because
5
+ of Realm's specific, we still have to vendor Objective-C schema files.
6
+
7
+ ## Realm setup
8
+
9
+ I would suggest compiling Realm from their sources available at https://github.com/realm/realm-cocoa
10
+
11
+ `git clone https://github.com/realm/realm-cocoa`
12
+ `cd realm-cocoa`
13
+ `sh build.sh build`
14
+
15
+ When build will be finished, copy `build/ios/Realm.framework` into your app's `vendor/realm` folder. Don't forget to create `schemas` folder that will contain your DB schema definitions.
16
+
17
+ Now we need to tell Rubymotion to include realm and schemas. In your `Rakefile` add:
18
+
19
+ `app.libs << '/usr/lib/libc++.dylib'`
20
+ `app.external_frameworks << 'vendor/realm/Realm.framework'`
21
+ `app.vendor_project 'schemas', :static, :cflags => '-F ../vendor/realm/'`
22
+
23
+ You can start using Realm in your project now.
24
+
25
+ ## motion-realm installation
26
+
27
+ Add this line to your application's Gemfile:
28
+
29
+ gem 'motion-realm'
30
+
31
+ And then execute:
32
+
33
+ $ bundle
34
+
35
+ Or install it yourself as:
36
+
37
+ $ gem install motion-realm
38
+
39
+ ## Usage
40
+
41
+ ### Schemas and Models
42
+
43
+ Your schemas should be defined in `/schemas` folder. Unfortunately because of
44
+ the Realm's specific we will have to use Objective-C here. You can check Realm's docs on models at https://realm.io/docs/objc/latest/#models
45
+
46
+ `schemas/schema.h`
47
+
48
+ ```objective-c
49
+ #import <Realm/Realm.h>
50
+
51
+ @class Parent;
52
+
53
+ @interface Child : RLMObject
54
+
55
+ @property BOOL likes_math;
56
+ @property NSInteger favourite_number;
57
+ @property NSString *name;
58
+ @property NSString *sex;
59
+ @property NSDate *birthday;
60
+ @property NSData *some_data;
61
+
62
+ @property Parent *parent;
63
+
64
+ @end
65
+
66
+ RLM_ARRAY_TYPE(Child)
67
+
68
+ @interface Parent : RLMObject
69
+
70
+ @property NSString *job;
71
+ @property NSString *name;
72
+ @property NSString *sex;
73
+ @property NSDate *birthday;
74
+ @property BOOL likes_ruby;
75
+ @property NSInteger apps_in_appstore;
76
+ @property NSData *some_data;
77
+
78
+ @property RLMArray<Child *> <Child> *children;
79
+
80
+ @end
81
+ ```
82
+
83
+ And don't forget about implementation `.mm` file:
84
+
85
+ `schemas/schema.mm`
86
+
87
+ ```objective-c
88
+ #import "schema.h"
89
+
90
+ @implementation Child
91
+ @end
92
+
93
+ @implementation Parent
94
+ @end
95
+ ```
96
+
97
+ Now when we have schema defined, we can create `app/models/child.rb` and
98
+ `app/models/parent.rb`:
99
+
100
+ ```ruby
101
+ class Child
102
+ # it is important to include MotionRealm module in your model classes:
103
+ include MotionRealm
104
+
105
+ # if you want to set some default values, do it in this method:
106
+ def self.default_values
107
+ {
108
+ likes_math: true,
109
+ }
110
+ end
111
+
112
+ # indexes can be defined here:
113
+ def self.indexes
114
+ ["name", "favourite_number"]
115
+ end
116
+
117
+ # primary key, if needed:
118
+ def self.primary_key
119
+ "name"
120
+ end
121
+ end
122
+
123
+ class Parent
124
+ include MotionRealm
125
+ end
126
+ ```
127
+
128
+ This is it! Schema and Models were defined, and everything is ready for usage!
129
+
130
+ ### Create/Read/Update/Delete
131
+
132
+ ```ruby
133
+ # create in-memory objects:`
134
+ child = Child.new
135
+ child.name = "John"
136
+
137
+ parent = Parent.create name: "Jack"
138
+ parent.children << child
139
+
140
+ # persist them:
141
+ RLMRealm.write do |realm|
142
+ realm << child
143
+ realm << parent
144
+ end
145
+
146
+ # find objects:
147
+ parent = Parent.where("name = 'Jack'").first
148
+
149
+ # or using predicates:
150
+ predicate = NSPredicate.predicateWithFormat "name == %@", "some cool name"
151
+ cool_parents = Parent.with_predicate predicate
152
+
153
+ # we have to update objects inside write block only:
154
+ RLMRealm.write do |realm|
155
+ parent.name = 'Jack Smith'
156
+ end
157
+
158
+ # delete objects:
159
+ parent.delete
160
+
161
+ # or
162
+ RLMRealm.write do |realm|
163
+ realm.delete parent
164
+ end
165
+
166
+ # delete all objects:
167
+ RLMRealm.write do |realm|
168
+ realm.delete_all
169
+ end
170
+
171
+ # or all objects for a given class:
172
+ Parent.delete_all
173
+ ```
174
+
175
+ ### Saving objects
176
+
177
+ ```ruby
178
+ result = RLMRealm.write do |realm|
179
+ # add objects to realm, update objects, delete them here
180
+ end
181
+ # result is a Hash: { saved: true/false, error: error_if_any }
182
+
183
+
184
+ # RLMRealm.write is just a shorthand for:
185
+ realm = RLMRealm.default
186
+ realm.start_writing
187
+ # add objects to realm, update objects, delete them here
188
+ realm.end_writing
189
+ ```
190
+
191
+ By default if you are going to save an object without setting all its properties
192
+ to some value, they will be set to:
193
+
194
+ - Number or Mixed property to 0
195
+ - Array properties to []
196
+ - All other properties will be set to Nil.
197
+
198
+ If you want to change this behaviour, you can use class method `default_values`.
199
+ For example:
200
+
201
+ ```ruby
202
+ def self.default_values
203
+ {
204
+ bool_prop: true,
205
+ int_prop: 1
206
+ }
207
+ end
208
+ ```
209
+
210
+ ### Notifications
211
+
212
+ You can post notifications each time realm data has been updated. To do it
213
+ just tell your realm that you want to add a notification:
214
+
215
+ ```ruby
216
+ @notification_token = realm.add_notification do |notification, realm|
217
+ # some your actions here
218
+ end
219
+ ```
220
+
221
+ Don't forget to remove it when you won't need it anymore with:
222
+
223
+ ```ruby
224
+ realm.remove_notification @notification_token
225
+ ```
226
+
227
+ ## Migrations
228
+
229
+ Sometimes we have to update DB schema. Realm's docs describe it very well at https://realm.io/docs/objc/latest/#migrations
230
+
231
+ To migrate your DB to a newer schema version, you can use `RLMRealmConfiguration.migrate_to_version(new_version, &block)` method.
232
+
233
+ It is a good idea to use non-nested `if` conditions, because some users
234
+ may update your app rarely, and they may accidentally skip migration from X to Y
235
+ schema version:
236
+
237
+ ```ruby
238
+ RLMRealmConfiguration.migrate_to_version(3) do |migration, old_version|
239
+ migration.enumerate "Parent" do |old_object, new_object|
240
+ # user has not updated his app to the 1st schema version yet:
241
+ if old_version < 1
242
+ # migrate the object to 1st version
243
+ end
244
+
245
+ # user had 1st version of the schema already:
246
+ if old_version < 2
247
+ # migrate the object to the 2nd version
248
+ end
249
+
250
+ # user had latest available schema. Update him to a newer one:
251
+ if old_version < 3
252
+ # migrate the object to the 3rd version
253
+ end
254
+ end
255
+ end
256
+ ```
257
+
258
+ ## Contributing
259
+
260
+ 1. Fork it
261
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
262
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
263
+ 4. Push to the branch (`git push origin my-new-feature`)
264
+ 5. Create new Pull Request
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+
3
+ unless defined?(Motion::Project::Config)
4
+ raise "This file must be required within a RubyMotion project Rakefile."
5
+ end
6
+
7
+ lib_dir_path = File.dirname(File.expand_path(__FILE__))
8
+ Motion::Project::App.setup do |app|
9
+ app.files.unshift(Dir.glob(File.join(lib_dir_path, "project/**/*.rb")))
10
+ end
@@ -0,0 +1,101 @@
1
+ module MotionRealm
2
+ def self.included(base)
3
+ base.extend(ClassMethods)
4
+ end
5
+
6
+ module ClassMethods
7
+ def create(opts={})
8
+ # # Does not work correct in current version of RM or Realm:
9
+ # self.alloc.initWithValue opts
10
+
11
+ object = self.new
12
+ opts.each do |key, value|
13
+ method_name = "set" + key.to_s.capitalize
14
+ method_name = key.to_s + "="
15
+
16
+ # object.performSelector method_name, withObject: value
17
+ object.send(method_name, value)
18
+ end
19
+
20
+ object
21
+
22
+ end
23
+
24
+ def count
25
+ all.count
26
+ end
27
+
28
+ def first
29
+ all.first
30
+ end
31
+
32
+ def last
33
+ all.last
34
+ end
35
+
36
+ def defaultPropertyValues
37
+ # set all properties to nil
38
+ values = {}
39
+
40
+ self.schema.properties_by_name.each do |name, property|
41
+ values[name] = if default_values[name]
42
+ default_values[name]
43
+ elsif property.bool?
44
+ false
45
+ elsif property.number? || property.mixed?
46
+ 0
47
+ elsif property.array?
48
+ []
49
+ else
50
+ nil
51
+ end
52
+ end
53
+
54
+ values
55
+ end
56
+
57
+ def default_values
58
+ {}
59
+ end
60
+
61
+ def indexedProperties
62
+ indexes
63
+ end
64
+
65
+ def indexes
66
+ []
67
+ end
68
+
69
+ def primaryKey
70
+ primary_key
71
+ end
72
+
73
+ def primary_key
74
+ nil
75
+ end
76
+
77
+ def where(query)
78
+ self.objectsWhere(query)
79
+ end
80
+
81
+ def create_or_update(object, realm=nil)
82
+ if realm.nil?
83
+ realm = RLMRealm.default
84
+ end
85
+
86
+ self.createOrUpdateInRealm realm, withValue: object
87
+ end
88
+
89
+ def delete_all
90
+ RLMRealm.write do |realm|
91
+ self.all.each { |object| realm.delete(object) }
92
+ end
93
+ end
94
+ end
95
+
96
+ def delete
97
+ RLMRealm.write do |realm|
98
+ realm.delete(self)
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,5 @@
1
+ class RLMArray
2
+ def <<(object)
3
+ self.addObject(object)
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ class RLMMigration
2
+ def enumerate(class_name, &block)
3
+ # block should accept two variables: old_object and new_object
4
+ self.enumerateObjects class_name, block: block
5
+ end
6
+ end
@@ -0,0 +1,16 @@
1
+ class RLMObject
2
+ class << self
3
+ alias :schema :sharedSchema
4
+ alias :all :allObjects
5
+ end
6
+
7
+ def self.with_predicate(predicate)
8
+ self.objectsWithPredicate(predicate)
9
+ end
10
+
11
+ def save
12
+ RLMRealm.write do |realm|
13
+ realm << self
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,3 @@
1
+ class RLMObjectSchema
2
+ alias :properties_by_name :propertiesByName
3
+ end
@@ -0,0 +1,78 @@
1
+ class RLMProperty
2
+
3
+ # Primitives
4
+
5
+ def int?
6
+ type == RLMPropertyTypeInt
7
+ end
8
+
9
+ def bool?
10
+ type == RLMPropertyTypeBool
11
+ end
12
+
13
+ def float?
14
+ type == RLMPropertyTypeFloat
15
+ end
16
+
17
+ def double?
18
+ type == RLMPropertyTypeDouble
19
+ end
20
+
21
+ def number?
22
+ int? || float? || double?
23
+ end
24
+
25
+ # Objects
26
+
27
+ def string?
28
+ type == RLMPropertyTypeString
29
+ end
30
+
31
+ def data?
32
+ type == RLMPropertyTypeData
33
+ end
34
+
35
+ def mixed?
36
+ type == RLMPropertyTypeAny
37
+ end
38
+
39
+ def date?
40
+ type == RLMPropertyTypeDate
41
+ end
42
+
43
+ # Arrays/Linked types
44
+
45
+ def object?
46
+ type == RLMPropertyTypeObject
47
+ end
48
+
49
+ def array?
50
+ type == RLMPropertyTypeArray
51
+ end
52
+
53
+ def type_name
54
+ if int?
55
+ :int
56
+ elsif bool?
57
+ :bool
58
+ elsif float?
59
+ :float
60
+ elsif double?
61
+ :double
62
+ elsif string?
63
+ :string
64
+ elsif data?
65
+ :data
66
+ elsif mixed?
67
+ :mixed
68
+ elsif date?
69
+ :date
70
+ elsif object?
71
+ :object
72
+ elsif array?
73
+ :array
74
+ else
75
+ nil
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,41 @@
1
+ class RLMRealm
2
+ class << self
3
+ alias :default :defaultRealm
4
+ end
5
+
6
+ alias :start_writing :beginWriteTransaction
7
+
8
+ alias :delete_all :deleteAllObjects
9
+
10
+
11
+ def end_writing(error_ptr=nil)
12
+ self.commitWriteTransaction(error_ptr)
13
+ end
14
+
15
+ def delete(object)
16
+ self.deleteObject(object)
17
+ end
18
+
19
+ def add_notification(&block)
20
+ self.addNotificationBlock(block)
21
+ end
22
+
23
+ def remove_notification(token)
24
+ self.removeNotification(token)
25
+ end
26
+
27
+ def self.write(&block)
28
+ realm = RLMRealm.defaultRealm
29
+ error_ptr = Pointer.new(:object)
30
+
31
+ realm.start_writing
32
+ block.call(realm)
33
+ saved = realm.end_writing(error_ptr)
34
+
35
+ { saved: saved, error: error_ptr[0] }
36
+ end
37
+
38
+ def <<(object)
39
+ self.addObject(object)
40
+ end
41
+ end
@@ -0,0 +1,19 @@
1
+ class RLMRealmConfiguration
2
+ class << self
3
+ alias :default :defaultConfiguration
4
+ end
5
+
6
+ alias :schema_version :schemaVersion
7
+
8
+ def schema_version=(new_version)
9
+ self.schemaVersion = new_version
10
+ end
11
+
12
+ def self.migrate_to_version(version, &block)
13
+ config = self.default
14
+ config.schema_version = version
15
+
16
+ config.migrationBlock = block
17
+ RLMRealmConfiguration.setDefaultConfiguration(config)
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ class RLMResults
2
+ alias :first :firstObject
3
+ alias :last :lastObject
4
+ alias :where :objectsWhere
5
+
6
+ def [](index)
7
+ self.objectAtIndex(index)
8
+ end
9
+
10
+ def sort_by(property, opts={})
11
+ ascending = if opts[:asc].nil?
12
+ true
13
+ else
14
+ opts[:asc]
15
+ end
16
+
17
+ self.sortedResultsUsingProperty property, ascending: ascending
18
+ end
19
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: motion-realm
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.0'
5
+ platform: ruby
6
+ authors:
7
+ - Kyrylo Savytskyi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-10-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: Realm for Rubymotion
28
+ email:
29
+ - mail@savytskyi.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - README.md
35
+ - lib/motion-realm.rb
36
+ - lib/project/motion-realm.rb
37
+ - lib/project/realm/array.rb
38
+ - lib/project/realm/migration.rb
39
+ - lib/project/realm/object.rb
40
+ - lib/project/realm/object_schema.rb
41
+ - lib/project/realm/property.rb
42
+ - lib/project/realm/realm.rb
43
+ - lib/project/realm/realm_configuration.rb
44
+ - lib/project/realm/results.rb
45
+ homepage: https://github.com/savytskyi/motion-realm
46
+ licenses:
47
+ - MIT
48
+ metadata: {}
49
+ post_install_message:
50
+ rdoc_options: []
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ requirements: []
64
+ rubyforge_project:
65
+ rubygems_version: 2.2.2
66
+ signing_key:
67
+ specification_version: 4
68
+ summary: Realm for Rubymotion
69
+ test_files: []