cdq 0.1.2 → 0.1.5

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.
@@ -14,6 +14,7 @@ module CDQ
14
14
  # return to the previous state.
15
15
  #
16
16
  def push(context, &block)
17
+ @has_been_set_up = true
17
18
  if block_given?
18
19
  save_stack do
19
20
  push_to_stack(context)
@@ -41,6 +42,9 @@ module CDQ
41
42
  # The current context at the top of the stack.
42
43
  #
43
44
  def current
45
+ if stack.empty? && !@has_been_set_up
46
+ new(NSMainQueueConcurrencyType)
47
+ end
44
48
  stack.last
45
49
  end
46
50
 
@@ -61,6 +65,7 @@ module CDQ
61
65
  # will exist for the duration of the block and then the previous state will be restore_managerd.
62
66
  #
63
67
  def new(concurrency_type, &block)
68
+ @has_been_set_up = true
64
69
  context = NSManagedObjectContext.alloc.initWithConcurrencyType(concurrency_type)
65
70
  if current
66
71
  context.parentContext = current
@@ -1,37 +1,80 @@
1
1
 
2
2
  module CDQ
3
+
4
+ # A partial predicate is an intermediate state while constructing a
5
+ # query. It knows which attribute to use as the left operand, and
6
+ # then offers a range of methods to specify which operation to use,
7
+ # and what value to use as the right operand. They are most commonly
8
+ # created via the <tt>where</tt>, <tt>and</tt>, and <tt>or</tt>
9
+ # methods on query, and sometimes via the main <tt>cdq</tt> method.
10
+
3
11
  class CDQPartialPredicate < CDQObject
4
12
 
5
13
  attr_reader :key, :scope, :operation
6
14
 
7
- OPERATORS = {
8
- :eq => [NSEqualToPredicateOperatorType, :equal],
9
- :ne => [NSNotEqualToPredicateOperatorType, :not_equal],
10
- :lt => [NSLessThanPredicateOperatorType, :less_than],
11
- :le => [NSLessThanOrEqualToPredicateOperatorType, :less_than_or_equal],
12
- :gt => [NSGreaterThanPredicateOperatorType, :greater_than],
13
- :ge => [NSGreaterThanOrEqualToPredicateOperatorType, :greater_than_or_equal],
14
- :contains => [NSContainsPredicateOperatorType, :include],
15
- :matches => [NSMatchesPredicateOperatorType],
16
- :in => [NSInPredicateOperatorType],
17
- :begins_with => [NSBeginsWithPredicateOperatorType],
18
- :ends_with => [NSEndsWithPredicateOperatorType]
19
- }
20
-
21
15
  def initialize(key, scope, operation = :and)
22
16
  @key = key
23
17
  @scope = scope
24
18
  @operation = operation
25
19
  end
26
20
 
27
- OPERATORS.each do |op, (type, synonym)|
28
- define_method(op) do |value, options = 0|
29
- make_scope(type, value, options)
30
- end
31
- alias_method synonym, op if synonym
32
- end
21
+ # Equality
22
+ # @returns a new CDQQuery with the predicate appended
23
+ def eq(value, options = 0); make_scope(NSEqualToPredicateOperatorType, value, options); end
24
+
25
+ # Inequality
26
+ # @returns a new CDQQuery with the predicate appended
27
+ def ne(value, options = 0); make_scope(NSNotEqualToPredicateOperatorType, value, options); end
28
+
29
+ # Less Than
30
+ # @returns a new CDQQuery with the predicate appended
31
+ def lt(value, options = 0); make_scope(NSLessThanPredicateOperatorType, value, options); end
32
+
33
+ # Less Than or Equal To
34
+ # @returns a new CDQQuery with the predicate appended
35
+ def le(value, options = 0); make_scope(NSLessThanOrEqualToPredicateOperatorType, value, options); end
36
+
37
+ # Greater Than
38
+ # @returns a new CDQQuery with the predicate appended
39
+ def gt(value, options = 0); make_scope(NSGreaterThanPredicateOperatorType, value, options); end
40
+
41
+ # Greater Than or Equal To
42
+ # @returns a new CDQQuery with the predicate appended
43
+ def ge(value, options = 0); make_scope(NSGreaterThanOrEqualToPredicateOperatorType, value, options); end
44
+
45
+ # Contains Substring
46
+ # @returns a new CDQQuery with the predicate appended
47
+ def contains(substr, options = 0); make_scope(NSContainsPredicateOperatorType, substr, options); end
48
+
49
+ # Matches Regexp
50
+ # @returns a new CDQQuery with the predicate appended
51
+ def matches(regexp, options = 0); make_scope(NSMatchesPredicateOperatorType, regexp, options); end
52
+
53
+ # List membership
54
+ # @returns a new CDQQuery with the predicate appended
55
+ def in(list, options = 0); make_scope(NSInPredicateOperatorType, list, options); end
56
+
57
+ # Begins With String
58
+ # @returns a new CDQQuery with the predicate appended
59
+ def begins_with(substr, options = 0); make_scope(NSBeginsWithPredicateOperatorType, substr, options); end
60
+
61
+ # Ends With String
62
+ # @returns a new CDQQuery with the predicate appended
63
+ def ends_with(substr, options = 0); make_scope(NSEndsWithPredicateOperatorType, substr, options); end
64
+
65
+ # Between Min and Max Values
66
+ # @returns a new CDQQuery with the predicate appended
67
+ def between(min, max); make_scope(NSBetweenPredicateOperatorType, [min, max]); end
68
+
69
+
70
+ alias_method :equal, :eq
71
+ alias_method :not_equal, :ne
72
+ alias_method :less_than, :lt
73
+ alias_method :less_than_or_equal, :le
74
+ alias_method :greater_than, :gt
75
+ alias_method :greater_than_or_equal, :ge
76
+ alias_method :include, :contains
33
77
 
