Пример #1
0
    def _to_filter_stmt(self,
                        prefix: str = 'p',
                        relative_to: str = None) -> Stmt:

        if isinstance(self.compare_value, Var):
            return Stmt(
                f'FILTER {relative_to}.{self.attribute} {self.operator} {self.compare_value._name}{self.compare_value.attribute_return}',
                {})
        return Stmt(
            f'FILTER {relative_to}.{self.attribute} {self.operator} @{prefix} ',
            {prefix: self.compare_value})
Пример #2
0
    def _to_select_stmt(self, prefix: str, relative_to: str,
                        alias_to_result: Dict[str, Result]) -> Stmt:
        if self.field in (object, ):
            return Stmt(relative_to, {},
                        result=DOCUMENT_RESULT,
                        aliases=self.aliases,
                        alias_to_result=alias_to_result)

        return Stmt(f'''{relative_to}.{self.field}''', {},
                    result=VALUE_RESULT,
                    alias_to_result=alias_to_result,
                    aliases=self.aliases)
Пример #3
0
    def _to_group_stmt(self, prefix: str, collected: str,
                       alias_to_result: Dict[str, Result]) -> Stmt:
        if self.field in (object, ):
            return Stmt(collected, {},
                        result=ListResult(DOCUMENT_RESULT),
                        alias_to_result=alias_to_result,
                        aliases=self.aliases)

        if self.used_in_by:
            return Stmt(f'field_{self.field}', {},
                        result=VALUE_RESULT,
                        alias_to_result=alias_to_result,
                        aliases=self.aliases)

        return Stmt(f'''{collected}[*].{self.field}''', {},
                    result=ListResult(VALUE_RESULT),
                    alias_to_result=alias_to_result,
                    aliases=self.aliases)
Пример #4
0
 def _to_select_stmt(self, prefix: str, relative_to: str,
                     alias_to_result: Dict[str, Result]) -> Stmt:
     stmt = self.group._to_select_stmt(prefix,
                                       relative_to=relative_to,
                                       alias_to_result=alias_to_result)
     query_str, bind_vars = stmt.expand()
     alias_to_result.update(stmt.alias_to_result)
     return Stmt(f'''{self.func}({query_str})''',
                 bind_vars,
                 result=VALUE_RESULT,
                 alias_to_result=alias_to_result)
Пример #5
0
    def _get_traversal_stmt(self,
                            prefix: str,
                            relative_to: str = '',
                            alias_to_result: Dict[str, Result] = None):
        if not alias_to_result:
            alias_to_result = {}

        result = self._get_result(
            AnyResult([e.document_type for e in self.edge_collections]
                      ) if self.edge_collections else DOCUMENT_RESULT)
        step_stmts, bind_vars, bind_vars_index = self._get_step_stmts(
            relative_to=f'{prefix}_e',
            returns=f'{prefix}_e' + self.attribute_return,
            prefix=prefix)

        if self.outer_query:
            previous_stmt = self.outer_query._to_stmt(
                prefix=f'{prefix}_0', alias_to_result=alias_to_result)
            alias_to_result.update(previous_stmt.alias_to_result)
            previous_str, previous_vars = previous_stmt.expand_without_return()
            bind_vars.update(previous_vars)

            return Stmt(f'''
                {previous_str}
                    FOR {prefix}_v, {prefix}_e IN {self.min_depth}..{self.max_depth} {self.direction} {previous_stmt.returns}._id {traversal_edge_collection_names(self.edge_collections)}
                        {step_stmts}
                ''',
                        bind_vars,
                        returns=f'{prefix}_e' + self.attribute_return,
                        result=result,
                        aliases=self.aliases,
                        alias_to_result=alias_to_result)

        return Stmt(f'''
            FOR {prefix}_v, {prefix}_e IN {self.min_depth}..{self.max_depth} {self.direction} {relative_to}._id {traversal_edge_collection_names(self.edge_collections)}
                {step_stmts}
        ''',
                    bind_vars,
                    returns=f'{prefix}_e' + self.attribute_return,
                    result=result,
                    aliases=self.aliases)
