logic: add storage transformation to merge anonymous types and the respective typedef
* moved storage related classes to data/storage folder * implemented recording c++ unions as NODE_UNION instead of just using NODE_TYPE * added transformation to merge anonymous classes/structs/enums/unions and typedef nodes * added tests for this transformation * added setting for enabling/disabling this transformation
This commit is contained in:
@@ -0,0 +1,563 @@
|
||||
#include "data/storage/IntermediateStorage.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
IntermediateStorage::IntermediateStorage()
|
||||
: m_nextId(1)
|
||||
{
|
||||
}
|
||||
|
||||
IntermediateStorage::~IntermediateStorage()
|
||||
{
|
||||
}
|
||||
|
||||
void IntermediateStorage::clear()
|
||||
{
|
||||
m_nodes.clear();
|
||||
m_nodesIndex.clear();
|
||||
m_files.clear();
|
||||
m_symbols.clear();
|
||||
m_edges.clear();
|
||||
m_edgesIndex.clear();
|
||||
m_localSymbols.clear();
|
||||
m_sourceLocations.clear();
|
||||
m_occurrences.clear();
|
||||
m_componentAccesses.clear();
|
||||
m_commentLocations.clear();
|
||||
m_errors.clear();
|
||||
m_nextId = 1;
|
||||
}
|
||||
|
||||
size_t IntermediateStorage::getByteSize() const
|
||||
{
|
||||
unsigned int byteSize = 0;
|
||||
|
||||
for (const StorageFile& storageFile: getStorageFiles())
|
||||
{
|
||||
byteSize += sizeof(StorageFile);
|
||||
byteSize += storageFile.filePath.size();
|
||||
byteSize += storageFile.modificationTime.size();
|
||||
}
|
||||
|
||||
for (const StorageError& storageError: getErrors())
|
||||
{
|
||||
byteSize += sizeof(StorageError);
|
||||
byteSize += storageError.filePath.str().size();
|
||||
byteSize += storageError.message.size();
|
||||
}
|
||||
|
||||
for (const StorageNode& storageNode: getStorageNodes())
|
||||
{
|
||||
byteSize += sizeof(StorageNode);
|
||||
byteSize += storageNode.serializedName.size();
|
||||
}
|
||||
|
||||
for (const StorageLocalSymbol& storageLocalSymbol: getStorageLocalSymbols())
|
||||
{
|
||||
byteSize += sizeof(StorageLocalSymbol);
|
||||
byteSize += storageLocalSymbol.name.size();
|
||||
}
|
||||
|
||||
byteSize += sizeof(StorageEdge) * getStorageEdges().size();
|
||||
byteSize += sizeof(StorageCommentLocation) * getCommentLocations().size();
|
||||
byteSize += sizeof(StorageComponentAccess) * getComponentAccesses().size();
|
||||
byteSize += sizeof(StorageOccurrence) * getStorageOccurrences().size();
|
||||
byteSize += sizeof(StorageSymbol) * getStorageSymbols().size();
|
||||
byteSize += sizeof(StorageSourceLocation) * getStorageSourceLocations().size();
|
||||
|
||||
return byteSize;
|
||||
}
|
||||
|
||||
size_t IntermediateStorage::getSourceLocationCount() const
|
||||
{
|
||||
return m_sourceLocations.size();
|
||||
}
|
||||
|
||||
void IntermediateStorage::setAllFilesIncomplete()
|
||||
{
|
||||
for (StorageFile& file : m_files)
|
||||
{
|
||||
file.complete = false;
|
||||
}
|
||||
}
|
||||
|
||||
void IntermediateStorage::setFilesWithErrorsIncomplete()
|
||||
{
|
||||
std::set<std::string> errorFileNames;
|
||||
for (StorageError& error : m_errors)
|
||||
{
|
||||
errorFileNames.insert(error.filePath.str());
|
||||
}
|
||||
|
||||
for (StorageFile& file : m_files)
|
||||
{
|
||||
if (errorFileNames.find(file.filePath) != errorFileNames.end())
|
||||
{
|
||||
file.complete = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Id IntermediateStorage::addNode(int type, const std::string& serializedName)
|
||||
{
|
||||
StorageNode node(0, type, serializedName);
|
||||
|
||||
const std::string serialized = serialize(node);
|
||||
std::unordered_map<std::string, size_t>::iterator it = m_nodesIndex.find(serialized);
|
||||
if (it != m_nodesIndex.end())
|
||||
{
|
||||
StorageNode& storedNode = m_nodes[it->second];
|
||||
if (storedNode.type < type)
|
||||
{
|
||||
storedNode.type = type;
|
||||
}
|
||||
return storedNode.id;
|
||||
}
|
||||
|
||||
const Id id = m_nextId++;
|
||||
node.id = id;
|
||||
m_nodes.push_back(node);
|
||||
m_nodesIndex.emplace(serialized, m_nodes.size() - 1);
|
||||
return id;
|
||||
}
|
||||
|
||||
void IntermediateStorage::addFile(const Id id, const std::string& filePath, const std::string& modificationTime, bool complete)
|
||||
{
|
||||
const StorageFile file(id, filePath, modificationTime, complete);
|
||||
const std::string serialized = serialize(file);
|
||||
|
||||
if (m_serializedFiles.find(serialized) == m_serializedFiles.end())
|
||||
{
|
||||
m_files.push_back(file);
|
||||
m_serializedFiles.insert(serialized);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void IntermediateStorage::addSymbol(const Id id, int definitionKind)
|
||||
{
|
||||
m_symbols.push_back(StorageSymbol(id, definitionKind));
|
||||
}
|
||||
|
||||
Id IntermediateStorage::addEdge(int type, Id sourceId, Id targetId)
|
||||
{
|
||||
StorageEdge edge = StorageEdge(0, type, sourceId, targetId);
|
||||
|
||||
const std::string serialized = serialize(edge);
|
||||
std::unordered_map<std::string, size_t>::const_iterator it = m_edgesIndex.find(serialized);
|
||||
if (it != m_edgesIndex.end())
|
||||
{
|
||||
return m_edges[it->second].id;
|
||||
}
|
||||
|
||||
const Id id = m_nextId++;
|
||||
edge.id = id;
|
||||
m_edges.push_back(edge);
|
||||
m_edgesIndex.emplace(serialized, m_edges.size() - 1);
|
||||
return id;
|
||||
}
|
||||
|
||||
Id IntermediateStorage::addLocalSymbol(const std::string& name)
|
||||
{
|
||||
StorageLocalSymbol localSymbol = StorageLocalSymbol(0, name);
|
||||
|
||||
const std::string serialized = serialize(localSymbol);
|
||||
std::unordered_map<std::string, StorageLocalSymbol>::const_iterator it = m_localSymbols.find(serialized);
|
||||
if (it != m_localSymbols.end())
|
||||
{
|
||||
return it->second.id;
|
||||
}
|
||||
|
||||
const Id id = m_nextId++;
|
||||
localSymbol.id = id;
|
||||
m_localSymbols[serialized] = localSymbol;
|
||||
return id;
|
||||
}
|
||||
|
||||
Id IntermediateStorage::addSourceLocation(Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol, int type)
|
||||
{
|
||||
StorageSourceLocation sourceLocation = StorageSourceLocation(
|
||||
0,
|
||||
fileNodeId,
|
||||
startLine,
|
||||
startCol,
|
||||
endLine,
|
||||
endCol,
|
||||
type
|
||||
);
|
||||
|
||||
const std::string serialized = serialize(sourceLocation);
|
||||
std::unordered_map<std::string, StorageSourceLocation>::const_iterator it = m_sourceLocations.find(serialized);
|
||||
if (it != m_sourceLocations.end())
|
||||
{
|
||||
return it->second.id;
|
||||
}
|
||||
|
||||
const Id id = m_nextId++;
|
||||
sourceLocation.id = id;
|
||||
m_sourceLocations[serialized] = sourceLocation;
|
||||
return id;
|
||||
}
|
||||
|
||||
void IntermediateStorage::addOccurrence(Id elementId, Id sourceLocationId)
|
||||
{
|
||||
const StorageOccurrence occurrence(elementId, sourceLocationId);
|
||||
const std::string serialized = serialize(occurrence);
|
||||
|
||||
if (m_serializedOccurrences.find(serialized) == m_serializedOccurrences.end())
|
||||
{
|
||||
m_occurrences.push_back(occurrence);
|
||||
m_serializedOccurrences.insert(serialized);
|
||||
}
|
||||
}
|
||||
|
||||
void IntermediateStorage::addComponentAccess(Id nodeId, int type)
|
||||
{
|
||||
const StorageComponentAccess componentAccess(0, nodeId, type);
|
||||
const std::string serialized = serialize(componentAccess);
|
||||
|
||||
if (m_serializedComponentAccesses.find(serialized) == m_serializedComponentAccesses.end())
|
||||
{
|
||||
m_componentAccesses.push_back(componentAccess);
|
||||
m_serializedComponentAccesses.insert(serialized);
|
||||
}
|
||||
}
|
||||
|
||||
void IntermediateStorage::addCommentLocation(Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol)
|
||||
{
|
||||
const StorageCommentLocation commentLocation(
|
||||
0,
|
||||
fileNodeId,
|
||||
startLine,
|
||||
startCol,
|
||||
endLine,
|
||||
endCol
|
||||
);
|
||||
const std::string serialized = serialize(commentLocation);
|
||||
|
||||
if (m_serializedCommentLocations.find(serialized) == m_serializedCommentLocations.end())
|
||||
{
|
||||
m_commentLocations.push_back(commentLocation);
|
||||
m_serializedCommentLocations.insert(serialized);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void IntermediateStorage::addError(
|
||||
const std::string& message, const FilePath& filePath, uint startLine, uint startCol, bool fatal, bool indexed)
|
||||
{
|
||||
const StorageError error(
|
||||
0,
|
||||
message,
|
||||
filePath,
|
||||
startLine,
|
||||
startCol,
|
||||
fatal,
|
||||
indexed
|
||||
);
|
||||
const std::string serialized = serialize(error);
|
||||
|
||||
if (m_serializedErrors.find(serialized) == m_serializedErrors.end())
|
||||
{
|
||||
m_errors.push_back(error);
|
||||
m_serializedErrors.insert(serialized);
|
||||
}
|
||||
}
|
||||
|
||||
void IntermediateStorage::forEachNode(std::function<void(const StorageNode& /*data*/)> callback) const
|
||||
{
|
||||
for (const StorageNode& node : m_nodes)
|
||||
{
|
||||
callback(node);
|
||||
}
|
||||
}
|
||||
|
||||
void IntermediateStorage::forEachFile(std::function<void(const StorageFile& /*data*/)> callback) const
|
||||
{
|
||||
for (std::vector<StorageFile>::const_iterator it = m_files.begin(); it != m_files.end(); it++)
|
||||
{
|
||||
callback(*it);
|
||||
}
|
||||
}
|
||||
|
||||
void IntermediateStorage::forEachSymbol(std::function<void(const StorageSymbol& /*data*/)> callback) const
|
||||
{
|
||||
for (std::vector<StorageSymbol>::const_iterator it = m_symbols.begin(); it != m_symbols.end(); it++)
|
||||
{
|
||||
callback(*it);
|
||||
}
|
||||
}
|
||||
|
||||
void IntermediateStorage::forEachEdge(std::function<void(const StorageEdge& /*data*/)> callback) const
|
||||
{
|
||||
for (const StorageEdge& edge : m_edges)
|
||||
{
|
||||
callback(edge);
|
||||
}
|
||||
}
|
||||
|
||||
void IntermediateStorage::forEachLocalSymbol(std::function<void(const StorageLocalSymbol& /*data*/)> callback) const
|
||||
{
|
||||
for (std::unordered_map<std::string, StorageLocalSymbol>::const_iterator it = m_localSymbols.begin();
|
||||
it != m_localSymbols.end(); it++)
|
||||
{
|
||||
callback(it->second);
|
||||
}
|
||||
}
|
||||
|
||||
void IntermediateStorage::forEachSourceLocation(std::function<void(const StorageSourceLocation& /*data*/)> callback) const
|
||||
{
|
||||
for (std::unordered_map<std::string, StorageSourceLocation>::const_iterator it = m_sourceLocations.begin();
|
||||
it != m_sourceLocations.end(); it++)
|
||||
{
|
||||
callback(it->second);
|
||||
}
|
||||
}
|
||||
|
||||
void IntermediateStorage::forEachOccurrence(std::function<void(const StorageOccurrence& /*data*/)> callback) const
|
||||
{
|
||||
for (std::vector<StorageOccurrence>::const_iterator it = m_occurrences.begin(); it != m_occurrences.end(); it++)
|
||||
{
|
||||
callback(*it);
|
||||
}
|
||||
}
|
||||
|
||||
void IntermediateStorage::forEachComponentAccess(std::function<void(const StorageComponentAccess& /*data*/)> callback) const
|
||||
{
|
||||
for (std::vector<StorageComponentAccess>::const_iterator it = m_componentAccesses.begin(); it != m_componentAccesses.end(); it++)
|
||||
{
|
||||
callback(*it);
|
||||
}
|
||||
}
|
||||
|
||||
void IntermediateStorage::forEachCommentLocation(std::function<void(const StorageCommentLocation& /*data*/)> callback) const
|
||||
{
|
||||
for (std::vector<StorageCommentLocation>::const_iterator it = m_commentLocations.begin(); it != m_commentLocations.end(); it++)
|
||||
{
|
||||
callback(*it);
|
||||
}
|
||||
}
|
||||
|
||||
void IntermediateStorage::forEachError(std::function<void(const StorageError& /*data*/)> callback) const
|
||||
{
|
||||
for (std::vector<StorageError>::const_iterator it = m_errors.begin(); it != m_errors.end(); it++)
|
||||
{
|
||||
callback(*it);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<StorageNode> IntermediateStorage::getStorageNodes() const
|
||||
{
|
||||
return m_nodes;
|
||||
}
|
||||
|
||||
std::vector<StorageFile> IntermediateStorage::getStorageFiles() const
|
||||
{
|
||||
return m_files;
|
||||
}
|
||||
|
||||
std::vector<StorageSymbol> IntermediateStorage::getStorageSymbols() const
|
||||
{
|
||||
return m_symbols;
|
||||
}
|
||||
|
||||
std::vector<StorageEdge> IntermediateStorage::getStorageEdges() const
|
||||
{
|
||||
return m_edges;
|
||||
}
|
||||
|
||||
std::vector<StorageLocalSymbol> IntermediateStorage::getStorageLocalSymbols() const
|
||||
{
|
||||
std::vector<StorageLocalSymbol> localSymbol;
|
||||
localSymbol.reserve(m_localSymbols.size());
|
||||
for (auto it: m_localSymbols)
|
||||
{
|
||||
localSymbol.push_back(it.second);
|
||||
}
|
||||
return localSymbol;
|
||||
}
|
||||
|
||||
std::vector<StorageSourceLocation> IntermediateStorage::getStorageSourceLocations() const
|
||||
{
|
||||
std::vector<StorageSourceLocation> sourceLocations;
|
||||
sourceLocations.reserve(m_sourceLocations.size());
|
||||
for (auto it: m_sourceLocations)
|
||||
{
|
||||
sourceLocations.push_back(it.second);
|
||||
}
|
||||
return sourceLocations;
|
||||
}
|
||||
|
||||
std::vector<StorageOccurrence> IntermediateStorage::getStorageOccurrences() const
|
||||
{
|
||||
return m_occurrences;
|
||||
}
|
||||
|
||||
std::vector<StorageComponentAccess> IntermediateStorage::getComponentAccesses() const
|
||||
{
|
||||
return m_componentAccesses;
|
||||
}
|
||||
|
||||
std::vector<StorageCommentLocation> IntermediateStorage::getCommentLocations() const
|
||||
{
|
||||
return m_commentLocations;
|
||||
}
|
||||
|
||||
std::vector<StorageError> IntermediateStorage::getErrors() const
|
||||
{
|
||||
return m_errors;
|
||||
}
|
||||
|
||||
void IntermediateStorage::setStorageNodes(const std::vector<StorageNode>& storageNodes)
|
||||
{
|
||||
m_nodes.clear();
|
||||
m_nodesIndex.clear();
|
||||
for (const StorageNode& storageNode: storageNodes)
|
||||
{
|
||||
m_nodes.push_back(storageNode);
|
||||
m_nodesIndex.emplace(serialize(storageNode), m_nodes.size() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void IntermediateStorage::setStorageFiles(const std::vector<StorageFile>& storageFiles)
|
||||
{
|
||||
m_files = storageFiles;
|
||||
}
|
||||
|
||||
void IntermediateStorage::setStorageSymbols(const std::vector<StorageSymbol>& storageSymbols)
|
||||
{
|
||||
m_symbols = storageSymbols;
|
||||
}
|
||||
|
||||
void IntermediateStorage::setStorageEdges(const std::vector<StorageEdge>& storageEdges)
|
||||
{
|
||||
m_edges.clear();
|
||||
m_edgesIndex.clear();
|
||||
for (const StorageEdge& storageEdge: storageEdges)
|
||||
{
|
||||
m_edges.push_back(storageEdge);
|
||||
m_edgesIndex.emplace(serialize(storageEdge), m_edges.size() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void IntermediateStorage::setStorageLocalSymbols(const std::vector<StorageLocalSymbol>& storageLocalSymbols)
|
||||
{
|
||||
m_localSymbols.clear();
|
||||
for (const StorageLocalSymbol& storageLocalSymbol: storageLocalSymbols)
|
||||
{
|
||||
m_localSymbols[serialize(storageLocalSymbol)] = storageLocalSymbol;
|
||||
}
|
||||
}
|
||||
|
||||
void IntermediateStorage::setStorageSourceLocations(const std::vector<StorageSourceLocation>& storageSourceLocations)
|
||||
{
|
||||
m_sourceLocations.clear();
|
||||
for (const StorageSourceLocation& storageSourceLocation: storageSourceLocations)
|
||||
{
|
||||
m_sourceLocations[serialize(storageSourceLocation)] = storageSourceLocation;
|
||||
}
|
||||
}
|
||||
|
||||
void IntermediateStorage::setStorageOccurrences(const std::vector<StorageOccurrence>& storageOccurrences)
|
||||
{
|
||||
m_occurrences = storageOccurrences;
|
||||
}
|
||||
|
||||
void IntermediateStorage::setComponentAccesses(const std::vector<StorageComponentAccess>& componentAccesses)
|
||||
{
|
||||
m_componentAccesses = componentAccesses;
|
||||
}
|
||||
|
||||
void IntermediateStorage::setCommentLocations(const std::vector<StorageCommentLocation>& commentLocations)
|
||||
{
|
||||
m_commentLocations = commentLocations;
|
||||
}
|
||||
|
||||
void IntermediateStorage::setErrors(const std::vector<StorageError>& errors)
|
||||
{
|
||||
m_errors = errors;
|
||||
}
|
||||
|
||||
Id IntermediateStorage::getNextId() const
|
||||
{
|
||||
return m_nextId;
|
||||
}
|
||||
|
||||
void IntermediateStorage::setNextId(const Id nextId)
|
||||
{
|
||||
m_nextId = nextId;
|
||||
}
|
||||
|
||||
std::string IntermediateStorage::serialize(const StorageNode& node) const
|
||||
{
|
||||
return node.serializedName;
|
||||
}
|
||||
|
||||
std::string IntermediateStorage::serialize(const StorageFile& file) const
|
||||
{
|
||||
return file.filePath;
|
||||
}
|
||||
|
||||
std::string IntermediateStorage::serialize(const StorageEdge& edge) const
|
||||
{
|
||||
return (
|
||||
std::to_string(edge.type) + ";" +
|
||||
std::to_string(edge.sourceNodeId) + ";" +
|
||||
std::to_string(edge.targetNodeId)
|
||||
);
|
||||
}
|
||||
|
||||
std::string IntermediateStorage::serialize(const StorageLocalSymbol& localSymbol) const
|
||||
{
|
||||
return localSymbol.name;
|
||||
}
|
||||
|
||||
std::string IntermediateStorage::serialize(const StorageSourceLocation& sourceLocation) const
|
||||
{
|
||||
return (
|
||||
std::to_string(sourceLocation.fileNodeId) + ";" +
|
||||
std::to_string(sourceLocation.startLine) + ";" +
|
||||
std::to_string(sourceLocation.startCol) + ";" +
|
||||
std::to_string(sourceLocation.endLine) + ";" +
|
||||
std::to_string(sourceLocation.endCol) + ";" +
|
||||
std::to_string(sourceLocation.type)
|
||||
);
|
||||
}
|
||||
|
||||
std::string IntermediateStorage::serialize(const StorageOccurrence& occurrence) const
|
||||
{
|
||||
return std::to_string(occurrence.elementId) + ";" + std::to_string(occurrence.sourceLocationId);
|
||||
}
|
||||
|
||||
|
||||
std::string IntermediateStorage::serialize(const StorageComponentAccess& componentAccess) const
|
||||
{
|
||||
return std::to_string(componentAccess.nodeId);
|
||||
}
|
||||
|
||||
|
||||
std::string IntermediateStorage::serialize(const StorageCommentLocation& commentLocation) const
|
||||
{
|
||||
return (
|
||||
std::to_string(commentLocation.fileNodeId) + ";" +
|
||||
std::to_string(commentLocation.startLine) + ";" +
|
||||
std::to_string(commentLocation.startCol) + ";" +
|
||||
std::to_string(commentLocation.endLine) + ";" +
|
||||
std::to_string(commentLocation.endCol)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
std::string IntermediateStorage::serialize(const StorageError& error) const
|
||||
{
|
||||
return (
|
||||
error.message + ";" +
|
||||
std::to_string(error.fatal) + ";" +
|
||||
error.filePath.str() + ";" +
|
||||
std::to_string(error.lineNumber) + ";" +
|
||||
std::to_string(error.columnNumber)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
#ifndef INTERMEDIATE_STORAGE_H
|
||||
#define INTERMEDIATE_STORAGE_H
|
||||
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "data/storage/StorageTypes.h"
|
||||
#include "data/storage/Storage.h"
|
||||
|
||||
class IntermediateStorage: public Storage
|
||||
{
|
||||
public:
|
||||
IntermediateStorage();
|
||||
virtual ~IntermediateStorage();
|
||||
|
||||
void clear();
|
||||
|
||||
size_t getByteSize() const;
|
||||
size_t getSourceLocationCount() const;
|
||||
|
||||
void setAllFilesIncomplete();
|
||||
void setFilesWithErrorsIncomplete();
|
||||
|
||||
virtual Id addNode(int type, const std::string& serializedName);
|
||||
virtual void addFile(const Id id, const std::string& filePath, const std::string& modificationTime, bool complete);
|
||||
virtual void addSymbol(const Id id, int definitionKind);
|
||||
virtual Id addEdge(int type, Id sourceId, Id targetId);
|
||||
virtual Id addLocalSymbol(const std::string& name);
|
||||
virtual Id addSourceLocation(Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol, int type);
|
||||
virtual void addOccurrence(Id elementId, Id sourceLocationId);
|
||||
virtual void addComponentAccess(Id nodeId , int type);
|
||||
virtual void addCommentLocation(Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol);
|
||||
virtual void addError(const std::string& message, const FilePath& filePath, uint startLine, uint startCol, bool fatal, bool indexed);
|
||||
|
||||
virtual void forEachNode(std::function<void(const StorageNode& /*data*/)> callback) const;
|
||||
virtual void forEachFile(std::function<void(const StorageFile& /*data*/)> callback) const;
|
||||
virtual void forEachSymbol(std::function<void(const StorageSymbol& /*data*/)> callback) const;
|
||||
virtual void forEachEdge(std::function<void(const StorageEdge& /*data*/)> callback) const;
|
||||
virtual void forEachLocalSymbol(std::function<void(const StorageLocalSymbol& /*data*/)> callback) const;
|
||||
virtual void forEachSourceLocation(std::function<void(const StorageSourceLocation& /*data*/)> callback) const;
|
||||
virtual void forEachOccurrence(std::function<void(const StorageOccurrence& /*data*/)> callback) const;
|
||||
virtual void forEachComponentAccess(std::function<void(const StorageComponentAccess& /*data*/)> callback) const;
|
||||
virtual void forEachCommentLocation(std::function<void(const StorageCommentLocation& /*data*/)> callback) const;
|
||||
virtual void forEachError(std::function<void(const StorageError& /*data*/)> callback) const;
|
||||
|
||||
|
||||
// for conversion to and from 'SharedIntermediateStorage'
|
||||
|
||||
std::vector<StorageNode> getStorageNodes() const;
|
||||
std::vector<StorageFile> getStorageFiles() const;
|
||||
std::vector<StorageSymbol> getStorageSymbols() const;
|
||||
std::vector<StorageEdge> getStorageEdges() const;
|
||||
std::vector<StorageLocalSymbol> getStorageLocalSymbols() const;
|
||||
std::vector<StorageSourceLocation> getStorageSourceLocations() const;
|
||||
std::vector<StorageOccurrence> getStorageOccurrences() const;
|
||||
std::vector<StorageComponentAccess> getComponentAccesses() const;
|
||||
std::vector<StorageCommentLocation> getCommentLocations() const;
|
||||
std::vector<StorageError> getErrors() const;
|
||||
|
||||
void setStorageNodes(const std::vector<StorageNode>& storageNodes);
|
||||
void setStorageFiles(const std::vector<StorageFile>& storageFiles);
|
||||
void setStorageSymbols(const std::vector<StorageSymbol>& storageSymbols);
|
||||
void setStorageEdges(const std::vector<StorageEdge>& storageEdges);
|
||||
void setStorageLocalSymbols(const std::vector<StorageLocalSymbol>& storageLocalSymbols);
|
||||
void setStorageSourceLocations(const std::vector<StorageSourceLocation>& storageSourceLocations);
|
||||
void setStorageOccurrences(const std::vector<StorageOccurrence>& storageOccurrences);
|
||||
void setComponentAccesses(const std::vector<StorageComponentAccess>& componentAccesses);
|
||||
void setCommentLocations(const std::vector<StorageCommentLocation>& commentLocations);
|
||||
void setErrors(const std::vector<StorageError>& errors);
|
||||
|
||||
Id getNextId() const;
|
||||
void setNextId(const Id nextId);
|
||||
|
||||
private:
|
||||
std::string serialize(const StorageNode& node) const;
|
||||
std::string serialize(const StorageFile& file) const;
|
||||
std::string serialize(const StorageEdge& edge) const;
|
||||
std::string serialize(const StorageLocalSymbol& localSymbol) const;
|
||||
std::string serialize(const StorageSourceLocation& sourceLocation) const;
|
||||
std::string serialize(const StorageOccurrence& occurrence) const;
|
||||
std::string serialize(const StorageComponentAccess& componentAccess) const;
|
||||
std::string serialize(const StorageCommentLocation& commentLocation) const;
|
||||
std::string serialize(const StorageError& error) const;
|
||||
|
||||
std::unordered_map<std::string, size_t> m_nodesIndex;
|
||||
std::vector<StorageNode> m_nodes;
|
||||
|
||||
std::unordered_set<std::string> m_serializedFiles; // this is used to prevent duplicates (unique)
|
||||
std::vector<StorageFile> m_files;
|
||||
|
||||
std::vector<StorageSymbol> m_symbols;
|
||||
|
||||
std::unordered_map<std::string, size_t> m_edgesIndex;
|
||||
std::vector<StorageEdge> m_edges;
|
||||
|
||||
std::unordered_map<std::string, StorageLocalSymbol> m_localSymbols;
|
||||
|
||||
std::unordered_map<std::string, StorageSourceLocation> m_sourceLocations;
|
||||
|
||||
std::unordered_set<std::string> m_serializedOccurrences; // this is used to prevent duplicates (unique)
|
||||
std::vector<StorageOccurrence> m_occurrences;
|
||||
|
||||
std::unordered_set<std::string> m_serializedComponentAccesses; // this is used to prevent duplicates (unique)
|
||||
std::vector<StorageComponentAccess> m_componentAccesses;
|
||||
|
||||
std::unordered_set<std::string> m_serializedCommentLocations; // this is used to prevent duplicates (unique)
|
||||
std::vector<StorageCommentLocation> m_commentLocations;
|
||||
|
||||
std::unordered_set<std::string> m_serializedErrors; // this is used to prevent duplicates (unique)
|
||||
std::vector<StorageError> m_errors;
|
||||
|
||||
Id m_nextId;
|
||||
};
|
||||
|
||||
#endif // INTERMEDIATE_STORAGE_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,195 @@
|
||||
#ifndef PERSISTENT_STORAGE_H
|
||||
#define PERSISTENT_STORAGE_H
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "data/access/StorageAccess.h"
|
||||
#include "data/fulltextsearch/FullTextSearchIndex.h"
|
||||
#include "data/search/SearchIndex.h"
|
||||
#include "data/HierarchyCache.h"
|
||||
#include "data/storage/sqlite/SqliteIndexStorage.h"
|
||||
#include "data/storage/sqlite/SqliteBookmarkStorage.h"
|
||||
#include "data/storage/Storage.h"
|
||||
|
||||
class PersistentStorage
|
||||
: public Storage
|
||||
, public StorageAccess
|
||||
{
|
||||
public:
|
||||
PersistentStorage(const FilePath& dbPath, const FilePath& bookmarkPath);
|
||||
virtual ~PersistentStorage();
|
||||
|
||||
virtual Id addNode(int type, const std::string& serializedName);
|
||||
virtual void addFile(const Id id, const std::string& filePath, const std::string& modificationTime, bool complete);
|
||||
virtual void addSymbol(const Id id, int definitionKind);
|
||||
virtual Id addEdge(int type, Id sourceId, Id targetId);
|
||||
virtual Id addLocalSymbol(const std::string& name);
|
||||
virtual Id addSourceLocation(Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol, int type);
|
||||
virtual void addOccurrence(Id elementId, Id sourceLocationId);
|
||||
virtual void addComponentAccess(Id nodeId , int type);
|
||||
virtual void addCommentLocation(Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol);
|
||||
virtual void addError(const std::string& message, const FilePath& filePath, uint startLine, uint startCol, bool fatal, bool indexed);
|
||||
virtual Id addNodeBookmark(const NodeBookmark& bookmark);
|
||||
virtual Id addEdgeBookmark(const EdgeBookmark& bookmark);
|
||||
virtual Id addBookmarkCategory(const std::string& categoryName);
|
||||
|
||||
void updateBookmark(const Id bookmarkId, const std::string& name, const std::string& comment, const std::string& categoryName);
|
||||
|
||||
virtual void removeBookmark(const Id id);
|
||||
virtual void removeBookmarkCategory(const Id id);
|
||||
|
||||
std::vector<NodeBookmark> getAllNodeBookmarks() const;
|
||||
std::vector<EdgeBookmark> getAllEdgeBookmarks() const;
|
||||
|
||||
|
||||
virtual std::vector<BookmarkCategory> getAllBookmarkCategories() const;
|
||||
|
||||
virtual void forEachNode(std::function<void(const StorageNode& /*data*/)> callback) const;
|
||||
virtual void forEachFile(std::function<void(const StorageFile& /*data*/)> callback) const;
|
||||
virtual void forEachSymbol(std::function<void(const StorageSymbol& /*data*/)> callback) const;
|
||||
virtual void forEachEdge(std::function<void(const StorageEdge& /*data*/)> callback) const;
|
||||
virtual void forEachLocalSymbol(std::function<void(const StorageLocalSymbol& /*data*/)> callback) const;
|
||||
virtual void forEachSourceLocation(std::function<void(const StorageSourceLocation& /*data*/)> callback) const;
|
||||
virtual void forEachOccurrence(std::function<void(const StorageOccurrence& /*data*/)> callback) const;
|
||||
virtual void forEachComponentAccess(std::function<void(const StorageComponentAccess& /*data*/)> callback) const;
|
||||
virtual void forEachCommentLocation(std::function<void(const StorageCommentLocation& /*data*/)> callback) const;
|
||||
virtual void forEachError(std::function<void(const StorageError& /*data*/)> callback) const;
|
||||
|
||||
virtual void startInjection();
|
||||
virtual void finishInjection();
|
||||
|
||||
void setMode(const SqliteIndexStorage::StorageModeType mode);
|
||||
|
||||
FilePath getDbFilePath() const;
|
||||
|
||||
bool isEmpty() const;
|
||||
bool isIncompatible() const;
|
||||
std::string getProjectSettingsText() const;
|
||||
void setProjectSettingsText(std::string text);
|
||||
|
||||
void setup();
|
||||
void clear();
|
||||
void clearCaches();
|
||||
|
||||
std::set<FilePath> getReferenced(const std::set<FilePath>& filePaths);
|
||||
std::set<FilePath> getReferencing(const std::set<FilePath>& filePaths);
|
||||
|
||||
void clearFileElements(const std::vector<FilePath>& filePaths, std::function<void(int)> updateStatusCallback);
|
||||
|
||||
std::vector<FileInfo> getInfoOnAllFiles() const;
|
||||
|
||||
void buildCaches();
|
||||
|
||||
void optimizeMemory();
|
||||
|
||||
// StorageAccess implementation
|
||||
virtual Id getNodeIdForFileNode(const FilePath& filePath) const;
|
||||
virtual Id getNodeIdForNameHierarchy(const NameHierarchy& nameHierarchy) const;
|
||||
virtual std::vector<Id> getNodeIdsForNameHierarchies(const std::vector<NameHierarchy> nameHierarchies) const;
|
||||
|
||||
virtual NameHierarchy getNameHierarchyForNodeId(Id nodeId) const;
|
||||
virtual std::vector<NameHierarchy> getNameHierarchiesForNodeIds(const std::vector<Id> nodeIds) const;
|
||||
|
||||
virtual Node::NodeType getNodeTypeForNodeWithId(Id nodeId) const;
|
||||
|
||||
virtual Id getIdForEdge(
|
||||
Edge::EdgeType type, const NameHierarchy& fromNameHierarchy, const NameHierarchy& toNameHierarchy) const;
|
||||
virtual StorageEdge getEdgeById(Id edgeId) const;
|
||||
|
||||
virtual std::shared_ptr<SourceLocationCollection> getFullTextSearchLocations(
|
||||
const std::string& searchTerm, bool caseSensitive) const;
|
||||
|
||||
virtual std::vector<SearchMatch> getAutocompletionMatches(const std::string& query) const;
|
||||
std::vector<SearchMatch> getAutocompletionSymbolMatches(const std::string& query, size_t maxResultsCount) const;
|
||||
std::vector<SearchMatch> getAutocompletionFileMatches(const std::string& query, size_t maxResultsCount) const;
|
||||
std::vector<SearchMatch> getAutocompletionCommandMatches(const std::string& query) const;
|
||||
virtual std::vector<SearchMatch> getSearchMatchesForTokenIds(const std::vector<Id>& elementIds) const;
|
||||
|
||||
virtual std::shared_ptr<Graph> getGraphForAll() const;
|
||||
virtual std::shared_ptr<Graph> getGraphForActiveTokenIds(
|
||||
const std::vector<Id>& tokenIds, const std::vector<Id>& expandedNodeIds, bool* isActiveNamespace = nullptr) const;
|
||||
virtual std::shared_ptr<Graph> getGraphForChildrenOfNodeId(Id nodeId) const;
|
||||
virtual std::shared_ptr<Graph> getGraphForTrail(Id originId, Id targetId, Edge::EdgeTypeMask trailType, size_t depth) const;
|
||||
|
||||
virtual std::vector<Id> getActiveTokenIdsForId(Id tokenId, Id* declarationId) const;
|
||||
virtual std::vector<Id> getNodeIdsForLocationIds(const std::vector<Id>& locationIds) const;
|
||||
|
||||
virtual std::shared_ptr<SourceLocationCollection> getSourceLocationsForTokenIds(const std::vector<Id>& tokenIds) const;
|
||||
virtual std::shared_ptr<SourceLocationCollection> getSourceLocationsForLocationIds(const std::vector<Id>& locationIds) const;
|
||||
|
||||
virtual std::shared_ptr<SourceLocationFile> getSourceLocationsForFile(const FilePath& filePath) const;
|
||||
virtual std::shared_ptr<SourceLocationFile> getSourceLocationsForLinesInFile(
|
||||
const FilePath& filePath, uint firstLineNumber, uint lastLineNumber
|
||||
) const;
|
||||
|
||||
virtual std::shared_ptr<SourceLocationFile> getCommentLocationsInFile(const FilePath& filePath) const;
|
||||
|
||||
virtual std::shared_ptr<TextAccess> getFileContent(const FilePath& filePath) const;
|
||||
|
||||
virtual FileInfo getFileInfoForFilePath(const FilePath& filePath) const;
|
||||
virtual std::vector<FileInfo> getFileInfosForFilePaths(const std::vector<FilePath>& filePaths) const;
|
||||
|
||||
virtual StorageStats getStorageStats() const;
|
||||
|
||||
virtual ErrorCountInfo getErrorCount() const;
|
||||
virtual ErrorCountInfo getErrorCount(const std::vector<ErrorInfo>& errors) const;
|
||||
virtual std::vector<ErrorInfo> getErrors() const;
|
||||
virtual std::vector<ErrorInfo> getErrorsLimited() const;
|
||||
virtual std::shared_ptr<SourceLocationCollection> getErrorSourceLocationsLimited(std::vector<ErrorInfo>* errors) const;
|
||||
|
||||
private:
|
||||
Id getFileNodeId(const FilePath& filePath) const;
|
||||
std::vector<Id> getFileNodeIds(const std::vector<FilePath>& filePaths) const;
|
||||
std::set<Id> getFileNodeIds(const std::set<FilePath>& filePaths) const;
|
||||
FilePath getFileNodePath(Id fileId) const;
|
||||
bool getFileNodeComplete(const FilePath& filePath) const;
|
||||
|
||||
std::unordered_map<Id, std::set<Id>> getFileIdToIncludingFileIdMap() const;
|
||||
std::unordered_map<Id, std::set<Id>> getFileIdToImportingFileIdMap() const;
|
||||
std::set<Id> getReferenced(const std::set<Id>& filePaths, std::unordered_map<Id, std::set<Id>> idToReferencingIdMap) const;
|
||||
std::set<Id> getReferencing(const std::set<Id>& filePaths, std::unordered_map<Id, std::set<Id>> idToReferencingIdMap) const;
|
||||
|
||||
std::set<FilePath> getReferencedByIncludes(const std::set<FilePath>& filePaths);
|
||||
std::set<FilePath> getReferencedByImports(const std::set<FilePath>& filePaths);
|
||||
|
||||
std::set<FilePath> getReferencingByIncludes(const std::set<FilePath>& filePaths);
|
||||
std::set<FilePath> getReferencingByImports(const std::set<FilePath>& filePaths);
|
||||
|
||||
void addNodesToGraph(const std::vector<Id>& nodeIds, Graph* graph, bool addChildCount) const;
|
||||
void addEdgesToGraph(const std::vector<Id>& edgeIds, Graph* graph) const;
|
||||
void addNodesWithParentsAndEdgesToGraph(
|
||||
const std::vector<Id>& nodeIds, const std::vector<Id>& edgeIds, Graph* graph) const;
|
||||
|
||||
void addAggregationEdgesToGraph(const Id nodeId, const std::vector<StorageEdge>& edgesToAggregate, Graph* graph) const;
|
||||
void addComponentAccessToGraph(Graph* graph) const;
|
||||
|
||||
void addCompleteFlagsToSourceLocationCollection(SourceLocationCollection* collection) const;
|
||||
void addInheritanceChainsToGraph(const std::vector<Id>& nodeIds, Graph* graph) const;
|
||||
|
||||
void buildFilePathMaps();
|
||||
void buildSearchIndex();
|
||||
void buildFullTextSearchIndex() const;
|
||||
void buildHierarchyCache();
|
||||
|
||||
size_t m_preInjectionErrorCount;
|
||||
|
||||
SearchIndex m_commandIndex;
|
||||
SearchIndex m_symbolIndex;
|
||||
SearchIndex m_fileIndex;
|
||||
|
||||
mutable FullTextSearchIndex m_fullTextSearchIndex;
|
||||
|
||||
SqliteIndexStorage m_sqliteIndexStorage;
|
||||
SqliteBookmarkStorage m_sqliteBookmarkStorage;
|
||||
|
||||
std::map<FilePath, Id> m_fileNodeIds;
|
||||
std::map<Id, FilePath> m_fileNodePaths;
|
||||
std::map<Id, bool> m_fileNodeComplete;
|
||||
|
||||
std::map<Id, DefinitionKind> m_symbolDefinitionKinds;
|
||||
|
||||
HierarchyCache m_hierarchyCache;
|
||||
};
|
||||
|
||||
#endif // PERSISTENT_STORAGE_H
|
||||
@@ -0,0 +1,213 @@
|
||||
#include "data/storage/Storage.h"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include "data/storage/StorageTypes.h"
|
||||
#include "utility/tracing.h"
|
||||
|
||||
Storage::Storage()
|
||||
{
|
||||
}
|
||||
|
||||
Storage::~Storage()
|
||||
{
|
||||
}
|
||||
|
||||
void Storage::inject(Storage* injected)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_dataMutex);
|
||||
|
||||
TRACE();
|
||||
startInjection();
|
||||
|
||||
std::unordered_map<Id, Id> injectedIdToOwnId;
|
||||
|
||||
injected->forEachNode(
|
||||
[&](const StorageNode& injectedData)
|
||||
{
|
||||
const Id ownId = addNode(injectedData.type, injectedData.serializedName);
|
||||
if (ownId != 0)
|
||||
{
|
||||
injectedIdToOwnId[injectedData.id] = ownId;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
injected->forEachFile(
|
||||
[&](const StorageFile& injectedData)
|
||||
{
|
||||
std::unordered_map<Id, Id>::const_iterator it;
|
||||
it = injectedIdToOwnId.find(injectedData.id);
|
||||
if (it == injectedIdToOwnId.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
const Id ownId = it->second;
|
||||
|
||||
addFile(ownId, injectedData.filePath, injectedData.modificationTime, injectedData.complete);
|
||||
}
|
||||
);
|
||||
|
||||
injected->forEachSymbol(
|
||||
[&](const StorageSymbol& injectedData)
|
||||
{
|
||||
std::unordered_map<Id, Id>::const_iterator it;
|
||||
it = injectedIdToOwnId.find(injectedData.id);
|
||||
if (it == injectedIdToOwnId.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
const Id ownId = it->second;
|
||||
|
||||
addSymbol(ownId, injectedData.definitionKind);
|
||||
}
|
||||
);
|
||||
|
||||
injected->forEachEdge(
|
||||
[&](const StorageEdge& injectedData)
|
||||
{
|
||||
std::unordered_map<Id, Id>::const_iterator it;
|
||||
it = injectedIdToOwnId.find(injectedData.sourceNodeId);
|
||||
if (it == injectedIdToOwnId.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
const Id ownSourceId = it->second;
|
||||
|
||||
it = injectedIdToOwnId.find(injectedData.targetNodeId);
|
||||
if (it == injectedIdToOwnId.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
const Id ownTargetId = it->second;
|
||||
|
||||
const Id ownId = addEdge(injectedData.type, ownSourceId, ownTargetId);
|
||||
|
||||
if (ownId != 0)
|
||||
{
|
||||
injectedIdToOwnId[injectedData.id] = ownId;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
injected->forEachLocalSymbol(
|
||||
[&](const StorageLocalSymbol& injectedData)
|
||||
{
|
||||
const Id ownId = addLocalSymbol(injectedData.name);
|
||||
if (ownId != 0)
|
||||
{
|
||||
injectedIdToOwnId[injectedData.id] = ownId;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
injected->forEachSourceLocation(
|
||||
[&](const StorageSourceLocation& injectedData)
|
||||
{
|
||||
std::unordered_map<Id, Id>::const_iterator it;
|
||||
it = injectedIdToOwnId.find(injectedData.fileNodeId);
|
||||
if (it == injectedIdToOwnId.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
const Id ownFileNodeId = it->second;
|
||||
|
||||
const Id ownId = addSourceLocation(
|
||||
ownFileNodeId,
|
||||
injectedData.startLine,
|
||||
injectedData.startCol,
|
||||
injectedData.endLine,
|
||||
injectedData.endCol,
|
||||
injectedData.type
|
||||
);
|
||||
if (ownId != 0)
|
||||
{
|
||||
injectedIdToOwnId[injectedData.id] = ownId;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
injected->forEachOccurrence(
|
||||
[&](const StorageOccurrence& injectedData)
|
||||
{
|
||||
std::unordered_map<Id, Id>::const_iterator it;
|
||||
it = injectedIdToOwnId.find(injectedData.elementId);
|
||||
if (it == injectedIdToOwnId.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
const Id ownElementId = it->second;
|
||||
|
||||
it = injectedIdToOwnId.find(injectedData.sourceLocationId);
|
||||
if (it == injectedIdToOwnId.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
const Id ownSourceLocationId = it->second;
|
||||
|
||||
addOccurrence(ownElementId, ownSourceLocationId);
|
||||
}
|
||||
);
|
||||
|
||||
injected->forEachComponentAccess(
|
||||
[&](const StorageComponentAccess& injectedData)
|
||||
{
|
||||
std::unordered_map<Id, Id>::const_iterator it;
|
||||
it = injectedIdToOwnId.find(injectedData.nodeId);
|
||||
if (it == injectedIdToOwnId.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
const Id ownNodeId = it->second;
|
||||
|
||||
addComponentAccess(ownNodeId, injectedData.type);
|
||||
}
|
||||
);
|
||||
|
||||
injected->forEachCommentLocation(
|
||||
[&](const StorageCommentLocation& injectedData)
|
||||
{
|
||||
std::unordered_map<Id, Id>::const_iterator it;
|
||||
it = injectedIdToOwnId.find(injectedData.fileNodeId);
|
||||
if (it == injectedIdToOwnId.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
const Id ownFileNodeId = it->second;
|
||||
|
||||
addCommentLocation(
|
||||
ownFileNodeId,
|
||||
injectedData.startLine,
|
||||
injectedData.startCol,
|
||||
injectedData.endLine,
|
||||
injectedData.endCol
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
injected->forEachError(
|
||||
[&](const StorageError& injectedData)
|
||||
{
|
||||
addError(
|
||||
injectedData.message,
|
||||
injectedData.filePath,
|
||||
injectedData.lineNumber,
|
||||
injectedData.columnNumber,
|
||||
injectedData.fatal,
|
||||
injectedData.indexed
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
finishInjection();
|
||||
}
|
||||
|
||||
void Storage::startInjection()
|
||||
{
|
||||
// may be implemented in derived
|
||||
}
|
||||
|
||||
void Storage::finishInjection()
|
||||
{
|
||||
// may be implemented in derived
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#ifndef STORAGE_H
|
||||
#define STORAGE_H
|
||||
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
#include "data/storage/StorageTypes.h"
|
||||
#include "utility/types.h"
|
||||
|
||||
class Storage
|
||||
{
|
||||
public:
|
||||
Storage();
|
||||
virtual ~Storage();
|
||||
|
||||
virtual Id addNode(int type, const std::string& serializedName) = 0;
|
||||
virtual void addFile(const Id id, const std::string& filePath, const std::string& modificationTime, bool complete) = 0;
|
||||
virtual void addSymbol(const Id id, int definitionKind) = 0;
|
||||
virtual Id addEdge(int type, Id sourceId, Id targetId) = 0;
|
||||
virtual Id addLocalSymbol(const std::string& name) = 0;
|
||||
virtual Id addSourceLocation(Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol, int type) = 0;
|
||||
virtual void addOccurrence(Id elementId, Id sourceLocationId) = 0;
|
||||
virtual void addComponentAccess(Id nodeId , int type) = 0;
|
||||
virtual void addCommentLocation(Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol) = 0;
|
||||
virtual void addError(const std::string& message, const FilePath& filePath, uint startLine, uint startCol, bool fatal, bool indexed) = 0;
|
||||
|
||||
virtual void forEachNode(std::function<void(const StorageNode& /*data*/)> callback) const = 0;
|
||||
virtual void forEachFile(std::function<void(const StorageFile& /*data*/)> callback) const = 0;
|
||||
virtual void forEachSymbol(std::function<void(const StorageSymbol& /*data*/)> callback) const = 0;
|
||||
virtual void forEachEdge(std::function<void(const StorageEdge& /*data*/)> callback) const = 0;
|
||||
virtual void forEachLocalSymbol(std::function<void(const StorageLocalSymbol& /*data*/)> callback) const = 0;
|
||||
virtual void forEachSourceLocation(std::function<void(const StorageSourceLocation& /*data*/)> callback) const = 0;
|
||||
virtual void forEachOccurrence(std::function<void(const StorageOccurrence& /*data*/)> callback) const = 0;
|
||||
virtual void forEachComponentAccess(std::function<void(const StorageComponentAccess& /*data*/)> callback) const = 0;
|
||||
virtual void forEachCommentLocation(std::function<void(const StorageCommentLocation& /*data*/)> callback) const = 0;
|
||||
virtual void forEachError(std::function<void(const StorageError& /*data*/)> callback) const = 0;
|
||||
|
||||
void inject(Storage* injected);
|
||||
|
||||
private:
|
||||
virtual void startInjection();
|
||||
virtual void finishInjection();
|
||||
|
||||
std::mutex m_dataMutex;
|
||||
};
|
||||
|
||||
#endif // STORAGE_H
|
||||
@@ -0,0 +1,28 @@
|
||||
#include "data/storage/StorageCache.h"
|
||||
|
||||
void StorageCache::clear()
|
||||
{
|
||||
m_graphForAll.reset();
|
||||
|
||||
m_storageStats = StorageStats();
|
||||
}
|
||||
|
||||
std::shared_ptr<Graph> StorageCache::getGraphForAll() const
|
||||
{
|
||||
if (!m_graphForAll)
|
||||
{
|
||||
m_graphForAll = StorageAccessProxy::getGraphForAll();
|
||||
}
|
||||
|
||||
return m_graphForAll;
|
||||
}
|
||||
|
||||
StorageStats StorageCache::getStorageStats() const
|
||||
{
|
||||
if (!m_storageStats.nodeCount)
|
||||
{
|
||||
m_storageStats = StorageAccessProxy::getStorageStats();
|
||||
}
|
||||
|
||||
return m_storageStats;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef STORAGE_CACHE_H
|
||||
#define STORAGE_CACHE_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "data/access/StorageAccessProxy.h"
|
||||
|
||||
class StorageCache
|
||||
: public StorageAccessProxy
|
||||
{
|
||||
public:
|
||||
void clear();
|
||||
|
||||
virtual std::shared_ptr<Graph> getGraphForAll() const;
|
||||
|
||||
virtual StorageStats getStorageStats() const;
|
||||
|
||||
private:
|
||||
mutable std::shared_ptr<Graph> m_graphForAll;
|
||||
mutable StorageStats m_storageStats;
|
||||
};
|
||||
|
||||
#endif // STORAGE_CACHE_H
|
||||
@@ -0,0 +1,72 @@
|
||||
#include "data/storage/StorageProvider.h"
|
||||
|
||||
#include "utility/logging/logging.h"
|
||||
|
||||
int StorageProvider::getStorageCount() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_storagesMutex);
|
||||
return m_storages.size();
|
||||
}
|
||||
|
||||
void StorageProvider::insert(std::shared_ptr<IntermediateStorage> storage)
|
||||
{
|
||||
const std::size_t storageSize = storage->getSourceLocationCount();
|
||||
std::list<std::shared_ptr<IntermediateStorage>>::iterator it;
|
||||
|
||||
std::lock_guard<std::mutex> lock(m_storagesMutex);
|
||||
for (it = m_storages.begin(); it != m_storages.end(); it++)
|
||||
{
|
||||
if ((*it)->getSourceLocationCount() < storageSize)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_storages.insert(it, storage);
|
||||
}
|
||||
|
||||
std::shared_ptr<IntermediateStorage> StorageProvider::consumeSecondLargestStorage()
|
||||
{
|
||||
std::shared_ptr<IntermediateStorage> ret;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_storagesMutex);
|
||||
if (m_storages.size() > 1)
|
||||
{
|
||||
std::list<std::shared_ptr<IntermediateStorage>>::iterator it = m_storages.begin();
|
||||
it++;
|
||||
ret = *it;
|
||||
m_storages.erase(it);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::shared_ptr<IntermediateStorage> StorageProvider::consumeLargestStorage()
|
||||
{
|
||||
std::shared_ptr<IntermediateStorage> ret;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_storagesMutex);
|
||||
if (!m_storages.empty())
|
||||
{
|
||||
ret = m_storages.front();
|
||||
m_storages.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void StorageProvider::logCurrentState() const
|
||||
{
|
||||
std::string logString = "Storages waiting for injection:";
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_storagesMutex);
|
||||
for (std::shared_ptr<IntermediateStorage> storage: m_storages)
|
||||
{
|
||||
logString += " " + std::to_string(storage->getSourceLocationCount()) + ";";
|
||||
}
|
||||
}
|
||||
LOG_INFO(logString);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef STORAGE_PROVIDER_H
|
||||
#define STORAGE_PROVIDER_H
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <list>
|
||||
#include "data/storage/IntermediateStorage.h"
|
||||
|
||||
class StorageProvider
|
||||
{
|
||||
public:
|
||||
int getStorageCount() const;
|
||||
|
||||
void insert(std::shared_ptr<IntermediateStorage> storage);
|
||||
|
||||
// returns empty shared_ptr if no storages available
|
||||
std::shared_ptr<IntermediateStorage> consumeSecondLargestStorage();
|
||||
|
||||
// returns empty shared_ptr if no storages available
|
||||
std::shared_ptr<IntermediateStorage> consumeLargestStorage();
|
||||
|
||||
void logCurrentState() const;
|
||||
|
||||
private:
|
||||
std::list<std::shared_ptr<IntermediateStorage>> m_storages; // larger storages are in front
|
||||
mutable std::mutex m_storagesMutex;
|
||||
};
|
||||
|
||||
#endif // STORAGE_PROVIDER_H
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef STORAGE_STATS_H
|
||||
#define STORAGE_STATS_H
|
||||
|
||||
#include "utility/TimePoint.h"
|
||||
|
||||
struct StorageStats
|
||||
{
|
||||
StorageStats()
|
||||
: nodeCount(0)
|
||||
, edgeCount(0)
|
||||
, fileCount(0)
|
||||
, completedFileCount(0)
|
||||
, fileLOCCount(0)
|
||||
{}
|
||||
|
||||
size_t nodeCount;
|
||||
size_t edgeCount;
|
||||
|
||||
size_t fileCount;
|
||||
size_t completedFileCount;
|
||||
size_t fileLOCCount;
|
||||
|
||||
TimePoint timestamp;
|
||||
};
|
||||
|
||||
#endif // STORAGE_STATS_H
|
||||
@@ -0,0 +1,349 @@
|
||||
#ifndef STORAGE_TYPES_H
|
||||
#define STORAGE_TYPES_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "utility/file/FilePath.h"
|
||||
#include "utility/types.h"
|
||||
|
||||
#include "data/DefinitionKind.h"
|
||||
|
||||
struct StorageEdge
|
||||
{
|
||||
StorageEdge()
|
||||
: id(0)
|
||||
, type(0)
|
||||
, sourceNodeId(0)
|
||||
, targetNodeId(0)
|
||||
{}
|
||||
|
||||
StorageEdge(Id id, int type, Id sourceNodeId, Id targetNodeId)
|
||||
: id(id)
|
||||
, type(type)
|
||||
, sourceNodeId(sourceNodeId)
|
||||
, targetNodeId(targetNodeId)
|
||||
{}
|
||||
|
||||
Id id;
|
||||
int type;
|
||||
Id sourceNodeId;
|
||||
Id targetNodeId;
|
||||
};
|
||||
|
||||
struct StorageNode
|
||||
{
|
||||
StorageNode()
|
||||
: id(0)
|
||||
, type(0)
|
||||
, serializedName("")
|
||||
{}
|
||||
|
||||
StorageNode(Id id, int type, const std::string& serializedName)
|
||||
: id(id)
|
||||
, type(type)
|
||||
, serializedName(serializedName)
|
||||
{}
|
||||
|
||||
Id id;
|
||||
int type;
|
||||
std::string serializedName;
|
||||
};
|
||||
|
||||
struct StorageSymbol
|
||||
{
|
||||
StorageSymbol()
|
||||
: id(0)
|
||||
, definitionKind(definitionKindToInt(DEFINITION_NONE))
|
||||
{}
|
||||
|
||||
StorageSymbol(Id id, int definitionKind)
|
||||
: id(id)
|
||||
, definitionKind(definitionKind)
|
||||
{}
|
||||
|
||||
Id id;
|
||||
int definitionKind;
|
||||
};
|
||||
|
||||
struct StorageFile
|
||||
{
|
||||
StorageFile()
|
||||
: id(0)
|
||||
, filePath("")
|
||||
, modificationTime("")
|
||||
, complete(true)
|
||||
{}
|
||||
|
||||
StorageFile(Id id, const std::string& filePath, const std::string& modificationTime, bool complete)
|
||||
: id(id)
|
||||
, filePath(filePath)
|
||||
, modificationTime(modificationTime)
|
||||
, complete(complete)
|
||||
{}
|
||||
|
||||
Id id;
|
||||
std::string filePath;
|
||||
std::string modificationTime;
|
||||
bool complete;
|
||||
};
|
||||
|
||||
struct StorageLocalSymbol
|
||||
{
|
||||
StorageLocalSymbol()
|
||||
: id(0)
|
||||
, name("")
|
||||
{}
|
||||
|
||||
StorageLocalSymbol(Id id, const std::string& name)
|
||||
: id(id)
|
||||
, name(name)
|
||||
{}
|
||||
|
||||
Id id;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
struct StorageSourceLocation
|
||||
{
|
||||
StorageSourceLocation()
|
||||
: id(0)
|
||||
, fileNodeId(0)
|
||||
, startLine(-1)
|
||||
, startCol(-1)
|
||||
, endLine(-1)
|
||||
, endCol(-1)
|
||||
, type(0)
|
||||
{}
|
||||
|
||||
StorageSourceLocation(Id id, Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol, int type)
|
||||
: id(id)
|
||||
, fileNodeId(fileNodeId)
|
||||
, startLine(startLine)
|
||||
, startCol(startCol)
|
||||
, endLine(endLine)
|
||||
, endCol(endCol)
|
||||
, type(type)
|
||||
{}
|
||||
|
||||
Id id;
|
||||
Id fileNodeId;
|
||||
uint startLine;
|
||||
uint startCol;
|
||||
uint endLine;
|
||||
uint endCol;
|
||||
int type;
|
||||
};
|
||||
|
||||
struct StorageOccurrence
|
||||
{
|
||||
StorageOccurrence()
|
||||
: elementId(0)
|
||||
, sourceLocationId(0)
|
||||
{}
|
||||
|
||||
StorageOccurrence(Id elementId, Id sourceLocationId)
|
||||
: elementId(elementId)
|
||||
, sourceLocationId(sourceLocationId)
|
||||
{}
|
||||
|
||||
Id elementId;
|
||||
Id sourceLocationId;
|
||||
};
|
||||
|
||||
struct StorageComponentAccess
|
||||
{
|
||||
StorageComponentAccess()
|
||||
: id(0)
|
||||
, nodeId(0)
|
||||
, type(0)
|
||||
{}
|
||||
|
||||
StorageComponentAccess(Id id, Id nodeId, int type)
|
||||
: id(id)
|
||||
, nodeId(nodeId)
|
||||
, type(type)
|
||||
{}
|
||||
|
||||
Id id;
|
||||
Id nodeId;
|
||||
int type;
|
||||
};
|
||||
|
||||
struct StorageCommentLocation
|
||||
{
|
||||
StorageCommentLocation()
|
||||
: id(0)
|
||||
, fileNodeId(0)
|
||||
, startLine(-1)
|
||||
, startCol(-1)
|
||||
, endLine(-1)
|
||||
, endCol(-1)
|
||||
{}
|
||||
|
||||
StorageCommentLocation(Id id, Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol)
|
||||
: id(id)
|
||||
, fileNodeId(fileNodeId)
|
||||
, startLine(startLine)
|
||||
, startCol(startCol)
|
||||
, endLine(endLine)
|
||||
, endCol(endCol)
|
||||
{}
|
||||
|
||||
Id id;
|
||||
Id fileNodeId;
|
||||
uint startLine;
|
||||
uint startCol;
|
||||
uint endLine;
|
||||
uint endCol;
|
||||
};
|
||||
|
||||
struct StorageError
|
||||
{
|
||||
StorageError()
|
||||
: id(0)
|
||||
, message("")
|
||||
, lineNumber(-1)
|
||||
, columnNumber(-1)
|
||||
, fatal(0)
|
||||
, indexed(0)
|
||||
{}
|
||||
|
||||
StorageError(
|
||||
Id id,
|
||||
const std::string& message,
|
||||
const FilePath& filePath,
|
||||
uint lineNumber,
|
||||
uint columnNumber,
|
||||
bool fatal,
|
||||
bool indexed
|
||||
)
|
||||
: id(id)
|
||||
, message(message)
|
||||
, filePath(filePath)
|
||||
, lineNumber(lineNumber)
|
||||
, columnNumber(columnNumber)
|
||||
, fatal(fatal)
|
||||
, indexed(indexed)
|
||||
{}
|
||||
|
||||
Id id;
|
||||
std::string message;
|
||||
|
||||
FilePath filePath;
|
||||
uint lineNumber;
|
||||
uint columnNumber;
|
||||
|
||||
bool fatal;
|
||||
bool indexed;
|
||||
};
|
||||
|
||||
|
||||
struct StorageBookmarkCategory
|
||||
{
|
||||
StorageBookmarkCategory()
|
||||
: id(0)
|
||||
, name("")
|
||||
{}
|
||||
|
||||
StorageBookmarkCategory(
|
||||
Id id,
|
||||
const std::string& name
|
||||
)
|
||||
: id(id)
|
||||
, name(name)
|
||||
{}
|
||||
|
||||
Id id;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
struct StorageBookmark
|
||||
{
|
||||
StorageBookmark()
|
||||
: id(0)
|
||||
, name("")
|
||||
, comment("")
|
||||
, timestamp("")
|
||||
, categoryId(0)
|
||||
{}
|
||||
|
||||
StorageBookmark(
|
||||
Id id,
|
||||
const std::string& name,
|
||||
const std::string& comment,
|
||||
const std::string& timestamp,
|
||||
const Id categoryId
|
||||
)
|
||||
: id(id)
|
||||
, name(name)
|
||||
, comment(comment)
|
||||
, timestamp(timestamp)
|
||||
, categoryId(categoryId)
|
||||
{}
|
||||
|
||||
Id id;
|
||||
std::string name;
|
||||
std::string comment;
|
||||
std::string timestamp;
|
||||
Id categoryId;
|
||||
};
|
||||
|
||||
struct StorageBookmarkedNode
|
||||
{
|
||||
StorageBookmarkedNode()
|
||||
: id(0)
|
||||
, bookmarkId(0)
|
||||
, serializedNodeName("")
|
||||
{}
|
||||
|
||||
StorageBookmarkedNode(
|
||||
Id id,
|
||||
Id bookmarkId,
|
||||
const std::string& serializedNodeName
|
||||
)
|
||||
: id(id)
|
||||
, bookmarkId(bookmarkId)
|
||||
, serializedNodeName(serializedNodeName)
|
||||
{}
|
||||
|
||||
Id id;
|
||||
Id bookmarkId;
|
||||
std::string serializedNodeName;
|
||||
};
|
||||
|
||||
struct StorageBookmarkedEdge
|
||||
{
|
||||
StorageBookmarkedEdge()
|
||||
: id(0)
|
||||
, bookmarkId(0)
|
||||
, serializedSourceNodeName("")
|
||||
, serializedTargetNodeName("")
|
||||
, edgeType(0)
|
||||
, sourceNodeActive(false)
|
||||
{}
|
||||
|
||||
StorageBookmarkedEdge(
|
||||
Id id,
|
||||
Id bookmarkId,
|
||||
const std::string& serializedSourceNodeName,
|
||||
const std::string& serializedTargetNodeName,
|
||||
int edgeType,
|
||||
bool sourceNodeActive
|
||||
)
|
||||
: id(id)
|
||||
, bookmarkId(bookmarkId)
|
||||
, serializedSourceNodeName(serializedSourceNodeName)
|
||||
, serializedTargetNodeName(serializedTargetNodeName)
|
||||
, edgeType(edgeType)
|
||||
, sourceNodeActive(sourceNodeActive)
|
||||
{}
|
||||
|
||||
Id id;
|
||||
Id bookmarkId;
|
||||
std::string serializedSourceNodeName;
|
||||
std::string serializedTargetNodeName;
|
||||
int edgeType;
|
||||
bool sourceNodeActive;
|
||||
};
|
||||
|
||||
#endif // STORAGE_TYPES_H
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "data/storage/migration/SqliteStorageMigration.h"
|
||||
|
||||
SqliteStorageMigration::~SqliteStorageMigration()
|
||||
{
|
||||
}
|
||||
|
||||
bool SqliteStorageMigration::executeStatementInStorage(SqliteStorage* storage, const std::string& statement) const
|
||||
{
|
||||
return storage->executeStatement(statement);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#ifndef SQLITE_STORAGE_MIGRATION_H
|
||||
#define SQLITE_STORAGE_MIGRATION_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "data/storage/sqlite/SqliteStorage.h"
|
||||
#include "utility/migration/Migration.h"
|
||||
|
||||
class SqliteStorageMigration: public Migration<SqliteStorage>
|
||||
{
|
||||
public:
|
||||
virtual ~SqliteStorageMigration();
|
||||
|
||||
bool executeStatementInStorage(SqliteStorage* storage, const std::string& statement) const;
|
||||
};
|
||||
|
||||
#endif // SQLITE_STORAGE_MIGRATION_H
|
||||
@@ -0,0 +1,16 @@
|
||||
#include "data/storage/migration/SqliteStorageMigrationLambda.h"
|
||||
|
||||
|
||||
SqliteStorageMigrationLambda::SqliteStorageMigrationLambda(std::function<void(const SqliteStorageMigration*, SqliteStorage*)> m_lambda)
|
||||
: m_lambda(m_lambda)
|
||||
{
|
||||
}
|
||||
|
||||
SqliteStorageMigrationLambda::~SqliteStorageMigrationLambda()
|
||||
{
|
||||
}
|
||||
|
||||
void SqliteStorageMigrationLambda::apply(SqliteStorage* migratable) const
|
||||
{
|
||||
m_lambda(this, migratable);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#ifndef SQLITE_STORAGE_MIGRATION_LAMBDA_H
|
||||
#define SQLITE_STORAGE_MIGRATION_LAMBDA_H
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "data/storage/migration/SqliteStorageMigration.h"
|
||||
|
||||
class SqliteStorageMigrationLambda: public SqliteStorageMigration
|
||||
{
|
||||
public:
|
||||
SqliteStorageMigrationLambda(std::function<void(const SqliteStorageMigration*, SqliteStorage*)> m_lambda);
|
||||
virtual ~SqliteStorageMigrationLambda();
|
||||
virtual void apply(SqliteStorage* migratable) const;
|
||||
|
||||
private:
|
||||
std::function<void(const SqliteStorageMigration*, SqliteStorage*)> m_lambda;
|
||||
};
|
||||
|
||||
#endif // SQLITE_STORAGE_MIGRATION_LAMBDA_H
|
||||
@@ -0,0 +1,10 @@
|
||||
#ifndef SQLITE_STORAGE_MIGRATOR_H
|
||||
#define SQLITE_STORAGE_MIGRATOR_H
|
||||
|
||||
#include "utility/migration/Migrator.h"
|
||||
|
||||
class SqliteStorage;
|
||||
|
||||
typedef Migrator<SqliteStorage> SqliteStorageMigrator;
|
||||
|
||||
#endif // SQLITE_STORAGE_MIGRATOR_H
|
||||
@@ -0,0 +1,357 @@
|
||||
#include "data/storage/sqlite/SqliteBookmarkStorage.h"
|
||||
|
||||
#include "data/storage/migration/SqliteStorageMigrationLambda.h"
|
||||
#include "data/storage/migration/SqliteStorageMigrator.h"
|
||||
#include "settings/ProjectSettings.h"
|
||||
#include "utility/logging/logging.h"
|
||||
#include "Application.h"
|
||||
|
||||
const size_t SqliteBookmarkStorage::s_storageVersion = 2;
|
||||
|
||||
SqliteBookmarkStorage::SqliteBookmarkStorage(const FilePath& dbFilePath)
|
||||
: SqliteStorage(dbFilePath)
|
||||
{
|
||||
}
|
||||
|
||||
SqliteBookmarkStorage::~SqliteBookmarkStorage()
|
||||
{
|
||||
}
|
||||
|
||||
size_t SqliteBookmarkStorage::getStaticVersion() const
|
||||
{
|
||||
return s_storageVersion;
|
||||
}
|
||||
|
||||
void SqliteBookmarkStorage::migrateIfNecessary()
|
||||
{
|
||||
SqliteStorageMigrator migrator;
|
||||
|
||||
migrator.addMigration(2, std::make_shared<SqliteStorageMigrationLambda>([](const SqliteStorageMigration* migration, SqliteStorage* storage){
|
||||
std::string separator = "::";
|
||||
if (std::shared_ptr<Project> currentProject = Application::getInstance()->getCurrentProject())
|
||||
{
|
||||
LanguageType currentLanguage = ProjectSettings::getLanguageOfProject(currentProject->getProjectSettingsFilePath());
|
||||
if (currentLanguage == LANGUAGE_JAVA)
|
||||
{
|
||||
separator = ".";
|
||||
}
|
||||
}
|
||||
|
||||
migration->executeStatementInStorage(storage, "UPDATE bookmarked_node SET serialized_node_name = '" + separator + "\tm' || serialized_node_name");
|
||||
migration->executeStatementInStorage(storage, "UPDATE bookmarked_edge SET serialized_source_node_name = '" + separator + "\tm' || serialized_source_node_name");
|
||||
migration->executeStatementInStorage(storage, "UPDATE bookmarked_edge SET serialized_target_node_name = '" + separator + "\tm' || serialized_target_node_name");
|
||||
}));
|
||||
|
||||
migrator.migrate(this, SqliteBookmarkStorage::s_storageVersion);
|
||||
}
|
||||
|
||||
Id SqliteBookmarkStorage::addBookmarkCategory(const std::string& name)
|
||||
{
|
||||
std::string statement = "INSERT INTO bookmark_category(id, name) "
|
||||
"VALUES (NULL, ?);";
|
||||
|
||||
CppSQLite3Statement stmt = m_database.compileStatement(statement.c_str());
|
||||
stmt.bind(1, name.c_str());
|
||||
|
||||
executeStatement(stmt);
|
||||
const Id id = m_database.lastRowId();
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
Id SqliteBookmarkStorage::addBookmark(const std::string& name, const std::string& comment, const std::string& timestamp, const Id categoryId)
|
||||
{
|
||||
std::string statement = "INSERT INTO bookmark(id, name, comment, timestamp, category_id) "
|
||||
"VALUES (NULL, ?, ?, ?, " + std::to_string(categoryId) + ");";
|
||||
|
||||
try
|
||||
{
|
||||
CppSQLite3Statement stmt = m_database.compileStatement(statement.c_str());
|
||||
stmt.bind(1, name.c_str());
|
||||
stmt.bind(2, comment.c_str());
|
||||
stmt.bind(3, timestamp.c_str());
|
||||
executeStatement(stmt);
|
||||
|
||||
const Id id = m_database.lastRowId();
|
||||
return id;
|
||||
}
|
||||
catch (CppSQLite3Exception e)
|
||||
{
|
||||
LOG_ERROR(std::to_string(e.errorCode()) + ": " + e.errorMessage());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Id SqliteBookmarkStorage::addBookmarkedNode(const Id bookmarkId, const std::string& nodeName)
|
||||
{
|
||||
executeStatement("INSERT INTO bookmarked_element(id, bookmark_id) VALUES(NULL, " + std::to_string(bookmarkId) + ");");
|
||||
Id id = m_database.lastRowId();
|
||||
|
||||
std::string statement = "INSERT INTO bookmarked_node(id, serialized_node_name) "
|
||||
"VALUES (" + std::to_string(id) + ", ?);";
|
||||
CppSQLite3Statement stmt = m_database.compileStatement(statement.c_str());
|
||||
stmt.bind(1, nodeName.c_str());
|
||||
executeStatement(stmt);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
Id SqliteBookmarkStorage::addBookmarkedEdge(const Id bookmarkId, const std::string& sourceNodeName, const std::string& targetNodeName, const int edgeType, const bool sourceNodeActive)
|
||||
{
|
||||
executeStatement("INSERT INTO bookmarked_element(id, bookmark_id) VALUES(NULL, " + std::to_string(bookmarkId) + ");");
|
||||
Id id = m_database.lastRowId();
|
||||
|
||||
std::string statement = "INSERT INTO bookmarked_edge(id, serialized_source_node_name, serialized_target_node_name, edge_type, source_node_active) "
|
||||
"VALUES (" + std::to_string(id) + ", ?, ?, " + std::to_string(edgeType) + ", " + std::to_string(sourceNodeActive) + ");";
|
||||
CppSQLite3Statement stmt = m_database.compileStatement(statement.c_str());
|
||||
stmt.bind(1, sourceNodeName.c_str());
|
||||
stmt.bind(2, targetNodeName.c_str());
|
||||
executeStatement(stmt);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
std::vector<StorageBookmark> SqliteBookmarkStorage::getAllBookmarks() const
|
||||
{
|
||||
return doGetAll<StorageBookmark>("");
|
||||
}
|
||||
|
||||
void SqliteBookmarkStorage::removeBookmark(const Id id)
|
||||
{
|
||||
executeStatement(
|
||||
"DELETE FROM bookmark WHERE id = (" + std::to_string(id) + ");"
|
||||
);
|
||||
}
|
||||
|
||||
std::vector<StorageBookmarkedNode> SqliteBookmarkStorage::getAllBookmarkedNodes() const
|
||||
{
|
||||
return doGetAll<StorageBookmarkedNode>("");
|
||||
}
|
||||
|
||||
std::vector<StorageBookmarkedEdge> SqliteBookmarkStorage::getAllBookmarkedEdges() const
|
||||
{
|
||||
return doGetAll<StorageBookmarkedEdge>("");
|
||||
}
|
||||
|
||||
void SqliteBookmarkStorage::updateBookmark(const Id bookmarkId, const std::string& name, const std::string& comment, const Id categoryId)
|
||||
{
|
||||
executeStatement("UPDATE bookmark SET name = '" + name + "' WHERE id == " + std::to_string(bookmarkId) + ";");
|
||||
executeStatement("UPDATE bookmark SET comment = '" + comment + "' WHERE id == " + std::to_string(bookmarkId) + ";");
|
||||
executeStatement("UPDATE bookmark SET category_id = " + std::to_string(categoryId) + " WHERE id == " + std::to_string(bookmarkId) + ";");
|
||||
}
|
||||
|
||||
std::vector<StorageBookmarkCategory> SqliteBookmarkStorage::getAllBookmarkCategories() const
|
||||
{
|
||||
return doGetAll<StorageBookmarkCategory>("");
|
||||
}
|
||||
|
||||
StorageBookmarkCategory SqliteBookmarkStorage::getBookmarkCategoryByName(const std::string& name) const
|
||||
{
|
||||
return doGetFirst<StorageBookmarkCategory>("WHERE name == '" + name + "'");
|
||||
}
|
||||
|
||||
void SqliteBookmarkStorage::removeBookmarkCategory(Id id)
|
||||
{
|
||||
executeStatement(
|
||||
"DELETE FROM bookmark_category WHERE id = (" + std::to_string(id) + ");"
|
||||
);
|
||||
}
|
||||
|
||||
std::vector<std::pair<int, SqliteDatabaseIndex>> SqliteBookmarkStorage::getIndices() const
|
||||
{
|
||||
return std::vector<std::pair<int, SqliteDatabaseIndex>>();
|
||||
}
|
||||
|
||||
void SqliteBookmarkStorage::clearTables()
|
||||
{
|
||||
try
|
||||
{
|
||||
m_database.execDML("DROP TABLE IF EXISTS main.bookmarked_edge;");
|
||||
m_database.execDML("DROP TABLE IF EXISTS main.bookmarked_node;");
|
||||
m_database.execDML("DROP TABLE IF EXISTS main.bookmarked_element;");
|
||||
m_database.execDML("DROP TABLE IF EXISTS main.bookmark;");
|
||||
m_database.execDML("DROP TABLE IF EXISTS main.bookmark_category;");
|
||||
}
|
||||
catch (CppSQLite3Exception& e)
|
||||
{
|
||||
LOG_ERROR(std::to_string(e.errorCode()) + ": " + e.errorMessage());
|
||||
}
|
||||
}
|
||||
|
||||
void SqliteBookmarkStorage::setupTables()
|
||||
{
|
||||
try
|
||||
{
|
||||
m_database.execDML(
|
||||
"CREATE TABLE IF NOT EXISTS bookmark_category("
|
||||
"id INTEGER NOT NULL, "
|
||||
"name TEXT, "
|
||||
"PRIMARY KEY(id)"
|
||||
");"
|
||||
);
|
||||
|
||||
m_database.execDML(
|
||||
"CREATE TABLE IF NOT EXISTS bookmark("
|
||||
"id INTEGER NOT NULL, "
|
||||
"name TEXT, "
|
||||
"comment TEXT, "
|
||||
"timestamp TEXT, "
|
||||
"category_id INTEGER, "
|
||||
"FOREIGN KEY(category_id) REFERENCES bookmark_category(id) ON DELETE CASCADE, "
|
||||
"PRIMARY KEY(id)"
|
||||
");"
|
||||
);
|
||||
|
||||
m_database.execDML(
|
||||
"CREATE TABLE IF NOT EXISTS bookmarked_element("
|
||||
"id INTEGER NOT NULL, "
|
||||
"bookmark_id INTEGER NOT NULL, "
|
||||
"FOREIGN KEY(bookmark_id) REFERENCES bookmark(id) ON DELETE CASCADE, "
|
||||
"PRIMARY KEY(id)"
|
||||
");"
|
||||
);
|
||||
|
||||
m_database.execDML(
|
||||
"CREATE TABLE IF NOT EXISTS bookmarked_node("
|
||||
"id INTEGER NOT NULL, "
|
||||
"serialized_node_name TEXT, "
|
||||
"FOREIGN KEY(id) REFERENCES bookmarked_element(id) ON DELETE CASCADE, "
|
||||
"PRIMARY KEY(id)"
|
||||
");"
|
||||
);
|
||||
|
||||
m_database.execDML(
|
||||
"CREATE TABLE IF NOT EXISTS bookmarked_edge("
|
||||
"id INTEGER NOT NULL, "
|
||||
"serialized_source_node_name TEXT, "
|
||||
"serialized_target_node_name TEXT, "
|
||||
"edge_type INTEGER, "
|
||||
"source_node_active INTEGER, "
|
||||
"FOREIGN KEY(id) REFERENCES bookmarked_element(id) ON DELETE CASCADE, "
|
||||
"PRIMARY KEY(id)"
|
||||
");"
|
||||
);
|
||||
}
|
||||
catch (CppSQLite3Exception& e)
|
||||
{
|
||||
LOG_ERROR_STREAM(<< "Failed to create tables: " << std::to_string(e.errorCode()) << ": " << e.errorMessage());
|
||||
throw e;
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
LOG_ERROR_STREAM(<< "Failed to create tables: " << e.what());
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
void SqliteBookmarkStorage::setupPrecompiledStatements()
|
||||
{
|
||||
}
|
||||
|
||||
template <>
|
||||
std::vector<StorageBookmarkCategory> SqliteBookmarkStorage::doGetAll<StorageBookmarkCategory>(const std::string& query) const
|
||||
{
|
||||
CppSQLite3Query q = executeQuery(
|
||||
"SELECT id, name FROM bookmark_category " + query + ";"
|
||||
);
|
||||
|
||||
std::vector<StorageBookmarkCategory> categories;
|
||||
while (!q.eof())
|
||||
{
|
||||
const Id id = q.getIntField(0, 0);
|
||||
const std::string name = q.getStringField(1, "");
|
||||
|
||||
if (id != 0 && name != "")
|
||||
{
|
||||
categories.push_back(StorageBookmarkCategory(id, name));
|
||||
}
|
||||
|
||||
q.nextRow();
|
||||
}
|
||||
return categories;
|
||||
}
|
||||
|
||||
template <>
|
||||
std::vector<StorageBookmark> SqliteBookmarkStorage::doGetAll<StorageBookmark>(const std::string& query) const
|
||||
{
|
||||
CppSQLite3Query q = executeQuery(
|
||||
"SELECT id, name, comment, timestamp, category_id FROM bookmark " + query + ";"
|
||||
);
|
||||
|
||||
std::vector<StorageBookmark> bookmarks;
|
||||
while (!q.eof())
|
||||
{
|
||||
const Id id = q.getIntField(0, 0);
|
||||
const std::string name = q.getStringField(1, "");
|
||||
const std::string comment = q.getStringField(2, "");
|
||||
const std::string timestamp = q.getStringField(3, "");
|
||||
const Id categoryId = q.getIntField(4, 0);
|
||||
|
||||
if (id != 0 && name != "" && timestamp != "")
|
||||
{
|
||||
bookmarks.push_back(StorageBookmark(id, name, comment, timestamp, categoryId));
|
||||
}
|
||||
|
||||
q.nextRow();
|
||||
}
|
||||
return bookmarks;
|
||||
}
|
||||
|
||||
template <>
|
||||
std::vector<StorageBookmarkedNode> SqliteBookmarkStorage::doGetAll<StorageBookmarkedNode>(const std::string& query) const
|
||||
{
|
||||
CppSQLite3Query q = executeQuery(
|
||||
"SELECT "
|
||||
"bookmarked_node.id, bookmarked_element.bookmark_id, bookmarked_node.serialized_node_name "
|
||||
"FROM bookmarked_node "
|
||||
"INNER JOIN "
|
||||
"bookmarked_element ON bookmarked_node.id = bookmarked_element.id " + query + ";"
|
||||
);
|
||||
|
||||
std::vector<StorageBookmarkedNode> bookmarkedNodes;
|
||||
while (!q.eof())
|
||||
{
|
||||
const Id id = q.getIntField(0, 0);
|
||||
const Id bookmarkId = q.getIntField(1, 0);
|
||||
const std::string serializedNodeName = q.getStringField(2, "");
|
||||
|
||||
if (id != 0 && bookmarkId != 0 && serializedNodeName != "")
|
||||
{
|
||||
bookmarkedNodes.push_back(StorageBookmarkedNode(id, bookmarkId, serializedNodeName));
|
||||
}
|
||||
|
||||
q.nextRow();
|
||||
}
|
||||
return bookmarkedNodes;
|
||||
}
|
||||
|
||||
template <>
|
||||
std::vector<StorageBookmarkedEdge> SqliteBookmarkStorage::doGetAll<StorageBookmarkedEdge>(const std::string& query) const
|
||||
{
|
||||
CppSQLite3Query q = executeQuery(
|
||||
"SELECT "
|
||||
"bookmarked_edge.id, bookmarked_element.bookmark_id, bookmarked_edge.serialized_source_node_name, bookmarked_edge.serialized_target_node_name, bookmarked_edge.edge_type, bookmarked_edge.source_node_active "
|
||||
"FROM bookmarked_edge "
|
||||
"INNER JOIN "
|
||||
"bookmarked_element ON bookmarked_edge.id = bookmarked_element.id " + query + ";"
|
||||
);
|
||||
|
||||
std::vector<StorageBookmarkedEdge> bookmarkedEdges;
|
||||
while (!q.eof())
|
||||
{
|
||||
const Id id = q.getIntField(0, 0);
|
||||
const Id bookmarkId = q.getIntField(1, 0);
|
||||
const std::string serializedSourceNodeName = q.getStringField(2, "");
|
||||
const std::string serializedTargetNodeName = q.getStringField(3, "");
|
||||
const int edgeType = q.getIntField(4, -1);
|
||||
const int sourceNodeActive = q.getIntField(5, -1);
|
||||
|
||||
if (id != 0 && bookmarkId != 0 && serializedSourceNodeName != "" && serializedTargetNodeName != "" && edgeType != -1 && sourceNodeActive != -1)
|
||||
{
|
||||
bookmarkedEdges.push_back(StorageBookmarkedEdge(id, bookmarkId, serializedSourceNodeName, serializedTargetNodeName, edgeType, sourceNodeActive));
|
||||
}
|
||||
|
||||
q.nextRow();
|
||||
}
|
||||
return bookmarkedEdges;
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
#ifndef SQLITE_BOOKMARK_STORAGE_H
|
||||
#define SQLITE_BOOKMARK_STORAGE_H
|
||||
|
||||
#include "data/storage/sqlite/SqliteStorage.h"
|
||||
#include "data/storage/StorageTypes.h"
|
||||
#include "utility/types.h"
|
||||
|
||||
class SqliteBookmarkStorage
|
||||
: public SqliteStorage
|
||||
{
|
||||
public:
|
||||
SqliteBookmarkStorage(const FilePath& dbFilePath);
|
||||
virtual ~SqliteBookmarkStorage();
|
||||
|
||||
virtual size_t getStaticVersion() const;
|
||||
|
||||
void migrateIfNecessary();
|
||||
|
||||
Id addBookmarkCategory(const std::string& name);
|
||||
Id addBookmark(const std::string& name, const std::string& comment, const std::string& timestamp, const Id categoryId);
|
||||
Id addBookmarkedNode(const Id bookmarkId, const std::string& nodeName);
|
||||
Id addBookmarkedEdge(const Id bookmarkId, const std::string& sourceNodeName, const std::string& targetNodeName, const int edgeType, const bool sourceNodeActive);
|
||||
|
||||
void removeBookmarkCategory(Id id);
|
||||
void removeBookmark(const Id id);
|
||||
|
||||
std::vector<StorageBookmark> getAllBookmarks() const;
|
||||
std::vector<StorageBookmarkedNode> getAllBookmarkedNodes() const;
|
||||
std::vector<StorageBookmarkedEdge> getAllBookmarkedEdges() const;
|
||||
|
||||
void updateBookmark(const Id bookmarkId, const std::string& name, const std::string& comment, const Id categoryId);
|
||||
|
||||
std::vector<StorageBookmarkCategory> getAllBookmarkCategories() const;
|
||||
StorageBookmarkCategory getBookmarkCategoryByName(const std::string& name) const;
|
||||
|
||||
private:
|
||||
static const size_t s_storageVersion;
|
||||
|
||||
virtual std::vector<std::pair<int, SqliteDatabaseIndex>> getIndices() const;
|
||||
virtual void clearTables();
|
||||
virtual void setupTables();
|
||||
virtual void setupPrecompiledStatements();
|
||||
|
||||
//void updateBookmarkMetaData(const BookmarkMetaData& metaData);
|
||||
|
||||
template <typename ResultType>
|
||||
std::vector<ResultType> doGetAll(const std::string& query) const;
|
||||
|
||||
template <typename ResultType>
|
||||
ResultType doGetFirst(const std::string& query) const
|
||||
{
|
||||
std::vector<ResultType> results = doGetAll<ResultType>(query + " LIMIT 1");
|
||||
if (results.size() > 0)
|
||||
{
|
||||
return results[0];
|
||||
}
|
||||
return ResultType();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
std::vector<StorageBookmarkCategory> SqliteBookmarkStorage::doGetAll<StorageBookmarkCategory>(const std::string& query) const;
|
||||
template <>
|
||||
std::vector<StorageBookmark> SqliteBookmarkStorage::doGetAll<StorageBookmark>(const std::string& query) const;
|
||||
template <>
|
||||
std::vector<StorageBookmarkedNode> SqliteBookmarkStorage::doGetAll<StorageBookmarkedNode>(const std::string& query) const;
|
||||
template <>
|
||||
std::vector<StorageBookmarkedEdge> SqliteBookmarkStorage::doGetAll<StorageBookmarkedEdge>(const std::string& query) const;
|
||||
|
||||
#endif // SQLITE_BOOKMARK_STORAGE_H
|
||||
@@ -0,0 +1,43 @@
|
||||
#include "data/storage/sqlite/SqliteDatabaseIndex.h"
|
||||
|
||||
#include "utility/logging/logging.h"
|
||||
|
||||
SqliteDatabaseIndex::SqliteDatabaseIndex(const std::string& indexName, const std::string& indexTarget)
|
||||
: m_indexName(indexName)
|
||||
, m_indexTarget(indexTarget)
|
||||
{
|
||||
}
|
||||
|
||||
SqliteDatabaseIndex::~SqliteDatabaseIndex()
|
||||
{
|
||||
}
|
||||
|
||||
void SqliteDatabaseIndex::createOnDatabase(CppSQLite3DB& database)
|
||||
{
|
||||
try
|
||||
{
|
||||
LOG_INFO_STREAM(<< "Creating database index \"" << m_indexName << "\"");
|
||||
database.execDML((
|
||||
"CREATE INDEX IF NOT EXISTS " + m_indexName + " ON " + m_indexTarget + ";"
|
||||
).c_str());
|
||||
}
|
||||
catch (CppSQLite3Exception e)
|
||||
{
|
||||
LOG_ERROR(std::to_string(e.errorCode()) + ": " + e.errorMessage());
|
||||
}
|
||||
}
|
||||
|
||||
void SqliteDatabaseIndex::removeFromDatabase(CppSQLite3DB& database)
|
||||
{
|
||||
try
|
||||
{
|
||||
LOG_INFO_STREAM(<< "Removing database index \"" << m_indexName << "\"");
|
||||
database.execDML((
|
||||
"DROP INDEX IF EXISTS main." + m_indexName + ";"
|
||||
).c_str());
|
||||
}
|
||||
catch (CppSQLite3Exception e)
|
||||
{
|
||||
LOG_ERROR(std::to_string(e.errorCode()) + ": " + e.errorMessage());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef SQLITE_DATABASE_INDEX_H
|
||||
#define SQLITE_DATABASE_INDEX_H
|
||||
|
||||
#include <string>
|
||||
#include "sqlite/CppSQLite3.h"
|
||||
|
||||
class SqliteDatabaseIndex
|
||||
{
|
||||
public:
|
||||
SqliteDatabaseIndex(const std::string& indexName, const std::string& indexTarget);
|
||||
~SqliteDatabaseIndex();
|
||||
|
||||
void createOnDatabase(CppSQLite3DB& database);
|
||||
void removeFromDatabase(CppSQLite3DB& database);
|
||||
|
||||
private:
|
||||
std::string m_indexName;
|
||||
std::string m_indexTarget;
|
||||
};
|
||||
|
||||
#endif // SQLITE_DATABASE_INDEX_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,188 @@
|
||||
#ifndef SQLITE_INDEX_STORAGE_H
|
||||
#define SQLITE_INDEX_STORAGE_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "data/location/SourceLocationFile.h"
|
||||
#include "data/storage/sqlite/SqliteDatabaseIndex.h"
|
||||
#include "data/storage/sqlite/SqliteStorage.h"
|
||||
#include "data/storage/StorageTypes.h"
|
||||
#include "utility/types.h"
|
||||
#include "utility/utility.h"
|
||||
#include "utility/utilityString.h"
|
||||
|
||||
class TextAccess;
|
||||
class Version;
|
||||
struct ParseLocation;
|
||||
|
||||
class SqliteIndexStorage
|
||||
: public SqliteStorage
|
||||
{
|
||||
public:
|
||||
SqliteIndexStorage(const FilePath& dbFilePath);
|
||||
virtual ~SqliteIndexStorage();
|
||||
|
||||
virtual size_t getStaticVersion() const;
|
||||
|
||||
std::string getProjectSettingsText() const;
|
||||
void setProjectSettingsText(std::string text);
|
||||
|
||||
Id addEdge(int type, Id sourceNodeId, Id targetNodeId);
|
||||
|
||||
Id addNode(const int type, const std::string& serializedName);
|
||||
void addSymbol(const int id, int definitionKind);
|
||||
void addFile(const int id, const std::string& filePath, const std::string& modificationTime, bool complete);
|
||||
Id addLocalSymbol(const std::string& name);
|
||||
Id addSourceLocation(Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol, int type);
|
||||
bool addOccurrence(Id elementId, Id sourceLocationId);
|
||||
Id addComponentAccess(Id nodeId, int type);
|
||||
Id addCommentLocation(Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol);
|
||||
Id addError(const std::string& message, const FilePath& filePath, uint lineNumber, uint columnNumber, bool fatal, bool indexed);
|
||||
|
||||
void removeElement(Id id);
|
||||
void removeElements(const std::vector<Id>& ids);
|
||||
void removeElementsWithLocationInFiles(const std::vector<Id>& fileIds, std::function<void(int)> updateStatusCallback);
|
||||
|
||||
void removeErrorsInFiles(const std::vector<FilePath>& filePaths);
|
||||
|
||||
bool isEdge(Id elementId) const;
|
||||
bool isNode(Id elementId) const;
|
||||
bool isFile(Id elementId) const;
|
||||
|
||||
StorageEdge getEdgeById(Id edgeId) const;
|
||||
StorageEdge getEdgeBySourceTargetType(Id sourceId, Id targetId, int type) const;
|
||||
|
||||
std::vector<StorageEdge> getEdgesBySourceId(Id sourceId) const;
|
||||
std::vector<StorageEdge> getEdgesBySourceIds(const std::vector<Id>& sourceIds) const;
|
||||
std::vector<StorageEdge> getEdgesByTargetId(Id targetId) const;
|
||||
std::vector<StorageEdge> getEdgesByTargetIds(const std::vector<Id>& targetIds) const;
|
||||
std::vector<StorageEdge> getEdgesBySourceOrTargetId(Id id) const;
|
||||
|
||||
std::vector<StorageEdge> getEdgesByType(int type) const;
|
||||
std::vector<StorageEdge> getEdgesBySourceType(Id sourceId, int type) const;
|
||||
std::vector<StorageEdge> getEdgesBySourcesType(const std::vector<Id>& sourceIds, int type) const;
|
||||
std::vector<StorageEdge> getEdgesByTargetType(Id targetId, int type) const;
|
||||
std::vector<StorageEdge> getEdgesByTargetsType(const std::vector<Id>& targetIds, int type) const;
|
||||
|
||||
StorageNode getNodeById(Id id) const;
|
||||
StorageNode getNodeBySerializedName(const std::string& serializedName) const;
|
||||
|
||||
StorageLocalSymbol getLocalSymbolByName(const std::string& name) const;
|
||||
|
||||
StorageFile getFileByPath(const std::string& filePath) const;
|
||||
|
||||
std::vector<StorageFile> getFilesByPaths(const std::vector<FilePath>& filePaths) const;
|
||||
std::shared_ptr<TextAccess> getFileContentByPath(const std::string& filePath) const;
|
||||
std::shared_ptr<TextAccess> getFileContentById(Id fileId) const;
|
||||
|
||||
void setFileComplete(bool complete, Id fileId);
|
||||
void setNodeType(int type, Id nodeId);
|
||||
|
||||
std::shared_ptr<SourceLocationFile> getSourceLocationsForFile(const FilePath& filePath) const;
|
||||
|
||||
std::vector<StorageOccurrence> getOccurrencesForLocationId(Id locationId) const;
|
||||
std::vector<StorageOccurrence> getOccurrencesForLocationIds(const std::vector<Id>& locationIds) const;
|
||||
std::vector<StorageOccurrence> getOccurrencesForElementIds(const std::vector<Id>& elementIds) const;
|
||||
|
||||
StorageComponentAccess getComponentAccessByNodeId(Id memberEdgeId) const;
|
||||
std::vector<StorageComponentAccess> getComponentAccessesByNodeIds(const std::vector<Id>& memberEdgeIds) const;
|
||||
|
||||
std::vector<StorageCommentLocation> getCommentLocationsInFile(const FilePath& filePath) const;
|
||||
|
||||
template <typename ResultType>
|
||||
std::vector<ResultType> getAll() const
|
||||
{
|
||||
return doGetAll<ResultType>("");
|
||||
}
|
||||
|
||||
template <typename ResultType>
|
||||
ResultType getFirstById(const Id id) const
|
||||
{
|
||||
if (id != 0)
|
||||
{
|
||||
return doGetFirst<ResultType>("WHERE id == " + std::to_string(id));
|
||||
}
|
||||
return ResultType();
|
||||
}
|
||||
|
||||
template <typename ResultType>
|
||||
std::vector<ResultType> getAllByIds(const std::vector<Id>& ids) const
|
||||
{
|
||||
if (ids.size())
|
||||
{
|
||||
return doGetAll<ResultType>("WHERE id IN (" + utility::join(utility::toStrings(ids), ',') + ")");
|
||||
}
|
||||
return std::vector<ResultType>();
|
||||
}
|
||||
|
||||
int getNodeCount() const;
|
||||
int getEdgeCount() const;
|
||||
int getFileCount() const;
|
||||
int getCompletedFileCount() const;
|
||||
int getFileLineSum() const;
|
||||
int getSourceLocationCount() const;
|
||||
|
||||
private:
|
||||
static const size_t s_storageVersion;
|
||||
|
||||
virtual std::vector<std::pair<int, SqliteDatabaseIndex>> getIndices() const;
|
||||
virtual void clearTables();
|
||||
virtual void setupTables();
|
||||
virtual void setupPrecompiledStatements();
|
||||
|
||||
template <typename ResultType>
|
||||
std::vector<ResultType> doGetAll(const std::string& query) const;
|
||||
|
||||
template <typename ResultType>
|
||||
ResultType doGetFirst(const std::string& query) const
|
||||
{
|
||||
std::vector<ResultType> results = doGetAll<ResultType>(query + " LIMIT 1");
|
||||
if (results.size() > 0)
|
||||
{
|
||||
return results[0];
|
||||
}
|
||||
return ResultType();
|
||||
}
|
||||
|
||||
CppSQLite3Statement m_insertElementStmt;
|
||||
CppSQLite3Statement m_insertEdgeStmt;
|
||||
CppSQLite3Statement m_inserNodeStmt;
|
||||
CppSQLite3Statement m_insertSymbolStmt;
|
||||
CppSQLite3Statement m_insertFileStmt;
|
||||
CppSQLite3Statement m_insertFileContentStmt;
|
||||
CppSQLite3Statement m_inserLocalSymbolStmt;
|
||||
CppSQLite3Statement m_checkSourceLocationExistsStmt;
|
||||
CppSQLite3Statement m_insertSourceLocationStmt;
|
||||
CppSQLite3Statement m_checkOccurrenceExistsStmt;
|
||||
CppSQLite3Statement m_insertOccurrenceStmt;
|
||||
CppSQLite3Statement m_insertComponentAccessStmt;
|
||||
CppSQLite3Statement m_checkCommentLocationExistsStmt;
|
||||
CppSQLite3Statement m_insertCommentLocationStmt;
|
||||
CppSQLite3Statement m_checkErrorExistsStmt;
|
||||
CppSQLite3Statement m_insertErrorStmt;
|
||||
};
|
||||
|
||||
template <>
|
||||
std::vector<StorageEdge> SqliteIndexStorage::doGetAll<StorageEdge>(const std::string& query) const;
|
||||
template <>
|
||||
std::vector<StorageNode> SqliteIndexStorage::doGetAll<StorageNode>(const std::string& query) const;
|
||||
template <>
|
||||
std::vector<StorageSymbol> SqliteIndexStorage::doGetAll<StorageSymbol>(const std::string& query) const;
|
||||
template <>
|
||||
std::vector<StorageFile> SqliteIndexStorage::doGetAll<StorageFile>(const std::string& query) const;
|
||||
template <>
|
||||
std::vector<StorageLocalSymbol> SqliteIndexStorage::doGetAll<StorageLocalSymbol>(const std::string& query) const;
|
||||
template <>
|
||||
std::vector<StorageSourceLocation> SqliteIndexStorage::doGetAll<StorageSourceLocation>(const std::string& query) const;
|
||||
template <>
|
||||
std::vector<StorageOccurrence> SqliteIndexStorage::doGetAll<StorageOccurrence>(const std::string& query) const;
|
||||
template <>
|
||||
std::vector<StorageComponentAccess> SqliteIndexStorage::doGetAll<StorageComponentAccess>(const std::string& query) const;
|
||||
template <>
|
||||
std::vector<StorageCommentLocation> SqliteIndexStorage::doGetAll<StorageCommentLocation>(const std::string& query) const;
|
||||
template <>
|
||||
std::vector<StorageError> SqliteIndexStorage::doGetAll<StorageError>(const std::string& query) const;
|
||||
|
||||
#endif // SQLITE_INDEX_STORAGE_H
|
||||
@@ -0,0 +1,305 @@
|
||||
#include "data/storage/sqlite/SqliteStorage.h"
|
||||
|
||||
#include "utility/logging/logging.h"
|
||||
#include "utility/TimePoint.h"
|
||||
|
||||
SqliteStorage::SqliteStorage(const FilePath& dbFilePath)
|
||||
: m_dbFilePath(dbFilePath.canonical())
|
||||
{
|
||||
m_database.open(m_dbFilePath.str().c_str());
|
||||
|
||||
executeStatement("PRAGMA foreign_keys=ON;");
|
||||
|
||||
m_mode = STORAGE_MODE_UNKNOWN;
|
||||
}
|
||||
|
||||
SqliteStorage::~SqliteStorage()
|
||||
{
|
||||
try
|
||||
{
|
||||
m_database.close();
|
||||
}
|
||||
catch (CppSQLite3Exception e)
|
||||
{
|
||||
LOG_ERROR(e.errorMessage());
|
||||
}
|
||||
}
|
||||
|
||||
void SqliteStorage::setup()
|
||||
{
|
||||
m_indices = getIndices();
|
||||
|
||||
executeStatement("PRAGMA foreign_keys=ON;");
|
||||
setupMetaTable();
|
||||
setupTables();
|
||||
setupPrecompiledStatements();
|
||||
m_mode = STORAGE_MODE_UNKNOWN;
|
||||
}
|
||||
|
||||
void SqliteStorage::clear()
|
||||
{
|
||||
executeStatement("PRAGMA foreign_keys=OFF;");
|
||||
clearMetaTable();
|
||||
clearTables();
|
||||
|
||||
setup();
|
||||
}
|
||||
|
||||
size_t SqliteStorage::getVersion() const
|
||||
{
|
||||
std::string storageVersionStr = getMetaValue("storage_version");
|
||||
|
||||
if (storageVersionStr.size())
|
||||
{
|
||||
return std::stoi(storageVersionStr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SqliteStorage::setVersion(size_t version)
|
||||
{
|
||||
insertOrUpdateMetaValue("storage_version", std::to_string(version));
|
||||
}
|
||||
|
||||
void SqliteStorage::setMode(const StorageModeType mode)
|
||||
{
|
||||
if (mode == m_mode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < m_indices.size(); i++)
|
||||
{
|
||||
if (m_indices[i].first & mode)
|
||||
{
|
||||
m_indices[i].second.createOnDatabase(m_database);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_indices[i].second.removeFromDatabase(m_database);
|
||||
}
|
||||
}
|
||||
|
||||
m_mode = mode;
|
||||
}
|
||||
|
||||
void SqliteStorage::beginTransaction()
|
||||
{
|
||||
executeStatement("BEGIN TRANSACTION;");
|
||||
}
|
||||
|
||||
void SqliteStorage::commitTransaction()
|
||||
{
|
||||
executeStatement("COMMIT TRANSACTION;");
|
||||
}
|
||||
|
||||
void SqliteStorage::rollbackTransaction()
|
||||
{
|
||||
executeStatement("ROLLBACK TRANSACTION;");
|
||||
}
|
||||
|
||||
void SqliteStorage::optimizeMemory() const
|
||||
{
|
||||
executeStatement("VACUUM;");
|
||||
}
|
||||
|
||||
FilePath SqliteStorage::getDbFilePath() const
|
||||
{
|
||||
return m_dbFilePath;
|
||||
}
|
||||
|
||||
bool SqliteStorage::isEmpty() const
|
||||
{
|
||||
return getVersion() <= 0;
|
||||
}
|
||||
|
||||
bool SqliteStorage::isIncompatible() const
|
||||
{
|
||||
size_t storageVersion = getVersion();
|
||||
if (isEmpty() || storageVersion != getStaticVersion())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void SqliteStorage::setTime()
|
||||
{
|
||||
insertOrUpdateMetaValue("timestamp", TimePoint::now().toString());
|
||||
}
|
||||
|
||||
TimePoint SqliteStorage::getTime() const
|
||||
{
|
||||
return TimePoint(getMetaValue("timestamp"));
|
||||
}
|
||||
|
||||
void SqliteStorage::setupMetaTable()
|
||||
{
|
||||
try
|
||||
{
|
||||
m_database.execDML(
|
||||
"CREATE TABLE IF NOT EXISTS meta("
|
||||
"id INTEGER, "
|
||||
"key TEXT, "
|
||||
"value TEXT, "
|
||||
"PRIMARY KEY(id)"
|
||||
");"
|
||||
);
|
||||
}
|
||||
catch (CppSQLite3Exception& e)
|
||||
{
|
||||
LOG_ERROR(std::to_string(e.errorCode()) + ": " + e.errorMessage());
|
||||
|
||||
throw(std::exception());
|
||||
}
|
||||
}
|
||||
|
||||
void SqliteStorage::clearMetaTable()
|
||||
{
|
||||
try
|
||||
{
|
||||
m_database.execDML("DROP TABLE IF EXISTS main.meta;");
|
||||
}
|
||||
catch (CppSQLite3Exception& e)
|
||||
{
|
||||
LOG_ERROR(std::to_string(e.errorCode()) + ": " + e.errorMessage());
|
||||
}
|
||||
}
|
||||
|
||||
bool SqliteStorage::executeStatement(const std::string& statement) const
|
||||
{
|
||||
try
|
||||
{
|
||||
m_database.execDML(statement.c_str());
|
||||
}
|
||||
catch (CppSQLite3Exception e)
|
||||
{
|
||||
LOG_ERROR(std::to_string(e.errorCode()) + ": " + e.errorMessage());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SqliteStorage::executeStatement(CppSQLite3Statement& statement) const
|
||||
{
|
||||
try
|
||||
{
|
||||
statement.execDML();
|
||||
}
|
||||
catch (CppSQLite3Exception e)
|
||||
{
|
||||
LOG_ERROR(std::to_string(e.errorCode()) + ": " + e.errorMessage());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int SqliteStorage::executeStatementScalar(const std::string& statement, const int nullValue) const
|
||||
{
|
||||
int ret = 0;
|
||||
try
|
||||
{
|
||||
ret = m_database.execScalar(statement.c_str(), nullValue);
|
||||
}
|
||||
catch (CppSQLite3Exception e)
|
||||
{
|
||||
LOG_ERROR(std::to_string(e.errorCode()) + ": " + e.errorMessage());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SqliteStorage::executeStatementScalar(CppSQLite3Statement& statement, const int nullValue) const
|
||||
{
|
||||
int ret = 0;
|
||||
try
|
||||
{
|
||||
CppSQLite3Query q = executeQuery(statement);
|
||||
|
||||
if (q.eof() || q.numFields() < 1)
|
||||
{
|
||||
throw CppSQLite3Exception(
|
||||
CPPSQLITE_ERROR,
|
||||
"Invalid scalar query",
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
ret = q.getIntField(0, nullValue);
|
||||
}
|
||||
catch (CppSQLite3Exception e)
|
||||
{
|
||||
LOG_ERROR(std::to_string(e.errorCode()) + ": " + e.errorMessage());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
CppSQLite3Query SqliteStorage::executeQuery(const std::string& statement) const
|
||||
{
|
||||
try
|
||||
{
|
||||
return m_database.execQuery(statement.c_str());
|
||||
}
|
||||
catch (CppSQLite3Exception e)
|
||||
{
|
||||
LOG_ERROR(std::to_string(e.errorCode()) + ": " + e.errorMessage());
|
||||
}
|
||||
return CppSQLite3Query();
|
||||
}
|
||||
|
||||
CppSQLite3Query SqliteStorage::executeQuery(CppSQLite3Statement& statement) const
|
||||
{
|
||||
try
|
||||
{
|
||||
return statement.execQuery();
|
||||
}
|
||||
catch (CppSQLite3Exception e)
|
||||
{
|
||||
LOG_ERROR(std::to_string(e.errorCode()) + ": " + e.errorMessage());
|
||||
}
|
||||
return CppSQLite3Query();
|
||||
}
|
||||
|
||||
bool SqliteStorage::hasTable(const std::string& tableName) const
|
||||
{
|
||||
CppSQLite3Query q = executeQuery(
|
||||
"SELECT name FROM sqlite_master WHERE type='table' AND name='" + tableName + "';"
|
||||
);
|
||||
|
||||
if (!q.eof())
|
||||
{
|
||||
return q.getStringField(0, "") == tableName;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string SqliteStorage::getMetaValue(const std::string& key) const
|
||||
{
|
||||
if (hasTable("meta"))
|
||||
{
|
||||
CppSQLite3Query q = executeQuery("SELECT value FROM meta WHERE key = '" + key + "';");
|
||||
|
||||
if (!q.eof())
|
||||
{
|
||||
return q.getStringField(0, "");
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
void SqliteStorage::insertOrUpdateMetaValue(const std::string& key, const std::string& value)
|
||||
{
|
||||
CppSQLite3Statement stmt = m_database.compileStatement(std::string(
|
||||
"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);
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
#ifndef SQLITE_STORAGE_H
|
||||
#define SQLITE_STORAGE_H
|
||||
|
||||
#include "sqlite/CppSQLite3.h"
|
||||
|
||||
#include "data/storage/sqlite/SqliteDatabaseIndex.h"
|
||||
#include "utility/file/FilePath.h"
|
||||
|
||||
class SqliteStorageMigration;
|
||||
class TimePoint;
|
||||
|
||||
class SqliteStorage
|
||||
{
|
||||
public:
|
||||
enum StorageModeType
|
||||
{
|
||||
STORAGE_MODE_UNKNOWN = 0,
|
||||
STORAGE_MODE_READ = 1,
|
||||
STORAGE_MODE_WRITE = 2,
|
||||
STORAGE_MODE_CLEAR = 4,
|
||||
};
|
||||
|
||||
SqliteStorage(const FilePath& dbFilePath);
|
||||
virtual ~SqliteStorage();
|
||||
|
||||
void setup();
|
||||
void clear();
|
||||
|
||||
size_t getVersion() const;
|
||||
void setVersion(size_t version);
|
||||
|
||||
void setMode(const StorageModeType mode);
|
||||
|
||||
void beginTransaction();
|
||||
void commitTransaction();
|
||||
void rollbackTransaction();
|
||||
|
||||
void optimizeMemory() const;
|
||||
|
||||
FilePath getDbFilePath() const;
|
||||
|
||||
bool isEmpty() const;
|
||||
bool isIncompatible() const;
|
||||
|
||||
void setTime();
|
||||
TimePoint getTime() const;
|
||||
|
||||
protected:
|
||||
void setupMetaTable();
|
||||
void clearMetaTable();
|
||||
|
||||
bool executeStatement(const std::string& statement) const;
|
||||
bool executeStatement(CppSQLite3Statement& statement) const;
|
||||
int executeStatementScalar(const std::string& statement, const int nullValue) const;
|
||||
int executeStatementScalar(CppSQLite3Statement& statement, const int nullValue) const;
|
||||
CppSQLite3Query executeQuery(const std::string& statement) const;
|
||||
CppSQLite3Query executeQuery(CppSQLite3Statement& statement) const;
|
||||
|
||||
bool hasTable(const std::string& tableName) const;
|
||||
|
||||
std::string getMetaValue(const std::string& key) const;
|
||||
void insertOrUpdateMetaValue(const std::string& key, const std::string& value);
|
||||
|
||||
mutable CppSQLite3DB m_database;
|
||||
FilePath m_dbFilePath;
|
||||
|
||||
StorageModeType m_mode;
|
||||
|
||||
private:
|
||||
virtual size_t getStaticVersion() const = 0;
|
||||
virtual std::vector<std::pair<int, SqliteDatabaseIndex>> getIndices() const = 0;
|
||||
virtual void clearTables() = 0;
|
||||
virtual void setupTables() = 0;
|
||||
virtual void setupPrecompiledStatements() = 0;
|
||||
|
||||
std::vector<std::pair<int, SqliteDatabaseIndex>> m_indices;
|
||||
|
||||
friend SqliteStorageMigration;
|
||||
};
|
||||
|
||||
#endif // SQLITE_STORAGE_H
|
||||
Reference in New Issue
Block a user