34
- def between(min, max); make_scope(NSBetweenPredicateOperatorType, [min, max]); end
35
78
 
36
79
  private
37
80
 
@@ -1,7 +1,16 @@
1
1
 
2
2
  module CDQ
3
+
4
+ #
5
+ # CDQ Queries are the primary way of describing a set of objects.
6
+ #
3
7
  class CDQQuery < CDQObject
4
8
 
9
+ # @private
10
+ #
11
+ # This is a singleton object needed to represent "empty" in limit and
12
+ # offset, because they need to be able to accept nil as a real value.
13
+ #
5
14
  EMPTY = Object.new
6
15
 
7
16
  attr_reader :predicate, :sort_descriptors
@@ -14,6 +23,10 @@ module CDQ
14
23
  @saved_key = opts[:saved_key]
15
24
  end
16
25
 
26
+ # Return or set the fetch limit. If passed an argument, return a new
27
+ # query with the specified limit value. Otherwise, return the current
28
+ # value.
29
+ #
17
30
  def limit(value = EMPTY)
18
31
  if value == EMPTY
19
32
  @limit
@@ -22,6 +35,10 @@ module CDQ
22
35
  end
23
36
  end
24
37
 
38
+ # Return or set the fetch offset. If passed an argument, return a new
39
+ # query with the specified offset value. Otherwise, return the current
40
+ # value.
41
+ #
25
42
  def offset(value = EMPTY)
26
43
  if value == EMPTY
27
44
  @offset
@@ -30,7 +47,36 @@ module CDQ
30
47
  end
31
48
  end
32
49
 
33
- # Combine this query with others in an intersection ("and") relationship
50
+ # Combine this query with others in an intersection ("and") relationship. Can be
51
+ # used to begin a new query as well, especially when called in its <tt>where</tt>
52
+ # variant.
53
+ #
54
+ # The query passed in can be a wide variety of types:
55
+ #
56
+ # Symbol: This is by far the most common, and it is also a special
57
+ # case -- the return value when passing a symbol is a CDQPartialPredicate,
58
+ # rather than CDQQuery. Methods on CDQPartialPredicate are then comparison
59
+ # operators against the attribute indicated by the symbol itself, which take
60
+ # a value operand. For example:
61
+ #
62
+ # query.where(:name).equal("Chuck").and(:title).not_equal("Manager")
63
+ #
64
+ # @see CDQPartialPredicate
65
+ #
66
+ # String: Interpreted as an NSPredicate format string. Additional arguments are
67
+ # the positional parameters.
68
+ #
69
+ # NilClass: If the argument is nil (most likely because it was omitted), and there
70
+ # was a previous use of a symbol, then reuse that last symbol. For example:
71
+ #
72
+ # query.where(:name).contains("Chuck").and.contains("Norris")
73
+ #
74
+ # CDQQuery: If you have another CDQQuery from somewhere else, you can pass it in directly.
75
+ #
76
+ # NSPredicate: You can pass in a raw NSPredicate and it will work as you'd expect.
77
+ #
78
+ # Hash: Each key/value pair is treated as equality and anded together.
79
+ #
34
80
  def and(query = nil, *args)
35
81
  merge_query(query, :and, *args) do |left, right|
36
82
  NSCompoundPredicate.andPredicateWithSubpredicates([left, right])
@@ -38,26 +84,20 @@ module CDQ
38
84
  end
39
85
  alias_method :where, :and
40
86
 
41
- # Combine this query with others in a union ("or") relationship
87
+ # Combine this query with others in a union ("or") relationship. Accepts
88
+ # all the same argument types as <tt>and</tt>.
42
89
  def or(query = nil, *args)
43
90
  merge_query(query, :or, *args) do |left, right|
