Beispiel #1
0
    def queryToSQL(self, schema, query, alias=''):
        # noinspection PyShadowingNames
        QUOTE = self.baseSQL().byName('QUOTE')

        column = query.column(schema)
        output = QUOTE(alias or schema.dbname(), column.fieldName())

        # process any functions on the query
        for func in query.functions():
            sql_func = self.baseSQL().byName('Func::{0}'.format(orb.Query.Function(func)))
            if not sql_func:
                msg = 'Unknown function type {0}'.format(orb.Query.Function(func))
                raise errors.QueryInvalid(msg)
            else:
                output = sql_func.format(output)

        return output
Beispiel #2
0
    def render(self, schema, changes, **scope):
        """
        Generates the UPDATE sql for an <orb.Table>.

        :param      schema  | <orb.Table> || <orb.TableSchema>
                    changes | [(<orb.Table>, [<orb.Column>, ..]) ..]
                    **scope | <dict>

        :return     <str>
        """
        if orb.Table.typecheck(schema):
            schema = schema.schema()
        elif orb.View.typecheck(schema):
            raise errors.QueryInvalid('Views are read-only.')

        scope['schema'] = schema
        scope['changes'] = changes

        return super(UPDATE, self).render(**scope)
Beispiel #3
0
    def render(self, schema, count=1, **scope):
        """
        Generates the INSERTED KEYS sql for an <orb.Table> or <orb.TableSchema>.

        :param      schema  | <orb.Table> || <orb.TableSchema>
                    count   | <int>
                    **scope | <dict>

        :return     <str>
        """
        if orb.Table.typecheck(schema):
            schema = schema.schema()
        elif orb.View.typecheck(schema):
            raise errors.QueryInvalid('Views are read-only.')

        scope['schema'] = schema
        scope['field'] = schema.primaryColumns()[0].fieldName()
        scope['table'] = schema.dbname()
        scope['count'] = count

        return super(INSERTED_KEYS, self).render(**scope)
Beispiel #4
0
    def render(self, schema, records, columns=None, **scope):
        """
        Generates the INSERT sql for an <orb.Table>.

        :param      schema  | <orb.Table> || <orb.TableSchema>
                    records | [<orb.Table>, ..]
                    columns | [<str>, ..]
                    **scope | <dict>

        :return     <str>
        """
        if orb.Table.typecheck(schema):
            schema = schema.schema()
        elif orb.View.typecheck(schema):
            raise errors.QueryInvalid('Views are read-only.')

        if columns is None:
            columns = schema.columns(kind=orb.Column.Kind.Field)
        else:
            columns = [schema.column(col) for col in columns]

        locale = scope.get('locale', orb.system.locale())
        io = scope.get('IO', {})
        io['locale'] = locale

        columns, insertions = self.collectInsertions(records, columns, io, locale)

        new_scope = {
            'table': schema.dbname(),
            'schema': schema,
            'records': records,
            'columns': columns,
            'insertions': insertions,
            'IO': io
        }
        new_scope.update(**scope)

        return super(INSERT, self).render(**new_scope)
Beispiel #5
0
    def render(self, schema, query, **scope):
        """
        Generates the WHERE sql for an <orb.Table>.

        :param      schema  | <orb.Schema>
                    where   | <orb.Query> || <orb.QueryCompound>
                    **scope | <dict>

        :return     <str>
        """
        if query is None:
            return ''

        scope.setdefault('IO', {})
        scope.setdefault('GLOBALS', {})

        io = scope['IO']
        glbls = scope['GLOBALS']
        db = scope.get('db', orb.system.database())
        query = query.expandShortcuts(schema.model())

        # create a compound query
        if orb.QueryCompound.typecheck(query):
            queries = [self(schema, subq, schema_alias=scope.get('schema_alias'), GLOBALS=glbls, IO=io) for subq in query.queries()]
            joiner = u' AND ' if query.operatorType() == orb.QueryCompound.Op.And else u' OR '
            result = joiner.join([q for q in queries if q])
            return u'({0})'.format(result) if result else ''

        # create a basic query
        else:
            glbls.setdefault('join_count', 0)
            glbls.setdefault('field_mapper', {})

            # grab the column from the query
            column = query.column(schema, db=db)
            if not column:
                raise errors.ColumnNotFound(schema.name(), query.columnName())

            # grab the field information
            try:
                field = glbls['field_mapper'][column]
            except KeyError:
                field = self.queryToSQL(schema, query, scope.get('schema_alias', ''))

            # calculate the field math modifications
            for op, target in query.math():
                opts = {
                    'math': orb.Query.Math(op),
                    'type': orb.ColumnType(column.columnType())
                }

                base = self.baseSQL()
                sql = base.byName('Math::{math}::{type}'.format(**opts)) or base.byName('Math::{math}'.format(**opts))
                if not sql:
                    msg = 'Cannot {math} {type} types.'.format(**opts)
                    raise errors.QueryInvalid(msg)
                else:
                    field += sql
                    if orb.Query.typecheck(target):
                        field += self.queryToSQL(schema, target, scope.get('schema_alias', ''))
                    else:
                        key = len(io)
                        io[str(key)] = target
                        field += '%({0})s'.format(key)

            # calculate the value
            operator = query.operatorType()
            value = query.value()

            # check for a record value
            if orb.Table.recordcheck(value) or orb.View.recordcheck(value):
                value = value.primaryKey()

            # calculate the sql operation
            op_name = orb.Query.Op(operator)
            op = self.baseSQL().byName('Op::{0}'.format(op_name))
            if op is None:
                raise orb.errors.QueryInvalid('{0} is an unknown operator.'.format(op_name))

            if query.caseSensitive():
                case = self.baseSQL().byName('Op::{0}::CaseSensitive'.format(op_name))
                op = case or op

            # update the scope
            scope.setdefault('schema_alias', '')
            scope['WHERE'] = self
            scope['schema'] = schema
            scope['query'] = query
            scope['column'] = column
            scope['field'] = field
            scope['value'] = value
            scope['operator'] = operator
            scope['op'] = op

            return super(WHERE, self).render(**scope)