Class: DataMapper::Query

Inherits:
Object
  • Object
show all
Includes:
Assertions
Defined in:
lib/dm-core/query.rb

Defined Under Namespace

Classes: Direction, Operator, Path

Constant Summary collapse

OPTIONS =
[
  :reload, :offset, :limit, :order, :add_reversed, :fields, :links, :includes, :conditions, :unique
]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Assertions

#assert_kind_of

Instance Attribute Details

#add_reversed=(value) ⇒ Object (writeonly)

Sets the attribute add_reversed

Parameters:

  • value

    the value to set the attribute add_reversed to.



10
11
12
# File 'lib/dm-core/query.rb', line 10

def add_reversed=(value)
  @add_reversed = value
end

Class Method Details

._load(marshalled) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

TODO: add docs



199
200
201
# File 'lib/dm-core/query.rb', line 199

def self._load(marshalled)
  new(*Marshal.load(marshalled))
end

Instance Method Details

#==(other) ⇒ Object Also known as: eql?



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/dm-core/query.rb', line 67

def ==(other)
  return true if super
  return false unless other.kind_of?(self.class)

  # TODO: add a #hash method, and then use it in the comparison, eg:
  #   return hash == other.hash
  @model        == other.model         &&
  @reload       == other.reload?       &&
  @unique       == other.unique?       &&
  @offset       == other.offset        &&
  @limit        == other.limit         &&
  @order        == other.order         &&  # order is significant, so do not sort this
  @add_reversed == other.add_reversed? &&
  @fields       == other.fields        &&  # TODO: sort this so even if the order is different, it is equal
  @links        == other.links         &&  # TODO: sort this so even if the order is different, it is equal
  @includes     == other.includes      &&  # TODO: sort this so even if the order is different, it is equal
  @conditions.sort_by { |c| c.at(0).hash + c.at(1).hash + c.at(2).hash } == other.conditions.sort_by { |c| c.at(0).hash + c.at(1).hash + c.at(2).hash }
end

#_dumpObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

TODO: add docs



193
194
195
# File 'lib/dm-core/query.rb', line 193

def _dump(*)
  Marshal.dump([ repository, model, to_hash ])
end

#bind_valuesObject



88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/dm-core/query.rb', line 88

def bind_values
  bind_values = []
  conditions.each do |tuple|
    next if tuple.size == 2
    operator, property, bind_value = *tuple
    if :raw == operator
      bind_values.push(*bind_value)
    else
      bind_values << bind_value
    end
  end
  bind_values
end

#inheritance_propertyObject



102
103
104
# File 'lib/dm-core/query.rb', line 102

def inheritance_property
  fields.detect { |property| property.type == DataMapper::Types::Discriminator }
end

#inheritance_property_indexObject



106
107
108
# File 'lib/dm-core/query.rb', line 106

def inheritance_property_index
  fields.index(inheritance_property)
end

#inspectObject



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/dm-core/query.rb', line 137

def inspect
  attrs = [
    [ :repository, repository.name ],
    [ :model,      model           ],
    [ :fields,     fields          ],
    [ :links,      links           ],
    [ :conditions, conditions      ],
    [ :order,      order           ],
    [ :limit,      limit           ],
    [ :offset,     offset          ],
    [ :reload,     reload?         ],
    [ :unique,     unique?         ],
  ]

  "#<#{self.class.name} #{attrs.map { |(k,v)| "@#{k}=#{v.inspect}" } * ' '}>"
end

#key_property_indexes(repository) ⇒ Object

TODO: spec this



111
112
113
114
115
# File 'lib/dm-core/query.rb', line 111

def key_property_indexes(repository)
  if (key_property_indexes = model.key(repository.name).map { |property| fields.index(property) }).all?
    key_property_indexes
  end
end

#merge(other) ⇒ Object



63
64
65
# File 'lib/dm-core/query.rb', line 63

def merge(other)
  dup.update(other)
end

#merge_subquery(operator, property, value) ⇒ Object

find the point in self.conditions where the sub select tuple is located. Delete the tuple and add value.conditions. value must be a <DM::Query>



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/dm-core/query.rb', line 121

def merge_subquery(operator, property, value)
  assert_kind_of 'value', value, self.class

  new_conditions = []
  conditions.each do |tuple|
    if tuple.at(0).to_s == operator.to_s && tuple.at(1) == property && tuple.at(2) == value
      value.conditions.each do |subquery_tuple|
        new_conditions << subquery_tuple
      end
    else
      new_conditions << tuple
    end
  end
  @conditions = new_conditions
end

#reload?Boolean

Returns:

  • (Boolean)


13
14
15
# File 'lib/dm-core/query.rb', line 13

def reload?
  @reload
end

#reverseObject



21
22
23
# File 'lib/dm-core/query.rb', line 21

def reverse
  dup.reverse!
end

#reverse!Object



25
26
27
28
29
30
# File 'lib/dm-core/query.rb', line 25

def reverse!
  # reverse the sort order
  update(:order => self.order.map { |o| o.reverse })

  self
end

#to_hashObject

TODO: add docs



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/dm-core/query.rb', line 156

def to_hash
  hash = {
    :reload       => reload?,
    :unique       => unique?,
    :offset       => offset,
    :order        => order,
    :add_reversed => add_reversed?,
    :fields       => fields,
  }

  hash[:limit]    = limit    unless limit    == nil
  hash[:links]    = links    unless links    == []
  hash[:includes] = includes unless includes == []

  conditions  = {}
  raw_queries = []
  bind_values = []

  conditions.each do |condition|
    if condition[0] == :raw
      raw_queries << condition[1]
      bind_values << condition[2]
    else
      operator, property, bind_value = condition
      conditions[ Query::Operator.new(property, operator) ] = bind_value
    end
  end

  if raw_queries.any?
    hash[:conditions] = [ raw_queries.join(' ') ].concat(bind_values)
  end

  hash.update(conditions)
end

#unique?Boolean

Returns:

  • (Boolean)


17
18
19
# File 'lib/dm-core/query.rb', line 17

def unique?
  @unique
end

#update(other) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/dm-core/query.rb', line 32

def update(other)
  assert_kind_of 'other', other, self.class, Hash

  assert_valid_other(other)

  if other.kind_of?(Hash)
    return self if other.empty?
    other = self.class.new(@repository, model, other)
  end

  return self if self == other

  # TODO: update this so if "other" had a value explicitly set
  #       overwrite the attributes in self

  # only overwrite the attributes with non-default values
  @reload       = other.reload?       unless other.reload?       == false
  @unique       = other.unique?       unless other.unique?       == false
  @offset       = other.offset        if other.reload? || other.offset != 0
  @limit        = other.limit         unless other.limit         == nil
  @order        = other.order         unless other.order         == model.default_order
  @add_reversed = other.add_reversed? unless other.add_reversed? == false
  @fields       = other.fields        unless other.fields        == @properties.defaults
  @links        = other.links         unless other.links         == []
  @includes     = other.includes      unless other.includes      == []

  update_conditions(other)

  self
end