Пример #6
0
 def _to_group_stmt(self, prefix: str, collected: str,
                    alias_to_result: Dict[str, Result]) -> Stmt:
     stmt = self.group._to_group_stmt(prefix,
                                      collected=collected,
                                      alias_to_result=alias_to_result)
     query_str, bind_vars = stmt.expand()
     alias_to_result.update(stmt.alias_to_result)
     return Stmt(f'''{self.func}({query_str})''',
                 bind_vars,
                 result=VALUE_RESULT,
                 aliases=self.aliases,
                 alias_to_result=alias_to_result)
Пример #7
0
    def _to_select_stmt(self, prefix: str, relative_to: str,
                        alias_to_result: Dict[str, Result]) -> Stmt:

        returns = f'o_{prefix}' + self.attribute_return
        step_stmts, bind_vars, bind_vars_index = self._get_step_stmts(
            returns=returns,
            relative_to=f'o_{prefix}',
            prefix=prefix,
            bind_vars_index=1)

        if self.collection:
            return Stmt(f'''
                    FOR o_{prefix} IN {self.collection.name}
                        {step_stmts}
                    ''',
                        bind_vars,
                        returns=f'o_{prefix}' + self.attribute_return,
                        result=VALUE_RESULT if self.attribute_return else
                        self.collection.document_type,
                        aliases=self.aliases)

        if self.previous:
            previous_stmt = self.previous._to_stmt(
                prefix=f'{prefix}_0', alias_to_result=alias_to_result)
            alias_to_result.update(previous_stmt.alias_to_result)
            previous_str, previous_bind_vars = previous_stmt.expand()
            bind_vars.update(previous_bind_vars)
            return Stmt(f'''
                    LET previous = ({previous_str})
                        FOR o_{prefix} IN previous
                        {step_stmts}
                    ''',
                        bind_vars,
                        returns=f'o_{prefix}{self.attribute_return}',
                        result=VALUE_RESULT if self.attribute_return else
                        self.collection.document_type,
                        aliases=self.aliases)

        raise ValueError
Пример #8
0
    def _to_stmt(self,
                 prefix: str = 'p',
                 alias_to_result: Dict[str, Result] = None) -> Stmt:
        if not alias_to_result:
            alias_to_result = {}
        returns = f'o_{prefix}' + self.attribute_return
        step_stmts, bind_vars, bind_vars_index = self._get_step_stmts(
            returns=returns,
            relative_to=f'o_{prefix}',
            prefix=prefix,
            bind_vars_index=1)

        if self.collection:
            return Stmt(f'''
            FOR o_{prefix} IN {self.collection.name}
                {step_stmts}
            ''',
                        bind_vars,
                        returns=returns,
                        result=self._get_result(self.collection.document_type),
                        aliases=self.aliases,
                        alias_to_result=alias_to_result)

        if self.previous:
            previous_stmt = self.previous._to_stmt(
                prefix=f'{prefix}_0', alias_to_result=alias_to_result)
            alias_to_result.update(previous_stmt.alias_to_result)
            previous_str, previous_bind_vars = previous_stmt.expand()
            return Stmt(f'''
            LET previous = ({previous_str})
                FOR o_{prefix} IN previous
                    {step_stmts}
            ''',
                        bind_vars,
                        returns=returns,
                        result=self._get_result(self.collection.document_type),
                        aliases=self.aliases)

        raise ValueError
