示例#1
0
    def model_limit(model, query, values):
        """
        Adds sort informaiton to the query
        """

        if model._limit is None:
            return

        if model._offset:
            query.add(limits="%s OFFSET %s")
            values.extend([model._limit, model._offset])
        else:
            query.add(limits="%s")
            values.append(model._limit)
示例#2
0
    def model_sort(model, query):
        """
        Adds sort information to the query
        """

        sort = model._sort or model._order

        if sort:
            order_bys = []
            for field in sort:
                order_bys.append(f'"{field[1:]}"' if field[0] ==
                                 "+" else f'"{field[1:]}" DESC')
            query.add(order_bys=order_bys)

        model._sort = None
    def model_retrieve(self, model, verify=True):
        """
        Executes the retrieve
        """

        model._collate()

        cursor = self.connection.cursor()

        query = copy.deepcopy(model.QUERY)
        values = []

        sort = model._sort or model._order

        if sort:
            order_bys = []
            for field in sort:
                order_bys.append(field[1:] if field[0] == "+" else f"{field[1:]} DESC")
            query.add(order_bys=order_bys)

        if model._limit is not None:
            if model._offset:
                query.add(limits="%s OFFSET %s")
                values.extend([model._limit, model._offset])
            else:
                query.add(limits="%s")
                values.append(model._limit)

        self.record_retrieve(model._record, query, values)

        cursor.execute(query.get(), values)

        if model._mode == "one" and cursor.rowcount > 1:
            raise relations.model.ModelError(model, "more than one retrieved")

        if model._mode == "one" and model._role != "child":

            if cursor.rowcount < 1:

                if verify:
                    raise relations.model.ModelError(model, "none retrieved")
                return None

            model._record = model._build("update", _read=cursor.fetchone())

        else:

            model._models = []

            while len(model._models) < cursor.rowcount:
                model._models.append(model.__class__(_read=cursor.fetchone()))

            model._record = None

        model._action = "update"

        cursor.close()

        return model
    def field_retrieve(self, field, query, values):
        """
        Adds where caluse to query
        """

        for operator, value in (field.criteria or {}).items():
            if operator == "in":
                query.add(wheres=f'"{field.store}" IN ({",".join(["%s" for each in value])})')
                values.extend(value)
            elif operator == "ne":
                query.add(wheres=f'"{field.store}" NOT IN ({",".join(["%s" for each in value])})')
                values.extend(value)
            else:
                query.add(wheres=f'"{field.store}"{self.RETRIEVE[operator]}%s')
                values.append(value)
示例#5
0
    def model_like(cls, model, query, values):
        """
        Adds like information to the query
        """

        if model._like is None:
            return

        ors = []

        for name in model._label:

            path = name.split("__", 1)
            name = path.pop(0)

            field = model._fields._names[name]

            parent = False

            for relation in model.PARENTS.values():
                if field.name == relation.child_field:
                    parent = relation.Parent.many(like=model._like).limit(
                        model._chunk)
                    if parent[relation.parent_field]:
                        ors.append(
                            f'"{field.store}" IN ({",".join(["%s" for _ in parent[relation.parent_field]])})'
                        )
                        values.extend(parent[relation.parent_field])
                        model.overflow = model.overflow or parent.overflow
                    else:
                        parent = True

            if not parent:

                paths = path if path else field.label

                if paths:

                    for path in paths:

                        if path in (field.extract or {}):

                            ors.append(
                                f'"{field.store}__{path}"::VARCHAR(255) ILIKE %s'
                            )
                            values.append(f"%{model._like}%")

                        else:

                            ors.append(
                                f'("{field.store}"#>>%s)::VARCHAR(255) ILIKE %s'
                            )
                            values.append(cls.walk(path))
                            values.append(f"%{model._like}%")

                else:

                    ors.append(f'"{field.store}"::VARCHAR(255) ILIKE %s')
                    values.append(f"%{model._like}%")

        query.add(wheres="(%s)" % " OR ".join(ors))
示例#6
0
    def field_retrieve(self, field, query, values):  # pylint: disable=too-many-branches
        """
        Adds where caluse to query
        """

        for operator, value in (field.criteria or {}).items():

            if operator not in relations.Field.OPERATORS:

                path, operator = operator.rsplit("__", 1)

                if path in (field.extract or {}):

                    store = store = f'"{field.store}__{path}"'

                else:

                    values.append(self.walk(path))

                    cast = value[0] if isinstance(value,
                                                  list) and value else value

                    if isinstance(cast, bool):
                        store = f'("{field.store}"#>>%s)::BOOLEAN'
                    elif isinstance(cast, int):
                        store = f'("{field.store}"#>>%s)::INT'
                    elif isinstance(cast, float):
                        store = f'("{field.store}"#>>%s)::FLOAT'
                    else:
                        store = f'("{field.store}"#>>%s)'

            else:

                store = f'"{field.store}"'

            if operator == "in":
                if value:
                    query.add(
                        wheres=f'{store} IN ({",".join(["%s" for _ in value])})'
                    )
                    values.extend(value)
                else:
                    query.add(wheres='FALSE')
            elif operator == "ne":
                if value:
                    query.add(
                        wheres=
                        f'{store} NOT IN ({",".join(["%s" for _ in value])})')
                    values.extend(value)
                else:
                    query.add(wheres='TRUE')
            elif operator == "like":
                query.add(wheres=f'{store}::VARCHAR(255) ILIKE %s')
                values.append(f"%{value}%")
            elif operator == "notlike":
                query.add(wheres=f'{store}::VARCHAR(255) NOT ILIKE %s')
                values.append(f"%{value}%")
            elif operator == "null":
                query.add(wheres=f"{store} {'IS' if value else 'IS NOT'} NULL")
            else:
                query.add(wheres=f'{store}{self.RETRIEVE[operator]}%s')
                values.append(value)