class NativeQuery::Join

Represents join request.

Attributes

joins[R]

Public Class Methods

new(original, table) click to toggle source

Constructor.

# File lib/native-query/join.rb, line 72
def initialize(original, table)
    @table = table
    @original = original
    @fields = [ ]
    @where = [ ]
    @joins = [ ]
    @type = :direct
    
    @indirect_source = original
end

Public Instance Methods

backward(*args) click to toggle source

Indicates backward joining.

# File lib/native-query/join.rb, line 151
def backward(*args)
    @direct = [:backward, args]
end
build() click to toggle source

Builds ON join string.

# File lib/native-query/join.rb, line 159
def build
    result = nil
    
    case @type
        when :indirect
            result = __indirect
        when :direct
            result = __direct
    end
    
    return result
end
direct(*args) click to toggle source

Indicates direct joining. (1:M)

# File lib/native-query/join.rb, line 136
def direct(*args)
    @type = :direct
    if args.first.array? and (args.first.first == :backward) and (args.first.second.array?)
        @direct = args.first
    else
        @direct = args
    end
    
    return self
end
fields(*args) click to toggle source

Sets hash for select from joined table. Without arguments returns fields list.

# File lib/native-query/join.rb, line 88
def fields(*args)
    if args.empty?
        result = { }
        @fields.each do |i|
            if not i.kind_of? Hash
                i = {i => i}
            end
            
            i.each_pair do |from, to|
                result[__fix_field(from)] = @table.to_s << "_" << to.to_s
            end
        end
        
        return result
    else
        @fields += args
        return self
    end
end
indirect(*args) click to toggle source

Indicates indirect joining. (M:N)

# File lib/native-query/join.rb, line 121
def indirect(*args)
    @type = :indirect
    if args.first.array? and (args.first.first == :backward) and (args.first.second.array?)
        @indirect = args.first
    else
        @indirect = args
    end
    
    return self
end
method_missing(sym, *args, &block) click to toggle source

Calls mapping to joins specification. Call name is name of the target table.

Block works by the same way as query, but for join. But intra-join calls doesn’t work because it returns Query too.

# File lib/native-query/join.rb, line 188
def method_missing(sym, *args, &block)
    join = self.class::new(@table, sym)

    if args and not args.empty?
        join.fields(*args)
    end

    join.instance_eval(&block)
    @joins << join
    
    return self
end
where(*args) click to toggle source

Selects where conditions to load.

# File lib/native-query/join.rb, line 112
def where(*args)
    @where << args
    return self
end
wheres() click to toggle source

Return wheres.

# File lib/native-query/join.rb, line 176
def wheres
    self._fix_where
end

Protected Instance Methods

_fix_where() click to toggle source

Fixes where specification(s) if it’s hash with symbol key.

# File lib/native-query/join.rb, line 217
def _fix_where
    NativeQuery::Query::fix_conditions(@where) do |arg|
        #p args
        #args.each do |i|
        #    __fix_field(i)
        #end
        __fix_field(arg)
    end
end

Private Instance Methods

__direct() click to toggle source

Builds direct join.

# File lib/native-query/join.rb, line 284
def __direct
    
    if @direct.array? and (@direct.first == :backward) and (@direct.second.array?)
        backward = true
        direct = @direct.second
    else
        backward = false
        direct = [ ]
    end
    
    ##
    
    empty = direct.empty?
    direct = direct.first
    from = @original.to_s
    to = @table.to_s
    result = { }
    
    # automatic joining
    if empty
        from.swap_with(to) if backward
        result[@table] = "[" << from << ".id] = [" << to << "." << from << "_id]"
    # manual joining
    elsif direct.hash?
        result[@table] = "[" << from << "." << direct.keys.first.to_s << "] = [" << to << "." << direct.values.first.to_s << "]"
    # special joining
    elsif direct.string?
        result[@table] = direct
    # error
    else
        raise Exception::new("Hash or String expected.")
    end
    
    return result
end
__fix_field(name, formatted = false) click to toggle source

Fixes field name. Joins table name if SQL table joining required.

# File lib/native-query/join.rb, line 207
def __fix_field(name, formatted = false)
    NativeQuery::Query::fix_field(name, @table, formatted)
end
__indirect() click to toggle source

Builds indirect join.

# File lib/native-query/join.rb, line 232
def __indirect

    if (@indirect.first == :backward) and (@indirect.second.array?)
        backward = true
        indirect = @indirect.second
    else
        backward = false
        indirect = @indirect
    end
    
    ##
    
    result = { }
    to = @table.to_s
    from = @original.to_s
    arg1, arg2, arg3 = indirect

    # automatic joining
    if indirect.empty?
        from.swap_with(to) if backward
        through = from + "_" + to
        joining_table = through.to_sym
        result[joining_table] = "[" << from << ".id] = [" << through << "." << from << "_id]"
        result[@table] = "[" << through << "." << to << "_id] = [" << to << ".id]"
        
    # standard specification (semiautomatic joining)
    elsif arg1.symbol? and arg2.hash?
        through = arg1.to_s
        joining_table = arg1
        result[joining_table] = "[" << from << "." << arg2.keys.first.to_s << "] = [" << through << "." << from << "_id]"
        result[@table] = "[" << through << "." << to << "_id] = [" << to << "." << arg2.values.first.to_s << "]"
        
    # fluent query specification (manual joining)
    elsif arg1.symbol? and arg2.string? and arg3.string?
        joining_table = arg1
        result[joining_table] = arg2
        result[@table] = arg3
    
    # error
    else
        raise Exception::new("Symbol and Hash or Symbol and two Strings expected.")
        
    end
    
    return result
end