Class: CDQ::CDQQuery

Inherits:
CDQObject show all
Defined in:
motion/cdq/query.rb,
motion/cdq.rb

Overview

CDQ Queries are the primary way of describing a set of objects.

Direct Known Subclasses

CDQTargetedQuery

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from CDQObject

#background, #contexts, #find, #models, #reset!, #save, #setup, #stores

Methods included from CDQ

#cdq

Constructor Details

#initialize(opts = {}) ⇒ CDQQuery

Returns a new instance of CDQQuery.


18
19
20
21
22
23
24
# File 'motion/cdq/query.rb', line 18

def initialize(opts = {})
  @predicate = opts[:predicate]
  @limit = opts[:limit]
  @offset = opts[:offset]
  @sort_descriptors = opts[:sort_descriptors] || []
  @saved_key = opts[:saved_key]
end

Instance Attribute Details

#predicateObject (readonly)

Returns the value of attribute predicate


16
17
18
# File 'motion/cdq/query.rb', line 16

def predicate
  @predicate
end

#sort_descriptorsObject (readonly)

Returns the value of attribute sort_descriptors


16
17
18
# File 'motion/cdq/query.rb', line 16

def sort_descriptors
  @sort_descriptors
end

Instance Method Details

#and(query = nil, *args) ⇒ Object Also known as: where

Combine this query with others in an intersection (“and”) relationship. Can be used to begin a new query as well, especially when called in its where variant.

The query passed in can be a wide variety of types:

Symbol: This is by far the most common, and it is also a special case – the return value when passing a symbol is a CDQPartialPredicate, rather than CDQQuery. Methods on CDQPartialPredicate are then comparison operators against the attribute indicated by the symbol itself, which take a value operand. For example:

query.where(:name).equal("Chuck").and(:title).not_equal("Manager")

String: Interpreted as an NSPredicate format string. Additional arguments are the positional parameters.

NilClass: If the argument is nil (most likely because it was omitted), and there was a previous use of a symbol, then reuse that last symbol. For example:

query.where(:name).contains("Chuck").and.contains("Norris")

CDQQuery: If you have another CDQQuery from somewhere else, you can pass it in directly.

NSPredicate: You can pass in a raw NSPredicate and it will work as you'd expect.

Hash: Each key/value pair is treated as equality and anded together.


80
81
82
83
84
# File 'motion/cdq/query.rb', line 80

def and(query = nil, *args)
  merge_query(query, :and, *args) do |left, right|
    NSCompoundPredicate.andPredicateWithSubpredicates([left, right])
  end
end

#fetch_requestObject

Return an NSFetchRequest that will implement this query


139
140
141
142
143
144
145
146
# File 'motion/cdq/query.rb', line 139

def fetch_request
  NSFetchRequest.new.tap do |req|
    req.predicate = predicate
    req.fetchLimit = limit if limit
    req.fetchOffset = offset if offset
    req.sortDescriptors = sort_descriptors unless sort_descriptors.empty?
  end
end

#limit(value = EMPTY) ⇒ Object

Return or set the fetch limit. If passed an argument, return a new query with the specified limit value. Otherwise, return the current value.


30
31
32
33
34
35
36
# File 'motion/cdq/query.rb', line 30

def limit(value = EMPTY)
  if value == EMPTY
    @limit
  else
    clone(limit: value)
  end
end

#offset(value = EMPTY) ⇒ Object

Return or set the fetch offset. If passed an argument, return a new query with the specified offset value. Otherwise, return the current value.


42
43
44
45
46
47
48
# File 'motion/cdq/query.rb', line 42

def offset(value = EMPTY)
  if value == EMPTY
    @offset
  else
    clone(offset: value)
  end
end

#or(query = nil, *args) ⇒ Object

Combine this query with others in a union (“or”) relationship. Accepts all the same argument types as and.


89
90
91
92
93
# File 'motion/cdq/query.rb', line 89

def or(query = nil, *args)
  merge_query(query, :or, *args) do |left, right|
    NSCompoundPredicate.orPredicateWithSubpredicates([left, right])
  end
end

#sort_by(key, options = {}) ⇒ Object

Add a new sort key. Multiple invocations add additional sort keys rather than replacing old ones.

@param key The attribute to sort on
@param options Optional options.

Options include:

order:  If :descending or (or :desc), order is descrnding.  Otherwise,
        it is ascending.
case_insensitive:  True or false.  If true, the sort descriptor is
        built using <tt>localizedCaseInsensitiveCompare</tt>

107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'motion/cdq/query.rb', line 107

def sort_by(key, options = {})
  # backwards compat:  if options is not a hash, it is a sort ordering.
  unless options.is_a?Hash
    sort_order = options
    options = {
      order: sort_order,
      case_insensitive: false,
    }
  end

  options = {
    order: :ascending,
  }.merge(options)

  order = options[:order].to_s

  if order[0,4].downcase == 'desc'
    ascending = false
  else
    ascending = true
  end

  if options[:case_insensitive]
    descriptor = NSSortDescriptor.sortDescriptorWithKey(key, ascending: ascending, selector: "localizedCaseInsensitiveCompare:")
  else
    descriptor = NSSortDescriptor.sortDescriptorWithKey(key, ascending: ascending)
  end

  clone(sort_descriptors: @sort_descriptors + [descriptor])
end