cdq 1.0.8 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
[![Dependency Status](https://gemnasium.com/infinitered/cdq.png)](https://gemnasium.com/infinitered/cdq)
|
9
8
|
[![Build Status](https://travis-ci.org/infinitered/cdq.png?branch=master)](https://travis-ci.org/infinitered/cdq)
|
10
9
|
[![Gem Version](https://badge.fury.io/rb/cdq.png)](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
|