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
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
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
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
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))
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
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)
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 + '$'
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
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))
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))
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
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)
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))