self.text.setReadOnly(True) self.text.setOpenExternalLinks(True) self.setCentralWidget(self.text) # PostqreSQL server version def PostqreSQLServerVersion(db): query = QSqlQuery(db) QueryExec(query, "SELECT VERSION()") if query.next(): v_str = query.value(0) v_list = v_str.strip().split(" ") if v_list[0] == "PostgreSQL" and v_list[2] == "on": return v_list[1] return v_str return "Unknown" # SQLite version def SQLiteVersion(db): query = QSqlQuery(db) QueryExec(query, "SELECT sqlite_version()") if query.next(): return query.value(0) return "Unknown" # About dialog class AboutDialog(QDialog): def __init__(self, glb, parent=None): super(AboutDialog, self).__init__(parent) self.setWindowTitle("About Exported SQL Viewer") self.setMinimumWidth(300) pyside_version = "1" if pyside_version_1 else "2" text = "<pre>" text += "Python version: " + sys.version.split(" ")[0] + "\n" text += "PySide version: " + pyside_version + "\n" text += "Qt version: " + qVersion() + "\n" if glb.dbref.is_sqlite3: text += "SQLite version: " + SQLiteVersion(glb.db) + "\n" else: text += "PostqreSQL version: " + PostqreSQLServerVersion(glb.db) + "\n" text += "</pre>" self.text = QTextBrowser() self.text.setHtml(text) self.text.setReadOnly(True) self.text.setOpenExternalLinks(True) self.vbox = QVBoxLayout() self.vbox.addWidget(self.text) self.setLayout(self.vbox) # Font resize def ResizeFont(widget, diff): font = widget.font() sz = font.pointSize() font.setPointSize(sz + diff) widget.setFont(font) def ShrinkFont(widget): ResizeFont(widget, -1) def EnlargeFont(widget): ResizeFont(widget, 1) # Unique name for sub-windows def NumberedWindowName(name, nr): if nr > 1: name += " <" + str(nr) + ">" return name def UniqueSubWindowName(mdi_area, name): nr = 1 while True: unique_name = NumberedWindowName(name, nr) ok = True for sub_window in mdi_area.subWindowList(): if sub_window.name == unique_name: ok = False break if ok: return unique_name nr += 1 # Add a sub-window def AddSubWindow(mdi_area, sub_window, name): unique_name = UniqueSubWindowName(mdi_area, name) sub_window.setMinimumSize(200, 100) sub_window.resize(800, 600) sub_window.setWindowTitle(unique_name) sub_window.setAttribute(Qt.WA_DeleteOnClose) sub_window.setWindowIcon(sub_window.style().standardIcon(QStyle.SP_FileIcon)) sub_window.name = unique_name mdi_area.addSubWindow(sub_window) sub_window.show() # Main window class MainWindow(QMainWindow): def __init__(self, glb, parent=None): super(MainWindow, self).__init__(parent) self.glb = glb self.setWindowTitle("Exported SQL Viewer: " + glb.dbname) self.setWindowIcon(self.style().standardIcon(QStyle.SP_ComputerIcon)) self.setMinimumSize(200, 100) self.mdi_area = QMdiArea() self.mdi_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.mdi_area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.setCentralWidget(self.mdi_area) menu = self.menuBar() file_menu = menu.addMenu("&File") file_menu.addAction(CreateExitAction(glb.app, self)) edit_menu = menu.addMenu("&Edit") edit_menu.addAction(CreateAction("&Copy", "Copy to clipboard", self.CopyToClipboard, self, QKeySequence.Copy)) edit_menu.addAction(CreateAction("Copy as CS&V", "Copy to clipboard as CSV", self.CopyToClipboardCSV, self)) edit_menu.addAction(CreateAction("&Find...", "Find items", self.Find, self, QKeySequence.Find)) edit_menu.addAction(CreateAction("Fetch &more records...", "Fetch more records", self.FetchMoreRecords, self, [QKeySequence(Qt.Key_F8)])) edit_menu.addAction(CreateAction("&Shrink Font", "Make text smaller", self.ShrinkFont, self, [QKeySequence("Ctrl+-")])) edit_menu.addAction(CreateAction("&Enlarge Font", "Make text bigger", self.EnlargeFont, self, [QKeySequence("Ctrl++")])) reports_menu = menu.addMenu("&Reports") if IsSelectable(glb.db, "calls"): reports_menu.addAction(CreateAction("Context-Sensitive Call &Graph", "Create a new window containing a context-sensitive call graph", self.NewCallGraph, self)) if IsSelectable(glb.db, "calls", "WHERE parent_id >= 0"): reports_menu.addAction(CreateAction("Call &Tree", "Create a new window containing a call tree", self.NewCallTree, self)) self.EventMenu(GetEventList(glb.db), reports_menu) if IsSelectable(glb.db, "calls"): reports_menu.addAction(CreateAction("&Top calls by elapsed time", "Create a new window displaying top calls by elapsed time", self.NewTopCalls, self)) if IsSelectable(glb.db, "context_switches"): charts_menu = menu.addMenu("&Charts") charts_menu.addAction(CreateAction("&Time chart by CPU", "Create a new window displaying time charts by CPU", self.TimeChartByCPU, self)) self.TableMenu(GetTableList(glb), menu) self.window_menu = WindowMenu(self.mdi_area, menu) help_menu = menu.addMenu("&Help") help_menu.addAction(CreateAction("&Exported SQL Viewer Help", "Helpful information", self.Help, self, QKeySequence.HelpContents)) help_menu.addAction(CreateAction("&About Exported SQL Viewer", "About this application", self.About, self)) def Try(self, fn): win = self.mdi_area.activeSubWindow() if win: try: fn(win.view) except: pass def CopyToClipboard(self): self.Try(CopyCellsToClipboardHdr) def CopyToClipboardCSV(self): self.Try(CopyCellsToClipboardCSV) def Find(self): win = self.mdi_area.activeSubWindow() if win: try: win.find_bar.Activate() except: pass def FetchMoreRecords(self): win = self.mdi_area.activeSubWindow() if win: try: win.fetch_bar.Activate() except: pass def ShrinkFont(self): self.Try(ShrinkFont) def EnlargeFont(self): self.Try(EnlargeFont) def EventMenu(self, events, reports_menu): branches_events = 0 for event in events: event = event.split(":")[0] if event == "branches": branches_events += 1 dbid = 0 for event in events: dbid += 1 event = event.split(":")[0] if event == "branches": label = "All branches" if branches_events == 1 else "All branches " + "(id=" + dbid + ")" reports_menu.addAction(CreateAction(label, "Create a new window displaying branch events", lambda a=None,x=dbid: self.NewBranchView(x), self)) label = "Selected branches" if branches_events == 1 else "Selected branches " + "(id=" + dbid + ")" reports_menu.addAction(CreateAction(label, "Create a new window displaying branch events", lambda a=None,x=dbid: self.NewSelectedBranchView(x), self)) def TimeChartByCPU(self): TimeChartByCPUWindow(self.glb, self) def TableMenu(self, tables, menu): table_menu = menu.addMenu("&Tables") for table in tables: table_menu.addAction(CreateAction(table, "Create a new window containing a table view", lambda a=None,t=table: self.NewTableView(t), self)) def NewCallGraph(self): CallGraphWindow(self.glb, self) def NewCallTree(self): CallTreeWindow(self.glb, self) def NewTopCalls(self): dialog = TopCallsDialog(self.glb, self) ret = dialog.exec_() if ret: TopCallsWindow(self.glb, dialog.report_vars, self) def NewBranchView(self, event_id): BranchWindow(self.glb, event_id, ReportVars(), self) def NewSelectedBranchView(self, event_id): dialog = SelectedBranchDialog(self.glb, self) ret = dialog.exec_() if ret: BranchWindow(self.glb, event_id, dialog.report_vars, self) def NewTableView(self, table_name): TableWindow(self.glb, table_name, self) def Help(self): HelpWindow(self.glb, self) def About(self): dialog = AboutDialog(self.glb, self) dialog.exec_() def TryOpen(file_name): try: return open(file_name, "rb") except: return None def Is64Bit(f): result = sizeof(c_void_p) # ELF support only pos = f.tell() f.seek(0) header = f.read(7) f.seek(pos) magic = header[0:4] if sys.version_info[0] == 2: eclass = ord(header[4]) encoding = ord(header[5]) version = ord(header[6]) else: eclass = header[4] encoding = header[5] version = header[6] if magic == chr(127) + "ELF" and eclass > 0 and eclass < 3 and encoding > 0 and encoding < 3 and version == 1: result = True if eclass == 2 else False return result # Global data class Glb(): def __init__(self, dbref, db, dbname): self.dbref = dbref self.db = db self.dbname = dbname self.home_dir = os.path.expanduser("~") self.buildid_dir = os.getenv("PERF_BUILDID_DIR") if self.buildid_dir: self.buildid_dir += "/.build-id/" else: self.buildid_dir = self.home_dir + "/.debug/.build-id/" self.app = None self.mainwindow = None self.instances_to_shutdown_on_exit = weakref.WeakSet() try: self.disassembler = LibXED() self.have_disassembler = True except: self.have_disassembler = False self.host_machine_id = 0 self.host_start_time = 0 self.host_finish_time = 0 def FileFromBuildId(self, build_id): file_name = self.buildid_dir + build_id[0:2] + "/" + build_id[2:] + "/elf" return TryOpen(file_name) def FileFromNamesAndBuildId(self, short_name, long_name, build_id): # Assume current machine i.e. no support for virtualization if short_name[0:7] == "[kernel" and os.path.basename(long_name) == "kcore": file_name = os.getenv("PERF_KCORE") f = TryOpen(file_name) if file_name else None if f: return f # For now, no special handling if long_name is /proc/kcore f = TryOpen(long_name) if f: return f f = self.FileFromBuildId(build_id) if f: return f return None def AddInstanceToShutdownOnExit(self, instance): self.instances_to_shutdown_on_exit.add(instance) # Shutdown any background processes or threads def ShutdownInstances(self): for x in self.instances_to_shutdown_on_exit: try: x.Shutdown() except: pass def GetHostMachineId(self): query = QSqlQuery(self.db) QueryExec(query, "SELECT id FROM machines WHERE pid = -1") if query.next(): self.host_machine_id = query.value(0) else: self.host_machine_id = 0 return self.host_machine_id def HostMachineId(self): if self.host_machine_id: return self.host_machine_id return self.GetHostMachineId() def SelectValue(self, sql): query = QSqlQuery(self.db) try: QueryExec(query, sql) except: return None if query.next(): return Decimal(query.value(0)) return None def SwitchesMinTime(self, machine_id): return self.SelectValue("SELECT time" " FROM context_switches" " WHERE time != 0 AND machine_id = " + str(machine_id) + " ORDER BY id LIMIT 1") def SwitchesMaxTime(self, machine_id): return self.SelectValue("SELECT time" " FROM context_switches" " WHERE time != 0 AND machine_id = " + str(machine_id) + " ORDER BY id DESC LIMIT 1") def SamplesMinTime(self, machine_id): return self.SelectValue("SELECT time" " FROM samples" " WHERE time != 0 AND machine_id = " + str(machine_id) + " ORDER BY id LIMIT 1") def SamplesMaxTime(self, machine_id): return self.SelectValue("SELECT time" " FROM samples" " WHERE time != 0 AND machine_id = " + str(machine_id) + " ORDER BY id DESC LIMIT 1") def CallsMinTime(self, machine_id): return self.SelectValue("SELECT calls.call_time" " FROM calls" " INNER JOIN threads ON threads.thread_id = calls.thread_id" " WHERE calls.call_time != 0 AND threads.machine_id = " + str(machine_id) + " ORDER BY calls.id LIMIT 1") def CallsMaxTime(self, machine_id): return self.SelectValue("SELECT calls.return_time" " FROM calls" " INNER JOIN threads ON threads.thread_id = calls.thread_id" " WHERE calls.return_time != 0 AND threads.machine_id = " + str(machine_id) + " ORDER BY calls.return_time DESC LIMIT 1") def GetStartTime(self, machine_id): t0 = self.SwitchesMinTime(machine_id) t1 = self.SamplesMinTime(machine_id) t2 = self.CallsMinTime(machine_id) if t0 is None or (not(t1 is None) and t1 < t0): t0 = t1 if t0 is None or (not(t2 is None) and t2 < t0): t0 = t2 return t0 def GetFinishTime(self, machine_id): t0 = self.SwitchesMaxTime(machine_id) t1 = self.SamplesMaxTime(machine_id) t2 = self.CallsMaxTime(machine_id) if t0 is None or (not(t1 is None) and t1 > t0): t0 = t1 if t0 is None or (not(t2 is None) and t2 > t0): t0 = t2 return t0 def HostStartTime(self): if self.host_start_time: return self.host_start_time self.host_start_time = self.GetStartTime(self.HostMachineId()) return self.host_start_time def HostFinishTime(self): if self.host_finish_time: return self.host_finish_time self.host_finish_time = self.GetFinishTime(self.HostMachineId()) return self.host_finish_time def StartTime(self, machine_id): if machine_id == self.HostMachineId(): return self.HostStartTime() return self.GetStartTime(machine_id) def FinishTime(self, machine_id): if machine_id == self.HostMachineId(): return self.HostFinishTime() return self.GetFinishTime(machine_id) # Database reference class DBRef(): def __init__(self, is_sqlite3, dbname): self.is_sqlite3 = is_sqlite3 self.dbname = dbname self.TRUE = "TRUE" self.FALSE = "FALSE" # SQLite prior to version 3.23 does not support TRUE and FALSE if self.is_sqlite3: self.TRUE = "1" self.FALSE = "0" def Open(self, connection_name): dbname = self.dbname if self.is_sqlite3: db = QSqlDatabase.addDatabase("QSQLITE", connection_name) else: db = QSqlDatabase.addDatabase("QPSQL", connection_name) opts = dbname.split() for opt in opts: if "=" in opt: opt = opt.split("=") if opt[0] == "hostname": db.setHostName(opt[1]) elif opt[0] == "port": db.setPort(int(opt[1])) elif opt[0] == "username": db.setUserName(opt[1]) elif opt[0] == "password": db.setPassword(opt[1]) elif opt[0] == "dbname": dbname = opt[1] else: dbname = opt db.setDatabaseName(dbname) if not db.open(): raise Exception("Failed to open database " + dbname + " error: " + db.lastError().text()) return db, dbname # Main def Main(): usage_str = "exported-sql-viewer.py [--pyside-version-1] <database name>\n" \ " or: exported-sql-viewer.py --help-only" ap = argparse.ArgumentParser(usage = usage_str, add_help = False) ap.add_argument("--pyside-version-1", action='store_true') ap.add_argument("dbname", nargs="?") ap.add_argument("--help-only", action='store_true') args = ap.parse_args() if args.help_only: app = QApplication(sys.argv) mainwindow = HelpOnlyWindow() mainwindow.show() err = app.exec_() sys.exit(err) Lines 4501–5000 of 5030. Previous lines Load more
self.text.setReadOnly(True) self.text.setOpenExternalLinks(True) self.setCentralWidget(self.text) # PostqreSQL server version def PostqreSQLServerVersion(db): query = QSqlQuery(db) QueryExec(query, "SELECT VERSION()") if query.next(): v_str = query.value(0) v_list = v_str.strip().split(" ") if v_list[0] == "PostgreSQL" and v_list[2] == "on": return v_list[1] return v_str return "Unknown" # SQLite version def SQLiteVersion(db): query = QSqlQuery(db) QueryExec(query, "SELECT sqlite_version()") if query.next(): return query.value(0) return "Unknown" # About dialog class AboutDialog(QDialog): def __init__(self, glb, parent=None): super(AboutDialog, self).__init__(parent) self.setWindowTitle("About Exported SQL Viewer") self.setMinimumWidth(300) pyside_version = "1" if pyside_version_1 else "2" text = "<pre>" text += "Python version: " + sys.version.split(" ")[0] + "\n" text += "PySide version: " + pyside_version + "\n" text += "Qt version: " + qVersion() + "\n" if glb.dbref.is_sqlite3: text += "SQLite version: " + SQLiteVersion(glb.db) + "\n" else: text += "PostqreSQL version: " + PostqreSQLServerVersion(glb.db) + "\n" text += "</pre>" self.text = QTextBrowser() self.text.setHtml(text) self.text.setReadOnly(True) self.text.setOpenExternalLinks(True) self.vbox = QVBoxLayout() self.vbox.addWidget(self.text) self.setLayout(self.vbox) # Font resize def ResizeFont(widget, diff): font = widget.font() sz = font.pointSize() font.setPointSize(sz + diff) widget.setFont(font) def ShrinkFont(widget): ResizeFont(widget, -1) def EnlargeFont(widget): ResizeFont(widget, 1) # Unique name for sub-windows def NumberedWindowName(name, nr): if nr > 1: name += " <" + str(nr) + ">" return name def UniqueSubWindowName(mdi_area, name): nr = 1 while True: unique_name = NumberedWindowName(name, nr) ok = True for sub_window in mdi_area.subWindowList(): if sub_window.name == unique_name: ok = False break if ok: return unique_name nr += 1 # Add a sub-window def AddSubWindow(mdi_area, sub_window, name): unique_name = UniqueSubWindowName(mdi_area, name) sub_window.setMinimumSize(200, 100) sub_window.resize(800, 600) sub_window.setWindowTitle(unique_name) sub_window.setAttribute(Qt.WA_DeleteOnClose) sub_window.setWindowIcon(sub_window.style().standardIcon(QStyle.SP_FileIcon)) sub_window.name = unique_name mdi_area.addSubWindow(sub_window) sub_window.show() # Main window class MainWindow(QMainWindow): def __init__(self, glb, parent=None): super(MainWindow, self).__init__(parent) self.glb = glb self.setWindowTitle("Exported SQL Viewer: " + glb.dbname) self.setWindowIcon(self.style().standardIcon(QStyle.SP_ComputerIcon)) self.setMinimumSize(200, 100) self.mdi_area = QMdiArea() self.mdi_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.mdi_area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.setCentralWidget(self.mdi_area) menu = self.menuBar() file_menu = menu.addMenu("&File") file_menu.addAction(CreateExitAction(glb.app, self)) edit_menu = menu.addMenu("&Edit") edit_menu.addAction(CreateAction("&Copy", "Copy to clipboard", self.CopyToClipboard, self, QKeySequence.Copy)) edit_menu.addAction(CreateAction("Copy as CS&V", "Copy to clipboard as CSV", self.CopyToClipboardCSV, self)) edit_menu.addAction(CreateAction("&Find...", "Find items", self.Find, self, QKeySequence.Find)) edit_menu.addAction(CreateAction("Fetch &more records...", "Fetch more records", self.FetchMoreRecords, self, [QKeySequence(Qt.Key_F8)])) edit_menu.addAction(CreateAction("&Shrink Font", "Make text smaller", self.ShrinkFont, self, [QKeySequence("Ctrl+-")])) edit_menu.addAction(CreateAction("&Enlarge Font", "Make text bigger", self.EnlargeFont, self, [QKeySequence("Ctrl++")])) reports_menu = menu.addMenu("&Reports") if IsSelectable(glb.db, "calls"): reports_menu.addAction(CreateAction("Context-Sensitive Call &Graph", "Create a new window containing a context-sensitive call graph", self.NewCallGraph, self)) if IsSelectable(glb.db, "calls", "WHERE parent_id >= 0"): reports_menu.addAction(CreateAction("Call &Tree", "Create a new window containing a call tree", self.NewCallTree, self)) self.EventMenu(GetEventList(glb.db), reports_menu) if IsSelectable(glb.db, "calls"): reports_menu.addAction(CreateAction("&Top calls by elapsed time", "Create a new window displaying top calls by elapsed time", self.NewTopCalls, self)) if IsSelectable(glb.db, "context_switches"): charts_menu = menu.addMenu("&Charts") charts_menu.addAction(CreateAction("&Time chart by CPU", "Create a new window displaying time charts by CPU", self.TimeChartByCPU, self)) self.TableMenu(GetTableList(glb), menu) self.window_menu = WindowMenu(self.mdi_area, menu) help_menu = menu.addMenu("&Help") help_menu.addAction(CreateAction("&Exported SQL Viewer Help", "Helpful information", self.Help, self, QKeySequence.HelpContents)) help_menu.addAction(CreateAction("&About Exported SQL Viewer", "About this application", self.About, self)) def Try(self, fn): win = self.mdi_area.activeSubWindow() if win: try: fn(win.view) except: pass def CopyToClipboard(self): self.Try(CopyCellsToClipboardHdr) def CopyToClipboardCSV(self): self.Try(CopyCellsToClipboardCSV) def Find(self): win = self.mdi_area.activeSubWindow() if win: try: win.find_bar.Activate() except: pass def FetchMoreRecords(self): win = self.mdi_area.activeSubWindow() if win: try: win.fetch_bar.Activate() except: pass def ShrinkFont(self): self.Try(ShrinkFont) def EnlargeFont(self): self.Try(EnlargeFont) def EventMenu(self, events, reports_menu): branches_events = 0 for event in events: event = event.split(":")[0] if event == "branches": branches_events += 1 dbid = 0 for event in events: dbid += 1 event = event.split(":")[0] if event == "branches": label = "All branches" if branches_events == 1 else "All branches " + "(id=" + dbid + ")" reports_menu.addAction(CreateAction(label, "Create a new window displaying branch events", lambda a=None,x=dbid: self.NewBranchView(x), self)) label = "Selected branches" if branches_events == 1 else "Selected branches " + "(id=" + dbid + ")" reports_menu.addAction(CreateAction(label, "Create a new window displaying branch events", lambda a=None,x=dbid: self.NewSelectedBranchView(x), self)) def TimeChartByCPU(self): TimeChartByCPUWindow(self.glb, self) def TableMenu(self, tables, menu): table_menu = menu.addMenu("&Tables") for table in tables: table_menu.addAction(CreateAction(table, "Create a new window containing a table view", lambda a=None,t=table: self.NewTableView(t), self)) def NewCallGraph(self): CallGraphWindow(self.glb, self) def NewCallTree(self): CallTreeWindow(self.glb, self) def NewTopCalls(self): dialog = TopCallsDialog(self.glb, self) ret = dialog.exec_() if ret: TopCallsWindow(self.glb, dialog.report_vars, self) def NewBranchView(self, event_id): BranchWindow(self.glb, event_id, ReportVars(), self) def NewSelectedBranchView(self, event_id): dialog = SelectedBranchDialog(self.glb, self) ret = dialog.exec_() if ret: BranchWindow(self.glb, event_id, dialog.report_vars, self) def NewTableView(self, table_name): TableWindow(self.glb, table_name, self) def Help(self): HelpWindow(self.glb, self) def About(self): dialog = AboutDialog(self.glb, self) dialog.exec_() def TryOpen(file_name): try: return open(file_name, "rb") except: return None def Is64Bit(f): result = sizeof(c_void_p) # ELF support only pos = f.tell() f.seek(0) header = f.read(7) f.seek(pos) magic = header[0:4] if sys.version_info[0] == 2: eclass = ord(header[4]) encoding = ord(header[5]) version = ord(header[6]) else: eclass = header[4] encoding = header[5] version = header[6] if magic == chr(127) + "ELF" and eclass > 0 and eclass < 3 and encoding > 0 and encoding < 3 and version == 1: result = True if eclass == 2 else False return result # Global data class Glb(): def __init__(self, dbref, db, dbname): self.dbref = dbref self.db = db self.dbname = dbname self.home_dir = os.path.expanduser("~") self.buildid_dir = os.getenv("PERF_BUILDID_DIR") if self.buildid_dir: self.buildid_dir += "/.build-id/" else: self.buildid_dir = self.home_dir + "/.debug/.build-id/" self.app = None self.mainwindow = None self.instances_to_shutdown_on_exit = weakref.WeakSet() try: self.disassembler = LibXED() self.have_disassembler = True except: self.have_disassembler = False self.host_machine_id = 0 self.host_start_time = 0 self.host_finish_time = 0 def FileFromBuildId(self, build_id): file_name = self.buildid_dir + build_id[0:2] + "/" + build_id[2:] + "/elf" return TryOpen(file_name) def FileFromNamesAndBuildId(self, short_name, long_name, build_id): # Assume current machine i.e. no support for virtualization if short_name[0:7] == "[kernel" and os.path.basename(long_name) == "kcore": file_name = os.getenv("PERF_KCORE") f = TryOpen(file_name) if file_name else None if f: return f # For now, no special handling if long_name is /proc/kcore f = TryOpen(long_name) if f: return f f = self.FileFromBuildId(build_id) if f: return f return None def AddInstanceToShutdownOnExit(self, instance): self.instances_to_shutdown_on_exit.add(instance) # Shutdown any background processes or threads def ShutdownInstances(self): for x in self.instances_to_shutdown_on_exit: try: x.Shutdown() except: pass def GetHostMachineId(self): query = QSqlQuery(self.db) QueryExec(query, "SELECT id FROM machines WHERE pid = -1") if query.next(): self.host_machine_id = query.value(0) else: self.host_machine_id = 0 return self.host_machine_id def HostMachineId(self): if self.host_machine_id: return self.host_machine_id return self.GetHostMachineId() def SelectValue(self, sql): query = QSqlQuery(self.db) try: QueryExec(query, sql) except: return None if query.next(): return Decimal(query.value(0)) return None def SwitchesMinTime(self, machine_id): return self.SelectValue("SELECT time" " FROM context_switches" " WHERE time != 0 AND machine_id = " + str(machine_id) + " ORDER BY id LIMIT 1") def SwitchesMaxTime(self, machine_id): return self.SelectValue("SELECT time" " FROM context_switches" " WHERE time != 0 AND machine_id = " + str(machine_id) + " ORDER BY id DESC LIMIT 1") def SamplesMinTime(self, machine_id): return self.SelectValue("SELECT time" " FROM samples" " WHERE time != 0 AND machine_id = " + str(machine_id) + " ORDER BY id LIMIT 1") def SamplesMaxTime(self, machine_id): return self.SelectValue("SELECT time" " FROM samples" " WHERE time != 0 AND machine_id = " + str(machine_id) + " ORDER BY id DESC LIMIT 1") def CallsMinTime(self, machine_id): return self.SelectValue("SELECT calls.call_time" " FROM calls" " INNER JOIN threads ON threads.thread_id = calls.thread_id" " WHERE calls.call_time != 0 AND threads.machine_id = " + str(machine_id) + " ORDER BY calls.id LIMIT 1") def CallsMaxTime(self, machine_id): return self.SelectValue("SELECT calls.return_time" " FROM calls" " INNER JOIN threads ON threads.thread_id = calls.thread_id" " WHERE calls.return_time != 0 AND threads.machine_id = " + str(machine_id) + " ORDER BY calls.return_time DESC LIMIT 1") def GetStartTime(self, machine_id): t0 = self.SwitchesMinTime(machine_id) t1 = self.SamplesMinTime(machine_id) t2 = self.CallsMinTime(machine_id) if t0 is None or (not(t1 is None) and t1 < t0): t0 = t1 if t0 is None or (not(t2 is None) and t2 < t0): t0 = t2 return t0 def GetFinishTime(self, machine_id): t0 = self.SwitchesMaxTime(machine_id) t1 = self.SamplesMaxTime(machine_id) t2 = self.CallsMaxTime(machine_id) if t0 is None or (not(t1 is None) and t1 > t0): t0 = t1 if t0 is None or (not(t2 is None) and t2 > t0): t0 = t2 return t0 def HostStartTime(self): if self.host_start_time: return self.host_start_time self.host_start_time = self.GetStartTime(self.HostMachineId()) return self.host_start_time def HostFinishTime(self): if self.host_finish_time: return self.host_finish_time self.host_finish_time = self.GetFinishTime(self.HostMachineId()) return self.host_finish_time def StartTime(self, machine_id): if machine_id == self.HostMachineId(): return self.HostStartTime() return self.GetStartTime(machine_id) def FinishTime(self, machine_id): if machine_id == self.HostMachineId(): return self.HostFinishTime() return self.GetFinishTime(machine_id) # Database reference class DBRef(): def __init__(self, is_sqlite3, dbname): self.is_sqlite3 = is_sqlite3 self.dbname = dbname self.TRUE = "TRUE" self.FALSE = "FALSE" # SQLite prior to version 3.23 does not support TRUE and FALSE if self.is_sqlite3: self.TRUE = "1" self.FALSE = "0" def Open(self, connection_name): dbname = self.dbname if self.is_sqlite3: db = QSqlDatabase.addDatabase("QSQLITE", connection_name) else: db = QSqlDatabase.addDatabase("QPSQL", connection_name) opts = dbname.split() for opt in opts: if "=" in opt: opt = opt.split("=") if opt[0] == "hostname": db.setHostName(opt[1]) elif opt[0] == "port": db.setPort(int(opt[1])) elif opt[0] == "username": db.setUserName(opt[1]) elif opt[0] == "password": db.setPassword(opt[1]) elif opt[0] == "dbname": dbname = opt[1] else: dbname = opt db.setDatabaseName(dbname) if not db.open(): raise Exception("Failed to open database " + dbname + " error: " + db.lastError().text()) return db, dbname # Main def Main(): usage_str = "exported-sql-viewer.py [--pyside-version-1] <database name>\n" \ " or: exported-sql-viewer.py --help-only" ap = argparse.ArgumentParser(usage = usage_str, add_help = False) ap.add_argument("--pyside-version-1", action='store_true') ap.add_argument("dbname", nargs="?") ap.add_argument("--help-only", action='store_true') args = ap.parse_args() if args.help_only: app = QApplication(sys.argv) mainwindow = HelpOnlyWindow() mainwindow.show() err = app.exec_() sys.exit(err)