44
91
  NSCompoundPredicate.orPredicateWithSubpredicates([left, right])
45
92
  end
46
93
  end
47
94
 
48
- # Create a new query with the same values as this one, optionally overriding
49
- # any of them in the options
50
- def clone(opts = {})
51
- self.class.new(locals.merge(opts))
52
- end
53
-
54
- def locals
55
- { sort_descriptors: sort_descriptors,
56
- predicate: predicate,
57
- limit: limit,
58
- offset: offset }
59
- end
60
-
95
+ # Add a new sort key. Multiple invocations add additional sort keys rather than replacing
96
+ # old ones.
97
+ #
98
+ # @param key The attribute to sort on
99
+ # @param dir The sort direction (default = :ascending)
100
+ #
61
101
  def sort_by(key, dir = :ascending)
62
102
  if dir.to_s[0,4].downcase == 'desc'
63
103
  ascending = false
@@ -68,6 +108,7 @@ module CDQ
68
108
  clone(sort_descriptors: @sort_descriptors + [NSSortDescriptor.sortDescriptorWithKey(key, ascending: ascending)])
69
109
  end
70
110
 
111
+ # Return an NSFetchRequest that will implement this query
71
112
  def fetch_request
72
113
  NSFetchRequest.new.tap do |req|
73
114
  req.predicate = predicate
@@ -79,6 +120,19 @@ module CDQ
79
120
 
80
121
  private
81
122
 
123
+ # Create a new query with the same values as this one, optionally overriding
124
+ # any of them in the options
125
+ def clone(opts = {})
126
+ self.class.new(locals.merge(opts))
127
+ end
128
+
129
+ def locals
130
+ { sort_descriptors: sort_descriptors,
131
+ predicate: predicate,
132
+ limit: limit,
133
+ offset: offset }
134
+ end
135
+
82
136
  def merge_query(query, operation, *args, &block)
83
137
  key_to_save = nil
84
138
  case query
@@ -108,8 +108,6 @@ module CDQ #:nodoc:
108
108
  # Create a new entity in the current context. Accepts a hash of attributes that will be assigned to
109
109
  # the newly-created entity. Does not save the context.
110
110
  #
111
- # [TODO: Will apply validation.]
112
- #
113
111
  def create(*args)
114
112
  new(*args)
115
113
  end
@@ -9,7 +9,7 @@ describe '<%= @name_camel_case %>' do
9
9
  cdq.reset!
10
10
  end
11
11
 
12
- it 'should be a <%= @name_camel_case %> entity'
12
+ it 'should be a <%= @name_camel_case %> entity' do
13
13
  <%= @name_camel_case %>.entity_description.name.should == '<%= @name_camel_case %>'
14
14
  end
15
15
  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: 0.1.2
4
+ version: 0.1.5
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: 2014-01-02 00:00:00.000000000 Z
12
+ date: 2014-01-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ruby-xcdm
@@ -53,21 +53,12 @@ executables:
53
53
  extensions: []
54
54
  extra_rdoc_files: []
55
55
  files:
56
- - .gitignore
57
- - .travis.yml
58
- - Gemfile
59
- - Gemfile.lock
60
56
  - README.md
61
- - Rakefile
62
- - app/app_delegate.rb
63
- - app/test_models.rb
64
- - bin/cdq
65
- - cdq.gemspec
66
- - lib/cdq.rb
57
+ - LICENSE
67
58
  - lib/cdq/cli.rb
68
59
  - lib/cdq/generators.rb
69
60
  - lib/cdq/version.rb
70
- - motion/cdq.rb
61
+ - lib/cdq.rb
71
62
  - motion/cdq/collection_proxy.rb
72
63
  - motion/cdq/config.rb
73
64
  - motion/cdq/context.rb
@@ -79,34 +70,17 @@ files:
79
70
  - motion/cdq/relationship_query.rb
80
71
  - motion/cdq/store.rb
81
72
  - motion/cdq/targeted_query.rb
73
+ - motion/cdq.rb
82
74
  - motion/managed_object.rb
83
- - resources/CDQ.xcdatamodeld/.xccurrentversion
84
- - resources/CDQ.xcdatamodeld/0.0.1.xcdatamodel/contents
85
- - resources/Default-568h@2x.png
86
- - resources/KEEPME
87
- - schemas/001_baseline.rb
88
- - spec/cdq/collection_proxy_spec.rb
89
- - spec/cdq/config_spec.rb
90
- - spec/cdq/context_spec.rb
91
- - spec/cdq/managed_object_spec.rb
92
- - spec/cdq/model_spec.rb
93
- - spec/cdq/module_spec.rb
94
- - spec/cdq/object_proxy_spec.rb
95
- - spec/cdq/object_spec.rb
96
- - spec/cdq/partial_predicate_spec.rb
97
- - spec/cdq/query_spec.rb
98
- - spec/cdq/relationship_query_spec.rb
99
- - spec/cdq/store_spec.rb
100
- - spec/cdq/targeted_query_spec.rb
101
- - spec/helpers/thread_helper.rb
102
- - spec/integration_spec.rb
103
75
  - templates/init/schemas/0001_initial.rb
