From ea931ceb9f78e5306d0b24dc4b8ae6650fc14ad7 Mon Sep 17 00:00:00 2001 From: Eberhard Graether Date: Sat, 15 Dec 2018 01:44:38 +0100 Subject: [PATCH] improved sqlite performance with indices and compiled statements --- core/include/DatabaseStorage.h | 30 +- core/src/DatabaseStorage.cpp | 837 ++++++++++-------- core/src/SourcetrailDBWriter.cpp | 4 +- .../poetry_indexer.srctrlprj.in | 2 +- 4 files changed, 496 insertions(+), 377 deletions(-) diff --git a/core/include/DatabaseStorage.h b/core/include/DatabaseStorage.h index ef89859..b67d9f7 100644 --- a/core/include/DatabaseStorage.h +++ b/core/include/DatabaseStorage.h @@ -48,8 +48,8 @@ namespace sourcetrail static std::shared_ptr openDatabase(const std::string& dbFilePath); ~DatabaseStorage(); - void setupTables(); - void clearTables(); + void setupDatabase(); + void clearDatabase(); bool isEmpty() const; bool isCompatible() const; @@ -80,7 +80,13 @@ namespace sourcetrail private: DatabaseStorage() = default; + void setupTables(); + void setupIndices(); + void setupPrecompiledStatements(); + + int insertElement(); void insertOrUpdateMetaValue(const std::string& key, const std::string& value); + CppSQLite3Statement compileStatement(const std::string& statement) const; void executeStatement(const std::string& statement) const; void executeStatement(CppSQLite3Statement& statement) const; CppSQLite3Query executeQuery(const std::string& query) const; @@ -90,6 +96,26 @@ namespace sourcetrail std::vector doGetAll(const std::string& query) const; mutable CppSQLite3DB m_database; + + CppSQLite3Statement m_insertElementStatement; + CppSQLite3Statement m_findNodeStatement; + CppSQLite3Statement m_insertNodeStatement; + CppSQLite3Statement m_setNodeTypeStmt; + CppSQLite3Statement m_insertSymbolStatement; + CppSQLite3Statement m_findFileStatement; + CppSQLite3Statement m_insertFileStatement; + CppSQLite3Statement m_setFileLanguageStmt; + CppSQLite3Statement m_insertFileContentStatement; + CppSQLite3Statement m_findEdgeStatement; + CppSQLite3Statement m_insertEdgeStatement; + CppSQLite3Statement m_findLocalSymbolStmt; + CppSQLite3Statement m_insertLocalSymbolStmt; + CppSQLite3Statement m_findSourceLocationStmt; + CppSQLite3Statement m_insertSourceLocationStmt; + CppSQLite3Statement m_insertOccurenceStmt; + CppSQLite3Statement m_findErrorStatement; + CppSQLite3Statement m_insertErrorStatement; + CppSQLite3Statement m_insertOrUpdateMetaValueStmt; }; template <> diff --git a/core/src/DatabaseStorage.cpp b/core/src/DatabaseStorage.cpp index c03a1f0..e9063d7 100644 --- a/core/src/DatabaseStorage.cpp +++ b/core/src/DatabaseStorage.cpp @@ -52,10 +52,30 @@ namespace sourcetrail DatabaseStorage::~DatabaseStorage() { + m_insertElementStatement.finalize(); + m_findNodeStatement.finalize(); + m_insertNodeStatement.finalize(); + m_setNodeTypeStmt.finalize(); + m_insertSymbolStatement.finalize(); + m_findFileStatement.finalize(); + m_insertFileStatement.finalize(); + m_setFileLanguageStmt.finalize(); + m_insertFileContentStatement.finalize(); + m_findEdgeStatement.finalize(); + m_insertEdgeStatement.finalize(); + m_findLocalSymbolStmt.finalize(); + m_insertLocalSymbolStmt.finalize(); + m_findSourceLocationStmt.finalize(); + m_insertSourceLocationStmt.finalize(); + m_insertOccurenceStmt.finalize(); + m_findErrorStatement.finalize(); + m_insertErrorStatement.finalize(); + m_insertOrUpdateMetaValueStmt.finalize(); + m_database.close(); } - void DatabaseStorage::setupTables() + void DatabaseStorage::setupDatabase() { executeStatement("PRAGMA foreign_keys=ON;"); @@ -64,6 +84,328 @@ namespace sourcetrail throw SourcetrailException("Unable to setup database tables because database is not compatible."); } + setupTables(); + + setupIndices(); + + setupPrecompiledStatements(); + + insertOrUpdateMetaValue("storage_version", std::to_string(getSupportedDatabaseVersion())); + } + + void DatabaseStorage::clearDatabase() + { + executeStatement("PRAGMA foreign_keys=OFF;"); + + const std::vector tableNames = { + "meta", + "error", + "component_access", + "occurrence", + "source_location", + "local_symbol", + "filecontent", + "file", + "symbol", + "node", + "edge", + "element" + }; + + for (const std::string& tableName : tableNames) + { + executeStatement("DROP TABLE IF EXISTS main." + tableName + ";"); + } + + setupDatabase(); + } + + bool DatabaseStorage::isEmpty() const + { + const std::string tableName = "meta"; + CppSQLite3Query q = executeQuery( + "SELECT name FROM sqlite_master WHERE type='table' AND name='" + tableName + "';" + ); + + if (!q.eof()) + { + return q.getStringField(0, "") == tableName; + } + + return true; + } + + bool DatabaseStorage::isCompatible() const + { + if (isEmpty()) + { + return true; + } + + return getLoadedDatabaseVersion() == getSupportedDatabaseVersion(); + } + + int DatabaseStorage::getLoadedDatabaseVersion() const + { + if (isEmpty()) + { + throw SourcetrailException("Unable to determine version of an empty database."); + } + + CppSQLite3Query q = executeQuery("SELECT value FROM meta WHERE key = 'storage_version';"); + if (!q.eof()) + { + return std::stoi(q.getStringField(0, "0")); + } + return 0; + } + + void DatabaseStorage::beginTransaction() + { + executeStatement("BEGIN TRANSACTION;"); + } + + void DatabaseStorage::commitTransaction() + { + executeStatement("COMMIT TRANSACTION;"); + } + + void DatabaseStorage::rollbackTransaction() + { + executeStatement("ROLLBACK TRANSACTION;"); + } + + void DatabaseStorage::optimizeDatabaseMemory() + { + executeStatement("VACUUM;"); + } + + int DatabaseStorage::addNode(const StorageNodeData& storageNodeData) + { + int id = 0; + + { + m_findNodeStatement.bind(1, storageNodeData.serializedName.c_str()); + CppSQLite3Query q = executeQuery(m_findNodeStatement); + if (!q.eof()) + { + id = q.getIntField(0, 0); + } + m_findNodeStatement.reset(); + } + + // FIXME: update node nodeKind here + + if (id == 0) + { + id = insertElement(); + + m_insertNodeStatement.bind(1, id); + m_insertNodeStatement.bind(2, storageNodeData.nodeKind); + m_insertNodeStatement.bind(3, storageNodeData.serializedName.c_str()); + executeStatement(m_insertNodeStatement); + m_insertNodeStatement.reset(); + } + return id; + } + + void DatabaseStorage::addSymbol(const StorageSymbol& storageSymbol) + { + m_insertSymbolStatement.bind(1, storageSymbol.id); + m_insertSymbolStatement.bind(2, storageSymbol.definitionKind); + executeStatement(m_insertSymbolStatement); + m_insertSymbolStatement.reset(); + } + + void DatabaseStorage::addFile(const StorageFile& storageFile) + { + { + m_findFileStatement.bind(1, storageFile.id); + CppSQLite3Query q = executeQuery(m_findFileStatement); + bool exists = !q.eof(); + m_findFileStatement.reset(); + if (exists) + { + return; + } + } + + std::string content = ""; + if (utility::getFileExists(storageFile.filePath)) + { + content = utility::getFileContent(storageFile.filePath); + } + const int lineCount = utility::getLineCount(content); + + { + m_insertFileStatement.bind(1, storageFile.id); + m_insertFileStatement.bind(2, storageFile.filePath.c_str()); + m_insertFileStatement.bind(3, storageFile.languageIdentifier.c_str()); + m_insertFileStatement.bind(4, storageFile.modificationTime.c_str()); + m_insertFileStatement.bind(5, storageFile.indexed); + m_insertFileStatement.bind(6, storageFile.complete); + m_insertFileStatement.bind(7, lineCount); + executeStatement(m_insertFileStatement); + m_insertFileStatement.reset(); + } + + if (!content.empty()) + { + m_insertFileContentStatement.bind(1, storageFile.id); + m_insertFileContentStatement.bind(2, content.c_str()); + executeStatement(m_insertFileContentStatement); + m_insertFileContentStatement.reset(); + } + } + + int DatabaseStorage::addEdge(const StorageEdgeData& storageEdgeData) + { + int id = 0; + + { + m_findEdgeStatement.bind(1, storageEdgeData.sourceNodeId); + m_findEdgeStatement.bind(2, storageEdgeData.targetNodeId); + m_findEdgeStatement.bind(3, storageEdgeData.edgeKind); + CppSQLite3Query q = executeQuery(m_findEdgeStatement); + if (!q.eof()) + { + id = q.getIntField(0, 0); + } + m_findEdgeStatement.reset(); + } + + if (id == 0) + { + id = insertElement(); + + m_insertEdgeStatement.bind(1, id); + m_insertEdgeStatement.bind(2, storageEdgeData.edgeKind); + m_insertEdgeStatement.bind(3, storageEdgeData.sourceNodeId); + m_insertEdgeStatement.bind(4, storageEdgeData.targetNodeId); + executeStatement(m_insertEdgeStatement); + m_insertEdgeStatement.reset(); + } + return id; + } + + int DatabaseStorage::addLocalSymbol(const StorageLocalSymbolData& storageLocalSymbolData) + { + int id = 0; + + { + m_findLocalSymbolStmt.bind(1, storageLocalSymbolData.name.c_str()); + CppSQLite3Query q = executeQuery(m_findLocalSymbolStmt); + if (!q.eof()) + { + id = q.getIntField(0, 0); + } + m_findLocalSymbolStmt.reset(); + } + + if (id == 0) + { + id = insertElement(); + + m_insertLocalSymbolStmt.bind(1, id); + m_insertLocalSymbolStmt.bind(2, storageLocalSymbolData.name.c_str()); + executeStatement(m_insertLocalSymbolStmt); + m_insertLocalSymbolStmt.reset(); + } + return id; + } + + int DatabaseStorage::addSourceLocation(const StorageSourceLocationData& storageSourceLocationData) + { + int id = 0; + + { + m_findSourceLocationStmt.bind(1, storageSourceLocationData.fileNodeId); + m_findSourceLocationStmt.bind(2, storageSourceLocationData.startLineNumber); + m_findSourceLocationStmt.bind(3, storageSourceLocationData.startColumnNumber); + m_findSourceLocationStmt.bind(4, storageSourceLocationData.endLineNumber); + m_findSourceLocationStmt.bind(5, storageSourceLocationData.endColumnNumber); + m_findSourceLocationStmt.bind(6, storageSourceLocationData.locationKind); + CppSQLite3Query q = executeQuery(m_findSourceLocationStmt); + if (!q.eof()) + { + id = q.getIntField(0, 0); + } + m_findSourceLocationStmt.reset(); + } + + if (id == 0) + { + m_insertSourceLocationStmt.bind(1, storageSourceLocationData.fileNodeId); + m_insertSourceLocationStmt.bind(2, storageSourceLocationData.startLineNumber); + m_insertSourceLocationStmt.bind(3, storageSourceLocationData.startColumnNumber); + m_insertSourceLocationStmt.bind(4, storageSourceLocationData.endLineNumber); + m_insertSourceLocationStmt.bind(5, storageSourceLocationData.endColumnNumber); + m_insertSourceLocationStmt.bind(6, storageSourceLocationData.locationKind); + executeStatement(m_insertSourceLocationStmt); + id = m_database.lastRowId(); + m_insertSourceLocationStmt.reset(); + } + return id; + } + + void DatabaseStorage::addOccurrence(const StorageOccurrence& storageOccurrence) + { + m_insertOccurenceStmt.bind(1, storageOccurrence.elementId); + m_insertOccurenceStmt.bind(2, storageOccurrence.sourceLocationId); + executeStatement(m_insertOccurenceStmt); + m_insertOccurenceStmt.reset(); + } + + int DatabaseStorage::addError(const StorageErrorData& storageErrorData) + { + int id = 0; + { + m_findErrorStatement.bind(1, storageErrorData.message.c_str()); + m_findErrorStatement.bind(2, storageErrorData.fatal); + CppSQLite3Query q = executeQuery(m_findErrorStatement); + if (!q.eof() && q.numFields() > 0) + { + id = q.getIntField(0, -1); + } + m_findErrorStatement.reset(); + } + + if (id == 0) + { + id = insertElement(); + + m_insertErrorStatement.bind(1, id); + m_insertErrorStatement.bind(2, storageErrorData.message.c_str()); + m_insertErrorStatement.bind(3, storageErrorData.fatal); + m_insertErrorStatement.bind(4, storageErrorData.indexed); + m_insertErrorStatement.bind(5, storageErrorData.translationUnit.c_str()); + executeStatement(m_insertErrorStatement); + id = m_database.lastRowId(); + m_insertErrorStatement.reset(); + } + return id; + } + + void DatabaseStorage::setNodeType(int nodeId, int nodeType) + { + m_setNodeTypeStmt.bind(1, nodeType); + m_setNodeTypeStmt.bind(2, nodeId); + executeStatement(m_setNodeTypeStmt); + m_setNodeTypeStmt.reset(); + } + + void DatabaseStorage::setFileLanguage(int fileId, const std::string& languageIdentifier) + { + m_setFileLanguageStmt.bind(1, languageIdentifier.c_str()); + m_setFileLanguageStmt.bind(2, fileId); + executeStatement(m_setFileLanguageStmt); + m_setFileLanguageStmt.reset(); + } + + // --- Private Interface --- + + void DatabaseStorage::setupTables() + { executeStatement( "CREATE TABLE IF NOT EXISTS meta(" " id INTEGER, " @@ -189,404 +531,155 @@ namespace sourcetrail " FOREIGN KEY(id) REFERENCES element(id) ON DELETE CASCADE" ");" ); - - insertOrUpdateMetaValue("storage_version", std::to_string(getSupportedDatabaseVersion())); } - void DatabaseStorage::clearTables() + void DatabaseStorage::setupIndices() { - executeStatement("PRAGMA foreign_keys=OFF;"); - - const std::vector tableNames = { - "meta", - "error", - "component_access", - "occurrence", - "source_location", - "local_symbol", - "filecontent", - "file", - "symbol", - "node", - "edge", - "element" - }; - - for (const std::string& tableName : tableNames) - { - executeStatement("DROP TABLE IF EXISTS main." + tableName + ";"); - } - - setupTables(); - } - - bool DatabaseStorage::isEmpty() const - { - const std::string tableName = "meta"; - CppSQLite3Query q = executeQuery( - "SELECT name FROM sqlite_master WHERE type='table' AND name='" + tableName + "';" + executeStatement( + "CREATE INDEX IF NOT EXISTS node_serialized_name_index ON node(serialized_name);" ); - if (!q.eof()) - { - return q.getStringField(0, "") == tableName; - } - - return true; - } - - bool DatabaseStorage::isCompatible() const - { - if (isEmpty()) - { - return true; - } - - return getLoadedDatabaseVersion() == getSupportedDatabaseVersion(); - } - - int DatabaseStorage::getLoadedDatabaseVersion() const - { - if (isEmpty()) - { - throw SourcetrailException("Unable to determine version of an empty database."); - } - - CppSQLite3Query q = executeQuery("SELECT value FROM meta WHERE key = 'storage_version';"); - if (!q.eof()) - { - return std::stoi(q.getStringField(0, "0")); - } - return 0; - } - - void DatabaseStorage::beginTransaction() - { - executeStatement("BEGIN TRANSACTION;"); - } - - void DatabaseStorage::commitTransaction() - { - executeStatement("COMMIT TRANSACTION;"); - } - - void DatabaseStorage::rollbackTransaction() - { - executeStatement("ROLLBACK TRANSACTION;"); - } - - void DatabaseStorage::optimizeDatabaseMemory() - { - executeStatement("VACUUM;"); - } - - int DatabaseStorage::addNode(const StorageNodeData& storageNodeData) - { - int id = 0; - - { - CppSQLite3Statement stmt = m_database.compileStatement( - "SELECT id FROM node WHERE serialized_name == ? LIMIT 1;" - ); - stmt.bind(1, storageNodeData.serializedName.c_str()); - CppSQLite3Query q = executeQuery(stmt); - if (!q.eof()) - { - id = q.getIntField(0, 0); - } - } - - // FIXME: update node nodeKind here - - if (id == 0) - { - { - CppSQLite3Statement stmt = m_database.compileStatement( - "INSERT INTO element(id) VALUES(NULL);" - ); - executeStatement(stmt); - id = m_database.lastRowId(); - } - { - CppSQLite3Statement stmt = m_database.compileStatement( - "INSERT INTO node(id, type, serialized_name) VALUES(?, ?, ?);" - ); - stmt.bind(1, id); - stmt.bind(2, storageNodeData.nodeKind); - stmt.bind(3, storageNodeData.serializedName.c_str()); - executeStatement(stmt); - } - } - return id; - } - - void DatabaseStorage::addSymbol(const StorageSymbol& storageSymbol) - { - CppSQLite3Statement stmt = m_database.compileStatement( - "INSERT OR IGNORE INTO symbol(id, definition_kind) VALUES(?, ?);" + executeStatement( + "CREATE INDEX IF NOT EXISTS edge_source_target_type_index ON edge(source_node_id, target_node_id, type);" ); - stmt.bind(1, storageSymbol.id); - stmt.bind(2, storageSymbol.definitionKind); - executeStatement(stmt); - } - void DatabaseStorage::addFile(const StorageFile& storageFile) - { - { - CppSQLite3Statement stmt = m_database.compileStatement( - "SELECT id FROM file WHERE id == ?;" - ); - stmt.bind(1, storageFile.id); - CppSQLite3Query q = executeQuery(stmt); - if (!q.eof()) - { - return; // early exit if the file already exists - } - } + executeStatement( + "CREATE INDEX IF NOT EXISTS local_symbol_name_index ON local_symbol(name);" + ); - std::string content = ""; - if (utility::getFileExists(storageFile.filePath)) - { - content = utility::getFileContent(storageFile.filePath); - } - const int lineCount = utility::getLineCount(content); + executeStatement( + "CREATE INDEX IF NOT EXISTS source_location_all_data_index " + "ON source_location(file_node_id, start_line, start_column, end_line, end_column, type);" + ); - { - CppSQLite3Statement stmt = m_database.compileStatement( - "INSERT OR IGNORE INTO file(id, path, language, modification_time, indexed, complete, line_count) VALUES(?, ?, ?, ?, ?, ?, ?);" - ); - stmt.bind(1, storageFile.id); - stmt.bind(2, storageFile.filePath.c_str()); - stmt.bind(3, storageFile.languageIdentifier.c_str()); - stmt.bind(4, storageFile.modificationTime.c_str()); - stmt.bind(5, storageFile.indexed); - stmt.bind(6, storageFile.complete); - stmt.bind(7, lineCount); - executeStatement(stmt); - } - - if (!content.empty()) - { - CppSQLite3Statement stmt = m_database.compileStatement( - "INSERT INTO filecontent(id, content) VALUES(?, ?);" - ); - stmt.bind(1, storageFile.id); - stmt.bind(2, content.c_str()); - executeStatement(stmt); - } - } - - int DatabaseStorage::addEdge(const StorageEdgeData& storageEdgeData) - { - int id = 0; - - { - CppSQLite3Statement stmt = m_database.compileStatement( - "SELECT id FROM edge WHERE source_node_id == ? AND target_node_id == ? AND type == ? LIMIT 1;" - ); - stmt.bind(1, storageEdgeData.sourceNodeId); - stmt.bind(2, storageEdgeData.targetNodeId); - stmt.bind(3, storageEdgeData.edgeKind); - CppSQLite3Query q = executeQuery(stmt); - if (!q.eof()) - { - id = q.getIntField(0, 0); - } - } - - if (id == 0) - { - { - CppSQLite3Statement stmt = m_database.compileStatement( - "INSERT INTO element(id) VALUES(NULL);" - ); - executeStatement(stmt); - id = m_database.lastRowId(); - } - { - CppSQLite3Statement stmt = m_database.compileStatement( - "INSERT INTO edge(id, type, source_node_id, target_node_id) VALUES(?, ?, ?, ?);" - ); - stmt.bind(1, id); - stmt.bind(2, storageEdgeData.edgeKind); - stmt.bind(3, storageEdgeData.sourceNodeId); - stmt.bind(4, storageEdgeData.targetNodeId); - executeStatement(stmt); - } - } - return id; - } - - int DatabaseStorage::addLocalSymbol(const StorageLocalSymbolData& storageLocalSymbolData) - { - int id = 0; - - { - CppSQLite3Statement stmt = m_database.compileStatement( - "SELECT id FROM local_symbol WHERE name == ? LIMIT 1;" - ); - stmt.bind(1, storageLocalSymbolData.name.c_str()); - CppSQLite3Query q = executeQuery(stmt); - if (!q.eof()) - { - id = q.getIntField(0, 0); - } - } - - if (id == 0) - { - { - CppSQLite3Statement stmt = m_database.compileStatement( - "INSERT INTO element(id) VALUES(NULL);" - ); - executeStatement(stmt); - id = m_database.lastRowId(); - } - { - CppSQLite3Statement stmt = m_database.compileStatement( - "INSERT INTO local_symbol(id, name) VALUES(?, ?);" - ); - stmt.bind(1, id); - stmt.bind(2, storageLocalSymbolData.name.c_str()); - executeStatement(stmt); - } - } - return id; - } - - int DatabaseStorage::addSourceLocation(const StorageSourceLocationData& storageSourceLocationData) - { - int id = 0; - - { - CppSQLite3Statement stmt = m_database.compileStatement( - "SELECT id FROM source_location WHERE " - "file_node_id = ? AND " - "start_line = ? AND " - "start_column = ? AND " - "end_line = ? AND " - "end_column = ? AND " - "type = ? " - "LIMIT 1;" - ); - stmt.bind(1, storageSourceLocationData.fileNodeId); - stmt.bind(2, storageSourceLocationData.startLineNumber); - stmt.bind(3, storageSourceLocationData.startColumnNumber); - stmt.bind(4, storageSourceLocationData.endLineNumber); - stmt.bind(5, storageSourceLocationData.endColumnNumber); - stmt.bind(6, storageSourceLocationData.locationKind); - CppSQLite3Query q = executeQuery(stmt); - if (!q.eof()) - { - id = q.getIntField(0, 0); - } - } - - if (id == 0) - { - CppSQLite3Statement stmt = m_database.compileStatement( - "INSERT INTO source_location(id, file_node_id, start_line, start_column, end_line, end_column, type) VALUES(NULL, ?, ?, ?, ?, ?, ?);" - ); - stmt.bind(1, storageSourceLocationData.fileNodeId); - stmt.bind(2, storageSourceLocationData.startLineNumber); - stmt.bind(3, storageSourceLocationData.startColumnNumber); - stmt.bind(4, storageSourceLocationData.endLineNumber); - stmt.bind(5, storageSourceLocationData.endColumnNumber); - stmt.bind(6, storageSourceLocationData.locationKind); - executeStatement(stmt); - id = m_database.lastRowId(); - } - return id; - } - - void DatabaseStorage::addOccurrence(const StorageOccurrence& storageOccurrence) - { - CppSQLite3Statement stmt = m_database.compileStatement( - "INSERT OR IGNORE INTO occurrence(element_id, source_location_id) VALUES(?, ?);" + executeStatement( + "CREATE INDEX IF NOT EXISTS error_all_data_index ON error(message, fatal);" ); - stmt.bind(1, storageOccurrence.elementId); - stmt.bind(2, storageOccurrence.sourceLocationId); - executeStatement(stmt); } - int DatabaseStorage::addError(const StorageErrorData& storageErrorData) + void DatabaseStorage::setupPrecompiledStatements() { - int id = 0; - { - CppSQLite3Statement stmt = m_database.compileStatement( - "SELECT id FROM error WHERE " - "message = ? AND " - "fatal == ? " - "LIMIT 1;" - ); - stmt.bind(1, storageErrorData.message.c_str()); - stmt.bind(2, storageErrorData.fatal); - CppSQLite3Query q = executeQuery(stmt); - if (!q.eof() && q.numFields() > 0) - { - id = q.getIntField(0, -1); - } - } + m_insertElementStatement = compileStatement( + "INSERT INTO element(id) VALUES(NULL);" + ); - if (id == 0) - { - { - CppSQLite3Statement stmt = m_database.compileStatement( - "INSERT INTO element(id) VALUES(NULL);" - ); - executeStatement(stmt); - id = m_database.lastRowId(); - } + m_findNodeStatement = compileStatement( + "SELECT id FROM node WHERE serialized_name == ? LIMIT 1;" + ); - CppSQLite3Statement stmt = m_database.compileStatement( - "INSERT INTO error(id, message, fatal, indexed, translation_unit) " - "VALUES(?, ?, ?, ?, ?);" - ); - stmt.bind(1, id); - stmt.bind(2, storageErrorData.message.c_str()); - stmt.bind(3, storageErrorData.fatal); - stmt.bind(4, storageErrorData.indexed); - stmt.bind(5, storageErrorData.translationUnit.c_str()); - executeStatement(stmt); - id = m_database.lastRowId(); - } - return id; - } + m_insertNodeStatement = compileStatement( + "INSERT INTO node(id, type, serialized_name) VALUES(?, ?, ?);" + ); - void DatabaseStorage::setNodeType(int nodeId, int nodeType) - { - CppSQLite3Statement stmt = m_database.compileStatement( + m_setNodeTypeStmt = compileStatement( "UPDATE node SET type = ? WHERE id == ?;" ); - stmt.bind(1, nodeType); - stmt.bind(2, nodeId); - executeStatement(stmt); - } - void DatabaseStorage::setFileLanguage(int fileId, const std::string& languageIdentifier) - { - CppSQLite3Statement stmt = m_database.compileStatement( + m_insertSymbolStatement = compileStatement( + "INSERT OR IGNORE INTO symbol(id, definition_kind) VALUES(?, ?);" + ); + + m_findFileStatement = compileStatement( + "SELECT id FROM file WHERE id == ?;" + ); + + m_insertFileStatement = compileStatement( + "INSERT OR IGNORE INTO file(id, path, language, modification_time, indexed, complete, line_count) VALUES(?, ?, ?, ?, ?, ?, ?);" + ); + + m_setFileLanguageStmt = compileStatement( "UPDATE file SET language = ? WHERE id == ?;" ); - stmt.bind(1, languageIdentifier.c_str()); - stmt.bind(2, fileId); - executeStatement(stmt); - } - // --- Private Interface --- + m_insertFileContentStatement = compileStatement( + "INSERT INTO filecontent(id, content) VALUES(?, ?);" + ); - void DatabaseStorage::insertOrUpdateMetaValue(const std::string& key, const std::string& value) - { - CppSQLite3Statement stmt = m_database.compileStatement(std::string( + m_findEdgeStatement = compileStatement( + "SELECT id FROM edge WHERE source_node_id == ? AND target_node_id == ? AND type == ? LIMIT 1;" + ); + + m_insertEdgeStatement = compileStatement( + "INSERT INTO edge(id, type, source_node_id, target_node_id) VALUES(?, ?, ?, ?);" + ); + + m_findLocalSymbolStmt = compileStatement( + "SELECT id FROM local_symbol WHERE name == ? LIMIT 1;" + ); + + m_insertLocalSymbolStmt = compileStatement( + "INSERT INTO local_symbol(id, name) VALUES(?, ?);" + ); + + m_findSourceLocationStmt = compileStatement( + "SELECT id FROM source_location WHERE " + "file_node_id = ? AND " + "start_line = ? AND " + "start_column = ? AND " + "end_line = ? AND " + "end_column = ? AND " + "type = ? " + "LIMIT 1;" + ); + + m_insertSourceLocationStmt = compileStatement( + "INSERT INTO source_location(" + "id, file_node_id, start_line, start_column, end_line, end_column, type) " + "VALUES(NULL, ?, ?, ?, ?, ?, ?);" + ); + + m_insertOccurenceStmt = compileStatement( + "INSERT OR IGNORE INTO occurrence(element_id, source_location_id) VALUES(?, ?);" + ); + + m_findErrorStatement = compileStatement( + "SELECT id FROM error WHERE " + "message = ? AND " + "fatal == ? " + "LIMIT 1;" + ); + + m_insertErrorStatement = compileStatement( + "INSERT INTO error(id, message, fatal, indexed, translation_unit) " + "VALUES(?, ?, ?, ?, ?);" + ); + + m_insertOrUpdateMetaValueStmt = compileStatement( "INSERT OR REPLACE INTO meta(id, key, value) VALUES(" "(SELECT id FROM meta WHERE key = ?), ?, ?" ");" - ).c_str()); + ); + } - stmt.bind(1, key.c_str()); - stmt.bind(2, key.c_str()); - stmt.bind(3, value.c_str()); - executeStatement(stmt); + int DatabaseStorage::insertElement() + { + executeStatement(m_insertElementStatement); + int id = m_database.lastRowId(); + m_insertElementStatement.reset(); + return id; + } + + void DatabaseStorage::insertOrUpdateMetaValue(const std::string& key, const std::string& value) + { + m_insertOrUpdateMetaValueStmt.bind(1, key.c_str()); + m_insertOrUpdateMetaValueStmt.bind(2, key.c_str()); + m_insertOrUpdateMetaValueStmt.bind(3, value.c_str()); + executeStatement(m_insertOrUpdateMetaValueStmt); + m_insertOrUpdateMetaValueStmt.reset(); + } + + CppSQLite3Statement DatabaseStorage::compileStatement(const std::string& statement) const + { + try + { + return m_database.compileStatement(statement.c_str()); + } + catch (CppSQLite3Exception e) + { + throw SourcetrailException("Failed to compile statement \"" + statement + "\" with message \"" + e.errorMessage() + "\"."); + } + + return CppSQLite3Statement(); } void DatabaseStorage::executeStatement(const std::string& statement) const diff --git a/core/src/SourcetrailDBWriter.cpp b/core/src/SourcetrailDBWriter.cpp index 6234fd0..ef39146 100644 --- a/core/src/SourcetrailDBWriter.cpp +++ b/core/src/SourcetrailDBWriter.cpp @@ -629,7 +629,7 @@ namespace sourcetrail { throw SourcetrailException("Unable to setup database tables, because no database is currently open."); } - m_storage->setupTables(); + m_storage->setupDatabase(); } void SourcetrailDBWriter::clearDatabaseTables() @@ -638,7 +638,7 @@ namespace sourcetrail { throw SourcetrailException("Unable to setup database tables, because no database is currently open."); } - m_storage->clearTables(); + m_storage->clearDatabase(); } void SourcetrailDBWriter::createOrResetProjectFile() diff --git a/examples/cpp_poetry_indexer/poetry_indexer.srctrlprj.in b/examples/cpp_poetry_indexer/poetry_indexer.srctrlprj.in index 269c9ae..adbf942 100644 --- a/examples/cpp_poetry_indexer/poetry_indexer.srctrlprj.in +++ b/examples/cpp_poetry_indexer/poetry_indexer.srctrlprj.in @@ -4,7 +4,7 @@ ./poetry_indexer $DB_PATH $DB_VERSION $SOURCE_PATH - @POETRY_INDEXER_DATA_PATH@/copyright.txt + @POETRY_INDEXER_DATA_PATH@/COPYRIGHT.txt Custom Command Source Group