def open_file_by_name(self, file_name, create=True): with database_cursor(self.database) as cur: self.ui.log('Searching for file named "' + str(file_name) + '"') cmd = sql.SQL('SELECT name, id FROM {} WHERE name = %s;').format(sql.Identifier(self.database.tablify('files'))) cur.execute(cmd, (str(file_name),)) res = cur.fetchall() if res: if len(res) == 1: self.__set_file(res[0][0], res[0][1]) self.ui.log('File found with id ' + str(res[0][1])) return 0 else: # len(res) > 1 warning_str = 'Name conflict: files with ids' for r in res: warning_str = warning_str + ' ' + str(r[1]) warning_str = warning_str + ' have the same name "' + file_name + '"' self.ui.log_warning(warning_str) return 2 else: self.ui.log_warning('File not found with name "' + str(file_name) + '"') if create: file_id = self.create_file(file_name) self.ui.log_warning('Created file with id ' + str(file_id)) self.__set_file(file_name, file_id) return 1
def add_connection_by_name(self, origin_name, destination_name, origin_discrim=None, destination_discrim=None): if not self.current_file(): self.log_error('Cannot add connections when no file is open.') if origin_discrim: self.ui.log('Looking up "' + str(origin_name) + '":' + str(origin_discrim) + ' by name and discrim') else: self.ui.log('Looking up "' + str(origin_name) + '" by name') origin = self.lookup_node_by_name(origin_name, origin_discrim) if destination_discrim: self.ui.log('Looking up "' + str(destination_name) + '":' + str(destination_discrim) + ' by name and discrim') else: self.ui.log('Looking up "' + str(destination_name) + '" by name') destination = self.lookup_node_by_name(destination_name, destination_discrim) if not (origin and destination): self.ui.log_error('Could not identify nodes to connect.') return 1 with database_cursor(self.database) as cur: cmd = sql.SQL('SELECT connection_id FROM {} WHERE (first_id=%s AND second_id=%s) OR (first_id=%s AND second_id=%s);').format(sql.Identifier(self.database.tablify('connections'))) cur.execute(cmd, (origin[1],destination[1],destination[1],origin[1])) res = cur.fetchall() if res: self.ui.log_warning('Connection between "' + str(origin_name) + '" and "' + str(destination_name) + '" already exists.') return 2 self.add_connection_by_id(origin[1], destination[1]) return 0
def add_node(self, node_name): if not self.current_file(): self.ui.log_warning('Attempted to add node, but no file is open') return 1 node_id = random.randint(-1*sys.maxsize, sys.maxsize) with database_cursor(self.database) as cur: self.ui.log('Adding node named "' + node_name + '" as id ' + str(node_id) + ' with parent file id ' + str(self.file_id)) cmd = sql.SQL('INSERT INTO {}(name, id, parent_file_id) VALUES (%s,%s,%s);').format(sql.Identifier(self.database.tablify('nodes'))) cur.execute(cmd, (str(node_name), node_id, self.file_id)) self.database.commit()
def create_file(self, file_name, file_id=None): if not file_id: file_id = random.randint(-1*sys.maxsize, sys.maxsize) self.ui.log_debug('Generated id ' + str(file_id)) cmd = sql.SQL('INSERT INTO {} (name, id) VALUES (%s,%s);').format(sql.Identifier(self.database.tablify('files'))) with database_cursor(self.database) as cur: cur.execute(cmd, (str(file_name), file_id)) self.database.commit() return file_id
def add_connection_by_id(self, origin_id, destination_id): if not self.current_file(): self.log_error('Cannot add connections when no file is open.') with database_cursor(self.database) as cur: connection_id = random.randint(-1*sys.maxsize, sys.maxsize) self.ui.log('Connecting ' + str(origin_id) + ' to ' + str(destination_id) + ' with connection id ' + str(connection_id)) cmd = sql.SQL('INSERT INTO {} (first_id, second_id, connection_id, parent_file_id) VALUES (%s,%s,%s,%s);').format(sql.Identifier(self.database.tablify('connections'))) cur.execute(cmd, (origin_id,destination_id,connection_id,self.file_id)) self.database.commit() return 0
def open_file_by_id(self, file_id): with database_cursor(self.database) as cur: self.ui.log('Searching for file with id ' + str(file_id)) cmd = sql.SQL('SELECT name, id FROM {} WHERE id = %s;').format(sql.Identifier(self.database.tablify('files'))) cur.execute(cmd, (str(file_id),)) res = cur.fetchall() if res: if len(res) == 1: self.__set_file(res[0][0], res[0][1]) self.ui.log('File found with name "' + str(res[0][0]) + '"') return 0 else: self.ui.log_warning('File not found with id ' + str(file_id)) return 1 else: self.ui.log_warning('File not found with id ' + str(file_id)) return 1
def list_connections(self): file_filter = None if self.current_file(): file_filter = self.file_id else: self.ui.log('Listing all connections') with database_cursor(self.database) as cur: cmd = '' appendage = '' if file_filter: appendage = ' WHERE parent_file_id=%s' cmd = sql.SQL('SELECT first_id, second_id, connection_id FROM {}' + appendage + ';').format(sql.Identifier(self.database.tablify('connections'))) if file_filter: cur.execute(cmd, (self.file_id,)) else: cur.execute(cmd) return cur.fetchall()
def lookup_node_by_name(self, node_name, node_discrim=None): nodes = [] with database_cursor(self.database) as cur: appendage = '' if self.current_file(): appendage = ' AND parent_file_id=%s' cmd = sql.SQL('SELECT name, id FROM {} WHERE name=%s' + appendage + ';').format(sql.Identifier(self.database.tablify('nodes'))) if self.current_file(): cur.execute(cmd, (str(node_name), str(self.file_id))) else: cur.execute(cmd, (str(node_name),)) nodes = cur.fetchall() if not nodes: nodes = [] if len(nodes) == 1: return nodes[0] elif len(nodes) == 0: self.ui.log_warning('No matches found for node name "' + str(node_name) + '"') return None else: if not node_discrim: self.ui.log_warning('Multiple matches for node name " ' + str(node_name) + '", but no discrim provided.') raise name_conflict_error else: self.ui.log_debug('Attempting to resolve name conflict by name discriminator.') found = None # Check all possibilities for discrim for node in nodes: # conflicts, just in case if abs(node[1]) % 100000 == node_discrim: if found: # Discrim conflict! My paranoia is justified! self.ui.log_warning('Multiple nodes have the same name "' + str(node_name) + '" and the same discrim ' + str(node_discrim) + '!') raise name_conflict_error else: found = node if found: self.ui.log_debug('Conflict successfully resolved by name discriminator.') return found else: self.ui.log_warning('Discriminator did not match any nodes.') return None
def list_files(self): cmd = sql.SQL('SELECT name, id FROM {};').format(sql.Identifier(self.database.tablify('files'))) with database_cursor(self.database) as cur: cur.execute(cmd) return cur.fetchall()