--- a/AssistantEric/APIsManager.py Sat Mar 31 12:26:27 2018 +0200 +++ b/AssistantEric/APIsManager.py Sat Sep 15 15:59:29 2018 +0200 @@ -77,8 +77,12 @@ file_delete_id_stmt = """ DELETE FROM file WHERE id = :id """ + + api_files_stmt = """ + SELECT file FROM file + """ - def __init__(self, proxy, language, apiFiles, projectPath="", + def __init__(self, proxy, language, apiFiles, dbName, projectPath="", refresh=False, projectType=""): """ Constructor @@ -89,6 +93,8 @@ @type str @param apiFiles list of API files to process @type list of str + @param dbName path name of the database file + @type str @param projectPath path of the project. Only needed, if the APIs are extracted out of the sources of a project. @type str @@ -118,11 +124,14 @@ self.__projectPath = projectPath self.__refresh = refresh + self.__databaseName = dbName + if self.__projectType: + self.__connectionName = "{0}_{1}_{2}".format( + self.__language, self.__projectType, id(self)) + else: self.__connectionName = "{0}_{1}".format( - self.__language, self.__projectType) - else: - self.__connectionName = self.__language + self.__language, id(self)) def __autoCompletionWordSeparators(self, language): """ @@ -131,7 +140,10 @@ @param language language of the APIs object (string) @return word separator characters (list of strings) """ - return self.__wseps.get(language, None) + if language: + return self.__wseps.get(language, None) + else: + return self.__proxy.autoCompletionWordSeparators() def abort(self): """ @@ -157,6 +169,7 @@ loadTime = QDateTime.fromString(query.value(0), Qt.ISODate) else: loadTime = QDateTime(1970, 1, 1, 0, 0) + query.finish() del query finally: db.commit() @@ -278,6 +291,7 @@ query.bindValue(":file", apiFile) query.exec_() finally: + query.finish() del query if self.__aborted: db.rollback() @@ -293,10 +307,7 @@ @param apiFile filename of the file read to get the APIs (string) @param language programming language of the file of the APIs (string) """ - if language: - wseps = self.__autoCompletionWordSeparators(language) - else: - wseps = self.__proxy.autoCompletionWordSeparators() + wseps = self.__autoCompletionWordSeparators(language) if wseps is None: return @@ -412,6 +423,7 @@ query.bindValue(":file", apiFile) query.exec_() finally: + query.finish() del query if self.__aborted: db.rollback() @@ -451,8 +463,32 @@ query.bindValue(":id", fileId) query.exec_() finally: + query.finish() del query db.commit() + + def __getApiFiles(self): + """ + Private method to get a list of API files loaded into the database. + + @return list of API filenames + @rtype list of str + """ + apiFiles = [] + + db = QSqlDatabase.database(self.__connectionName) + db.transaction() + try: + query = QSqlQuery(db) + query.exec_(self.api_files_stmt) + while query.next(): # __IGNORE_WARNING_M513__ + apiFiles.append(query.value(0)) + finally: + query.finish() + del query + db.commit() + + return apiFiles def run(self): """ @@ -460,11 +496,14 @@ """ self.processing.emit(WorkerStatusStarted, "") - db = QSqlDatabase.database(self.__connectionName) + db = QSqlDatabase.addDatabase("QSQLITE", self.__connectionName) + db.setDatabaseName(self.__databaseName) + db.open() + if db.isValid() and db.isOpen(): # step 1: remove API files not wanted any longer if not self.__refresh: - loadedApiFiles = self.__proxy.getApiFiles() + loadedApiFiles = self.__getApiFiles() for apiFile in loadedApiFiles: if not self.__aborted and apiFile not in self.__apiFiles: self.__deleteApiFile(apiFile) @@ -474,6 +513,8 @@ if not self.__aborted: self.__loadApiFileIfNewer(apiFile) + db.close() + if self.__aborted: self.processing.emit(WorkerStatusAborted, "") else: @@ -697,7 +738,9 @@ if QSqlDatabase and QSqlDatabase.database( self.__connectionName).isOpen(): QSqlDatabase.database(self.__connectionName).close() - QSqlDatabase.removeDatabase(self.__language) + + for connectionName in QSqlDatabase.connectionNames(): + QSqlDatabase.removeDatabase(connectionName) self.__opened = False @@ -757,6 +800,7 @@ query.exec_(self.create_bases_idx) query.exec_(self.create_file_idx) finally: + query.finish() del query db.commit() @@ -776,6 +820,7 @@ while query.next(): # __IGNORE_WARNING_M513__ apiFiles.append(query.value(0)) finally: + query.finish() del query db.commit() @@ -801,6 +846,7 @@ if formatVersion >= self.DB_VERSION: prepared = True finally: + query.finish() del query db.commit() return prepared @@ -848,6 +894,7 @@ completions.append({"completion": query.value(0), "context": query.value(1), "pictureId": query.value(2)}) + query.finish() del query finally: db.commit() @@ -864,6 +911,8 @@ for base in bases: completions.extend(self.getCompletions(start, base, followHierarchy=True)) + query.finish() + del query return completions @@ -922,6 +971,7 @@ word, sig)) else: calltips.append("{0}{1}".format(word, sig)) + query.finish() del query finally: db.commit() @@ -939,6 +989,8 @@ calltips.extend(self.getCalltips( acWord, commas, context=base, showContext=showContext, followHierarchy=True)) + query.finish() + del query if context and len(calltips) == 0 and not followHierarchy: # nothing found, try without a context @@ -1036,7 +1088,8 @@ apiFiles = Preferences.getEditorAPI(self.__language) projectType = self.__projectType self.__worker = DbAPIsWorker(self, self.__language, apiFiles, - projectPath, projectType=projectType) + self._apiDbName(), projectPath, + projectType=projectType) self.__worker.processing.connect( self.__processingStatus, Qt.QueuedConnection) self.__worker.start() @@ -1059,8 +1112,8 @@ projectPath = "" projectType = self.__projectType self.__worker = DbAPIsWorker(self, self.__language, apiFiles, - projectPath, projectType=projectType, - refresh=True) + self._apiDbName(), projectPath, + projectType=projectType, refresh=True) self.__worker.processing.connect( self.__processingStatus, Qt.QueuedConnection) self.__worker.start()