Exemplo n.º 1
0
def act_context(context):
    """Action routine for CONTEXT directive."""
    if len(context.line.split()) != 1:
        raise ExtraToken('CONTEXT', line=context.line_num)
    if context.context:
        raise DuplicateName('CONTEXT', context.line_num)
    context.context = import_by_path(context.line)
Exemplo n.º 2
0
def act_exception(context):
    """Action routine for EXCEPTION directive."""
    if len(context.line.split()) != 1:
        raise ExtraToken('EXCEPTION', line=context.line_num)
    if context.exception is not None:
        raise DuplicateDirective('EXCEPTION', context.line_num)
    context.exception = import_by_path(context.line)
Exemplo n.º 3
0
def _coerce_type(type, enum, enums):
    def validate_int(value):
        try:
            return int(value)
        except Exception:
            raise ValueError('must be an int')

    def validate_count(value):
        try:
            value = int(value)
            if value > 0:
                return value
        except Exception:
            pass
        raise ValueError('must be a postive int')

    if enum:
        if enum not in enums:
            raise Exception("enum '%s' not defined" % enum)
        type = enums[enum]
    elif type == 'int':
        type = validate_int
    elif type == 'count':
        type = validate_count
    elif type == 'bool':
        type = config_file.validate_bool
    else:
        try:
            type = import_by_path(type)
        except Exception:
            raise Exception(
                "unable to import validation function '{}'".format(type))

    return type
Exemplo n.º 4
0
    def _normalize(self, table, table2):

        if table2:
            if table2 in self._tables:
                # lookup by alias
                table2 = self._tables[table2]
            else:
                # lookup by class
                table2 = import_by_path(table2)
                match = [t for t in self._tables if t.cls == table2]
                if not match:
                    raise TypeError("'{}' does not match any tables".format(
                        table2.__name__))
                elif len(match) > 1:
                    raise TypeError("'{}' matches multiple tables".format(
                        table2.__name__))
                table2 = match[0]

        ref = self._find_foreign_key_reference(table, table2)
        if ref:
            t, field = ref
            return table, field.field_name, t, t.cls._fields.pk

        ref = self._find_primary_key_reference(table, table2)
        if ref:
            t, field = ref
            return table, table._fields.pk, t, field

        raise TypeError(
            "no primary or foreign key matches found for '{}'".format(
                table.__name__))
Exemplo n.º 5
0
def act_handler(context):
    """Action routine for HANDLER directive."""
    args = context.line.split()
    if len(args) == 1:
        raise TooFewTokens('HANDLER', line=context.line_num)
    if len(args) > 2:
        raise ExtraToken('HANDLER', line=context.line_num)
    name, path = args
    name = name.strip()
    if name in context.handlers:
        raise DuplicateName('HANDLER', context.line_num)
    handler = import_by_path(path)
    context.handlers[name] = handler
Exemplo n.º 6
0
 def cls(self):
     self._cls = import_by_path(self._cls)
     return self._cls
Exemplo n.º 7
0
    def join(self, table, table2=None, alias=None, outer=None):
        """Add a table to the query

           The table will be joined to another table in the query using
           foreign or primary key matches.

            Parameters:
                table  - DAO of the table to add to the query (1)(4)
                table2 - name, alias or DAO of table to join (2)
                alias  - name of joined table (3)
                outer  - OUTER join indicator
                         LEFT or RIGHT

           Notes:
               1. The table can be specified as a DAO or as a dot separated
                  path to a DAO for import. First, foreign keys in 'table'
                  will be checked for a single matching primary key in one
                  of the tables that is already part of the query. If no
                  match is found, the primary key of 'table' will be matched
                  in the same way.
               2. If multiple matches occur when trying to join 'table',
                  the ambiguity can be removed by specifying which existing
                  table to match. Foreign keys from 'table' will be checked
                  first, followed by the primary key.
               3. The 'alias' parameter can be used to prevent collision with
                  an existing DAO attribute, or to allow the same DAO to be
                  joined more than once.
               4. Any joined DAO is accesible as an attribute of the DAO used
                  to create the Query object. The default attribute name is
                  the lower case classname of the DAO. Specifying 'alias' will
                  override this default.

                  Example of join result structure:

                      This query:

                        Root.query().join(Node).execute(...)

                      will result in a set of Root instances, each joined
                      to a Node instance. Each Node instance is added as
                      an attribute of a Root instance. Therefore:

                        root = result[0]
                        node = root.node

                  In the case of multiple join clauses, each joined instance
                  will be added to the DAO used to create the Query object.
        """
        try:
            table = import_by_path(table)
        except ValueError:
            raise TypeError("invalid path to table: '{}'".format(table))
        except ModuleNotFoundError:
            raise TypeError("unable to load '{}'".format(table))
        if alias is None:
            alias = table.__name__.lower()
        if alias in [t.alias for t in self._tables]:
            raise ValueError("duplicate table '{}'".format(alias))

        table, field, table2, field2 = self._normalize(table, table2)
        self._tables.append(QueryTable(table, alias))

        if outer is None:
            join = ' JOIN '
        elif outer.lower() == 'right':
            join = ' RIGHT OUTER JOIN '
        elif outer.lower() == 'left':
            join = ' LEFT OUTER JOIN '
        else:
            raise ValueError("invalid outer join value: '{}'".format(outer))

        self._join += '{} `{}` AS `{}` ON `{}`.`{}` = `{}`.`{}`'.format(
            join,
            table.TABLENAME,
            alias,
            alias,
            table._fields[field].name,
            table2.alias,
            table2.cls._fields[field2].name,
        )

        return self