logic: Add unique constraints to SQLite tables
This commit is contained in:
@@ -619,11 +619,6 @@ Node::NodeType PersistentStorage::getNodeTypeForNodeWithId(Id nodeId) const
|
||||
return Node::intToType(m_sqliteIndexStorage.getFirstById<StorageNode>(nodeId).type);
|
||||
}
|
||||
|
||||
bool PersistentStorage::checkNodeExistsByName(const std::string& serializedName) const
|
||||
{
|
||||
return m_sqliteIndexStorage.checkNodeExistsByName(serializedName);
|
||||
}
|
||||
|
||||
Id PersistentStorage::getIdForEdge(
|
||||
Edge::EdgeType type, const NameHierarchy& fromNameHierarchy, const NameHierarchy& toNameHierarchy
|
||||
) const
|
||||
|
||||
@@ -99,7 +99,6 @@ public:
|
||||
virtual std::vector<NameHierarchy> getNameHierarchiesForNodeIds(const std::vector<Id> nodeIds) const;
|
||||
|
||||
virtual Node::NodeType getNodeTypeForNodeWithId(Id nodeId) const;
|
||||
virtual bool checkNodeExistsByName(const std::string& serializedName) const;
|
||||
|
||||
virtual Id getIdForEdge(
|
||||
Edge::EdgeType type, const NameHierarchy& fromNameHierarchy, const NameHierarchy& toNameHierarchy) const;
|
||||
|
||||
@@ -72,19 +72,21 @@ void SqliteIndexStorage::addFile(const int id, const std::string& filePath, cons
|
||||
std::shared_ptr<TextAccess> content = TextAccess::createFromFile(filePath);
|
||||
unsigned int lineCount = content->getLineCount();
|
||||
|
||||
executeStatement(
|
||||
const bool success = executeStatement(
|
||||
"INSERT INTO file(id, path, modification_time, complete, line_count) VALUES("
|
||||
+ std::to_string(id) + ", '" + filePath + "', '" + modificationTime + "', '" + std::to_string(complete) + "', " + std::to_string(lineCount) + ");"
|
||||
);
|
||||
|
||||
CppSQLite3Statement stmt = m_database.compileStatement((
|
||||
"INSERT INTO filecontent(id, content) VALUES("
|
||||
+ std::to_string(id) + ", ?);"
|
||||
if (success)
|
||||
{
|
||||
CppSQLite3Statement stmt = m_database.compileStatement((
|
||||
"INSERT INTO filecontent(id, content) VALUES("
|
||||
+ std::to_string(id) + ", ?);"
|
||||
).c_str());
|
||||
|
||||
stmt.bind(1, content->getText().c_str());
|
||||
executeStatement(stmt);
|
||||
|
||||
stmt.bind(1, content->getText().c_str());
|
||||
executeStatement(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
Id SqliteIndexStorage::addLocalSymbol(const std::string& name)
|
||||
@@ -135,60 +137,92 @@ bool SqliteIndexStorage::addOccurrence(Id elementId, Id sourceLocationId)
|
||||
|
||||
Id SqliteIndexStorage::addComponentAccess(Id nodeId, int type)
|
||||
{
|
||||
executeStatement(
|
||||
const bool success = executeStatement(
|
||||
"INSERT INTO component_access(id, node_id, type) "
|
||||
"VALUES (NULL, " + std::to_string(nodeId) + ", " + std::to_string(type) + ");"
|
||||
);
|
||||
|
||||
return m_database.lastRowId();
|
||||
Id id = 0;
|
||||
if (success)
|
||||
{
|
||||
id = m_database.lastRowId();
|
||||
}
|
||||
else
|
||||
{
|
||||
id = executeStatementScalar("SELECT id FROM component_access WHERE node_id == " + std::to_string(nodeId) + ";");
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
Id SqliteIndexStorage::addCommentLocation(Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol)
|
||||
{
|
||||
executeStatement(
|
||||
const bool success = executeStatement(
|
||||
"INSERT INTO comment_location(id, file_node_id, start_line, start_column, end_line, end_column) "
|
||||
"VALUES(NULL, " + std::to_string(fileNodeId) + ", "
|
||||
+ std::to_string(startLine) + ", " + std::to_string(startCol) + ", "
|
||||
+ std::to_string(endLine) + ", " + std::to_string(endCol) + ");"
|
||||
);
|
||||
|
||||
return m_database.lastRowId();
|
||||
Id id = 0;
|
||||
if (success)
|
||||
{
|
||||
id = m_database.lastRowId();
|
||||
}
|
||||
else
|
||||
{
|
||||
id = executeStatementScalar(
|
||||
"SELECT id FROM comment_location WHERE "
|
||||
"file_node_id == " + std::to_string(fileNodeId) + " AND "
|
||||
"start_line == " + std::to_string(startLine) + " AND "
|
||||
"start_column == " + std::to_string(startCol) + " AND "
|
||||
"end_line == " + std::to_string(endLine) + " AND "
|
||||
"end_column == " + std::to_string(endCol) + ";"
|
||||
);
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
Id SqliteIndexStorage::addError(const std::string& message, const FilePath& filePath, uint lineNumber, uint columnNumber, bool fatal, bool indexed)
|
||||
{
|
||||
std::string sanitizedMessage = utility::replace(message, "'", "''");
|
||||
|
||||
// check for duplicate
|
||||
CppSQLite3Statement stmt = m_database.compileStatement((
|
||||
"SELECT * FROM error WHERE "
|
||||
"message == ? AND "
|
||||
"fatal == " + std::to_string(fatal) + " AND "
|
||||
"file_path == '" + filePath.str() + "' AND "
|
||||
"line_number == " + std::to_string(lineNumber) + " AND "
|
||||
"column_number == " + std::to_string(columnNumber) + ";"
|
||||
).c_str());
|
||||
|
||||
stmt.bind(1, sanitizedMessage.c_str());
|
||||
CppSQLite3Query q = executeQuery(stmt);
|
||||
|
||||
if (!q.eof())
|
||||
{
|
||||
return q.getIntField(0, -1);
|
||||
}
|
||||
|
||||
stmt.finalize();
|
||||
|
||||
stmt = m_database.compileStatement((
|
||||
"INSERT INTO error(message, fatal, indexed, file_path, line_number, column_number) "
|
||||
"VALUES (?, " + std::to_string(fatal) + ", " + std::to_string(indexed) + ", '" + filePath.str() +
|
||||
"', " + std::to_string(lineNumber) + ", " + std::to_string(columnNumber) + ");"
|
||||
).c_str());
|
||||
|
||||
stmt.bind(1, sanitizedMessage.c_str());
|
||||
executeStatement(stmt);
|
||||
const bool success = executeStatement(stmt);
|
||||
|
||||
return m_database.lastRowId();
|
||||
Id id = 0;
|
||||
if (success)
|
||||
{
|
||||
id = m_database.lastRowId();
|
||||
}
|
||||
else
|
||||
{
|
||||
CppSQLite3Statement selectStmt = m_database.compileStatement((
|
||||
"SELECT * FROM error WHERE "
|
||||
"message == ? AND "
|
||||
"fatal == " + std::to_string(fatal) + " AND "
|
||||
"file_path == '" + filePath.str() + "' AND "
|
||||
"line_number == " + std::to_string(lineNumber) + " AND "
|
||||
"column_number == " + std::to_string(columnNumber) + ";"
|
||||
).c_str());
|
||||
|
||||
selectStmt.bind(1, sanitizedMessage.c_str());
|
||||
CppSQLite3Query q = executeQuery(selectStmt);
|
||||
|
||||
if (!q.eof())
|
||||
{
|
||||
id = q.getIntField(0, -1);
|
||||
}
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
void SqliteIndexStorage::removeElement(Id id)
|
||||
@@ -500,28 +534,6 @@ StorageNode SqliteIndexStorage::getNodeBySerializedName(const std::string& seria
|
||||
return StorageNode();
|
||||
}
|
||||
|
||||
bool SqliteIndexStorage::checkNodeExistsByName(const std::string& serializedName) const
|
||||
{
|
||||
CppSQLite3Statement stmt = m_database.compileStatement(
|
||||
"SELECT id FROM node WHERE serialized_name == ? LIMIT 1;"
|
||||
);
|
||||
|
||||
stmt.bind(1, serializedName.c_str());
|
||||
CppSQLite3Query q = executeQuery(stmt);
|
||||
|
||||
if (!q.eof())
|
||||
{
|
||||
const Id id = q.getIntField(0, 0);
|
||||
|
||||
if (id != -1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
StorageLocalSymbol SqliteIndexStorage::getLocalSymbolByName(const std::string& name) const
|
||||
{
|
||||
return doGetFirst<StorageLocalSymbol>("WHERE name == '" + name + "'");
|
||||
@@ -817,6 +829,7 @@ void SqliteIndexStorage::setupTables()
|
||||
"modification_time TEXT, "
|
||||
"complete INTEGER, "
|
||||
"line_count INTEGER, "
|
||||
"UNIQUE(path) ON CONFLICT FAIL,"
|
||||
"PRIMARY KEY(id), "
|
||||
"FOREIGN KEY(id) REFERENCES node(id) ON DELETE CASCADE);"
|
||||
);
|
||||
@@ -827,8 +840,8 @@ void SqliteIndexStorage::setupTables()
|
||||
"content TEXT, "
|
||||
"FOREIGN KEY(id)"
|
||||
"REFERENCES file(id)"
|
||||
"ON DELETE CASCADE "
|
||||
"ON UPDATE CASCADE);"
|
||||
"ON DELETE CASCADE "
|
||||
"ON UPDATE CASCADE);"
|
||||
);
|
||||
|
||||
m_database.execDML(
|
||||
@@ -866,6 +879,7 @@ void SqliteIndexStorage::setupTables()
|
||||
"id INTEGER NOT NULL, "
|
||||
"node_id INTEGER, "
|
||||
"type INTEGER NOT NULL, "
|
||||
"UNIQUE(node_id) ON CONFLICT FAIL,"
|
||||
"PRIMARY KEY(id), "
|
||||
"FOREIGN KEY(node_id) REFERENCES node(id) ON DELETE CASCADE);"
|
||||
);
|
||||
@@ -878,6 +892,7 @@ void SqliteIndexStorage::setupTables()
|
||||
"start_column INTEGER, "
|
||||
"end_line INTEGER, "
|
||||
"end_column INTEGER, "
|
||||
"UNIQUE(file_node_id, start_line, start_column, end_line, end_column) ON CONFLICT FAIL,"
|
||||
"PRIMARY KEY(id), "
|
||||
"FOREIGN KEY(file_node_id) REFERENCES node(id) ON DELETE CASCADE);"
|
||||
);
|
||||
@@ -891,6 +906,7 @@ void SqliteIndexStorage::setupTables()
|
||||
"file_path TEXT, "
|
||||
"line_number INTEGER, "
|
||||
"column_number INTEGER, "
|
||||
"UNIQUE(message, fatal, file_path, line_number, column_number) ON CONFLICT FAIL,"
|
||||
"PRIMARY KEY(id));"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -71,7 +71,6 @@ public:
|
||||
|
||||
StorageNode getNodeById(Id id) const;
|
||||
StorageNode getNodeBySerializedName(const std::string& serializedName) const;
|
||||
bool checkNodeExistsByName(const std::string& serializedName) const;
|
||||
|
||||
StorageLocalSymbol getLocalSymbolByName(const std::string& name) const;
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ void SqliteStorage::clearMetaTable()
|
||||
}
|
||||
}
|
||||
|
||||
void SqliteStorage::executeStatement(const std::string& statement) const
|
||||
bool SqliteStorage::executeStatement(const std::string& statement) const
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -161,10 +161,12 @@ void SqliteStorage::executeStatement(const std::string& statement) const
|
||||
catch (CppSQLite3Exception e)
|
||||
{
|
||||
LOG_ERROR(std::to_string(e.errorCode()) + ": " + e.errorMessage());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SqliteStorage::executeStatement(CppSQLite3Statement& statement) const
|
||||
bool SqliteStorage::executeStatement(CppSQLite3Statement& statement) const
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -173,7 +175,9 @@ void SqliteStorage::executeStatement(CppSQLite3Statement& statement) const
|
||||
catch (CppSQLite3Exception e)
|
||||
{
|
||||
LOG_ERROR(std::to_string(e.errorCode()) + ": " + e.errorMessage());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int SqliteStorage::executeStatementScalar(const std::string& statement) const
|
||||
|
||||
@@ -43,8 +43,8 @@ protected:
|
||||
void setupMetaTable();
|
||||
void clearMetaTable();
|
||||
|
||||
void executeStatement(const std::string& statement) const;
|
||||
void executeStatement(CppSQLite3Statement& statement) const;
|
||||
bool executeStatement(const std::string& statement) const;
|
||||
bool executeStatement(CppSQLite3Statement& statement) const;
|
||||
int executeStatementScalar(const std::string& statement) const;
|
||||
CppSQLite3Query executeQuery(const std::string& statement) const;
|
||||
CppSQLite3Query executeQuery(CppSQLite3Statement& statement) const;
|
||||
|
||||
@@ -38,7 +38,6 @@ public:
|
||||
virtual std::vector<NameHierarchy> getNameHierarchiesForNodeIds(const std::vector<Id> nodeIds) const = 0;
|
||||
|
||||
virtual Node::NodeType getNodeTypeForNodeWithId(Id id) const = 0;
|
||||
virtual bool checkNodeExistsByName(const std::string& serializedName) const = 0;
|
||||
|
||||
virtual Id getIdForEdge(
|
||||
Edge::EdgeType type, const NameHierarchy& fromNameHierarchy, const NameHierarchy& toNameHierarchy) const = 0;
|
||||
|
||||
@@ -93,15 +93,6 @@ Node::NodeType StorageAccessProxy::getNodeTypeForNodeWithId(Id id) const
|
||||
return Node::NODE_NON_INDEXED;
|
||||
}
|
||||
|
||||
bool StorageAccessProxy::checkNodeExistsByName(const std::string& serializedName) const
|
||||
{
|
||||
if (hasSubject())
|
||||
{
|
||||
return m_subject->checkNodeExistsByName(serializedName);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Id StorageAccessProxy::getIdForEdge(
|
||||
Edge::EdgeType type, const NameHierarchy& fromNameHierarchy, const NameHierarchy& toNameHierarchy
|
||||
) const {
|
||||
|
||||
@@ -26,7 +26,6 @@ public:
|
||||
virtual std::vector<NameHierarchy> getNameHierarchiesForNodeIds(const std::vector<Id> nodeIds) const;
|
||||
|
||||
virtual Node::NodeType getNodeTypeForNodeWithId(Id id) const;
|
||||
virtual bool checkNodeExistsByName(const std::string& serializedName) const;
|
||||
|
||||
virtual Id getIdForEdge(
|
||||
Edge::EdgeType type, const NameHierarchy& fromNameHierarchy, const NameHierarchy& toNameHierarchy) const;
|
||||
|
||||
@@ -11,11 +11,11 @@ class MessageActivateEdge
|
||||
: public Message<MessageActivateEdge>
|
||||
{
|
||||
public:
|
||||
MessageActivateEdge(Id tokenId, Edge::EdgeType type, const NameHierarchy& fromName, const NameHierarchy& toName)
|
||||
MessageActivateEdge(Id tokenId, Edge::EdgeType type, const NameHierarchy& sourceNameHierarchy, const NameHierarchy& targetNameHierarchy)
|
||||
: tokenId(tokenId)
|
||||
, type(type)
|
||||
, fromNameHierarchy(fromName)
|
||||
, toNameHierarchy(toName)
|
||||
, sourceNameHierarchy(sourceNameHierarchy)
|
||||
, targetNameHierarchy(targetNameHierarchy)
|
||||
{
|
||||
if (!isAggregation())
|
||||
{
|
||||
@@ -36,8 +36,8 @@ public:
|
||||
std::string getFullName() const
|
||||
{
|
||||
std::string name = Edge::getReadableTypeString(type) + ":";
|
||||
name += fromNameHierarchy.getQualifiedNameWithSignature() + "->";
|
||||
name += toNameHierarchy.getQualifiedNameWithSignature();
|
||||
name += sourceNameHierarchy.getQualifiedNameWithSignature() + "->";
|
||||
name += targetNameHierarchy.getQualifiedNameWithSignature();
|
||||
return name;
|
||||
}
|
||||
|
||||
@@ -48,8 +48,8 @@ public:
|
||||
|
||||
const Id tokenId;
|
||||
const Edge::EdgeType type;
|
||||
const NameHierarchy fromNameHierarchy;
|
||||
const NameHierarchy toNameHierarchy;
|
||||
const NameHierarchy sourceNameHierarchy;
|
||||
const NameHierarchy targetNameHierarchy;
|
||||
|
||||
std::vector<Id> aggregationIds;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user