class Mongoo::ModifierBuilder

Public Class Methods

new(opts, doc) click to toggle source
# File lib/mongoo/modifiers.rb, line 3
def initialize(opts, doc)
  @opts  = opts
  @doc   = doc
  @queue = {}
  @key_prefix = opts[:key_prefix] || ""
end

Public Instance Methods

add_to_set(k,v) click to toggle source
# File lib/mongoo/modifiers.rb, line 61
def add_to_set(k,v)
  @queue["$addToSet"] ||= {}
  @queue["$addToSet"]["#{@key_prefix}#{k}"] = cast_value(v)
end
cast_value(v) click to toggle source
# File lib/mongoo/modifiers.rb, line 24
def cast_value(v)
  if v.is_a?(Mongoo::Embedded::Base)
    return v.to_hash
  elsif v.is_a?(Array)
    v.collect { |e| e.is_a?(Mongoo::Embedded::Base) ? e.to_hash : e }
  else
    v
  end
end
inc(k, v=1) click to toggle source
# File lib/mongoo/modifiers.rb, line 34
def inc(k, v=1)
  v = sanitize_value(k,v)
  @queue["$inc"] ||= {}
  @queue["$inc"]["#{@key_prefix}#{k}"] = cast_value(v)
end
known_attribute?(k) click to toggle source
# File lib/mongoo/modifiers.rb, line 10
def known_attribute?(k)
  @doc.known_attribute?("#{@key_prefix}#{k}")
end
pop(k) click to toggle source
# File lib/mongoo/modifiers.rb, line 66
def pop(k)
  @queue["$pop"] ||= {}
  @queue["$pop"]["#{@key_prefix}#{k}"] = 1
end
pull(k, v) click to toggle source
# File lib/mongoo/modifiers.rb, line 71
def pull(k, v)
  @queue["$pull"] ||= {}
  @queue["$pull"]["#{@key_prefix}#{k}"] = cast_value(v)
end
pull_all(k, v) click to toggle source
# File lib/mongoo/modifiers.rb, line 76
def pull_all(k, v)
  @queue["$pullAll"] ||= {}
  @queue["$pullAll"]["#{@key_prefix}#{k}"] = cast_value(v)
end
push(k, v) click to toggle source
# File lib/mongoo/modifiers.rb, line 51
def push(k, v)
  @queue["$push"] ||= {}
  @queue["$push"]["#{@key_prefix}#{k}"] = cast_value(v)
end
push_all(k, v) click to toggle source
# File lib/mongoo/modifiers.rb, line 56
def push_all(k, v)
  @queue["$pushAll"] ||= {}
  @queue["$pushAll"]["#{@key_prefix}#{k}"] = cast_value(v)
