Beispiel #1
0
def test_pg_select_count(orb, User, pg_sql, pg_db):
    select_st = pg_sql.statement('SELECT')
    select_sql, data = select_st(User, orb.Context())

    conn = pg_db.connection()
    records, count = conn.execute(select_sql, data)

    select_count_st = pg_sql.statement('SELECT COUNT')
    select_count_sql, data = select_count_st(User, orb.Context())
    results, _ = conn.execute(select_count_sql, data)

    assert results[0]['count'] == count
Beispiel #2
0
def test_pg_statement_create_table_in_namespace(User, pg_sql):
    import orb
    with orb.Context(namespace='custom'):
        st = pg_sql.statement('CREATE')
        assert st is not None

        statement, data = st(User)
        assert 'CREATE TABLE IF NOT EXISTS "custom"."users"' in statement
Beispiel #3
0
def test_pg_select_bob_and_sally(orb, pg_sql, pg_db, User):
    st = pg_sql.statement('SELECT')
    q = orb.Query('username') == 'bob'
    q &= orb.Query('username') == 'sally'

    sql, data = st(User, orb.Context(where=q))
    conn = pg_db.connection()
    _, count = conn.execute(sql, data)
    assert count == 0
Beispiel #4
0
def test_my_select_bob_or_sally(orb, my_sql, my_db, User):
    st = my_sql.statement('SELECT')
    q = orb.Query('username') == 'bob'
    q |= orb.Query('username') == 'sally'

    sql, data = st(User, orb.Context(where=q))
    conn = my_db.connection()
    records, count = conn.execute(sql, data)
    assert count == 2 and records[0]['username'] in ('bob', 'sally') and records[1]['username'] in ('bob', 'sally')
Beispiel #5
0
def test_pg_statement_insert_records_in_namespace(orb, User, pg_sql):
    user_a = User(username='******')
    user_b = User(username='******')

    with orb.Context(namespace='custom'):
        st = pg_sql.statement('INSERT')
        assert st is not None

        statement, data = st([user_a, user_b])
        assert 'INSERT INTO "custom"."users"' in statement
Beispiel #6
0
    def search(self, model, terms, **context):
        search_context = context.get('context') or orb.Context(**context)
        locale = search_context.locale
        nodes = self.__parser.parseString(terms)

        # separate into 2 categories general (searchable by any column) and specific (user gave a column)
        general_nodes = [
            node for node in nodes if not isinstance(node, ComparisonNode)
        ]
        comparison_nodes = [
            node for node in nodes if isinstance(node, ComparisonNode)
        ]

        # build general search column matches
        q = orb.Query()
        if general_nodes:
            expr = u'.*\s{0}'
            pattern = u'(^|.*\s){0}'.format(general_nodes[0].pattern(
                self.__thesaurus, locale))
            pattern += ''.join(
                expr.format(node.pattern(self.__thesaurus, locale))
                for node in general_nodes[1:])

            general_q = orb.Query()
            searchable_columns = model.schema().columns(
                flags=orb.Column.Flags.Searchable).values()
            if not searchable_columns:
                raise orb.errors.InvalidSearch(
                    'No searchable columns found for {0}'.format(
                        model.schema().name()))

            for column in searchable_columns:
                general_q |= orb.Query(column).asString().matches(
                    pattern, caseSensitive=False)
            q &= general_q

        # build comparison nodes
        if comparison_nodes:
            schema = model.schema()
            for node in comparison_nodes:
                column = schema.column(node[0])
                value_node = node[-1]
                value = value_node[0]
                q &= orb.Query(column) == value

        if not q.isNull():
            context['where'] = q & context.get('where')

        return model.select(**context)
