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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: ec68953e11bba01e74f3eee7eaab74c2c0e23242
4
- data.tar.gz: 7108f694c4c3a2fd0d38734198a9167577953781
2
+ SHA256:
3
+ metadata.gz: 1cf56ea93694970f2f7e38947189765b8593fa4ee81572a5e996f14a1c1fd6a9
4
+ data.tar.gz: 45c3fe30524de6445c893aaf055a136a4b9d29720eb96eb3b6aa262f2dea1fc5
5
5
  SHA512:
6
- metadata.gz: dd58cf6e1101052c91fd7b3a3a367ed6f827746941ba4728859769dc2ceced4facc7c1ce231af3231bd71c0e66085093d518fba8af07aaeda77755721596072a
7
- data.tar.gz: 96880f37bcea7dbc6a31e10626551a6fcdc1cd1f6109aece29d552ee016d13ff674c9d7dbee508b375dc42eae834e565809c4503f4c30f7fd03c37570bfbf2cc
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
- has_many :articles
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.
@@ -1,4 +1,4 @@
1
1
 
2
2
  module CDQ
3
- VERSION = '1.0.8'
3
+ VERSION = '2.0.0'
4
4
  end
@@ -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, :icloud, :icloud_container, :app_group_id, :app_group_container_uuid
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
@@ -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.
@@ -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
- if @icloud
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)
@@ -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: 1.0.8
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: 2015-08-11 00:00:00.000000000 Z
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.4'
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.4'
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
- rubyforge_project:
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