예제 #1
0
def generate_sql(field_map, input_data, macro_map={}):
    """
    This is method to be call for transpiling SQL query.
    e.g. generate_sql({1 : 'name'}, ['!=', ['field', 1], None]))
    shoud return SELECT * FROM data WHERE name IS NOT NULL.

    For bonus point, you may pass in a macro map as well.
    If that is the case, please specify macro id in the input
    data, do it like ['macro' : 'is_joe'].

    :type field_map: dict
    :type input_data: list
    :type macro_map: dict
    :rtype: str
    """
    if input_data == []:
        return SQL_HEADER

    entity = Entity(input_data)

    where_clause = ''
    if entity.is_simple_clause():
        where_clause = transpile_simple_clause(field_map, entity, macro_map)
    elif entity.is_compound_clause():
        where_clause = transpile_compound_clause(field_map, entity, macro_map)
    elif entity.is_macro():
        where_clause = transpile_macro(field_map, entity, macro_map)
    else:
        raise TranspilerError("Input (%s) not recognized." % (input_data))

    return SQL_HEADER + ' WHERE '+ where_clause
예제 #2
0
def transpile_field(field_map, field_entity):
    """ Map field id to column name in the field_map """
    field_id = field_entity.get_field_id()

    if field_id not in field_map:
        raise TranspilerError("Field id (%s) does not exist." % (field_id))

    return field_map.get(field_id)
예제 #3
0
def transpile_compound_clause(field_map,
                              clause_entity,
                              macro_map={},
                              subclause=False):
    """
    Transpile compound clause.
    subclause parameter indicates whether this compound clause is
    a sub clause of another compound clause.
    """
    if not clause_entity.is_compound_clause():
        raise TranspilerError("Clause (%s) is not a compound clause." %
                              (clause))

    operator = clause_entity.get_operator()
    entities = clause_entity.get_arguments()

    transpiled_entities = []

    # Each sub entity can either be a simple clause, compound clause or macro.
    # If it is a compound clause, then it needs to be wrapped in a pair of
    # parenthesis.
    for sub_entity in entities:
        if sub_entity.is_simple_clause():
            transpiled_entities.append(
                transpile_simple_clause(field_map, sub_entity))
        elif sub_entity.is_compound_clause():
            transpiled_entities.append(
                transpile_compound_clause(field_map,
                                          sub_entity,
                                          subclause=True))
        elif sub_entity.is_macro():
            transpiled_entities.append(
                transpile_macro(field_map,
                                sub_entity,
                                macro_map,
                                subclause=True))
        else:
            raise TranspilerError(
                'Entity (%s) should be a clause but it is not.' % (sub_entity))

    transpiled_compound_clause = join_tokens(transpiled_entities, operator)

    # If the input compound clause is a subclause of another compound clause, then we wrap it up
    # with '()'.
    return '(' + transpiled_compound_clause + ')' if subclause else transpiled_compound_clause
예제 #4
0
def transpile_macro(field_map, macro_entity, macro_map={}, subclause=False):
    """
    Transpile macro entity.
    """
    macro_id = macro_entity.get_macro_id()

    if macro_id not in macro_map:
        raise TranspilerError("Macro id: (%s) does not exist." % (macro_id))

    entity = Entity(macro_map[macro_id])

    if entity.is_macro():
        # This takes care of one macro point to another macro, which
        # is weird, but possible.
        return transpile_macro(field_map, entity, macro_map)
    elif entity.is_simple_clause():
        return transpile_simple_clause(field_map, entity, macro_map)
    elif entity.is_compound_clause():
        return transpile_compound_clause(field_map,
                                         entity,
                                         macro_map,
                                         subclause=subclause)
    else:
        raise TranspilerError('Macro entity (%s) not recognized.' % (entity))
예제 #5
0
def transpile_simple_clause(field_map, clause_entity, macro_map={}):
    """
    Transpile the whole simple clause.
    """
    if not clause_entity.is_simple_clause():
        raise TranspilerError("Clause (%s) is not a simple clause." %
                              (clause_entity))
    else:
        operator = clause_entity.get_operator()
        arguments = clause_entity.get_arguments()

        if operator in ['is_empty', 'not_empty']:
            field_entity = arguments[0]
            return {
                'is_empty': lambda m, f: transpile_is_empty(m, f),
                'not_empty': lambda m, f: transpile_not_empty(m, f)
            }[operator](field_map, field_entity)
        else:
            # It is simple clause with one operator and two arguments, follows
            # [<operator>, <field>, <literal>] format.
            field_entity, literal_entity = arguments
            return transpile_comparison(field_map, operator, field_entity,
                                        literal_entity)
예제 #6
0
 def __validate_macro(self):
     if not self.is_macro():
         raise TranspilerError("Not a macro: %s" % (self.i__item))
예제 #7
0
 def __validate_field_value(self):
     if not self.is_field_value():
         raise TranspilerError("Not a field value entity: %s!" % (self.__item))
예제 #8
0
 def __validate_literal_value(self):
     if not self.is_literal_value():
         raise TranspilerError("Not a literal value entity: %s!" % (self.__item))
예제 #9
0
 def __validate_clause(self):
     if not self.is_clause():
         raise TranspilerError("Not a clause entity: %s!" % (self.__item))