Пример #1
0
    def parse(self):
        sm = self.query.statement
        tok_id, tok = sm.token_next(self.begin_id)
        sql = SQLToken(tok, self.query.alias2op)
        right_table = self.right_table = sql.table
        if sql.alias:
            self.query.alias2op[sql.alias] = sql

        tok_id, tok = sm.token_next(tok_id)
        if not tok.match(tokens.Keyword, 'ON'):
            raise SQLDecodeError

        tok_id, tok = sm.token_next(tok_id)
        if isinstance(tok, Parenthesis):
            tok = tok[1]

        sql = SQLToken(tok, self.query.alias2op)
        if right_table == sql.right_table:
            self.left_table = sql.left_table
            self.left_column = sql.left_column
            self.right_column = sql.right_column
        else:
            self.left_table = sql.right_table
            self.left_column = sql.right_column
            self.right_column = sql.left_column

        self.end_id = tok_id
Пример #2
0
    def parse(self):
        tok_id, tok = self.query.statement.token_next(self.begin_id)
        if isinstance(tok, Identifier):
            self.sql_tokens.append(SQLToken(tok, self.query.alias2op))
        else:
            for atok in tok.get_identifiers():
                self.sql_tokens.append(SQLToken(atok, self.query.alias2op))

        self.end_id = tok_id
Пример #3
0
    def parse(self):
        tok_id, tok = self.query.statement.token_next(self.begin_id)

        if isinstance(tok, Comparison):
            self.sql_tokens.append(SQLToken(tok, self.query.alias2op))

        elif isinstance(tok, IdentifierList):
            for atok in tok.get_identifiers():
                self.sql_tokens.append((SQLToken(atok, self.query.alias2op)))

        else:
            raise SQLDecodeError

        self.end_id = tok_id
Пример #4
0
    def parse(self):
        sm = self.query.statement
        tok_id, tok = sm.token_next(self.begin_id)
        if not tok.match(tokens.Keyword, 'BY'):
            raise SQLDecodeError

        tok_id, tok = sm.token_next(tok_id)
        if isinstance(tok, Identifier):
            self.columns.append((SQLToken(tok[0], self.query.alias2op), SQLToken(tok, self.query.alias2op)))

        elif isinstance(tok, IdentifierList):
            for _id in tok.get_identifiers():
                self.columns.append((SQLToken(_id[0], self.query.alias2op), SQLToken(_id, self.query.alias2op)))

        self.end_id = tok_id
Пример #5
0
    def parse(self):
        db = self.db_ref
        sm = self.statement
        insert = {}

        nextid, nexttok = sm.token_next(2)
        if isinstance(nexttok, Identifier):
            collection = nexttok.get_name()
            self.left_table = collection
            auto = db['__schema__'].find_one_and_update(
                {
                    'name': collection,
                    'auto': {
                        '$exists': True
                    }
                }, {'$inc': {
                    'auto.seq': 1
                }},
                return_document=ReturnDocument.AFTER)

            if auto:
                auto_field_id = auto['auto']['seq']
                for name in auto['auto']['field_names']:
                    insert[name] = auto_field_id
            else:
                auto_field_id = None
        else:
            raise SQLDecodeError

        nextid, nexttok = sm.token_next(nextid)

        if isinstance(nexttok[1], IdentifierList):
            for an_id in nexttok[1].get_identifiers():
                sql = SQLToken(an_id, None)
                insert[sql.column] = self.params.pop(0)
        else:
            sql = SQLToken(nexttok[1], None)
            insert[sql.column] = self.params.pop(0)

        if self.params:
            raise SQLDecodeError

        result = db[collection].insert_one(insert)
        if not auto_field_id:
            auto_field_id = str(result.inserted_id)

        self._result_ref.last_row_id = auto_field_id
        logger.debug('insert id {}'.format(result.inserted_id))
Пример #6
0
 def parse(self):
     sm = self.query.statement
     self.end_id, tok = sm.token_next(self.begin_id)
     sql = SQLToken(tok, self.query.alias2op)
     self.query.left_table = sql.table
     if sql.alias:
         self.query.alias2op[sql.alias] = sql
Пример #7
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        identifier = SQLToken(
            self.token.token_prev(self._token_id)[1], self.query.alias2op)

        if identifier.table == self.left_table:
            self._field = identifier.column
        else:
            self._field = '{}.{}'.format(identifier.table, identifier.column)
Пример #8
0
    def _make_regex(self, token):
        index = SQLToken.placeholder_index(token)

        to_match = self.params[index]
        if not isinstance(to_match, str):
            raise SQLDecodeError

        to_match = to_match.replace('%', '.*')
        self._regex = '^' + to_match + '$'
Пример #9
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self._identifier = SQLToken(self.token.left, self.query.alias2op)

        if isinstance(self.token.right, Identifier):
            raise SQLDecodeError('Join using WHERE not supported')

        self._operator = OPERATOR_MAP[self.token.token_next(0)[1].value]
        index = re_index(self.token.right.value)

        self._constant = self.params[index] if index is not None else None
