logic: Add unique constraints to SQLite tables

This commit is contained in:
malte_langkabel
2017-04-24 17:38:16 +02:00
parent 4bfe59df76
commit e669064452
10 changed files with 88 additions and 86 deletions
-5
View File
@@ -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
-1
View File
@@ -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;
+73 -57
View File
@@ -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));"
);
}
-1
View File
@@ -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;
+6 -2
View File
@@ -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
+2 -2
View File
@@ -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;
-1
View File
@@ -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 {
-1
View File
@@ -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;
};