Esempio n. 1
0
    def _construct_query(self, query_chain):
        """Construct the query to be sent to de database.

        :param query_chain: iterable with the different subqueries to be constructed.
        :type query_chain: list(dict)
        :return: SQL query constructed
        :rtype: str
        """
        # here we take the query_chain and convert to a real sql sentence
        res_dict = query_chain.pop(0)

        for q in query_chain:
            if q["action"] == "_db__where":
                if res_dict["action"] == "_db__select_all":
                    res_dict.update({"action": "_db__select"})

                condition = res_dict.get("condition", "")
                if condition:
                    condition = " AND ".join([condition, q["condition"]])
                else:
                    condition = q["condition"]

                res_dict.update({"condition": condition})
            elif q["action"] == "_db__select_related":
                for model_join in q["fields"]:
                    join_const = getattr(self, q["action"]).format(**model_join)
                    res_dict["join"] += join_const

                    select = res_dict["select"][:]

                    if select == "COUNT(*)":
                        pass
                    elif select == "*":
                        select = select.replace(
                            "*",
                            "{left_table}.*, {f_formatter}".format(
                                left_table=model_join["left_table"], f_formatter=model_join["fields_formatter"]
                            ),
                        )
                        res_dict["select"] = select
                    else:
                        res_dict["select"] += ", " + model_join["fields_formatter"]

        # if we are not counting, then we can assign ordering
        operations = ["COUNT", "MAX", "MIN", "SUM", "AVG", "STDDEV"]
        if res_dict.get("select", "").split("(")[0] not in operations:
            res_dict["ordering"] = self._ordering_syntax(res_dict.get("ordering", []))
        else:
            res_dict["ordering"] = ""

        query = getattr(self, res_dict["action"]).format(**res_dict)
        query = self._query_clean(query)

        logger.debug("QUERY: {}, VALUES: {}".format(query, res_dict.get("field_values")))
        return query, res_dict.get("field_values")
Esempio n. 2
0
 async def request(self, query):
     logger.debug('QUERY: {}'.format(query))
     async with self.pool.acquire() as conn:
         async with conn.transaction():
             if isinstance(query, (tuple, list)):
                 if query[1]:
                     result = await conn.fetchrow(query[0], *query[1])
                 else:
                     result = await conn.fetchrow(query[0])
             else:
                 result = await conn.fetchrow(query)
     return result
Esempio n. 3
0
    def construct_query(self, query_chain):
        # here we take the query_chain and convert to a real sql sentence
        res_dict = query_chain.pop(0)

        for q in query_chain:
            if q['action'] == 'db__where':
                if res_dict['action'] == 'db__select_all':
                    res_dict.update({'action': 'db__select'})

                condition = res_dict.get('condition', '')
                if condition:
                    condition = ' AND '.join([condition, q['condition']])
                else:
                    condition = q['condition']

                res_dict.update({'condition': condition})
            elif q['action'] == 'db__select_related':
                for model_join in q['fields']:
                    join_const = getattr(self,
                                         q['action']).format(**model_join)
                    res_dict['join'] += join_const

                    select = res_dict['select'][:]

                    if select == 'COUNT(*)':
                        pass
                    elif select == '*':
                        select = select.replace(
                            '*', '{left_table}.*, {f_formatter}'.format(
                                left_table=model_join['left_table'],
                                f_formatter=model_join['fields_formatter'],
                            ))
                        res_dict['select'] = select
                    else:
                        res_dict[
                            'select'] += ', ' + model_join['fields_formatter']

        # if we are not counting, then we can assign ordering
        operations = ['COUNT', 'MAX', 'MIN', 'SUM', 'AVG', 'STDDEV']
        if res_dict.get('select', '').split('(')[0] not in operations:
            res_dict['ordering'] = self.ordering_syntax(
                res_dict.get('ordering', []))
        else:
            res_dict['ordering'] = ''

        query = getattr(self, res_dict['action']).format(**res_dict)
        query = self.query_clean(query)

        logger.debug('QUERY: {}, VALUES: {}'.format(
            query, res_dict.get('field_values')))
        return query, res_dict.get('field_values')
Esempio n. 4
0
 async def __anext__(self):
     if not self._cursor:
         query = self.db_manager.construct_query(self.query)
         logger.debug('QUERY: {}'.format(query))
         self._cursor = Cursor(
             self.db_manager.pool,
             query[0],
             values=query[1],
             forward=self.forward,
             stop=self.stop,
         )
     async for rec in self._cursor:
         item = self.modelconstructor(rec)
         return item
     raise StopAsyncIteration()
Esempio n. 5
0
    async def __getitem__(self, key):
        if isinstance(key, slice):
            # control the keys values
            if key.start is not None and key.start < 0:
                raise QuerysetError('Negative indices are not allowed')
            if key.stop is not None and key.stop < 0:
                raise QuerysetError('Negative indices are not allowed')
            if key.step is not None:
                raise QuerysetError('Step on Queryset is not allowed')

            # asign forward and stop to the modelmanager and return it
            self.forward = key.start
            self.stop = key.stop
            if key.start is None:
                self.forward = 0
            return self

        elif isinstance(key, int):
            # if its an int, the developer wants the object directly
            if key < 0:
                raise QuerysetError('Negative indices are not allowed')

            cursor = self._cursor
            if not cursor:
                query = self.db_manager.construct_query(self.query)
                logger.debug('QUERY: {}'.format(query))
                cursor = Cursor(
                    self.db_manager.pool,
                    query[0],
                    values=query[1],
                    forward=key,
                )

            async for res in cursor:
                item = self.modelconstructor(res)
                return item
            raise IndexError('That {} index does not exist'.format(
                self.model.__name__))

        else:
            raise TypeError("Invalid argument type.")