def select(self, name: str, fields: list, is_star: bool, condition, is_versioning, from_date, to_date): if not self.is_table_exists(name): return Result.Result( True, exception_for_client.DBExceptionForClient().TableNotExists( name)) elif type(self.is_fields_exist(name, fields)) is str: return Result.Result( True, exception_for_client.DBExceptionForClient().FieldNotExists( self.is_fields_exist(name, fields))) else: table_index = self.get_table_index(name) rows = [] fields = self.build_fields(fields, is_star, table_index) index = self.get_index_for_select(name, fields) if not (index) or not self.check_where_condition( condition, fields): for block in self.db.tables[table_index].iter_blocks(): for row in block.iter_rows(): if row.status == 1: if self.solve_condition(condition, row): rows.append(row) else: rows = self.get_rows_using_index(index, condition, table_index, fields) rows.sort(key=lambda x: x.index_in_file) transaction_index = 0 user = self.get_user(self.current_user_index) if user.is_transaction: self.begin_table_transaction(table_index) transaction_index = user.transactions[table_index] if is_versioning: from_date = datetime(from_date.year, from_date.month, from_date.day, from_date.hour, from_date.minute, from_date.second, from_date.millisecond) to_date = datetime(to_date.year, to_date.month, to_date.day, to_date.hour, to_date.minute, to_date.second, to_date.millisecond) rows = self.db.tables[table_index].select( fields, rows, transaction_index, from_date, to_date) else: rows = self.db.tables[table_index].select( fields, rows, transaction_index) for i in range(len(rows)): rows[i] = Row(self.dict_to_list(rows[i].fields_values_dict)) return Table(fields, rows)
def union(self, first_table: Table, second_table: Table, is_all=False) -> Table or Result.Result: if len(first_table.fields) != len(second_table.fields): return Result.Result( True, exception_for_client.DBExceptionForClient(). DifferentNumberOfColumns()) table = Table(first_table.fields, []) if is_all: for row in first_table.rows: table.rows.append(row) for row in second_table.rows: table.rows.append(row) else: for first_row in first_table.rows: is_unique = True for row in table.rows: if self.are_rows_equal([table.fields, first_row], [table.fields, row]): is_unique = False if is_unique: table.rows.append(first_row) for second_row in second_table.rows: is_unique = True for row in table.rows: if self.are_rows_equal([table.fields, second_row], [table.fields, row]): is_unique = False if is_unique: table.rows.append(second_row) return table
def get_values(self, name: str, values: list, fields=()) -> list or Result.Result: types = self.get_types(name, values, fields) if len(types) == 0: return [] for i in range(len(values)): if types[i].name == 'float': try: values[i] = float(values[i].name) except: return [] elif types[i].name == "int": try: values[i] = int(values[i].name) except: return [] elif types[i].name == "bool": if values[i].name == "False": values[i] = False elif values[i].name == "True": values[i] = True else: return [] elif types[i].name == "str": if values[i].is_str: values[i] = values[i].name else: return Result.Result( True, exception_for_client.DBExceptionForClient(). WrongFieldType(values[i].name)) else: return [] return values
def delete(self, name: str, condition): if not self.is_table_exists(name): return Result.Result( True, exception_for_client.DBExceptionForClient().TableNotExists( name)) else: table_index = self.get_table_index(name) if self.db.tables[table_index].is_locked: if not self.current_user_index == self.locked_tables[ table_index]: return Result.Result(True, "Table is locked") rows_indices = [] for block in self.db.tables[table_index].iter_blocks(): for row in block.iter_rows(): if row.status == 1: if self.solve_condition(condition, row): rows_indices.append(row.index_in_file) transaction_index = 0 user = self.get_user(self.current_user_index) if user.is_transaction: self.begin_table_transaction(table_index) transaction_index = user.transactions[table_index] self.db.tables[table_index].delete(rows_indices, transaction_index) return Result.Result(False)
def solve_expression(self, root, row) -> int or Result.Result: if root.getRootVal() == '+': value = self.solve_expression(root.getLeftChild(), row) + self.solve_expression( root.getRightChild(), row) elif root.getRootVal() == '-': value = self.solve_expression(root.getLeftChild(), row) - self.solve_expression( root.getRightChild(), row) elif root.getRootVal() == '*': value = self.solve_expression(root.getLeftChild(), row) * self.solve_expression( root.getRightChild(), row) elif root.getRootVal() == '/': value = self.solve_expression(root.getLeftChild(), row) / self.solve_expression( root.getRightChild(), row) else: try: value = float(root.getRootVal().name) except: if root.getRootVal().is_str: value = row.fields_values_dict[root.getRootVal().name] else: if root.getRootVal().name in row.fields_values_dict: value = row.fields_values_dict[root.getRootVal().name] else: return Result.Result( True, exception_for_client.DBExceptionForClient(). FieldNotExists(root.getRootVal().name)) return value
def drop_table(self, name: str) -> Result: if not self.is_table_exists(name): return Result.Result( True, exception_for_client.DBExceptionForClient().TableNotExists( name)) else: return Result.Result(False)
def update(self, name: str, fields: list, values: list, condition): if not self.is_table_exists(name): return Result.Result( True, exception_for_client.DBExceptionForClient().TableNotExists( name)) elif type(self.is_fields_exist(name, fields)) is str: return Result.Result( True, exception_for_client.DBExceptionForClient().FieldNotExists( self.is_fields_exist(name, fields))) else: table_index = self.get_table_index(name) if self.db.tables[table_index].is_locked: if not self.current_user_index == self.locked_tables[ table_index]: return Result.Result(True, "Table is locked") rows = [] new_values = [] for block in self.db.tables[table_index].iter_blocks(): for row in block.iter_rows(): if row.status == 1: if self.solve_condition(condition, row): temp = self.get_values_with_expression( name, values, row, fields) if type(temp) == Result.Result: return temp if len(temp) == 0: return Result.Result( True, exception_for_client.DBExceptionForClient( ).InvalidDataType()) new_values.append(temp) rows.append(row) for i in range(len(fields)): fields[i] = fields[i].name sorted(rows, key=lambda row: row.transaction_end) transaction_index = 0 user = self.get_user(self.current_user_index) if user.is_transaction: self.begin_table_transaction(table_index) transaction_index = user.transactions[table_index] self.db.tables[table_index].update(fields, new_values, rows, transaction_index) return Result.Result(False)
def create_table(self, name: str, fields: list = (), is_versioning: bool = False) -> Result: correct_fields = self.get_correct_fields(fields) if not (type(correct_fields) is dict): return Result.Result( True, exception_for_client.DBExceptionForClient().DuplicateFields( correct_fields)) elif self.is_table_exists(name): return Result.Result( True, exception_for_client.DBExceptionForClient().TableAlreadyExists( name)) else: self.db.create_table(name, correct_fields, is_versioning) return Result.Result(False)
def show_create_table(self, name: str) -> Result: if not self.is_table_exists(name): return Result.Result( True, exception_for_client.DBExceptionForClient().TableNotExists( name)) else: table_index = self.get_table_index(name) return Result.Result(False, self.db.tables[table_index].show_create())
def check_required_fields(left_table: Table, right_table: Table, fields: list, left_table_name: str, right_table_name: str) -> Result.Result: for field in fields: if field.type == "field": return Result.Result( True, exception_for_client.DBExceptionForClient(). NoTableSpecified(field.name)) if not (field.name_table in [left_table_name, right_table_name]): return Result.Result( True, exception_for_client.DBExceptionForClient().FieldNotExists( field.name)) if not (field.name in left_table.fields) or not ( field.name in right_table.fields): return Result.Result( True, exception_for_client.DBExceptionForClient().FieldNotExists( field.name))
def show_index(self, table_name): if not self.is_table_exists(table_name): return Result.Result( True, exception_for_client.DBExceptionForClient().TableNotExists( table_name)) str_for_print = "\n| index name | \n" for index in self.indices: if index.table_name == table_name: str_for_print += "| " + index.index_name + " | \n" return Result.Result(False, str_for_print)
def p_error(p): if p == None: pos = "Last symbol" val = "" else: pos = p.lexpos val = p.value global result result = Result.Result( True, exception_for_client.DBExceptionForClient().IncorrectSyntax(pos, val))
def drop_index(self, index_name, table_name): if not self.is_table_exists(table_name): return Result.Result( True, exception_for_client.DBExceptionForClient().TableNotExists( table_name)) elif not self.is_index_exist(index_name, table_name): return Result.Result( True, exception_for_client.DBExceptionForClient().IndexNotExists( index_name)) index_id = self.get_index(index_name, table_name) table_index = self.get_table_index(table_name) self.db.tables[table_index].delete_index(index_id) indices = [] for index in self.indices: if not (index.index_name == index_name and index.table_name == table_name): indices.append(index) self.indices = indices return Result.Result(False, "")
def end_transaction(self, user_index): user = self.pr.get_user(user_index) if not user.is_transaction: return Result.Result( True, exception_for_client.DBExceptionForClient(). TransactionNotDefined(user_index)) for table_index in user.transactions: self.pr.db.tables[table_index].end_transaction( user.transactions[table_index]) self.pr.db.tables[table_index].is_locked = False user.transactions = {} user.is_transaction = False return Result.Result(False, "")
def insert(self, name: str, fields: list, values: list): if not self.is_table_exists(name): return Result.Result( True, exception_for_client.DBExceptionForClient().TableNotExists( name)) elif type(self.is_fields_exist(name, fields)) is str: return Result.Result( True, exception_for_client.DBExceptionForClient().FieldNotExists( self.is_fields_exist(name, fields))) else: new_values = self.get_values(name, values, fields) if type(new_values) is Result.Result: return new_values if not len(new_values): return Result.Result( True, exception_for_client.DBExceptionForClient(). InvalidDataType()) table_index = self.get_table_index(name) if self.db.tables[table_index].is_locked: if not self.current_user_index == self.locked_tables[ table_index]: return Result.Result(True, "Table is locked") if len(fields) == 0: for i in range(len(values)): fields.append(self.db.tables[table_index].fields[i]) if len(new_values) != 0: transaction_index = 0 user = self.get_user(self.current_user_index) if user.is_transaction: self.begin_table_transaction(table_index) transaction_index = user.transactions[table_index] self.db.tables[table_index].insert(fields, new_values, -1, transaction_index) return Result.Result(False)
def create_index(self, index_name, table_name, fields): if not self.is_table_exists(table_name): return Result.Result( True, exception_for_client.DBExceptionForClient().TableNotExists( table_name)) elif type(self.is_fields_exist(table_name, fields)) is str: return Result.Result( True, exception_for_client.DBExceptionForClient().FieldNotExists( self.is_fields_exist(table_name, fields))) elif self.is_index_exist(index_name, table_name): return Result.Result( True, exception_for_client.DBExceptionForClient().IndexAlreadyExists( index_name)) table_index = self.get_table_index(table_name) fields_for_eng = [] for field in fields: fields_for_eng.append(field.name) index_id = self.db.tables[table_index].create_index(fields_for_eng) self.indices.append( Index(index_name, index_id, table_name, fields_for_eng)) return Result.Result(False, "")
def get_values_with_expression(self, name: str, values: list, row, fields=()) -> list or Result.Result: types = self.get_types(name, values, fields) if len(types) == 0: return [] new_values = [] for i in range(len(values)): if types[i].name == "float": try: new_values.append( float(self.solve_expression(values[i], row))) except: return [] elif types[i].name == "int": try: new_values.append( int(self.solve_expression(values[i], row))) except: return [] elif types[i].name == "bool": if self.solve_expression(values[i], row) == "False": new_values.append(False) elif self.solve_expression(values[i], row) == "True": new_values.append(True) else: return [] elif types[i].name == "str": if values[i].type == "field": if values[i].is_str: new_values.append(values[i].name) else: return Result.Result( True, exception_for_client.DBExceptionForClient(). WrongFieldType(values[i].name)) else: new_values.append(values[i].name) else: return [] return new_values