Beispiel #7
0
    def execute(self,
                command,
                data=None,
                returning=True,
                mapper=dict,
                writeAccess=False,
                dryRun=False,
                locale=None):
        """
        Executes the inputted command into the current \
        connection cursor.

        :param      command    | <str>
                    data       | <dict> || None
                    autoCommit | <bool> | commit database changes immediately
                    autoClose  | <bool> | closes connections immediately
                    returning  | <bool>
                    mapper     | <variant>
                    retries    | <int>

        :return     [{<str> key: <variant>, ..}, ..], <int> rowcount
        """
        command = command.strip()

        if not command:
            raise orb.errors.EmptyCommand()
        elif dryRun:
            print command % data
            raise orb.errors.DryRun()

        # define properties for execution
        data = data or {}
        command = command.strip()
        data.setdefault('locale', locale or orb.Context().locale)
        start = datetime.datetime.now()

        try:
            with self.native() as conn:
                results, rowcount = self._execute(conn, command, data,
                                                  returning, mapper)

        # always raise interruption errors as these need to be handled
        # from a thread properly
        except orb.errors.Interruption:
            delta = datetime.datetime.now() - start
            log.critical('Query took: %s' % delta)
            raise

        # handle any known a database errors with feedback information
        except orb.errors.DatabaseError as err:
            delta = datetime.datetime.now() - start
            log.error(u'{0}: \n {1}'.format(err, command))
            log.error('Query took: %s' % delta)
            raise

        # always raise any unknown issues for the developer
        except StandardError as err:
            delta = datetime.datetime.now() - start
            log.error(u'{0}: \n {1}'.format(err, command))
            log.error('Query took: %s' % delta)
            raise

        delta = (datetime.datetime.now() - start).total_seconds()
        if delta * 1000 < 3000:
            lvl = logging.DEBUG
        elif delta * 1000 < 6000:
            lvl = logging.WARNING
        else:
            lvl = logging.CRITICAL

        log.log(lvl, 'Query took: %s' % delta)

        return results, rowcount
Beispiel #8
0
def test_pg_select_bob(orb, User, pg_sql, pg_db):
    st = pg_sql.statement('SELECT')
    sql, data = st(User, orb.Context(where=orb.Query('username') == 'bob'))
    conn = pg_db.connection()
    records, count = conn.execute(sql, data)
    assert count == 1 and records[0]['username'] == 'bob'
Beispiel #9
0
def test_pg_select_one(orb, User, pg_sql, pg_db):
    st = pg_sql.statement('SELECT')
    sql, data = st(User, orb.Context(limit=1))
    conn = pg_db.connection()
    records, count = conn.execute(sql, data)
    assert count == 1
Beispiel #10
0
def test_pg_select_all(orb, User, pg_sql, pg_db):
    st = pg_sql.statement('SELECT')
    sql, data = st(User, orb.Context())
    conn = pg_db.connection()
    records, count = conn.execute(sql, data)
    assert len(records) == count
Beispiel #11
0
def get_context(request, model=None):
    """
    Extracts ORB context information from the request.

    :param request: <pyramid.request.Request>
    :param model: <orb.Model> || None

    :return: {<str> key: <variant> value} values, <orb.Context>
    """
    # convert request parameters to python
    param_values = get_param_values(request, model=model)

    # extract the full orb context if provided
    context = param_values.pop('orb_context', {})
    if isinstance(context, (unicode, str)):
        context = projex.rest.unjsonify(context)

    # otherwise, extract the limit information
    has_limit = 'limit' in context or 'limit' in param_values

    # create the new orb context
    orb_context = orb.Context(**context)

    # build up context information from the request params
    used = set()
    query_context = {}
    for key in orb.Context.Defaults:
        if key in param_values:
            used.add(key)
            query_context[key] = param_values.get(key)

    # generate a simple query object
    schema_values = {}
    if model:
        # extract match dict items
        for key, value in request.matchdict.items():
            if model.schema().column(key, raise_=False):
                schema_values[key] = value

        # extract payload items
        for key, value in param_values.items():
            schema_object = model.schema().column(
                key, raise_=False) or model.schema().collector(key)
            if schema_object:
                value = param_values.pop(key)
                if isinstance(
                        schema_object,
                        orb.Collector) and type(value) not in (tuple, list):
                    value = [value]
                schema_values[key] = value

    # generate the base context information
    query_context['scope'] = {'request': request}

    # include any request specific scoping information
    try:
        query_context['scope'].update(request.orb_scope)
    except AttributeError:
        pass

    orb_context.update(query_context)

    # set the default limit if none is provided
    if not has_limit and orb_context.returning == 'records':
        orb_context.limit = DEFAULT_MAX_LIMIT

    return schema_values, orb_context