def __init__(self, op_type, installed=None, erased=None, obsoleted=None, reason=SwdbReason.UNKNOWN): self.op_type = op_type self.installed = installed self.erased = erased self.obsoleted = list() if obsoleted is None else obsoleted self.reason = convert_reason(reason) # reason for it to be in the transaction set
def beg(self, rpmdb_version, using_pkgs, tsis, cmdline=None): tid = self.swdb.trans_beg( int(time.time()), str(rpmdb_version), cmdline or "", str(misc.getloginuid()), self.releasever) self._tid = tid for pkg in using_pkgs: pid = self.pkg2pid(pkg) self.swdb.trans_with(tid, pid) if self.group: self._log_group_trans(tid) for tsi in tsis: for (pkg, state, obsoleting) in tsi._history_iterator(): pid = self.pkg2pid(pkg) self.swdb.trans_data_beg( tid, pid, convert_reason(tsi.reason), state, obsoleting) return tid
def __init__(self, op_type, installed=None, erased=None, obsoleted=None, reason=SwdbReason.UNKNOWN): self.op_type = op_type self.installed = installed self.erased = erased self.obsoleted = list() if obsoleted is None else obsoleted self.reason = convert_reason( reason) # reason for it to be in the transaction set
def beg(self, rpmdb_version, using_pkgs, tsis, cmdline=None): tid = self.swdb.trans_beg(int(time.time()), str(rpmdb_version), cmdline or "", str(misc.getloginuid()), self.releasever) self._tid = tid for pkg in using_pkgs: pid = self.pkg2pid(pkg) self.swdb.trans_with(tid, pid) if self.group: self._log_group_trans(tid) for tsi in tsis: for (pkg, state, obsoleting) in tsi._history_iterator(): pid = self.pkg2pid(pkg) self.swdb.trans_data_beg(tid, pid, convert_reason(tsi.reason), state, obsoleting) return tid
def add_install(self, new, obsoleted, reason=SwdbReason.UNKNOWN): # :api reason = convert_reason(reason) # support for string reasons tsi = TransactionItem(INSTALL, new, obsoleted=obsoleted, reason=reason) self._tsis.append(tsi)
def get_yumdb_packages(cursor, yumdb_path, repo_fn): """ Insert additional data from yumdb info SWDB """ # prepare pid to pdid dictionary cursor.execute("SELECT PD_ID, P_ID FROM PACKAGE_DATA") pid_to_pdid = {} for row in cursor: pid_to_pdid[row[1]] = row[0] # load whole yumdb into dictionary structure pkgs = {} for path, dirs, files in os.walk(yumdb_path): if dirs: continue nvra = path.split('/')[-1].partition('-')[2] yumdata = {} for yumfile in files: with open(os.path.join(path, yumfile)) as f: yumdata[yumfile] = f.read() pkgs[nvra] = yumdata PDSTRINGS = ('from_repo_timestamp', 'from_repo_revision', 'changed_by', 'installed_by') # crate PD_ID to T_ID dictionary for further use pdid_to_tid = {} cursor.execute('SELECT PD_ID, T_ID FROM TRANS_DATA') for row in cursor: pdid_to_tid[row[0]] = row[1] # get all packages from swdb cursor.execute('SELECT P_ID, name, version, release, arch FROM PACKAGE') allrows = cursor.fetchall() # insert data into rows for row in allrows: # get PDID of the package pdid = pid_to_pdid.get(row[0]) if not pdid: continue # get package key name = '-'.join(row[1:]) if name in pkgs.keys(): command = [] vals = pkgs[name] # insert data into PACKAGE_DATA table for key in PDSTRINGS: temp = vals.get(key) if temp: command.append("{}='{}'".format(key, temp)) # get repository temp = vals.get('from_repo') if temp: repo = repo_fn(cursor, temp) command.append("R_ID='{}'".format(repo)) # Update PACKAGE_DATA row if command: cmd = "UPDATE PACKAGE_DATA SET {} WHERE PD_ID={}".format(','.join(command), pdid) cursor.execute(cmd) # resolve reason temp = vals.get('reason') if temp: reason = convert_reason(temp) cursor.execute('UPDATE TRANS_DATA SET reason=? WHERE PD_ID=?', (reason, pdid)) # resolve releasever and command_line releasever = vals.get('releasever') command_line = vals.get('command_line') if releasever or command_line: tid = pdid_to_tid.get(pdid) if not tid: continue # deciding in Python is faster than running both sqlite statements if releasever and command_line: cursor.execute('UPDATE TRANS SET cmdline=?, releasever=? WHERE T_ID=?', (command_line, releasever, tid)) elif releasever: cursor.execute('UPDATE TRANS SET releasever=? WHERE T_ID=?', (releasever, tid)) else: cursor.execute('UPDATE TRANS SET cmdline=? WHERE T_ID=?', (command_line, tid))
def transformSwdb(input_dir, output_file): yumdb_path = os.path.join(input_dir, 'yumdb') history_path = os.path.join(input_dir, 'history') groups_path = os.path.join(input_dir, 'groups.json') state_dict = {} repo_dict = {} # create binding with STATE_TYPE - returns ID def bind_state(cursor, desc): code = state_dict.get(desc) if code: return code cursor.execute('SELECT state FROM STATE_TYPE WHERE description=?', (desc, )) state_id = cursor.fetchone() if state_id is None: cursor.execute('INSERT INTO STATE_TYPE VALUES(null,?)', (desc, )) cursor.execute('SELECT last_insert_rowid()') state_id = cursor.fetchone() state_dict[desc] = state_id[0] return state_id[0] # create binding with repo - returns R_ID def bind_repo(cursor, name): code = repo_dict.get(name) if code: return code cursor.execute('SELECT R_ID FROM REPO WHERE name=?', (name, )) rid = cursor.fetchone() if rid is None: cursor.execute('INSERT INTO REPO VALUES(null,?)', (name, )) cursor.execute('SELECT last_insert_rowid()') rid = cursor.fetchone() repo_dict[name] = rid[0] return rid[0] # check path to yumdb dir if not os.path.isdir(yumdb_path): logger.error(_('Error: yumdb directory not valid')) return False # check path to history dir if not os.path.isdir(history_path): logger.error(_('Error: history directory not valid')) return False # check historyDB file and pick newest one historydb_file = glob.glob(os.path.join(history_path, "history*")) if len(historydb_file) < 1: logger.error(_('Error: history database file not valid')) return False historydb_file.sort() historydb_file = historydb_file[0] if not os.path.isfile(historydb_file): logger.error(_('Error: history database file not valid')) return False tmp_output_file = output_file + '.transform' try: # initialise historyDB historyDB = sqlite3.connect(historydb_file) h_cursor = historyDB.cursor() except: logger.error(_("ERROR: unable to open the database '{}'").format(historydb_file)) return False try: # initialise output DB os.rename(output_file, tmp_output_file) database = sqlite3.connect(tmp_output_file) cursor = database.cursor() except: logger.error(_("ERROR: unable to create the database '{}'").format(tmp_output_file)) return False # value distribution in tables PACKAGE_DATA = ['P_ID', 'R_ID', 'from_repo_revision', 'from_repo_timestamp', 'installed_by', 'changed_by'] TRANS_DATA = ['T_ID', 'PD_ID', 'TG_ID', 'done', 'obsoleting', 'reason', 'state'] GROUPS = ['name_id', 'name', 'ui_name', 'installed', 'pkg_types'] ENVIRONMENTS = ['name_id', 'name', 'ui_name', 'pkg_types', 'grp_types'] logger.info(_("Transforming the software database. It may take some time.")) # contruction of PACKAGE from pkgtups h_cursor.execute('SELECT * FROM pkgtups') for row in h_cursor: record_P = [ row[0], # P_ID row[1], # name row[3], # epoch row[4], # version row[5], # release row[2] # arch ] if row[6]: checksum_type, checksum_data = row[6].split(":", 2) record_P.append(checksum_data) record_P.append(checksum_type) else: record_P += ['', ''] record_P.append(SwdbItem.RPM) # type cursor.execute('INSERT INTO PACKAGE VALUES (?,?,?,?,?,?,?,?,?)', record_P) # save changes database.commit() # construction of PACKAGE_DATA according to pkg_yumdb actualPID = 0 record_PD = [''] * len(PACKAGE_DATA) h_cursor.execute('SELECT * FROM pkg_yumdb') # for each row in pkg_yumdb for row in h_cursor: newPID = row[0] if actualPID != newPID: if actualPID != 0: record_PD[0] = actualPID # insert new record into PACKAGE_DATA PACKAGE_DATA_INSERT(cursor, record_PD) actualPID = newPID record_PD = [''] * len(PACKAGE_DATA) if row[1] in PACKAGE_DATA: # collect data for record from pkg_yumdb record_PD[PACKAGE_DATA.index(row[1])] = row[2] elif row[1] == "from_repo": # create binding with REPO table record_PD[1] = bind_repo(cursor, row[2]) record_PD[0] = actualPID PACKAGE_DATA_INSERT(cursor, record_PD) # insert last record # save changes database.commit() # prepare pid to pdid dictionary cursor.execute("SELECT PD_ID, P_ID FROM PACKAGE_DATA") pid_to_pdid = {} for row in cursor: pid_to_pdid[row[1]] = row[0] obsoleting_pkgs = [] # trans_data construction h_cursor.execute('SELECT tid, pkgtupid, done, state FROM trans_data_pkgs') for row in h_cursor: state = row[3] pid = int(row[1]) tid = int(row[0]) # handle Obsoleting packages - save it as separate attribute if state == 'Obsoleting': obsoleting_pkgs.append((tid, pid)) continue data = [''] * len(TRANS_DATA) pdid = pid_to_pdid.get(pid, 0) if not pdid: # create new entry cursor.execute("INSERT INTO PACKAGE_DATA VALUES (null,?,'','','','','')", (pid,)) cursor.execute('SELECT last_insert_rowid()') pdid = cursor.fetchone()[0] else: # use this entry and delete it from the DB del pid_to_pdid[pid] # insert trans_data record data[TRANS_DATA.index('state')] = bind_state(cursor, state) data[TRANS_DATA.index('PD_ID')] = pdid data[TRANS_DATA.index('done')] = 1 if row[2] == 'TRUE' else 0 data[0] = row[0] cursor.execute('INSERT INTO TRANS_DATA VALUES (null,?,?,?,?,?,?,?)', data) update_cmd = """UPDATE TRANS_DATA SET obsoleting=1 WHERE TD_ID IN ( SELECT TD_ID FROM PACKAGE_DATA JOIN TRANS_DATA using (PD_ID) WHERE T_ID=? and P_ID=?)""" # set flag for Obsoleting PD_IDs for keys in obsoleting_pkgs: cursor.execute(update_cmd, keys) # save changes database.commit() trans_cmd = """SELECT tid, trans_beg.timestamp, trans_end.timestamp, trans_beg.rpmdb_version, trans_end.rpmdb_version, cmdline, loginuid, null, return_code FROM trans_beg join trans_end using(tid) join trans_cmdline using(tid)""" # Construction of TRANS h_cursor.execute(trans_cmd) for row in h_cursor: # override empty releasever r = list(row) del r[7] cursor.execute("INSERT INTO TRANS VALUES (?,?,?,?,?,?,?,'',?)", r) # get releasever for transactions cursor.execute('SELECT T_ID FROM TRANS WHERE releasever=?', ('', )) missing = cursor.fetchall() for row in missing: tid = row[0] cmd = "SELECT P_ID FROM TRANS_DATA join PACKAGE_DATA using (PD_ID) WHERE T_ID=? LIMIT 1" cursor.execute(cmd, (tid,)) pids = cursor.fetchall() for pid in pids: h_cursor.execute("""SELECT yumdb_val FROM pkg_yumdb WHERE pkgtupid=? AND yumdb_key='releasever' LIMIT 1""", pid) rlsver = h_cursor.fetchone() if rlsver: cursor.execute("UPDATE TRANS SET releasever=? WHERE T_ID=?", (rlsver[0], tid)) break # collect reasons cursor.execute("""SELECT TD_ID, P_ID FROM TRANS_DATA join PACKAGE_DATA using(PD_ID) join PACKAGE using(P_ID)""") missing = cursor.fetchall() for row in missing: h_cursor.execute("""SELECT yumdb_val FROM pkg_yumdb WHERE pkgtupid=? AND yumdb_key='reason' LIMIT 1""", (row[1],)) reason = h_cursor.fetchone() if reason: t_reason = convert_reason(reason[0]) cursor.execute('UPDATE TRANS_DATA SET reason=? WHERE TD_ID=?', (t_reason, row[0])) # fetch additional data from yumdb get_yumdb_packages(cursor, yumdb_path, bind_repo) # contruction of OUTPUT h_cursor.execute('SELECT * FROM trans_script_stdout') for row in h_cursor: cursor.execute('INSERT INTO OUTPUT VALUES (null,?,?,?)', (row[1], row[2], BIND_OUTPUT(cursor, 'stdout'))) h_cursor.execute('SELECT * FROM trans_error') for row in h_cursor: cursor.execute('INSERT INTO OUTPUT VALUES (null,?,?,?)', (row[1], row[2], BIND_OUTPUT(cursor, 'stderr'))) # construction of GROUPS if os.path.isfile(groups_path): with open(groups_path) as groups_file: data = json.load(groups_file) for key in data: if key == 'GROUPS': for value in data[key]: record_G = [''] * len(GROUPS) record_G[GROUPS.index('name_id')] = value if 'name' in data[key][value]: record_G[GROUPS.index('name')] = data[key][value]['name'] record_G[GROUPS.index('pkg_types')] = data[key][value]['pkg_types'] record_G[GROUPS.index('installed')] = True if 'ui_name' in data[key][value]: record_G[GROUPS.index('ui_name')] = data[key][value]['ui_name'] cursor.execute('''INSERT INTO GROUPS VALUES (null,?,?,?,?,?)''', (record_G)) cursor.execute('SELECT last_insert_rowid()') tmp_gid = cursor.fetchone()[0] for package in data[key][value]['full_list']: ADD_GROUPS_PACKAGE(cursor, tmp_gid, package) for package in data[key][value]['pkg_exclude']: ADD_GROUPS_EXCLUDE(cursor, tmp_gid, package) for key in data: if key == 'ENVIRONMENTS': for value in data[key]: record_E = [''] * len(ENVIRONMENTS) record_E[GROUPS.index('name_id')] = value if 'name' in data[key][value]: record_G[GROUPS.index('name')] = data[key][value]['name'] record_E[ENVIRONMENTS.index('grp_types')] = data[key][value]['grp_types'] record_E[ENVIRONMENTS.index('pkg_types')] = data[key][value]['pkg_types'] if 'ui_name' in data[key][value]: record_E[ENVIRONMENTS.index('ui_name')] = data[key][value]['ui_name'] cursor.execute('''INSERT INTO ENVIRONMENTS VALUES (null,?,?,?,?,?)''', (record_E)) cursor.execute('SELECT last_insert_rowid()') tmp_eid = cursor.fetchone()[0] for package in data[key][value]['full_list']: BIND_ENV_GROUP(cursor, tmp_eid, package) for package in data[key][value]['pkg_exclude']: ADD_ENV_EXCLUDE(cursor, tmp_eid, package) # construction of TRANS_GROUP_DATA from GROUPS cursor.execute('SELECT * FROM GROUPS') tmp_groups = cursor.fetchall() for row in tmp_groups: command = [] for pattern in row[1:4]: if pattern: command.append("cmdline LIKE '%{}%'".format(pattern)) if command: cursor.execute("SELECT T_ID FROM TRANS WHERE " + " or ".join(command)) tmp_trans = cursor.fetchall() if tmp_trans: for single_trans in tmp_trans: data = (single_trans[0], row[0], row[1], row[2], row[3], row[4], row[5]) cursor.execute("INSERT INTO TRANS_GROUP_DATA VALUES(null,?,?,?,?,?,?,?)", data) # construction of TRANS_GROUP_DATA from ENVIRONMENTS cursor.execute('SELECT * FROM ENVIRONMENTS WHERE ui_name!=?', ('', )) tmp_env = cursor.fetchall() for row in tmp_env: command = [] for pattern in row[1:4]: if pattern: command.append("cmdline LIKE '%{}%'".format(pattern)) if command: cursor.execute("SELECT T_ID FROM TRANS WHERE " + " or ".join(command)) tmp_trans = cursor.fetchall() if tmp_trans: for trans in tmp_trans: cursor.execute("SELECT G_ID FROM ENVIRONMENTS_GROUPS WHERE E_ID=?", (row[0],)) tmp_groups = cursor.fetchall() for gid in tmp_groups: cursor.execute("SELECT * FROM GROUPS WHERE G_ID=?", (gid[0],)) data = cursor.fetchone() tgdata = (trans[0], data[0], data[1], data[2], data[3], data[4], data[5]) cursor.execute("INSERT INTO TRANS_GROUP_DATA VALUES(null,?,?,?,?,?,?,?)", tgdata) # create Transaction performed with package h_cursor.execute('SELECT tid, pkgtupid FROM trans_with_pkgs') for row in h_cursor: cursor.execute('INSERT INTO TRANS_WITH VALUES (null,?,?)', row) # save changes database.commit() # close connection database.close() historyDB.close() # successful os.rename(tmp_output_file, output_file) return True
def get_yumdb_packages(cursor, yumdb_path, repo_fn): """ Insert additional data from yumdb info SWDB """ # prepare pid to pdid dictionary cursor.execute("SELECT PD_ID, P_ID FROM PACKAGE_DATA") pid_to_pdid = {} for row in cursor: pid_to_pdid[row[1]] = row[0] # load whole yumdb into dictionary structure pkgs = {} for path, dirs, files in os.walk(yumdb_path): if dirs: continue nvra = path.split('/')[-1].partition('-')[2] yumdata = {} for yumfile in files: with open(os.path.join(path, yumfile)) as f: yumdata[yumfile] = f.read() pkgs[nvra] = yumdata PDSTRINGS = ('from_repo_timestamp', 'from_repo_revision', 'changed_by', 'installed_by') # crate PD_ID to T_ID dictionary for further use pdid_to_tid = {} cursor.execute('SELECT PD_ID, T_ID FROM TRANS_DATA') for row in cursor: pdid_to_tid[row[0]] = row[1] # get all packages from swdb cursor.execute('SELECT P_ID, name, version, release, arch FROM PACKAGE') allrows = cursor.fetchall() # insert data into rows for row in allrows: # get PDID of the package pdid = pid_to_pdid.get(row[0]) if not pdid: continue # get package key name = '-'.join(row[1:]) if name in pkgs.keys(): command = [] vals = pkgs[name] # insert data into PACKAGE_DATA table for key in PDSTRINGS: temp = vals.get(key) if temp: command.append("{}='{}'".format(key, temp)) # get repository temp = vals.get('from_repo') if temp: repo = repo_fn(cursor, temp) command.append("R_ID='{}'".format(repo)) # Update PACKAGE_DATA row if command: cmd = "UPDATE PACKAGE_DATA SET {} WHERE PD_ID={}".format( ','.join(command), pdid) cursor.execute(cmd) # resolve reason temp = vals.get('reason') if temp: reason = convert_reason(temp) cursor.execute('UPDATE TRANS_DATA SET reason=? WHERE PD_ID=?', (reason, pdid)) # resolve releasever and command_line releasever = vals.get('releasever') command_line = vals.get('command_line') if releasever or command_line: tid = pdid_to_tid.get(pdid) if not tid: continue # deciding in Python is faster than running both sqlite statements if releasever and command_line: cursor.execute( 'UPDATE TRANS SET cmdline=?, releasever=? WHERE T_ID=?', (command_line, releasever, tid)) elif releasever: cursor.execute( 'UPDATE TRANS SET releasever=? WHERE T_ID=?', (releasever, tid)) else: cursor.execute('UPDATE TRANS SET cmdline=? WHERE T_ID=?', (command_line, tid))
def transformSwdb(input_dir, output_file): yumdb_path = os.path.join(input_dir, 'yumdb') history_path = os.path.join(input_dir, 'history') groups_path = os.path.join(input_dir, 'groups.json') state_dict = {} repo_dict = {} # create binding with STATE_TYPE - returns ID def bind_state(cursor, desc): code = state_dict.get(desc) if code: return code cursor.execute('SELECT state FROM STATE_TYPE WHERE description=?', (desc, )) state_id = cursor.fetchone() if state_id is None: cursor.execute('INSERT INTO STATE_TYPE VALUES(null,?)', (desc, )) cursor.execute('SELECT last_insert_rowid()') state_id = cursor.fetchone() state_dict[desc] = state_id[0] return state_id[0] # create binding with repo - returns R_ID def bind_repo(cursor, name): code = repo_dict.get(name) if code: return code cursor.execute('SELECT R_ID FROM REPO WHERE name=?', (name, )) rid = cursor.fetchone() if rid is None: cursor.execute('INSERT INTO REPO VALUES(null,?)', (name, )) cursor.execute('SELECT last_insert_rowid()') rid = cursor.fetchone() repo_dict[name] = rid[0] return rid[0] # check path to yumdb dir if not os.path.isdir(yumdb_path): logger.error(_('Error: yumdb directory not valid')) return False # check path to history dir if not os.path.isdir(history_path): logger.error(_('Error: history directory not valid')) return False # check historyDB file and pick newest one historydb_file = glob.glob(os.path.join(history_path, "history*")) if len(historydb_file) < 1: logger.error(_('Error: history database file not valid')) return False historydb_file.sort() historydb_file = historydb_file[0] if not os.path.isfile(historydb_file): logger.error(_('Error: history database file not valid')) return False tmp_output_file = output_file + '.transform' try: # initialise historyDB historyDB = sqlite3.connect(historydb_file) h_cursor = historyDB.cursor() except: logger.error( _("ERROR: unable to open the database '{}'").format( historydb_file)) return False try: # initialise output DB os.rename(output_file, tmp_output_file) database = sqlite3.connect(tmp_output_file) cursor = database.cursor() except: logger.error( _("ERROR: unable to create the database '{}'").format( tmp_output_file)) return False # value distribution in tables PACKAGE_DATA = [ 'P_ID', 'R_ID', 'from_repo_revision', 'from_repo_timestamp', 'installed_by', 'changed_by' ] TRANS_DATA = [ 'T_ID', 'PD_ID', 'TG_ID', 'done', 'obsoleting', 'reason', 'state' ] GROUPS = ['name_id', 'name', 'ui_name', 'installed', 'pkg_types'] ENVIRONMENTS = ['name_id', 'name', 'ui_name', 'pkg_types', 'grp_types'] logger.info( _("Transforming the software database. It may take some time.")) # contruction of PACKAGE from pkgtups h_cursor.execute('SELECT * FROM pkgtups') for row in h_cursor: record_P = [ row[0], # P_ID row[1], # name row[3], # epoch row[4], # version row[5], # release row[2] # arch ] if row[6]: checksum_type, checksum_data = row[6].split(":", 2) record_P.append(checksum_data) record_P.append(checksum_type) else: record_P += ['', ''] record_P.append(SwdbItem.RPM) # type cursor.execute('INSERT INTO PACKAGE VALUES (?,?,?,?,?,?,?,?,?)', record_P) # save changes database.commit() # construction of PACKAGE_DATA according to pkg_yumdb actualPID = 0 record_PD = [''] * len(PACKAGE_DATA) h_cursor.execute('SELECT * FROM pkg_yumdb') # for each row in pkg_yumdb for row in h_cursor: newPID = row[0] if actualPID != newPID: if actualPID != 0: record_PD[0] = actualPID # insert new record into PACKAGE_DATA PACKAGE_DATA_INSERT(cursor, record_PD) actualPID = newPID record_PD = [''] * len(PACKAGE_DATA) if row[1] in PACKAGE_DATA: # collect data for record from pkg_yumdb record_PD[PACKAGE_DATA.index(row[1])] = row[2] elif row[1] == "from_repo": # create binding with REPO table record_PD[1] = bind_repo(cursor, row[2]) record_PD[0] = actualPID PACKAGE_DATA_INSERT(cursor, record_PD) # insert last record # save changes database.commit() # prepare pid to pdid dictionary cursor.execute("SELECT PD_ID, P_ID FROM PACKAGE_DATA") pid_to_pdid = {} for row in cursor: pid_to_pdid[row[1]] = row[0] obsoleting_pkgs = [] # trans_data construction h_cursor.execute('SELECT tid, pkgtupid, done, state FROM trans_data_pkgs') for row in h_cursor: state = row[3] pid = int(row[1]) tid = int(row[0]) # handle Obsoleting packages - save it as separate attribute if state == 'Obsoleting': obsoleting_pkgs.append((tid, pid)) continue data = [''] * len(TRANS_DATA) pdid = pid_to_pdid.get(pid, 0) if not pdid: # create new entry cursor.execute( "INSERT INTO PACKAGE_DATA VALUES (null,?,'','','','','')", (pid, )) cursor.execute('SELECT last_insert_rowid()') pdid = cursor.fetchone()[0] else: # use this entry and delete it from the DB del pid_to_pdid[pid] # insert trans_data record data[TRANS_DATA.index('state')] = bind_state(cursor, state) data[TRANS_DATA.index('PD_ID')] = pdid data[TRANS_DATA.index('done')] = 1 if row[2] == 'TRUE' else 0 data[0] = row[0] cursor.execute('INSERT INTO TRANS_DATA VALUES (null,?,?,?,?,?,?,?)', data) update_cmd = """UPDATE TRANS_DATA SET obsoleting=1 WHERE TD_ID IN ( SELECT TD_ID FROM PACKAGE_DATA JOIN TRANS_DATA using (PD_ID) WHERE T_ID=? and P_ID=?)""" # set flag for Obsoleting PD_IDs for keys in obsoleting_pkgs: cursor.execute(update_cmd, keys) # save changes database.commit() trans_cmd = """SELECT tid, trans_beg.timestamp, trans_end.timestamp, trans_beg.rpmdb_version, trans_end.rpmdb_version, cmdline, loginuid, null, return_code FROM trans_beg join trans_end using(tid) join trans_cmdline using(tid)""" # Construction of TRANS h_cursor.execute(trans_cmd) for row in h_cursor: # override empty releasever r = list(row) del r[7] cursor.execute("INSERT INTO TRANS VALUES (?,?,?,?,?,?,?,'',?)", r) # get releasever for transactions cursor.execute('SELECT T_ID FROM TRANS WHERE releasever=?', ('', )) missing = cursor.fetchall() for row in missing: tid = row[0] cmd = "SELECT P_ID FROM TRANS_DATA join PACKAGE_DATA using (PD_ID) WHERE T_ID=? LIMIT 1" cursor.execute(cmd, (tid, )) pids = cursor.fetchall() for pid in pids: h_cursor.execute( """SELECT yumdb_val FROM pkg_yumdb WHERE pkgtupid=? AND yumdb_key='releasever' LIMIT 1""", pid) rlsver = h_cursor.fetchone() if rlsver: cursor.execute("UPDATE TRANS SET releasever=? WHERE T_ID=?", (rlsver[0], tid)) break # collect reasons cursor.execute( """SELECT TD_ID, P_ID FROM TRANS_DATA join PACKAGE_DATA using(PD_ID) join PACKAGE using(P_ID)""") missing = cursor.fetchall() for row in missing: h_cursor.execute( """SELECT yumdb_val FROM pkg_yumdb WHERE pkgtupid=? AND yumdb_key='reason' LIMIT 1""", (row[1], )) reason = h_cursor.fetchone() if reason: t_reason = convert_reason(reason[0]) cursor.execute('UPDATE TRANS_DATA SET reason=? WHERE TD_ID=?', (t_reason, row[0])) # fetch additional data from yumdb get_yumdb_packages(cursor, yumdb_path, bind_repo) # contruction of OUTPUT h_cursor.execute('SELECT * FROM trans_script_stdout') for row in h_cursor: cursor.execute('INSERT INTO OUTPUT VALUES (null,?,?,?)', (row[1], row[2], BIND_OUTPUT(cursor, 'stdout'))) h_cursor.execute('SELECT * FROM trans_error') for row in h_cursor: cursor.execute('INSERT INTO OUTPUT VALUES (null,?,?,?)', (row[1], row[2], BIND_OUTPUT(cursor, 'stderr'))) # construction of GROUPS if os.path.isfile(groups_path): with open(groups_path) as groups_file: data = json.load(groups_file) for key in data: if key == 'GROUPS': for value in data[key]: record_G = [''] * len(GROUPS) record_G[GROUPS.index('name_id')] = value if 'name' in data[key][value]: record_G[GROUPS.index( 'name')] = data[key][value]['name'] record_G[GROUPS.index( 'pkg_types')] = data[key][value]['pkg_types'] record_G[GROUPS.index('installed')] = True if 'ui_name' in data[key][value]: record_G[GROUPS.index( 'ui_name')] = data[key][value]['ui_name'] cursor.execute( '''INSERT INTO GROUPS VALUES (null,?,?,?,?,?)''', (record_G)) cursor.execute('SELECT last_insert_rowid()') tmp_gid = cursor.fetchone()[0] for package in data[key][value]['full_list']: ADD_GROUPS_PACKAGE(cursor, tmp_gid, package) for package in data[key][value]['pkg_exclude']: ADD_GROUPS_EXCLUDE(cursor, tmp_gid, package) for key in data: if key == 'ENVIRONMENTS': for value in data[key]: record_E = [''] * len(ENVIRONMENTS) record_E[GROUPS.index('name_id')] = value if 'name' in data[key][value]: record_G[GROUPS.index( 'name')] = data[key][value]['name'] record_E[ENVIRONMENTS.index( 'grp_types')] = data[key][value]['grp_types'] record_E[ENVIRONMENTS.index( 'pkg_types')] = data[key][value]['pkg_types'] if 'ui_name' in data[key][value]: record_E[ENVIRONMENTS.index( 'ui_name')] = data[key][value]['ui_name'] cursor.execute( '''INSERT INTO ENVIRONMENTS VALUES (null,?,?,?,?,?)''', (record_E)) cursor.execute('SELECT last_insert_rowid()') tmp_eid = cursor.fetchone()[0] for package in data[key][value]['full_list']: BIND_ENV_GROUP(cursor, tmp_eid, package) for package in data[key][value]['pkg_exclude']: ADD_ENV_EXCLUDE(cursor, tmp_eid, package) # construction of TRANS_GROUP_DATA from GROUPS cursor.execute('SELECT * FROM GROUPS') tmp_groups = cursor.fetchall() for row in tmp_groups: command = [] for pattern in row[1:4]: if pattern: command.append("cmdline LIKE '%{}%'".format(pattern)) if command: cursor.execute("SELECT T_ID FROM TRANS WHERE " + " or ".join(command)) tmp_trans = cursor.fetchall() if tmp_trans: for single_trans in tmp_trans: data = (single_trans[0], row[0], row[1], row[2], row[3], row[4], row[5]) cursor.execute( "INSERT INTO TRANS_GROUP_DATA VALUES(null,?,?,?,?,?,?,?)", data) # construction of TRANS_GROUP_DATA from ENVIRONMENTS cursor.execute('SELECT * FROM ENVIRONMENTS WHERE ui_name!=?', ('', )) tmp_env = cursor.fetchall() for row in tmp_env: command = [] for pattern in row[1:4]: if pattern: command.append("cmdline LIKE '%{}%'".format(pattern)) if command: cursor.execute("SELECT T_ID FROM TRANS WHERE " + " or ".join(command)) tmp_trans = cursor.fetchall() if tmp_trans: for trans in tmp_trans: cursor.execute( "SELECT G_ID FROM ENVIRONMENTS_GROUPS WHERE E_ID=?", (row[0], )) tmp_groups = cursor.fetchall() for gid in tmp_groups: cursor.execute("SELECT * FROM GROUPS WHERE G_ID=?", (gid[0], )) data = cursor.fetchone() tgdata = (trans[0], data[0], data[1], data[2], data[3], data[4], data[5]) cursor.execute( "INSERT INTO TRANS_GROUP_DATA VALUES(null,?,?,?,?,?,?,?)", tgdata) # create Transaction performed with package h_cursor.execute('SELECT tid, pkgtupid FROM trans_with_pkgs') for row in h_cursor: cursor.execute('INSERT INTO TRANS_WITH VALUES (null,?,?)', row) # save changes database.commit() # close connection database.close() historyDB.close() # successful os.rename(tmp_output_file, output_file) return True