class FluentQuery::Drivers::SQL

Represents abstract SQL driver.

Constants

AGREGATE

Indicates, appropriate token should be present by one real token, but more input tokens.

ALIASES

Indicates token aliases.

OPERATORS

Contains operators list.

Operators are defined as tokens whose multiple parameters in Array are appropriate to join by itself.

ORDERING

Contains ordering for typicall queries.

RELEVANT

Contains relevant methods index for this driver.

TOKEN

Holds internal token struct.

Public Class Methods

new(connection) click to toggle source

Initializes driver.

Calls superclass method
# File lib/fluent-query/drivers/sql.rb, line 147
def initialize(connection)
    if self.instance_of? SQL
        not_implemented
    end

    super(connection)

    @relevant = SQL::RELEVANT
    @ordering = SQL::ORDERING
    @operators = SQL::OPERATORS
    @aliases = SQL::ALIASES
    @agregate = SQL::AGREGATE

    @_tokens_required = { }
end

Public Instance Methods

build_query(query, mode = :build) click to toggle source

Builds given query.

# File lib/fluent-query/drivers/sql.rb, line 204
def build_query(query, mode = :build)
    self._build_query(query, FluentQuery::Drivers::Shared::Tokens::SQLToken, mode)
end
check_conditionally(query, sym, *args, &block) click to toggle source

Checks query conditionally. It's called after first token of the query.

@see execute_conditionally @since 0.9.2

# File lib/fluent-query/drivers/sql.rb, line 532
def check_conditionally(query, sym, *args, &block)
    self.execute_conditionally(query, sym, *args, &block)
end
execute_conditionally(query, sym, *args, &block) click to toggle source

Executes query conditionally.

If query isn't suitable for executing, returns it. In otherwise returns nil, result or number of changed rows.

# File lib/fluent-query/drivers/sql.rb, line 544
def execute_conditionally(query, sym, *args, &block)
    case query.type
        when :insert
            if (args.first.symbol?) and (args.second.hash?)
                result = query.do!
            end
        when :begin
            if args.empty?
                result = query.execute!
            end
        when :truncate
            if args.first.symbol?
                result = query.execute!
            end
        when :commit, :rollback
            result = query.execute!
        else
            result = nil
    end
    
    return result
end
known_token?(group, token_name, cache) click to toggle source

Indicates token is known.

# File lib/fluent-query/drivers/sql.rb, line 179
def known_token?(group, token_name, cache)

    # Checks
    if @ordering.has_key? group
        # Creates index
        if not cache.has_key? group  
            @ordering[group].each do |item|
                cache[group][item] = true
            end
        end
    
        result = cache[group].has_key? token_name.to_sym
    else
        result = false
    end

    return result
    
end
null() click to toggle source

Creates system-dependent NULL.

# File lib/fluent-query/drivers/sql.rb, line 477
def null
    "NULL"
end
open_connection(settings) click to toggle source

Opens the connection.

It's lazy, so it will open connection before first request through {@link native_connection()} method.

# File lib/fluent-query/drivers/sql.rb, line 519
def open_connection(settings)
    not_implemented
end
operator_token?(token_name) click to toggle source

Indicates, token is operator.

# File lib/fluent-query/drivers/sql.rb, line 213
def operator_token?(token_name)
    @operators.has_key? token_name
end
query_class() click to toggle source

Indicates which query subclass to use.

# File lib/fluent-query/drivers/sql.rb, line 260
def query_class
    FluentQuery::Queries::SQL
end
quote_boolean(boolean) click to toggle source

Quotes system-dependent boolean value.

# File lib/fluent-query/drivers/sql.rb, line 486
def quote_boolean(boolean)
    boolean ? 1 : 0
end
quote_date_time(date) click to toggle source

Quotes system-dependent date value.

# File lib/fluent-query/drivers/sql.rb, line 495
def quote_date_time(date)
    self.quote_string(date.to_s)
end
quote_equality(datatype, mode = :comparing) click to toggle source

Returns correct equality operator for given datatype.

Must handle three modes:

* "assigning" which classicaly keeps for example the '=' operator,
* "comparing" which sets for example 'IS' operator for booleans,
# File lib/fluent-query/drivers/sql.rb, line 235
def quote_equality(datatype, mode = :comparing)                    
    if not datatype.kind_of? Class
        datatype = datatype.class
    end
    
    if mode == :comparing
        if (datatype == TrueClass) or (datatype == FalseClass) or (datatype == NilClass)
            result = "IS"
        elsif datatype == Array
            result = "IN"
        else
            result = "="
        end
    else
        result = "="
    end

    return result
end
quote_float(float) click to toggle source

 Quotes float.

# File lib/fluent-query/drivers/sql.rb, line 459
def quote_float(float)
    float.to_s
end
quote_identifier(field) click to toggle source

Quotes field by field quoting.

