Exemple #1
0
    def parse_multiple_query(self, param):
        tables = []
        condition = true()
        order_by = []
        group_by = []
        limit = __default_limit__
        total = None
        page = 0
        columns = []

        for k, v in param.items():
            if isinstance(v, dict):  # Schema
                c = self.parse_param(k, v)
                tables.append(c.table)
                columns.extend(c.columns)
                condition = c.condition & condition
                if c.relation is not None:
                    condition = c.relation & condition
            else:
                if k.startswith('@'):
                    if k == '@limit':
                        limit = v
                    elif k == '@page':
                        page = v
                    elif k == '@order_by':
                        if isinstance(v, (str, unicode)):
                            orders = v.split(',')
                        else:
                            orders = v
                        for c in orders:
                            if '.' in c:
                                v = c.split('.')
                                if len(v) == 3:
                                    schema_name, col_name, dir = v
                                else:
                                    schema_name, col_name = v
                                    dir = 'asc'
                            else:
                                col_name = c
                                dir = 'asc'
                            S = get_schema(schema_name)
                            col = S.get_column(col_name)
                            if dir == 'desc':
                                order_by.append(col.desc())
                            else:
                                order_by.append(col)
                    elif k == '@group_by':
                        if isinstance(v, (str, unicode)):
                            groups = v.split(',')
                        else:
                            groups = v
                        for c in groups:
                            if '.' in c:
                                schema_name, col_name = c.split('.')
                            S = get_schema(schema_name)
                            col = S.get_column(col_name)
                            group_by.append(col)
                    elif k == '@total':
                        total = v

        config = Storage({})
        config.tables = tables
        config.condition = condition
        config.columns = columns
        config.order_by = order_by
        config.group_by = group_by
        config.page = page
        config.limit = limit
        config.total = total

        return config
Exemple #2
0
    def parse_param(self, name, param):
        """
        Parse schema parameter, it'll return
        {
            condition
            columns
            limit
            order_by
            group_by
            total
            page
            table
            name #schema name
        }
        :param name: schema name
        :param param: schema query parameter
        :return: dict
        """
        S = get_schema(name)

        # prepare condition
        condition = true()
        fields = []
        columns = []
        columns_param = {}
        limit = __default_limit__
        order_by = []
        group_by = []
        total = None
        page = 0
        table = S.__table__
        relation = None

        for k, v in param.items():
            if k.startswith('@'):
                if k == '@columns':
                    fields = v[:]
                elif k == '@limit':
                    limit = v
                elif k == '@page':
                    page = v
                elif k == '@order_by':
                    if isinstance(v, (str, unicode)):
                        orders = v.split(',')
                    else:
                        orders = v
                    for c in orders:
                        if '.' in c:
                            col_name, dir = c.split('.')
                        else:
                            col_name = c
                            dir = 'asc'
                        col = S.get_column(col_name)
                        if dir == 'desc':
                            order_by.append(col.desc())
                        else:
                            order_by.append(col)
                elif k == '@group_by':
                    if isinstance(v, (str, unicode)):
                        groups = v.split(',')
                    else:
                        groups = v
                    for c in groups:
                        col = S.get_column(c)
                        group_by.append(col)
                elif k == '@total':
                    total = v
                elif k == '@relation':
                    relation_key = name, v
                    relation = get_relation_condition(relation_key)
            elif k.startswith('$'):  # condition
                c = self.parse_condition(S, k[1:], v)
                if c is not None:
                    condition = c & condition
            elif isinstance(v, dict):  # guest schema
                # todo nested schema
                # if there is not one row, it'll using left join otherwise using standalone
                # query
                nested_alias, nested_name, nested_need_list = self.parse_entry(k)
                nested_config = self.parse_param(nested_name, value)
                if nested_need_list:
                    # insert resolve function
                    pass
                else:
                    relation = name, nested_config.name
                    outerjoin_condition = get_relation_condition(relation)
                    if outerjoin_condition is None:
                        raise RelationError("Relation between {!r} can not be found".format(relation))
                    table.outerjoin(nested_config.table, outerjoin_condition)
                    condition = nested_config.condition & condition
                    columns.extend(nested_config.columns)

            else:
                # columns
                if k not in fields:
                    fields.append(k)

        columns.extend([S.get_column(x) for x in fields or S._fields_list])  # used for select

        config = Storage({})
        config.table = table
        config.condition = condition
        config.columns = columns
        config.columns_param = columns_param
        config.total = total
        config.limit = limit
        config.page = page
        config.order_by = order_by
        config.group_by = group_by
        config.name = name
        config.schema = S
        config.relation = relation

        return config