cdq 1.0.8 → 2.0.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 +5 -5
- data/README.md +100 -3
- data/lib/cdq/version.rb +1 -1
- data/motion/cdq/config.rb +1 -13
- data/motion/cdq/context.rb +0 -12
- data/motion/cdq/store.rb +4 -65
- data/motion/managed_object.rb +12 -0
- metadata +7 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 1cf56ea93694970f2f7e38947189765b8593fa4ee81572a5e996f14a1c1fd6a9
|
4
|
+
data.tar.gz: 45c3fe30524de6445c893aaf055a136a4b9d29720eb96eb3b6aa262f2dea1fc5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0e599a61c04c2ed8455cac38934e77dbe2aea38237c2c1546fed69f7ef912290f425f97c9c2d8c8b05989ce933162158c66adb9bb983e6dfb7954fec1a3785c6
|
7
|
+
data.tar.gz: '0964a35ccbf50c8c0363e8db31d4cbfe55b971dcac085be1729fa9ff1cfbaa4e8e01a6084195ecfc384c4c71904744a841eb308ef9d47c22854cdef87989d481'
|
data/README.md
CHANGED
@@ -5,10 +5,11 @@ Core Data Query (CDQ) is a library to help you manage your Core Data stack
|
|
5
5
|
while using RubyMotion. It uses a data model file, which you can generate in
|
6
6
|
XCode, or you can use [ruby-xcdm](https://github.com/infinitered/ruby-xcdm).
|
7
7
|
|
8
|
-
[](https://gemnasium.com/infinitered/cdq)
|
9
8
|
[](https://travis-ci.org/infinitered/cdq)
|
10
9
|
[](http://badge.fury.io/rb/cdq)
|
11
10
|
|
11
|
+
CDQ is maintained by [Infinite Red](http://infinite.red), a web and mobile development company based in Portland, OR and San Francisco, CA.
|
12
|
+
|
12
13
|
## Get Started
|
13
14
|
1. [Introducing CDQ](#introducingCDQ)
|
14
15
|
2. [Greenfield Quick Start Tutorial](https://github.com/infinitered/cdq/wiki/Greenfield-Quick-Start)
|
@@ -96,7 +97,6 @@ app root, and they are versioned for automatic migrations, and this is what they
|
|
96
97
|
schema "0001 initial" do
|
97
98
|
|
98
99
|
entity "Article" do
|
99
|
-
|
100
100
|
string :body, optional: false
|
101
101
|
integer32 :length
|
102
102
|
boolean :published, default: false
|
@@ -109,7 +109,9 @@ app root, and they are versioned for automatic migrations, and this is what they
|
|
109
109
|
entity "Author" do
|
110
110
|
float :fee
|
111
111
|
string :name, optional: false
|
112
|
-
|
112
|
+
|
113
|
+
# Deleting an author will delete all associated articles
|
114
|
+
has_many :articles, deletionRule: "Cascade"
|
113
115
|
end
|
114
116
|
|
115
117
|
end
|
@@ -213,6 +215,8 @@ all the data over to your main context all at once. CDQ makes that easy too:
|
|
213
215
|
cdq.save
|
214
216
|
```
|
215
217
|
|
218
|
+
CDQ will automatically set the object's property `created_at` to `Time.now` if it exists. If you want to use this ActiveRecord-like automatic attribute, make sure to add `datetime :created_at` to your schema's model definition.
|
219
|
+
|
216
220
|
### Reading
|
217
221
|
|
218
222
|
```ruby
|
@@ -229,8 +233,34 @@ all the data over to your main context all at once. CDQ makes that easy too:
|
|
229
233
|
cdq.save
|
230
234
|
```
|
231
235
|
|
236
|
+
You can also update multiple attributes of a single object:
|
237
|
+
|
238
|
+
```ruby
|
239
|
+
author = Author.first
|
240
|
+
author.update(name: "Mark Twain", publish_count: 30, first_published: 1865)
|
241
|
+
cdq.save
|
242
|
+
```
|
243
|
+
|
244
|
+
The update command will raise an `UnknownAttributeError` if you try and set an attribute that doesn't exist on the object so it's good practice to sanitize the data before you call `update`:
|
245
|
+
|
246
|
+
```ruby
|
247
|
+
new_author_data = {
|
248
|
+
name: "Mark Twain",
|
249
|
+
publish_count: 30,
|
250
|
+
first_published: 1865,
|
251
|
+
some_attribute_that_doesnt_exist_on_author: "balderdash!"
|
252
|
+
}
|
253
|
+
sanitized = new_author_data.keep_if{|k,_| Author.attribute_names.include?(k) }
|
254
|
+
|
255
|
+
author = Author.first
|
256
|
+
author.update(sanitized)
|
257
|
+
cdq.save
|
258
|
+
```
|
259
|
+
|
232
260
|
**NOTE** Custom class methods will have to `include CDQ` in order to have access to the `cdq` object. If you're calling `cdq` from a class method, you also have to `extend CDQ`.
|
233
261
|
|
262
|
+
CDQ will automatically set the object's property `updated_at` to `Time.now` if it exists. If you want to use this ActiveRecord-like automatic attribute, make sure to add `datetime :updated_at` to your schema's model definition.
|
263
|
+
|
234
264
|
### Deleting
|
235
265
|
```ruby
|
236
266
|
author = Author.first
|
@@ -382,8 +412,71 @@ defining and using named scopes:
|
|
382
412
|
query generator for an entity, but `cdq(:attribute)` starts a predicate for an
|
383
413
|
attribute.
|
384
414
|
|
415
|
+
## Reserved model attributes
|
416
|
+
|
417
|
+
CDQ does some smart automatic attribute setting. If you add attributes `:created_at` and/or `:updated_at` to a model in your schema file, whenever a record is created or updated, these properties will be updated accordingly. Therefore, you can not define your own `:created_at` or `:updated_at` model attributes. These attributes must be of type `datetime`. Note that these attributes aren't set until you call `cdq.save`
|
418
|
+
|
419
|
+
Example:
|
420
|
+
|
421
|
+
```ruby
|
422
|
+
schema "0001 initial" do
|
423
|
+
entity "Author" do
|
424
|
+
string :name, optional: false
|
425
|
+
|
426
|
+
datetime :created_at
|
427
|
+
datetime :updated_at
|
428
|
+
end
|
429
|
+
end
|
430
|
+
```
|
431
|
+
|
432
|
+
```ruby
|
433
|
+
a = Author.create(name: "Le Guin")
|
434
|
+
# Notice that the properties aren't set yet
|
435
|
+
#
|
436
|
+
# <Author: 0x1175f9540> (entity: Author; id: 0x117504810
|
437
|
+
# <x-coredata:///Author/tA4E22210-72CF-4272-BF2C-0C5C63A55B072> ; data: {
|
438
|
+
# name: "Le Guin";
|
439
|
+
# created_at: nil;
|
440
|
+
# updated_at: nil;
|
441
|
+
# })
|
442
|
+
|
443
|
+
cdq.save
|
444
|
+
|
445
|
+
puts a # Original reference to created Author object
|
446
|
+
# <Author: 0x1175f9540> (entity: Author; id: 0x117504810
|
447
|
+
# <x-coredata:///Author/tA4E22210-72CF-4272-BF2C-0C5C63A55B072> ; data: {
|
448
|
+
# name: "Le Guin";
|
449
|
+
# created_at: 2015-08-19 20:44:40 +0000;
|
450
|
+
# updated_at: 2015-08-19 20:44:40 +0000;
|
451
|
+
# })
|
452
|
+
|
453
|
+
a.name = "Some Other Guy"
|
454
|
+
puts a
|
455
|
+
# Note that nothing has changed except the name:
|
456
|
+
#
|
457
|
+
# <Author: 0x1175f9540> (entity: Author; id: 0x117504810
|
458
|
+
# <x-coredata:///Author/tA4E22210-72CF-4272-BF2C-0C5C63A55B072> ; data: {
|
459
|
+
# name: "Some Other Guy";
|
460
|
+
# created_at: 2015-08-19 20:44:40 +0000;
|
461
|
+
# updated_at: 2015-08-19 20:44:40 +0000;
|
462
|
+
# })
|
463
|
+
|
464
|
+
cdq.save
|
465
|
+
puts a
|
466
|
+
# <Author: 0x1175f9540> (entity: Author; id: 0x117504810
|
467
|
+
# <x-coredata:///Author/tA4E22210-72CF-4272-BF2C-0C5C63A55B072> ; data: {
|
468
|
+
# name: "Some Other Guy";
|
469
|
+
# created_at: 2015-08-19 20:44:40 +0000;
|
470
|
+
# updated_at: 2015-08-19 20:47:40 +0000;
|
471
|
+
# })
|
472
|
+
```
|
473
|
+
|
474
|
+
Also note that you should never use `object_id` as a model attribute as it will conflict with an internally generated property.
|
475
|
+
|
385
476
|
## iCloud
|
386
477
|
|
478
|
+
**Removed as of version 2.0.0. If you still need this, pin cdq gem to before version 2.0.0**
|
479
|
+
|
387
480
|
As of version 0.1.10, there is some experimental support for iCloud, written by
|
388
481
|
@katsuyoshi. Please try it out and let us know how it's working for you. To
|
389
482
|
enable, initialize like this:
|
@@ -415,3 +508,7 @@ $ rake args='-com.apple.CoreData.SQLDebug 3'
|
|
415
508
|
```
|
416
509
|
|
417
510
|
`com.apple.CoreData.SQLDebug` takes a value between 1 and 3; the higher the value, the more verbose the output.
|
511
|
+
|
512
|
+
## Premium Support
|
513
|
+
|
514
|
+
[CDQ](https://github.com/infinitered/cdq), as an open source project, is free to use and always will be. [Infinite Red](https://infinite.red/) offers premium CDQ support and general mobile app design/development services. Email us at [hello@infinite.red](mailto:hello@infinite.red) to get in touch with us for more details.
|
data/lib/cdq/version.rb
CHANGED
data/motion/cdq/config.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
module CDQ
|
2
2
|
|
3
|
-
|
4
3
|
# = Configure the CDQ Stack
|
5
4
|
#
|
6
5
|
# This class wraps the YAML configuration file that will allow you to
|
@@ -14,8 +13,6 @@ module CDQ
|
|
14
13
|
# [model_name] The root name for the model file (relative to the bundle directory)
|
15
14
|
# [app_group_id] The app group id set in iTunes member center (group.com.mycompany.myapp)
|
16
15
|
# [app_group_container_uuid] WORKAROUND: The app group's UUID for iOS Simulator 8.1 which doesn't return an app group container path from the id
|
17
|
-
# [icloud] If it's true, CDQ works with iCloud.
|
18
|
-
# [icloud_container] Set id of iCloud container if you use iCloud. If it's nil, use first container listed in the com.apple.developer.ubiquity-container-identifiers entitlement array.
|
19
16
|
#
|
20
17
|
# Using the config file is not necessary. If you do not include it, the bundle display name
|
21
18
|
# will be used. For most people with a new app, this is what you want to do, especially if
|
@@ -26,7 +23,7 @@ module CDQ
|
|
26
23
|
#
|
27
24
|
class CDQConfig
|
28
25
|
|
29
|
-
attr_reader :config_file, :database_name, :database_dir, :model_name, :name, :
|
26
|
+
attr_reader :config_file, :database_name, :database_dir, :model_name, :name, :app_group_id, :app_group_container_uuid
|
30
27
|
|
31
28
|
def initialize(config_file)
|
32
29
|
h = nil
|
@@ -50,15 +47,6 @@ module CDQ
|
|
50
47
|
@model_name = h['model_name'] || h[:model_name] || name
|
51
48
|
@app_group_id = h['app_group_id'] || h[:app_group_id]
|
52
49
|
@app_group_container_uuid = h['app_group_container_uuid'] || h[:app_group_container_uuid]
|
53
|
-
@icloud = begin
|
54
|
-
case h['icloud'] || h[:icloud]
|
55
|
-
when true, 1
|
56
|
-
true
|
57
|
-
else
|
58
|
-
false
|
59
|
-
end
|
60
|
-
end
|
61
|
-
@icloud_container = h['icloud_container'] || h[:icloud_container]
|
62
50
|
end
|
63
51
|
|
64
52
|
def database_url
|
data/motion/cdq/context.rb
CHANGED
@@ -76,18 +76,6 @@ module CDQ
|
|
76
76
|
self.stack = []
|
77
77
|
end
|
78
78
|
|
79
|
-
# Create and push a new context with the specified concurrency type. Its parent
|
80
|
-
# will be set to the previous head context. If a block is supplied, the new context
|
81
|
-
# will exist for the duration of the block and then the previous state will be restore_managerd.
|
82
|
-
#
|
83
|
-
# REMOVE1.1
|
84
|
-
#
|
85
|
-
def new(concurrency_type, &block)
|
86
|
-
deprecate "cdq.contexts.new() is deprecated. Use push() or create()"
|
87
|
-
context = create(concurrency_type)
|
88
|
-
push(context, {}, &block)
|
89
|
-
end
|
90
|
-
|
91
79
|
# Create a new context by type, setting upstream to the topmost context if available,
|
92
80
|
# or to the persistent store coordinator if not. Return the context but do NOT push it
|
93
81
|
# onto the stack.
|
data/motion/cdq/store.rb
CHANGED
@@ -15,8 +15,6 @@ module CDQ
|
|
15
15
|
def new(opts = {})
|
16
16
|
@config = opts[:config] || CDQConfig.default
|
17
17
|
@model_manager = opts[:model_manager] || CDQ.cdq.models
|
18
|
-
@icloud = opts[:icloud] || opts[:iCloud] || @config.icloud
|
19
|
-
@icloud_container = @config.icloud_container
|
20
18
|
end
|
21
19
|
|
22
20
|
def current
|
@@ -24,7 +22,10 @@ module CDQ
|
|
24
22
|
end
|
25
23
|
|
26
24
|
def reset!
|
25
|
+
path = @config.database_url.absoluteString
|
27
26
|
NSFileManager.defaultManager.removeItemAtURL(@config.database_url, error: nil)
|
27
|
+
NSFileManager.defaultManager.removeItemAtURL(NSURL.URLWithString("#{path}-shm"), error: nil)
|
28
|
+
NSFileManager.defaultManager.removeItemAtURL(NSURL.URLWithString("#{path}-wal"), error: nil)
|
28
29
|
end
|
29
30
|
|
30
31
|
def invalid?
|
@@ -37,72 +38,10 @@ module CDQ
|
|
37
38
|
if invalid?
|
38
39
|
raise "No model found. Can't create a persistent store coordinator without it."
|
39
40
|
else
|
40
|
-
|
41
|
-
create_icloud_store
|
42
|
-
else
|
43
|
-
create_local_store
|
44
|
-
end
|
41
|
+
create_local_store
|
45
42
|
end
|
46
43
|
end
|
47
44
|
|
48
|
-
def create_icloud_store
|
49
|
-
coordinator = NSPersistentStoreCoordinator.alloc.initWithManagedObjectModel(@model_manager.current)
|
50
|
-
|
51
|
-
Dispatch::Queue.concurrent.async {
|
52
|
-
# get icloud first container
|
53
|
-
url = @config.database_url
|
54
|
-
icloud_url = NSFileManager.defaultManager.URLForUbiquityContainerIdentifier(@icloud_container)
|
55
|
-
if icloud_url
|
56
|
-
error = Pointer.new(:object)
|
57
|
-
icloud_url = icloud_url.URLByAppendingPathComponent("data")
|
58
|
-
error = Pointer.new(:object)
|
59
|
-
options = { NSMigratePersistentStoresAutomaticallyOption => true,
|
60
|
-
NSInferMappingModelAutomaticallyOption => true,
|
61
|
-
NSPersistentStoreUbiquitousContentNameKey => url.path.lastPathComponent.gsub(".", "_"),
|
62
|
-
NSPersistentStoreUbiquitousContentURLKey => icloud_url,
|
63
|
-
}
|
64
|
-
coordinator.lock
|
65
|
-
store = coordinator.addPersistentStoreWithType(NSSQLiteStoreType,
|
66
|
-
configuration:nil,
|
67
|
-
URL:url,
|
68
|
-
options:options,
|
69
|
-
error:error)
|
70
|
-
coordinator.unlock
|
71
|
-
|
72
|
-
if store.nil?
|
73
|
-
error[0].userInfo['metadata'] && error[0].userInfo['metadata'].each do |key, value|
|
74
|
-
NSLog "#{key}: #{value}"
|
75
|
-
end
|
76
|
-
raise error[0].userInfo['reason']
|
77
|
-
end
|
78
|
-
|
79
|
-
else
|
80
|
-
error = Pointer.new(:object)
|
81
|
-
options = { NSMigratePersistentStoresAutomaticallyOption => true,
|
82
|
-
NSInferMappingModelAutomaticallyOption => true }
|
83
|
-
url = @config.database_url
|
84
|
-
mkdir_p File.dirname(url.path)
|
85
|
-
store = coordinator.addPersistentStoreWithType(NSSQLiteStoreType,
|
86
|
-
configuration:nil,
|
87
|
-
URL:url,
|
88
|
-
options:options,
|
89
|
-
error:error)
|
90
|
-
if store.nil?
|
91
|
-
error[0].userInfo['metadata'] && error[0].userInfo['metadata'].each do |key, value|
|
92
|
-
NSLog "#{key}: #{value}"
|
93
|
-
end
|
94
|
-
raise error[0].userInfo['reason']
|
95
|
-
end
|
96
|
-
end
|
97
|
-
Dispatch::Queue.main.after(0) {
|
98
|
-
# This block is executed in a next run loop.
|
99
|
-
# So the managed object context has a store coordinator in this point.
|
100
|
-
NSNotificationCenter.defaultCenter.postNotificationName(STORE_DID_INITIALIZE_NOTIFICATION, object:coordinator)
|
101
|
-
}
|
102
|
-
}
|
103
|
-
coordinator
|
104
|
-
end
|
105
|
-
|
106
45
|
def create_local_store
|
107
46
|
coordinator = NSPersistentStoreCoordinator.alloc.initWithManagedObjectModel(@model_manager.current)
|
108
47
|
error = Pointer.new(:object)
|
data/motion/managed_object.rb
CHANGED
@@ -99,6 +99,16 @@ class CDQManagedObject < CoreDataQueryManagedObjectBase
|
|
99
99
|
|
100
100
|
end
|
101
101
|
|
102
|
+
def update(args)
|
103
|
+
args.each do |k,v|
|
104
|
+
if respond_to?("#{k}=")
|
105
|
+
self.send("#{k}=", v)
|
106
|
+
else
|
107
|
+
raise UnknownAttributeError.new("#{self.class} does not respond to `#{k}=`")
|
108
|
+
end
|
109
|
+
end if args.is_a?(Hash)
|
110
|
+
end
|
111
|
+
|
102
112
|
# Register this object for destruction with the current context. Will not
|
103
113
|
# actually be removed until the context is saved.
|
104
114
|
#
|
@@ -211,3 +221,5 @@ class CDQManagedObject < CoreDataQueryManagedObjectBase
|
|
211
221
|
end
|
212
222
|
|
213
223
|
end
|
224
|
+
|
225
|
+
class UnknownAttributeError < StandardError; end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cdq
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- infinitered
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2019-11-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ruby-xcdm
|
@@ -29,16 +29,16 @@ dependencies:
|
|
29
29
|
name: motion-yaml
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
|
-
- -
|
32
|
+
- - ">="
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: '1.
|
34
|
+
version: '1.6'
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
|
-
- -
|
39
|
+
- - ">="
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version: '1.
|
41
|
+
version: '1.6'
|
42
42
|
description: Core Data Query for RubyMotion
|
43
43
|
email:
|
44
44
|
- ken@infinitered.com
|
@@ -93,8 +93,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
93
93
|
- !ruby/object:Gem::Version
|
94
94
|
version: '0'
|
95
95
|
requirements: []
|
96
|
-
|
97
|
-
rubygems_version: 2.2.2
|
96
|
+
rubygems_version: 3.0.6
|
98
97
|
signing_key:
|
99
98
|
specification_version: 4
|
100
99
|
summary: A streamlined library for working with Core Data outside XCode
|