# File lib/fluent-query/drivers/sql.rb, line 468
def quote_identifier(field)
    '"' + field.to_s.gsub(".", '"."') + '"'
end
quote_integer(integer) click to toggle source

 Quotes integer.

# File lib/fluent-query/drivers/sql.rb, line 450
def quote_integer(integer)
    integer.to_s
end
quote_operator(operator) click to toggle source

Returns operator string according to operator symbol.

# File lib/fluent-query/drivers/sql.rb, line 222
def quote_operator(operator)
    @operators[operator]
end
quote_string(string) click to toggle source

 Quotes string.

# File lib/fluent-query/drivers/sql.rb, line 438
def quote_string(string)
    string = string.gsub("'", "''")
    string.gsub!("\\", "\\\\\\\\")
    
    return "'" + string + "'"
end
quote_subquery(subquery) click to toggle source

Quotes system-dependent subquery.

# File lib/fluent-query/drivers/sql.rb, line 504
def quote_subquery(subquery)
    "(" + subquery + ")"
end
relevant_method?(name) click to toggle source

Indicates, method is relevant for the driver.

# File lib/fluent-query/drivers/sql.rb, line 170
def relevant_method?(name)
    name.in? @relevant
end

Protected Instance Methods

_build_query(query, inittoken_class, mode = :build) click to toggle source

Builds given query.

# File lib/fluent-query/drivers/sql.rb, line 269
def _build_query(query, inittoken_class, mode = :build)

    stack = query.stack
    token_struct = self.class::TOKEN
    tokens = [ ]

    last_known = nil
    result = ""


    # Gets type of the query (select/update/insert/delete)

    type = query.type
    
    # Sorts according to known token type
    #
    # Unknown tokens are joined to the same subarray as preceded
    # known tokens.
    #
    
    stack.each do |item|
        name = item.name
        
        # If token is alias, renames it
        
        _alias = @aliases[name]

        if not _alias.nil?
            #_alias = _alias
            
            item.alias = _alias
            name = _alias
        end
        
        ##
        
        if self.known_token? type, name
            
            if not last_known.nil?
                last_name = last_known.first.name
                tokens.push(token_struct::new(last_name, last_known))
            end

            last_known = [item]
            
        elsif not last_known.array?
            tokens.push(token_struct::new(:__init__, [item]))
            
        else
            last_known << item
            
        end
    end

    if last_known
        last_name = last_known.first.name
        tokens.push(token_struct::new(last_name, last_known))
    end

    # Generates native tokens

    native_tokens = [ ]
    init_tokens = nil
    agregates = Hash::new { |hash, key| hash[key] = [ ] }

    tokens.each do |data|
        name = data.name
        subtokens = data.subtokens
        
        if (name == :__init__) and (not subtokens.nil?)
            init_tokens = [inittoken_class::new(self, query, subtokens)]
        
        elsif name.in? @agregate
            agregates[name] << data
            
        elsif self.known_token? type, name
            token_data = self._generate_token(name, query, subtokens)
            native_tokens << token_data
        
        end
        
    end

    # Process agregate tokens

    agregates.each_value do |tokens|
        first = tokens.shift

        tokens.each do |token|
            first.subtokens += token.subtokens
        end

        token_data = self._generate_token(first.name, query, first.subtokens)
        native_tokens << token_data
    end

    # Renders in ordered way
    if not init_tokens.nil?
        init_tokens.each do |token|
            result << token.render!(mode) << " "
        end
    end        

    if @ordering.has_key? type
        @ordering[type].each do |item|
            native_tokens.each do |data|
                if data.name == item
                    data.subtokens.each do |token|
                        result << token.render!(mode) << " "
                    end
                end
            end
        end
    end

    result.strip!
    return result
end
_generate_token(name, query, subtokens) click to toggle source

Generates token from token data.

# File lib/fluent-query/drivers/sql.rb, line 393
def _generate_token(name, query, subtokens)
    classobject = self._require_token(name)
    tokens = [classobject::new(self, query, subtokens)]
    
    ###

    return self.class::TOKEN::new(name, tokens)
end
_require_token(name) click to toggle source

Requires token class.

# File lib/fluent-query/drivers/sql.rb, line 407
def _require_token(name)

    if not @_tokens_required.has_key? name
        begin
            module_name = name.to_s.ucfirst
            classname = "FluentQuery::Drivers::Shared::Tokens::SQL::" << module_name
            classfile = classname.downcase
            classfile.strtr!("::" => "/", "fluentquery" => "fluent-query")

            Kernel.require(classfile)
            classobject = FluentQuery::Drivers::Shared::Tokens::SQL.get_module(module_name)
        rescue NameError, LoadError 
            classobject = FluentQuery::Drivers::Shared::Tokens::SQLToken
        end
        
         @_tokens_required[name] = classobject
    end 
    
    return @_tokens_required[name]
end