Пример #9
0
    def set(self,
            from_: Union[Query, Document],
            edge_document: Union[Type, TEdge],
            to_: Union[Query, Document],
            data: Dict[str, Any] = None):
        if isinstance(from_, Document) and isinstance(to_, Document):
            return self._set_from_objects(from_, to_, edge_document, data)

        self._ensure_edge_collection(edge_document._get_collection())
        bind_vars = {}

        from_stmt = from_._to_stmt(
            prefix='from_p') if isinstance(from_, Query) else Stmt(
                f'[{{_id: @from_id}}]', bind_vars={'from_id': from_._id})
        from_str, from_bind_vars = from_stmt.expand()
        bind_vars.update(from_bind_vars)
        to_stmt = to_._to_stmt(
            prefix='to_p') if isinstance(to_, Query) else Stmt(
                f'[{{_id: @to_id}}]', bind_vars={'to_id': to_._id})
        to_str, to_bind_vars = to_stmt.expand()
        bind_vars.update(to_bind_vars)

        if isclass(edge_document):
            dict_doc = Document._dump_from_dict(data, Document.INIT_PROPERTIES)
        else:
            dict_doc = edge_document._dump()

        for key, value in dict_doc.items():
            bind_vars[f'edge_{key}'] = value

        statement = f'''
        LET from_entities = ({from_str})
        LET to_entities = ({to_str})
        FOR from_entity IN from_entities
            FOR to_entity IN to_entities
                insert {{_from: from_entity._id, _to: to_entity._id{',' if len(dict_doc) > 0 else ''} {', '.join([f'{key}: @edge_{key}' for key in dict_doc.keys()])}}} INTO {edge_document._get_collection().name}
        '''

        self.db.aql.execute(statement, bind_vars=bind_vars)
Пример #10
0
    def _to_stmt(self,
                 prefix: str = 'p',
                 alias_to_result: Dict[str, Result] = None) -> Stmt:
        if not alias_to_result:
            alias_to_result = {}

        stmt = self.query._to_stmt(prefix=f'{prefix}_0',
                                   alias_to_result=alias_to_result)
        alias_to_result.update(stmt.alias_to_result)
        previous, bind_vars = stmt.expand_without_return()

        bind_vars_index = 1
        groups_stmt = []

        result = {}
        for display_field, group_field in self.display_field_to_grouped.items(
        ):
            if isinstance(group_field,
                          Field) and group_field.field in self.by_fields:
                group_field.used_in_by = True

            group_stmt = group_field._to_select_stmt(
                prefix=f'{prefix}_{bind_vars_index}',
                relative_to=stmt.returns,
                alias_to_result=alias_to_result)
            alias_to_result.update(group_stmt.alias_to_result)
            group_str, b_vars = group_stmt.expand()

            result[display_field] = group_stmt.result

            field_bind = f'{prefix}_{bind_vars_index + 1}'
            groups_stmt.append(f'@{field_bind}: ({group_str})')
            bind_vars[field_bind] = display_field
            bind_vars.update(b_vars)
            bind_vars_index += 2

        return Stmt(f'''
        {previous}
        RETURN {{
            {f',{DELIMITER}'.join(groups_stmt)}
        }}
        ''',
                    bind_vars,
                    result=self._get_result(DictResult(result)),
                    aliases=self.aliases,
                    alias_to_result=alias_to_result)
Пример #11
0
    def _to_stmt(self,
                 prefix: str = 'p',
                 alias_to_result: Dict[str, Result] = None) -> Stmt:
        if not alias_to_result:
            alias_to_result = {}

        returns = f'array_{prefix}'
        step_stmts, bind_vars, bind_vars_index = self._get_step_stmts(
            relative_to=returns,
            returns=f'array_{prefix}' + self.attribute_return,
            prefix=prefix,
            bind_vars_index=1)

        self.inner_query.outer_query_returns = f'oqr_{prefix}'

        outer_stmt = self.outer_query._to_stmt(f'{prefix}_0',
                                               alias_to_result=alias_to_result)
        alias_to_result.update(outer_stmt.alias_to_result)
        outer_str, outer_bind_vars = outer_stmt.expand_without_return()
        bind_vars.update(outer_bind_vars)

        inner_stmt = self.inner_query._to_stmt(f'{prefix}_1',
                                               alias_to_result=alias_to_result)
        alias_to_result.update(inner_stmt.alias_to_result)
        inner_str, inner_bind_vars = inner_stmt.expand()
        bind_vars.update(inner_bind_vars)

        return Stmt(f'''
            {outer_str}
            LET oqr_{prefix} = {outer_stmt.returns}
            LET {returns} = (
                {inner_str}
            )
            {step_stmts}
        ''',
                    bind_vars=bind_vars,
                    returns=returns + self.attribute_return,
                    alias_to_result=alias_to_result,
                    aliases=self.aliases,
                    result=self._get_result(ListResult(inner_stmt.result)))