end
run!() click to toggle source
# File lib/mongoo/modifiers.rb, line 81
def run!
  if @queue.blank?
    raise ModifierUpdateError, "modifier update queue is empty"
  end

  update_query = { "_id" => @doc.id }
  update_query.merge!(@opts[:q]) if @opts[:q]

  if @opts[:only_if_current] == true
    @queue.each do |op, op_queue|
      op_queue.each do |k,v|
        update_query[k] = @doc.persisted_mongohash.dot_get(k)
      end
    end
    @opts[:update_opts] ||= {}
    @opts[:update_opts][:safe] = true
  end

  if @opts[:find_and_modify]
    ret = @doc.collection.find_and_modify(query: update_query,
                                          update: @queue,
                                          new: true)
    @doc.reload(ret)
  else
    update_opts = @opts.delete(:update_opts) || {}
    ret = @doc.collection.update(update_query, @queue, update_opts)
    if !ret.is_a?(Hash) || (ret["err"] == nil && ret["n"] == 1)
      @queue.each do |op, op_queue|
        op_queue.each do |k, v|
          duped_v = Marshal.load(Marshal.dump(v))
          case op
          when "$inc" then
            new_val = @doc.persisted_mongohash.dot_get(k).to_i + v
            @doc.mongohash.dot_set( k, new_val )
            @doc.persisted_mongohash.dot_set( k, new_val )
          when "$set" then
            @doc.mongohash.dot_set( k, v )
            @doc.persisted_mongohash.dot_set( k, duped_v )
          when "$unset" then
            @doc.mongohash.dot_delete( k )
            @doc.persisted_mongohash.dot_delete( k )
          when "$push" then
            unless @doc.persisted_mongohash.dot_get(k)
              @doc.persisted_mongohash.dot_set(k, [])
            end
            unless @doc.mongohash.dot_get(k)
              @doc.mongohash.dot_set(k, [])
            end

            @doc.persisted_mongohash.dot_get(k) << duped_v
            @doc.mongohash.dot_get(k) << v
          when "$pushAll" then
            unless @doc.persisted_mongohash.dot_get(k)
              @doc.persisted_mongohash.dot_set(k, [])
            end
            unless @doc.mongohash.dot_get(k)
              @doc.mongohash.dot_set(k, [])
            end

            @doc.persisted_mongohash.dot_get(k).concat(duped_v)
            @doc.mongohash.dot_get(k).concat(v)
          when "$addToSet" then
            unless @doc.persisted_mongohash.dot_get(k)
              @doc.persisted_mongohash.dot_set(k, [])
            end
            unless @doc.mongohash.dot_get(k)
              @doc.mongohash.dot_set(k, [])
            end

            unless @doc.persisted_mongohash.dot_get(k).include?(v)
              @doc.persisted_mongohash.dot_get(k) << duped_v
            end
            unless @doc.mongohash.dot_get(k).include?(v)
              @doc.mongohash.dot_get(k) << v
            end
          when "$pop" then
           unless @doc.persisted_mongohash.dot_get(k)
              @doc.persisted_mongohash.dot_set(k, [])
            end
            unless @doc.mongohash.dot_get(k)
              @doc.mongohash.dot_set(k, [])
            end

            @doc.persisted_mongohash.dot_get(k).pop
            @doc.mongohash.dot_get(k).pop
          when "$pull" then
            unless @doc.persisted_mongohash.dot_get(k)
              @doc.persisted_mongohash.dot_set(k, [])
            end
            unless @doc.mongohash.dot_get(k)
              @doc.mongohash.dot_set(k, [])
            end

            @doc.persisted_mongohash.dot_get(k).delete(v)
            @doc.mongohash.dot_get(k).delete(v)
          when "$pullAll" then
            unless @doc.persisted_mongohash.dot_get(k)
              @doc.persisted_mongohash.dot_set(k, [])
            end
            unless @doc.mongohash.dot_get(k)
              @doc.mongohash.dot_set(k, [])
            end

            v.each do |val|
              @doc.persisted_mongohash.dot_get(k).delete(val)
              @doc.mongohash.dot_get(k).delete(val)
            end
          end
        end
      end # @queue.each
      true
    else
      raise ModifierUpdateError, ret.inspect
    end
  end # if opts[:find_any_modify]
rescue Mongo::OperationFailure => e
  if e.message.to_s =~ /^11000\:/
    raise Mongoo::DuplicateKeyError, e.message
  else
    raise e
  end
end
sanitize_value(k,v) click to toggle source
# File lib/mongoo/modifiers.rb, line 14
def sanitize_value(k,v)
  k = "#{@key_prefix}#{k}"
  if known_attribute?(k)
    field_type = @doc.class.attributes[k][:type]
    Mongoo::AttributeSanitizer.sanitize(field_type, v)
  else
    v
  end
end
set(k,v) click to toggle source
# File lib/mongoo/modifiers.rb, line 40
def set(k,v)
  v = sanitize_value(k,v)
  @queue["$set"] ||= {}
  @queue["$set"]["#{@key_prefix}#{k}"] = cast_value(v)
end
unset(k) click to toggle source
# File lib/mongoo/modifiers.rb, line 46
def unset(k)
  @queue["$unset"] ||= {}
  @queue["$unset"]["#{@key_prefix}#{k}"] = 1
end