104
76
  - templates/model/app/models/name.rb
105
77
  - templates/model/spec/models/name.rb
106
- - vendor/cdq/ext/CoreDataQueryManagedObjectBase.h
107
78
  - vendor/cdq/ext/CoreDataQueryManagedObjectBase.m
108
- homepage: http://github.com/infinitered/cdq
109
- licenses: []
79
+ - vendor/cdq/ext/CoreDataQueryManagedObjectBase.h
80
+ - bin/cdq
81
+ homepage: http://infinitered.com/cdq
82
+ licenses:
83
+ - MIT
110
84
  metadata: {}
111
85
  post_install_message:
112
86
  rdoc_options: []
@@ -127,20 +101,5 @@ rubyforge_project:
127
101
  rubygems_version: 2.1.5
128
102
  signing_key:
129
103
  specification_version: 4
130
- summary: Core Data Query for RubyMotion
131
- test_files:
132
- - spec/cdq/collection_proxy_spec.rb
133
- - spec/cdq/config_spec.rb
134
- - spec/cdq/context_spec.rb
135
- - spec/cdq/managed_object_spec.rb
136
- - spec/cdq/model_spec.rb
137
- - spec/cdq/module_spec.rb
138
- - spec/cdq/object_proxy_spec.rb
139
- - spec/cdq/object_spec.rb
140
- - spec/cdq/partial_predicate_spec.rb
141
- - spec/cdq/query_spec.rb
142
- - spec/cdq/relationship_query_spec.rb
143
- - spec/cdq/store_spec.rb
144
- - spec/cdq/targeted_query_spec.rb
145
- - spec/helpers/thread_helper.rb
146
- - spec/integration_spec.rb
104
+ summary: A streamlined library for working with Core Data outside XCode
105
+ test_files: []
data/.gitignore DELETED
@@ -1,12 +0,0 @@
1
- .repl_history
2
- .*.sw?
3
- build
4
- vendor/cdq/ext/build-*
5
- vendor/cdq/ext/ext.bridgesupport
6
- resources/*.nib
7
- resources/*.momd
8
- resources/*.storyboardc
9
- examples/**/*.nib
10
- tags
11
- .rbenv-version
12
- pkg
@@ -1,2 +0,0 @@
1
- language: objective-c
2
- before_install: ruby --version
data/Gemfile DELETED
@@ -1,7 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec
4
-
5
- gem 'rake'
6
- gem 'motion-stump', :group => :spec
7
- gem 'cdq', :path => '.'
@@ -1,32 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- cdq (0.1.2)
5
- motion-yaml
6
- ruby-xcdm (~> 0.0, >= 0.0.5)
7
-
8
- GEM
9
- remote: https://rubygems.org/
10
- specs:
11
- activesupport (3.2.16)
12
- i18n (~> 0.6, >= 0.6.4)
13
- multi_json (~> 1.0)
14
- builder (3.2.2)
15
- i18n (0.6.9)
16
- motion-stump (0.3.0)
17
- motion-yaml (1.2)
18
- multi_json (1.8.2)
19
- plist (3.1.0)
20
- rake (10.1.0)
21
- ruby-xcdm (0.0.5)
22
- activesupport (~> 3.2)
23
- builder (~> 3.2)
24
- plist (~> 3.1)
25
-
26
- PLATFORMS
27
- ruby
28
-
29
- DEPENDENCIES
30
- cdq!
31
- motion-stump
32
- rake
data/Rakefile DELETED
@@ -1,28 +0,0 @@
1
- $:.unshift("/Library/RubyMotion/lib")
2
- require 'motion/project/template/ios'
3
-
4
- require 'bundler'
5
- require 'bundler/gem_tasks'
6
-
7
- Motion::Project::App.setup do |app|
8
- # Use `rake config' to see complete project settings.
9
- app.name = 'CDQ'
10
- app.vendor_project('vendor/cdq/ext', :static)
11
- end
12
-
13
- if ARGV.join(' ') =~ /spec/
14
- Bundler.require :default, :spec
15
- else
16
- Bundler.require
17
- end
18
-
19
- require 'cdq'
20
- require 'motion-stump'
21
- require 'ruby-xcdm'
22
- require 'motion-yaml'
23
-
24
- task :"build:simulator" => :"schema:build"
25
- task :"build:simulator" => :"schema:build"
26
- task :"build:simulator" => :"schema:build"
27
- task :"build:simulator" => :"schema:build"
28
- task :"build:simulator" => :"schema:build"