Пример #12
0
    def _to_filter_stmt(self,
                        prefix: str = 'p',
                        relative_to: str = None) -> Stmt:

        relative_to = relative_to[:-1] + 'v' if relative_to.endswith(
            'e') else relative_to
        returns = f'{prefix}_v'

        if self.outer_query:
            edge_query = self.outer_query
            filter_target_collection = f'''FILTER {" OR ".join([f"IS_SAME_COLLECTION('{t.name}', {returns})" for t in self.target_collections])}''' if self.target_collections else ''
            previous_str = ''

            if self.outer_query.outer_query:
                filter_target_collection = f'''FILTER {" OR ".join([f"IS_SAME_COLLECTION('{t.name}', {relative_to})" for t in self.target_collections])}''' if self.target_collections else ''

                step_stmts, bind_vars, bind_vars_index = self._get_step_stmts(
                    relative_to=relative_to,
                    returns=returns + self.attribute_return,
                    prefix=prefix,
                    bind_vars_index=0)

                previous_stmt = self.outer_query.outer_query._to_stmt(
                    f'{prefix}_0')
                previous_str, previous_bind_vars = previous_stmt.expand_without_return(
                )
                bind_vars.update(previous_bind_vars)
                relative_to = previous_stmt.returns

            else:
                step_stmts, bind_vars, bind_vars_index = self._get_step_stmts(
                    relative_to=returns,
                    returns=returns + self.attribute_return,
                    prefix=prefix,
                    bind_vars_index=0)

            outer_query_step_stmts, bind_vars, bind_vars_index = self.outer_query._get_step_stmts(
                relative_to=f'{prefix}_e',
                bind_vars=bind_vars,
                bind_vars_index=bind_vars_index,
                prefix=f'{prefix}',
                returns=f'{prefix}_e' + self.outer_query.attribute_return)

            return Stmt(
                f'''
            LET {prefix}_sub = (
                {previous_str}
                FOR {prefix}_v, {prefix}_e IN {self.outer_query.min_depth}..{self.outer_query.max_depth} {edge_query.direction} {relative_to}._id {",".join([e.name for e in edge_query.edge_collections]) if edge_query.edge_collections else ""}
                    {filter_target_collection}
                    {step_stmts}
                    {outer_query_step_stmts}
                    RETURN 1
            )
            FILTER LENGTH({prefix}_sub) > 0
            ''', bind_vars)

        filter_target_collection = f'''FILTER {" OR ".join([f"IS_SAME_COLLECTION('{t.name}', {relative_to})" for t in self.target_collections])}''' if self.target_collections else ''

        step_stmts, bind_vars, bind_vars_index = self._get_step_stmts(
            relative_to=relative_to,
            returns=returns + self.attribute_return,
            prefix=prefix,
            bind_vars_index=0)

        return Stmt(
            f'''
            LET {prefix}_sub = (
                {filter_target_collection}
                {step_stmts}
                RETURN 1
            )
            FILTER LENGTH({prefix}_sub) > 0
            
        ''', bind_vars)