Пример #10
0
    def _create(self, sm):
        tok_id, tok = sm.token_next(0)
        if tok.match(tokens.Keyword, 'TABLE'):
            if '__schema__' not in self.db.collection_names(
                    include_system_collections=False):
                self.db.create_collection('__schema__')
                self.db['__schema__'].create_index('name', unique=True)
                self.db['__schema__'].create_index('auto')

            tok_id, tok = sm.token_next(tok_id)
            table = SQLToken(tok, None).table
            self.db.create_collection(table)
            logger.debug('Created table {}'.format(table))

            tok_id, tok = sm.token_next(tok_id)
            if isinstance(tok, Parenthesis):
                _filter = {'name': table}
                _set = {}
                push = {}
                update = {}

                for col in tok.value.strip('()').split(','):
                    field = col[col.find('"') + 1:col.rfind('"')]

                    if col.find('AUTOINCREMENT') != -1:
                        try:
                            push['auto.field_names']['$each'].append(field)
                        except KeyError:
                            push['auto.field_names'] = {'$each': [field]}

                        _set['auto.seq'] = 0

                    if col.find('PRIMARY KEY') != -1:
                        self.db[table].create_index(field,
                                                    unique=True,
                                                    name='__primary_key__')

                    if col.find('UNIQUE') != -1:
                        self.db[table].create_index(field, unique=True)

                if _set:
                    update['$set'] = _set
                if push:
                    update['$push'] = push
                if update:
                    self.db['__schema__'].update_one(filter=_filter,
                                                     update=update,
                                                     upsert=True)

        elif tok.match(tokens.Keyword, 'DATABASE'):
            pass
        else:
            logger.debug('Not supported {}'.format(sm))
Пример #11
0
    def _alter(self, sm):
        tok_id, tok = sm.token_next(0)
        if tok.match(tokens.Keyword, 'TABLE'):
            tok_id, tok = sm.token_next(tok_id)
            if not tok:
                logger.debug(
                    'Not implemented command not implemented for SQL {}'.
                    format(self._sql))
                return

            table = SQLToken(tok, None).table

            tok_id, tok = sm.token_next(tok_id)
            if (not tok or not tok.match(tokens.Keyword, 'ADD')):
                logger.debug(
                    'Not implemented command not implemented for SQL {}'.
                    format(self._sql))
                return

            tok_id, tok = sm.token_next(tok_id)
            if (not tok or not tok.match(tokens.Keyword, 'CONSTRAINT')):
                logger.debug(
                    'Not implemented command not implemented for SQL {}'.
                    format(self._sql))
                return

            tok_id, tok = sm.token_next(tok_id)
            if not isinstance(tok, Identifier):
                logger.debug(
                    'Not implemented command not implemented for SQL {}'.
                    format(self._sql))
                return

            constraint_name = tok.get_name()

            tok_id, tok = sm.token_next(tok_id)
            if not tok.match(tokens.Keyword, 'UNIQUE'):
                logger.debug(
                    'Not implemented command not implemented for SQL {}'.
                    format(self._sql))
                return

            tok_id, tok = sm.token_next(tok_id)
            if isinstance(tok, Parenthesis):
                index = [(field.strip(' "'), 1)
                         for field in tok.value.strip('()').split(',')]
                self.db[table].create_index(index,
                                            unique=True,
                                            name=constraint_name)
            else:
                raise NotImplementedError(
                    'Alter command not implemented for SQL {}'.format(
                        self._sql))
Пример #12
0
    def _identifier(self, tok):
        if isinstance(tok[0], Parenthesis):
            self.return_const = int(tok[0][1].value)
            return

        elif isinstance(tok[0], Function):
            if tok[0][0].value == 'COUNT':
                self.return_count = True

        else:
            sql = SQLToken(tok, self.query.alias2op)
            self.sql_tokens.append(sql)
            if sql.alias:
                self.query.alias2op[sql.alias] = sql
Пример #13
0
    def _fill_in(self, token):
        self._in = []

        # Check for nested
        if token[1].ttype == tokens.DML:
            from sql2mongo.converters import NestedInQueryConverter

            self.query.nested_query = NestedInQueryConverter(
                token, self.query, 0)
            return

        for index in SQLToken(token, self.query.alias2op):
            if index is not None:
                self._in.append(self.params[index])
            else:
                self._in.append(None)
Пример #14
0
    def parse(self):
        db_con = self.db_ref
        sm = self.statement
        kw = {}

        tok_id, tok = sm.token_next(2)
        sql_token = SQLToken(tok, None)
        collection = sql_token.table

        self.left_table = sql_token.table

        tok_id, tok = sm.token_next(tok_id)
        if tok_id and isinstance(tok, Where):
            where = WhereConverter(self, tok_id)
            kw.update(where.to_mongo())

        self.result = db_con[collection].delete_many(**kw)
        logger.debug('delete_many: {}'.format(self.result.deleted_count))