Пример #13
0
    def _get_traversal_stmt(self,
                            prefix: str,
                            relative_to: str,
                            alias_to_result: Dict[str, Result] = None):
        if self.outer_query_returns:
            relative_to = self.outer_query_returns

        if not alias_to_result:
            alias_to_result = {}

        returns = f'{prefix}_v'
        result = self._get_result(
            AnyResult([t.document_type for t in self.target_collections])
            if len(self.target_collections) > 0 else DOCUMENT_RESULT)

        step_stmts, bind_vars, bind_vars_index = self._get_step_stmts(
            relative_to=returns,
            returns=returns + self.attribute_return,
            prefix=prefix,
            bind_vars_index=1)

        filter_target_collection = f'''FILTER {" OR ".join([f"IS_SAME_COLLECTION('{t.name}', {returns})" for t in self.target_collections])}''' if self.target_collections else ''

        if self.outer_query:

            edge_query = self.outer_query

            previous_str = ''

            outer_query_step_stmts, bind_vars, bind_vars_index = self.outer_query._get_step_stmts(
                relative_to=f'{prefix}_e',
                bind_vars=bind_vars,
                bind_vars_index=bind_vars_index,
                prefix=f'{prefix}',
                returns=f'{prefix}_e' + self.outer_query.attribute_return)

            if self.outer_query.outer_query:
                previous_stmt = self.outer_query.outer_query._to_stmt(
                    f'{prefix}_0', alias_to_result=alias_to_result)
                alias_to_result.update(previous_stmt.alias_to_result)
                previous_str, previous_bind_vars = previous_stmt.expand_without_return(
                )
                bind_vars.update(previous_bind_vars)
                relative_to = previous_stmt.returns

            return Stmt(f'''
            {previous_str}
            FOR {prefix}_v, {prefix}_e IN {self.outer_query.min_depth}..{self.outer_query.max_depth} {edge_query.direction} {relative_to}._id {",".join([e.name for e in edge_query.edge_collections]) if edge_query.edge_collections else ""}
                {filter_target_collection}
                {step_stmts}
                {outer_query_step_stmts}
            ''',
                        bind_vars,
                        alias_to_result=alias_to_result,
                        returns=returns + self.attribute_return,
                        result=result,
                        aliases=self.aliases)

        return Stmt(f'''
            {filter_target_collection}
            {step_stmts}
        ''',
                    bind_vars,
                    alias_to_result=alias_to_result,
                    result=result,
                    returns=returns + self.attribute_return,
                    aliases=self.aliases)
Пример #14
0
    def _to_stmt(self,
                 prefix: str = 'p',
                 alias_to_result: Dict[str, Result] = None) -> Stmt:
        if not alias_to_result:
            alias_to_result = {}

        if len(self.by_fields) == 0:
            self.by_fields = ['_key']

        stmt = self.query._to_stmt(f'{prefix}_0', alias_to_result)

        alias_to_result.update(stmt.alias_to_result)
        previous, bind_vars = stmt.expand_without_return()
        previous_result = stmt.returns

        by_fields_stmt = []

        for by_field in self.by_fields:
            if isinstance(by_field, str):
                by_fields_stmt.append(
                    f'field_{by_field} = {previous_result}.{by_field}')
            elif isinstance(by_field, Var):
                by_fields_stmt.append(
                    f'field_{by_field._name} = {by_field.attribute_return}')
            else:
                raise TypeError

        bind_vars_index = 1
        groups_stmt = []

        result = {}
        for display_field, group_field in self.display_field_to_grouped.items(
        ):
            print(display_field, group_field)

            if isinstance(group_field,
                          Field) and group_field.field in self.by_fields:
                group_field.used_in_by = True

            group_stmt = group_field._to_group_stmt(
                prefix=f'{prefix}_{bind_vars_index}',
                collected='groups',
                alias_to_result=alias_to_result)
            alias_to_result.update(alias_to_result)
            group_str, b_vars = group_stmt.expand()
            result[display_field] = group_stmt.result

            field_bind = f'{prefix}_{bind_vars_index + 1}'
            groups_stmt.append(f'@{field_bind}: ({group_str})')
            bind_vars[field_bind] = display_field
            bind_vars.update(b_vars)
            bind_vars_index += 2

        return Stmt(f'''
        {previous}
        COLLECT {', '.join(by_fields_stmt)} INTO groups = {previous_result}
        RETURN {{
            {f',{DELIMITER}'.join(groups_stmt)}
        }}
        ''',
                    bind_vars,
                    result=self._get_result(DictResult(result)),
                    aliases=self.aliases)
Пример #15
0
 def _to_select_stmt(self,
                     prefix: str,
                     alias_to_result: Dict[str, Result],
                     relative_to: str = '') -> Stmt:
     return Stmt(f'''{self._name}{self.attribute_return}''', {},
                 result=self._get_result(alias_to_result[self._name]))
Пример #16
0
 def _to_group_stmt(self,
                    prefix: str,
                    alias_to_result: Dict[str, Result],
                    collected: str = 'groups') -> Stmt:
     return Stmt(f'''{self._name}{self.attribute_return}''', {},
                 result=self._get_result(alias_to_result[self._name]))