indev
This commit is contained in:
@@ -0,0 +1 @@
|
||||
/build/
|
||||
@@ -0,0 +1,86 @@
|
||||
cmake_minimum_required (VERSION 2.6)
|
||||
|
||||
set(PROJECT_NAME "SourcetrailDBCore")
|
||||
set(LIB_NAME "sourcetraildb")
|
||||
|
||||
set(INTERFACE_VERSION 0)
|
||||
set(DATABASE_VERSION 21)
|
||||
set(COMMIT_VERSION 1)
|
||||
set(VERSION_STRING "v${INTERFACE_VERSION}_db${DATABASE_VERSION}_c${COMMIT_VERSION}")
|
||||
|
||||
project(${PROJECT_NAME})
|
||||
|
||||
# check for current architecture
|
||||
if(NOT "${CMAKE_GENERATOR}" MATCHES "(Win64|IA64)")
|
||||
set(ARCH 32)
|
||||
else()
|
||||
set(ARCH 64)
|
||||
endif()
|
||||
|
||||
# configure default build type to Release
|
||||
set(CMAKE_BUILD_TYPE_INIT "Release")
|
||||
|
||||
# configure the output directory
|
||||
if (UNIX)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build/${ARCH}bit/${CMAKE_BUILD_TYPE}/")
|
||||
else ()
|
||||
foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES})
|
||||
string( TOUPPER ${OUTPUTCONFIG} UPPER_OUTPUTCONFIG )
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${UPPER_OUTPUTCONFIG} "${CMAKE_SOURCE_DIR}/build/${ARCH}bit/${OUTPUTCONFIG}/")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${UPPER_OUTPUTCONFIG} "${CMAKE_SOURCE_DIR}/build/${ARCH}bit/${OUTPUTCONFIG}/")
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${UPPER_OUTPUTCONFIG} "${CMAKE_SOURCE_DIR}/build/${ARCH}bit/${OUTPUTCONFIG}/")
|
||||
endforeach(OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES)
|
||||
endif ()
|
||||
|
||||
|
||||
set(GENERATED_INCLUDE_DIRECTORY "${CMAKE_BINARY_DIR}/include")
|
||||
set(GENERATED_VERSION_FILE "${GENERATED_INCLUDE_DIRECTORY}/version.h")
|
||||
|
||||
configure_file(
|
||||
${CMAKE_SOURCE_DIR}/version.h.in
|
||||
${GENERATED_VERSION_FILE}
|
||||
)
|
||||
|
||||
set(SRC_FILES
|
||||
external/sqlite/CppSQLite3.cpp
|
||||
external/sqlite/sqlite3.c
|
||||
src/DatabaseStorage.cpp
|
||||
src/DefinitionKind.cpp
|
||||
src/EdgeKind.cpp
|
||||
src/LocationKind.cpp
|
||||
src/NameHierarchy.cpp
|
||||
src/NodeKind.cpp
|
||||
src/ReferenceKind.cpp
|
||||
src/SourcetrailDBWriter.cpp
|
||||
src/SymbolKind.cpp
|
||||
src/utility.cpp
|
||||
)
|
||||
|
||||
set(HDR_FILES
|
||||
external/json/json.hpp
|
||||
external/sqlite/CppSQLite3.h
|
||||
external/sqlite/sqlite3.h
|
||||
include/DatabaseStorage.h
|
||||
include/DefinitionKind.h
|
||||
include/EdgeKind.h
|
||||
include/LocationKind.h
|
||||
include/NameElement.h
|
||||
include/NameHierarchy.h
|
||||
include/NodeKind.h
|
||||
include/ReferenceKind.h
|
||||
include/SourceLocation.h
|
||||
include/SourceRange.h
|
||||
include/SourcetrailException.h
|
||||
include/SourcetrailDBWriter.h
|
||||
include/SymbolKind.h
|
||||
include/utility.h
|
||||
${GENERATED_VERSION_FILE}
|
||||
)
|
||||
|
||||
add_library(${LIB_NAME} STATIC ${SRC_FILES} ${HDR_FILES})
|
||||
|
||||
target_include_directories(${LIB_NAME} PUBLIC
|
||||
"${CMAKE_SOURCE_DIR}/include"
|
||||
"${CMAKE_SOURCE_DIR}/external"
|
||||
"${GENERATED_INCLUDE_DIRECTORY}"
|
||||
)
|
||||
Vendored
+18912
File diff suppressed because it is too large
Load Diff
Vendored
+1587
File diff suppressed because it is too large
Load Diff
Vendored
+326
@@ -0,0 +1,326 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// CppSQLite3 - A C++ wrapper around the SQLite3 embedded database library.
|
||||
//
|
||||
// Copyright (c) 2004..2007 Rob Groves. All Rights Reserved. rob.groves@btinternet.com
|
||||
//
|
||||
// Permission to use, copy, modify, and distribute this software and its
|
||||
// documentation for any purpose, without fee, and without a written
|
||||
// agreement, is hereby granted, provided that the above copyright notice,
|
||||
// this paragraph and the following two paragraphs appear in all copies,
|
||||
// modifications, and distributions.
|
||||
//
|
||||
// IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT,
|
||||
// INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST
|
||||
// PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
|
||||
// EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
// PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF
|
||||
// ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". THE AUTHOR HAS NO OBLIGATION
|
||||
// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
//
|
||||
// V3.0 03/08/2004 -Initial Version for sqlite3
|
||||
//
|
||||
// V3.1 16/09/2004 -Implemented getXXXXField using sqlite3 functions
|
||||
// -Added CppSQLiteDB3::tableExists()
|
||||
//
|
||||
// V3.2 01/07/2005 -Fixed execScalar to handle a NULL result
|
||||
// 12/07/2007 -Added CppSQLiteDB::IsAutoCommitOn()
|
||||
// -Added int64 functions to CppSQLite3Query
|
||||
// -Added Name based parameter binding to CppSQLite3Statement.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef _CppSQLite3_H_
|
||||
#define _CppSQLite3_H_
|
||||
|
||||
#include "sqlite3.h"
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
#define CPPSQLITE_ERROR 1000
|
||||
|
||||
class CppSQLite3Exception
|
||||
{
|
||||
public:
|
||||
|
||||
CppSQLite3Exception(const int nErrCode,
|
||||
char* szErrMess,
|
||||
bool bDeleteMsg=true);
|
||||
|
||||
CppSQLite3Exception(const CppSQLite3Exception& e);
|
||||
|
||||
virtual ~CppSQLite3Exception();
|
||||
|
||||
const int errorCode() { return mnErrCode; }
|
||||
|
||||
const char* errorMessage() { return mpszErrMess; }
|
||||
|
||||
static const char* errorCodeAsString(int nErrCode);
|
||||
|
||||
private:
|
||||
|
||||
int mnErrCode;
|
||||
char* mpszErrMess;
|
||||
};
|
||||
|
||||
|
||||
class CppSQLite3Buffer
|
||||
{
|
||||
public:
|
||||
|
||||
CppSQLite3Buffer();
|
||||
|
||||
~CppSQLite3Buffer();
|
||||
|
||||
const char* format(const char* szFormat, ...);
|
||||
|
||||
operator const char*() { return mpBuf; }
|
||||
|
||||
void clear();
|
||||
|
||||
private:
|
||||
|
||||
char* mpBuf;
|
||||
};
|
||||
|
||||
|
||||
class CppSQLite3Binary
|
||||
{
|
||||
public:
|
||||
|
||||
CppSQLite3Binary();
|
||||
|
||||
~CppSQLite3Binary();
|
||||
|
||||
void setBinary(const unsigned char* pBuf, int nLen);
|
||||
void setEncoded(const unsigned char* pBuf);
|
||||
|
||||
const unsigned char* getEncoded();
|
||||
const unsigned char* getBinary();
|
||||
|
||||
int getBinaryLength();
|
||||
|
||||
unsigned char* allocBuffer(int nLen);
|
||||
|
||||
void clear();
|
||||
|
||||
private:
|
||||
|
||||
unsigned char* mpBuf;
|
||||
int mnBinaryLen;
|
||||
int mnBufferLen;
|
||||
int mnEncodedLen;
|
||||
bool mbEncoded;
|
||||
};
|
||||
|
||||
|
||||
class CppSQLite3Query
|
||||
{
|
||||
public:
|
||||
|
||||
CppSQLite3Query();
|
||||
|
||||
CppSQLite3Query(const CppSQLite3Query& rQuery);
|
||||
|
||||
CppSQLite3Query(sqlite3* pDB,
|
||||
sqlite3_stmt* pVM,
|
||||
bool bEof,
|
||||
bool bOwnVM=true);
|
||||
|
||||
CppSQLite3Query& operator=(const CppSQLite3Query& rQuery);
|
||||
|
||||
virtual ~CppSQLite3Query();
|
||||
|
||||
int numFields();
|
||||
|
||||
int fieldIndex(const char* szField);
|
||||
const char* fieldName(int nCol);
|
||||
|
||||
const char* fieldDeclType(int nCol);
|
||||
int fieldDataType(int nCol);
|
||||
|
||||
const char* fieldValue(int nField);
|
||||
const char* fieldValue(const char* szField);
|
||||
|
||||
int getIntField(int nField, int nNullValue=0);
|
||||
int getIntField(const char* szField, int nNullValue=0);
|
||||
|
||||
sqlite_int64 getInt64Field(int nField, sqlite_int64 nNullValue=0);
|
||||
sqlite_int64 getInt64Field(const char* szField, sqlite_int64 nNullValue=0);
|
||||
|
||||
double getFloatField(int nField, double fNullValue=0.0);
|
||||
double getFloatField(const char* szField, double fNullValue=0.0);
|
||||
|
||||
const char* getStringField(int nField, const char* szNullValue="");
|
||||
const char* getStringField(const char* szField, const char* szNullValue="");
|
||||
|
||||
const unsigned char* getBlobField(int nField, int& nLen);
|
||||
const unsigned char* getBlobField(const char* szField, int& nLen);
|
||||
|
||||
bool fieldIsNull(int nField);
|
||||
bool fieldIsNull(const char* szField);
|
||||
|
||||
bool eof();
|
||||
|
||||
void nextRow();
|
||||
|
||||
void finalize();
|
||||
|
||||
private:
|
||||
|
||||
void checkVM();
|
||||
|
||||
sqlite3* mpDB;
|
||||
sqlite3_stmt* mpVM;
|
||||
bool mbEof;
|
||||
int mnCols;
|
||||
bool mbOwnVM;
|
||||
};
|
||||
|
||||
|
||||
class CppSQLite3Table
|
||||
{
|
||||
public:
|
||||
|
||||
CppSQLite3Table();
|
||||
|
||||
CppSQLite3Table(const CppSQLite3Table& rTable);
|
||||
|
||||
CppSQLite3Table(char** paszResults, int nRows, int nCols);
|
||||
|
||||
virtual ~CppSQLite3Table();
|
||||
|
||||
CppSQLite3Table& operator=(const CppSQLite3Table& rTable);
|
||||
|
||||
int numFields();
|
||||
|
||||
int numRows();
|
||||
|
||||
const char* fieldName(int nCol);
|
||||
|
||||
const char* fieldValue(int nField);
|
||||
const char* fieldValue(const char* szField);
|
||||
|
||||
int getIntField(int nField, int nNullValue=0);
|
||||
int getIntField(const char* szField, int nNullValue=0);
|
||||
|
||||
double getFloatField(int nField, double fNullValue=0.0);
|
||||
double getFloatField(const char* szField, double fNullValue=0.0);
|
||||
|
||||
const char* getStringField(int nField, const char* szNullValue="");
|
||||
const char* getStringField(const char* szField, const char* szNullValue="");
|
||||
|
||||
bool fieldIsNull(int nField);
|
||||
bool fieldIsNull(const char* szField);
|
||||
|
||||
void setRow(int nRow);
|
||||
|
||||
void finalize();
|
||||
|
||||
private:
|
||||
|
||||
void checkResults();
|
||||
|
||||
int mnCols;
|
||||
int mnRows;
|
||||
int mnCurrentRow;
|
||||
char** mpaszResults;
|
||||
};
|
||||
|
||||
|
||||
class CppSQLite3Statement
|
||||
{
|
||||
public:
|
||||
|
||||
CppSQLite3Statement();
|
||||
|
||||
CppSQLite3Statement(const CppSQLite3Statement& rStatement);
|
||||
|
||||
CppSQLite3Statement(sqlite3* pDB, sqlite3_stmt* pVM);
|
||||
|
||||
virtual ~CppSQLite3Statement();
|
||||
|
||||
CppSQLite3Statement& operator=(const CppSQLite3Statement& rStatement);
|
||||
|
||||
int execDML();
|
||||
|
||||
CppSQLite3Query execQuery();
|
||||
|
||||
void bind(int nParam, const char* szValue);
|
||||
void bind(int nParam, const int nValue);
|
||||
void bind(int nParam, const double dwValue);
|
||||
void bind(int nParam, const unsigned char* blobValue, int nLen);
|
||||
void bindNull(int nParam);
|
||||
|
||||
int bindParameterIndex(const char* szParam);
|
||||
void bind(const char* szParam, const char* szValue);
|
||||
void bind(const char* szParam, const int nValue);
|
||||
void bind(const char* szParam, const double dwValue);
|
||||
void bind(const char* szParam, const unsigned char* blobValue, int nLen);
|
||||
void bindNull(const char* szParam);
|
||||
|
||||
void reset();
|
||||
|
||||
void finalize();
|
||||
|
||||
private:
|
||||
|
||||
void checkDB();
|
||||
void checkVM();
|
||||
|
||||
sqlite3* mpDB;
|
||||
sqlite3_stmt* mpVM;
|
||||
};
|
||||
|
||||
|
||||
class CppSQLite3DB
|
||||
{
|
||||
public:
|
||||
|
||||
CppSQLite3DB();
|
||||
|
||||
virtual ~CppSQLite3DB();
|
||||
|
||||
void open(const char* szFile);
|
||||
|
||||
void close();
|
||||
|
||||
bool tableExists(const char* szTable);
|
||||
|
||||
int execDML(const char* szSQL);
|
||||
|
||||
CppSQLite3Query execQuery(const char* szSQL);
|
||||
|
||||
int execScalar(const char* szSQL, int nNullValue=0);
|
||||
|
||||
CppSQLite3Table getTable(const char* szSQL);
|
||||
|
||||
CppSQLite3Statement compileStatement(const char* szSQL);
|
||||
|
||||
sqlite_int64 lastRowId();
|
||||
|
||||
void interrupt() { sqlite3_interrupt(mpDB); }
|
||||
|
||||
void setBusyTimeout(int nMillisecs);
|
||||
|
||||
static const char* SQLiteVersion() { return SQLITE_VERSION; }
|
||||
static const char* SQLiteHeaderVersion() { return SQLITE_VERSION; }
|
||||
static const char* SQLiteLibraryVersion() { return sqlite3_libversion(); }
|
||||
static int SQLiteLibraryVersionNumber() { return sqlite3_libversion_number(); }
|
||||
|
||||
bool IsAutoCommitOn();
|
||||
|
||||
private:
|
||||
|
||||
CppSQLite3DB(const CppSQLite3DB& db);
|
||||
CppSQLite3DB& operator=(const CppSQLite3DB& db);
|
||||
|
||||
sqlite3_stmt* compile(const char* szSQL);
|
||||
|
||||
void checkDB();
|
||||
|
||||
sqlite3* mpDB;
|
||||
int mnBusyTimeoutMs;
|
||||
};
|
||||
|
||||
#endif
|
||||
Vendored
+155866
File diff suppressed because it is too large
Load Diff
Vendored
+7831
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,69 @@
|
||||
#ifndef SOURCETRAIL_DATABASE_STORAGE_H
|
||||
#define SOURCETRAIL_DATABASE_STORAGE_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "sqlite/CppSQLite3.h"
|
||||
|
||||
namespace sourcetrail
|
||||
{
|
||||
/**
|
||||
* Class wrapping the write and update interface of the Sourcetrail database.
|
||||
*
|
||||
* The DatabaseStorage provides the interface for writing and updating the Sourcetrail database. This interface only
|
||||
* knows about basic data types, more elaborate types like enums, structs and classes need to be converted to basic
|
||||
* types before using this interface.
|
||||
*/
|
||||
class DatabaseStorage
|
||||
{
|
||||
public:
|
||||
static int getSupportedDatabaseVersion();
|
||||
static std::shared_ptr<DatabaseStorage> openDatabase(const std::string& dbFilePath);
|
||||
~DatabaseStorage();
|
||||
|
||||
void setupTables();
|
||||
void clearTables();
|
||||
|
||||
bool isEmpty() const;
|
||||
bool isCompatible() const;
|
||||
int getLoadedDatabaseVersion() const;
|
||||
void beginTransaction();
|
||||
void commitTransaction();
|
||||
void rollbackTransaction();
|
||||
void optimizeDatabaseMemory();
|
||||
|
||||
int addNode(const std::string& serializedNameHierarchy);
|
||||
void addSymbol(int symbolId, int definitionKind);
|
||||
void addFile(int nodeId, const std::string& filePath);
|
||||
int addEdge(int sourceId, int targetId, int edgeKind);
|
||||
int addLocalSymbol(const std::string& name);
|
||||
int addSourceLocation(
|
||||
int fileId,
|
||||
int startLineNumber,
|
||||
int startColumnNumber,
|
||||
int endLineNumber,
|
||||
int endColumnNumber,
|
||||
int locationKind);
|
||||
void addOccurrence(int elementId, int sourceLocationId);
|
||||
int addError(
|
||||
const std::string& message,
|
||||
bool fatal);
|
||||
|
||||
void setNodeType(int nodeId, int nodeKind);
|
||||
|
||||
private:
|
||||
DatabaseStorage() = default;
|
||||
|
||||
void insertOrUpdateMetaValue(const std::string& key, const std::string& value);
|
||||
void executeStatement(const std::string& statement) const;
|
||||
void executeStatement(CppSQLite3Statement& statement) const;
|
||||
CppSQLite3Query executeQuery(const std::string& query) const;
|
||||
CppSQLite3Query executeQuery(CppSQLite3Statement& statement) const;
|
||||
|
||||
mutable CppSQLite3DB m_database;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // SOURCETRAIL_DATABASE_STORAGE_H
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef SOURCETRAIL_DEFINITION_KIND_H
|
||||
#define SOURCETRAIL_DEFINITION_KIND_H
|
||||
|
||||
namespace sourcetrail
|
||||
{
|
||||
/**
|
||||
* Enum providing all possible values for a symbol's definition kind.
|
||||
*
|
||||
* The DefinitionKind specifies "how" a symbol is defined.
|
||||
* When recording the definition of a symbol, you would usually also record an explicit definition kind.
|
||||
* However, you may also want to record symbols that are implicitly generated by the compiler. In this case you can
|
||||
* record an implicit definition kind for those symbols.
|
||||
* If you do not record any definition kind for a symbol, Sourcetrail will show it as "non-indexed".
|
||||
*/
|
||||
enum DefinitionKind
|
||||
{
|
||||
DEFINITION_IMPLICIT = 1,
|
||||
DEFINITION_EXPLICIT = 2
|
||||
};
|
||||
|
||||
int definitionKindToInt(DefinitionKind v);
|
||||
DefinitionKind intToDefinitionKind(int v);
|
||||
}
|
||||
|
||||
#endif // SOURCETRAIL_DEFINITION_KIND_H
|
||||
@@ -0,0 +1,40 @@
|
||||
#ifndef SOURCETRAIL_EDGE_KIND_H
|
||||
#define SOURCETRAIL_EDGE_KIND_H
|
||||
|
||||
namespace sourcetrail
|
||||
{
|
||||
/**
|
||||
* Enum providing all possible values for kinds of edges that can be stored to the Sourcetrail database.
|
||||
*
|
||||
* The DatabaseStorage provides the interface for writing and updating the Sourcetrail database. This interface only
|
||||
* The EdgeKind enum should only be used internally and contains a complete list of values that may be written to
|
||||
* the Sourcetrail database file. This enum contains kinds for edges that can be recorded explicitly, but also kinds
|
||||
* for edges that will be created implicitly. For example edges of type "EDGE_MEMBER" will be created while storing parent
|
||||
* child node relations when recording symbols with hierarchical names (see NameHierarchy).
|
||||
*/
|
||||
enum EdgeKind
|
||||
{
|
||||
EDGE_UNKNOWN = 0,
|
||||
EDGE_MEMBER = 1 << 0,
|
||||
EDGE_TYPE_USAGE = 1 << 1,
|
||||
EDGE_USAGE = 1 << 2,
|
||||
EDGE_CALL = 1 << 3,
|
||||
EDGE_INHERITANCE = 1 << 4,
|
||||
EDGE_OVERRIDE = 1 << 5,
|
||||
EDGE_TEMPLATE_ARGUMENT = 1 << 6,
|
||||
EDGE_TYPE_ARGUMENT = 1 << 7,
|
||||
EDGE_TEMPLATE_DEFAULT_ARGUMENT = 1 << 8,
|
||||
EDGE_TEMPLATE_SPECIALIZATION = 1 << 9,
|
||||
EDGE_TEMPLATE_MEMBER_SPECIALIZATION = 1 << 10,
|
||||
EDGE_INCLUDE = 1 << 11,
|
||||
EDGE_IMPORT = 1 << 12,
|
||||
EDGE_AGGREGATION = 1 << 13,
|
||||
EDGE_MACRO_USAGE = 1 << 14,
|
||||
EDGE_ANNOTATION_USAGE = 1 << 15
|
||||
};
|
||||
|
||||
int edgeKindToInt(EdgeKind edgeKind);
|
||||
EdgeKind intToEdgeKind(int i);
|
||||
}
|
||||
|
||||
#endif // SOURCETRAIL_EDGE_KIND_H
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef SOURCETRAIL_LOCATION_KIND_H
|
||||
#define SOURCETRAIL_LOCATION_KIND_H
|
||||
|
||||
namespace sourcetrail
|
||||
{
|
||||
/**
|
||||
* Enum providing all possible values for kinds of locations that can be stored to the Sourcetrail database.
|
||||
*/
|
||||
enum LocationKind
|
||||
{
|
||||
LOCATION_TOKEN = 0,
|
||||
LOCATION_SCOPE = 1,
|
||||
LOCATION_QUALIFIER = 2,
|
||||
LOCATION_LOCAL_SYMBOL = 3,
|
||||
LOCATION_SIGNATURE = 4,
|
||||
LOCATION_COMMENT = 5,
|
||||
LOCATION_ERROR = 6,
|
||||
LOCATION_FULLTEXT_SEARCH = 7,
|
||||
LOCATION_SCREEN_SEARCH = 8
|
||||
};
|
||||
|
||||
LocationKind intToLocationKind(int i);
|
||||
int locationKindToInt(LocationKind locationKind);
|
||||
}
|
||||
|
||||
#endif // SOURCETRAIL_LOCATION_KIND_H
|
||||
@@ -0,0 +1,19 @@
|
||||
#ifndef SOURCETRAIL_NAME_ELEMENT_H
|
||||
#define SOURCETRAIL_NAME_ELEMENT_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace sourcetrail
|
||||
{
|
||||
/**
|
||||
* Struct that represents a single hierarchical element that is part of a symbol's name.
|
||||
*/
|
||||
struct NameElement
|
||||
{
|
||||
std::string prefix;
|
||||
std::string name;
|
||||
std::string postfix;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // SOURCETRAIL_NAME_ELEMENT_H
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef SOURCETRAIL_NAME_HIERARCHY_H
|
||||
#define SOURCETRAIL_NAME_HIERARCHY_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "NameElement.h"
|
||||
|
||||
namespace sourcetrail
|
||||
{
|
||||
/**
|
||||
* Struct that represents an entire name of a symbol.
|
||||
*/
|
||||
struct NameHierarchy
|
||||
{
|
||||
std::string nameDelimiter;
|
||||
std::vector<NameElement> nameElements;
|
||||
};
|
||||
|
||||
std::string serializeNameHierarchyToJson(const NameHierarchy& nameHierarchy);
|
||||
NameHierarchy deserializeNameHierarchyFromJson(const std::string& serializedNameHierarchy);
|
||||
}
|
||||
|
||||
#endif // SOURCETRAIL_NAME_HIERARCHY_H
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef SOURCETRAIL_NODE_KIND_H
|
||||
#define SOURCETRAIL_NODE_KIND_H
|
||||
|
||||
namespace sourcetrail
|
||||
{
|
||||
/**
|
||||
* Enum providing all possible values for kinds of nodes that can be stored to the Sourcetrail database.
|
||||
*/
|
||||
enum NodeKind
|
||||
{
|
||||
NODE_UNKNOWN = 1 << 0,
|
||||
NODE_TYPE = 1 << 1,
|
||||
NODE_BUILTIN_TYPE = 1 << 2,
|
||||
NODE_NAMESPACE = 1 << 3,
|
||||
NODE_PACKAGE = 1 << 4,
|
||||
NODE_STRUCT = 1 << 5,
|
||||
NODE_CLASS = 1 << 6,
|
||||
NODE_INTERFACE = 1 << 7,
|
||||
NODE_ANNOTATION = 1 << 8,
|
||||
NODE_GLOBAL_VARIABLE = 1 << 9,
|
||||
NODE_FIELD = 1 << 10,
|
||||
NODE_FUNCTION = 1 << 11,
|
||||
NODE_METHOD = 1 << 12,
|
||||
NODE_ENUM = 1 << 13,
|
||||
NODE_ENUM_CONSTANT = 1 << 14,
|
||||
NODE_TYPEDEF = 1 << 15,
|
||||
NODE_TEMPLATE_PARAMETER = 1 << 16,
|
||||
NODE_TYPE_PARAMETER = 1 << 17,
|
||||
NODE_FILE = 1 << 18,
|
||||
NODE_MACRO = 1 << 19,
|
||||
NODE_UNION = 1 << 20,
|
||||
};
|
||||
|
||||
int nodeKindToInt(NodeKind v);
|
||||
NodeKind intToNodeKind(int v);
|
||||
}
|
||||
|
||||
#endif // SOURCETRAIL_NODE_KIND_H
|
||||
@@ -0,0 +1,32 @@
|
||||
#ifndef SOURCETRAIL_REFERENCE_KIND_H
|
||||
#define SOURCETRAIL_REFERENCE_KIND_H
|
||||
|
||||
namespace sourcetrail
|
||||
{
|
||||
enum EdgeKind;
|
||||
|
||||
/**
|
||||
* Enum providing all possible values for kinds of references that can be recorded using the SourcetrailDBWriter interface.
|
||||
*/
|
||||
enum ReferenceKind
|
||||
{
|
||||
REFERENCE_TYPE_USAGE,
|
||||
REFERENCE_USAGE,
|
||||
REFERENCE_CALL,
|
||||
REFERENCE_INHERITANCE,
|
||||
REFERENCE_OVERRIDE,
|
||||
REFERENCE_TEMPLATE_ARGUMENT,
|
||||
REFERENCE_TYPE_ARGUMENT,
|
||||
REFERENCE_TEMPLATE_DEFAULT_ARGUMENT,
|
||||
REFERENCE_TEMPLATE_SPECIALIZATION,
|
||||
REFERENCE_TEMPLATE_MEMBER_SPECIALIZATION,
|
||||
REFERENCE_INCLUDE,
|
||||
REFERENCE_IMPORT,
|
||||
REFERENCE_MACRO_USAGE,
|
||||
REFERENCE_ANNOTATION_USAGE
|
||||
};
|
||||
|
||||
EdgeKind referenceKindToEdgeKind(ReferenceKind referenceKind);
|
||||
}
|
||||
|
||||
#endif // SOURCETRAIL_REFERENCE_KIND_H
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef SOURCETRAIL_SOURCE_LOCATION_H
|
||||
#define SOURCETRAIL_SOURCE_LOCATION_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace sourcetrail
|
||||
{
|
||||
/**
|
||||
* Struct that represents a single character location in a source file.
|
||||
*
|
||||
* Note: Line and column numbers start at 1 instead of 0!
|
||||
*/
|
||||
struct SourceLocation
|
||||
{
|
||||
std::string filePath;
|
||||
int line;
|
||||
int column;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // SOURCETRAIL_SOURCE_LOCATION_H
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef SOURCETRAIL_SOURCE_RANGE_H
|
||||
#define SOURCETRAIL_SOURCE_RANGE_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace sourcetrail
|
||||
{
|
||||
/**
|
||||
* Struct that represents the location of a range of characters in a source file.
|
||||
*
|
||||
* Note: Line and column numbers start at 1 instead of 0!
|
||||
*/
|
||||
struct SourceRange
|
||||
{
|
||||
std::string filePath;
|
||||
int startLine;
|
||||
int startColumn;
|
||||
int endLine;
|
||||
int endColumn;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // SOURCETRAIL_SOURCE_RANGE_H
|
||||
@@ -0,0 +1,95 @@
|
||||
#ifndef SOURCETRAIL_SRCTRLDB_WRITER_H
|
||||
#define SOURCETRAIL_SRCTRLDB_WRITER_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace sourcetrail
|
||||
{
|
||||
class DatabaseStorage;
|
||||
|
||||
struct SourceRange;
|
||||
struct NameHierarchy;
|
||||
|
||||
enum DefinitionKind;
|
||||
enum EdgeKind;
|
||||
enum LocationKind;
|
||||
enum ReferenceKind;
|
||||
enum SymbolKind;
|
||||
|
||||
/**
|
||||
* Class wrapping the main interface for writing data to a Sourcetrail project database.
|
||||
*
|
||||
* TODO: write a detailed description here.
|
||||
* TODO: document all public interface methods
|
||||
* TODO: add small example for usage here
|
||||
*/
|
||||
class SourcetrailDBWriter
|
||||
{
|
||||
public:
|
||||
SourcetrailDBWriter();
|
||||
|
||||
std::string getVersionString() const;
|
||||
|
||||
int getSupportedDatabaseVersion() const;
|
||||
const std::string& getLastError() const;
|
||||
void clearLastError();
|
||||
|
||||
bool openProject(const std::string& projectDirectory, const std::string& projectName);
|
||||
bool closeProject();
|
||||
bool clearProject();
|
||||
|
||||
bool isEmpty() const;
|
||||
bool isCompatible() const;
|
||||
int getLoadedDatabaseVersion() const;
|
||||
|
||||
bool beginTransaction();
|
||||
bool commitTransaction();
|
||||
bool rollbackTransaction();
|
||||
bool optimizeDatabaseMemory();
|
||||
|
||||
/// will return the same id for the same name hierarchy. will return 0 on failure. 0 is not a valid symbol id
|
||||
int recordSymbol(const NameHierarchy& nameHierarchy);
|
||||
bool recordSymbolDefinitionKind(int symbolId, DefinitionKind definitionKind);
|
||||
bool recordSymbolKind(int symbolId, SymbolKind symbolKind);
|
||||
/// The provided "location" will be clickable and displayable. When clicked it will cause the symbol with the specified "symbolId" to be activated. When
|
||||
/// the symbol with the specified "symbolId" is activated, this location will be displayed.
|
||||
bool recordSymbolLocation(int symbolId, const SourceRange& location);
|
||||
/// The provided "location" will be displayable. When the symbol with the specified "symbolId" is activated, this location will be displayed.
|
||||
bool recordSymbolScopeLocation(int symbolId, const SourceRange& location);
|
||||
bool recordSymbolSignatureLocation(int symbolId, const SourceRange& location);
|
||||
|
||||
int recordReference(int contextSymbolId, int referencedSymbolId, ReferenceKind referenceKind);
|
||||
bool recordReferenceLocation(int referenceId, const SourceRange& location);
|
||||
|
||||
int recordFile(const std::string& filePath);
|
||||
|
||||
int recordLocalSymbol(const std::string& name);
|
||||
bool recordLocalSymbolLocation(int localSymbolId, const SourceRange& location);
|
||||
|
||||
bool recordCommentLocation(const SourceRange& location);
|
||||
|
||||
bool recordError(const std::string& message, bool fatal, const SourceRange& location);
|
||||
|
||||
private:
|
||||
static std::string serializeNameHierarchy(const NameHierarchy& nameHierarchy);
|
||||
std::string getProjectFilePath() const;
|
||||
std::string getDatabaseFilePath() const;
|
||||
void openDatabase();
|
||||
void closeDatabase();
|
||||
void setupDatabaseTables();
|
||||
void clearDatabaseTables();
|
||||
void createOrResetProjectFile();
|
||||
int addNodeHierarchy(const NameHierarchy& nameHierarchy);
|
||||
int addFile(const std::string& filePath);
|
||||
int addEdge(int sourceId, int targetId, EdgeKind edgeKind);
|
||||
void addSourceLocation(int elementId, const SourceRange& location, LocationKind kind);
|
||||
|
||||
std::string m_projectDirectory;
|
||||
std::string m_projectName;
|
||||
std::shared_ptr<DatabaseStorage> m_storage;
|
||||
mutable std::string m_lastError;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // SOURCETRAIL_SRCTRLDB_WRITER_H
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef SOURCETRAIL_SOURCETRAIL_EXCEPTION_H
|
||||
#define SOURCETRAIL_SOURCETRAIL_EXCEPTION_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace sourcetrail
|
||||
{
|
||||
/**
|
||||
* Exception type that is thrown by the SourcetrailDBWriter API.
|
||||
*/
|
||||
class SourcetrailException
|
||||
{
|
||||
public:
|
||||
SourcetrailException(std::string message) : m_message(message) {}
|
||||
virtual ~SourcetrailException() = default;
|
||||
std::string getMessage() const { return m_message; }
|
||||
|
||||
private:
|
||||
std::string m_message;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // SOURCETRAIL_SOURCETRAIL_EXCEPTION_H
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef SOURCETRAIL_SYMBOL_KIND_H
|
||||
#define SOURCETRAIL_SYMBOL_KIND_H
|
||||
|
||||
namespace sourcetrail
|
||||
{
|
||||
enum NodeKind;
|
||||
|
||||
/**
|
||||
* Enum providing all possible values for kinds of symbols that can be recorded using the SourcetrailDBWriter interface.
|
||||
*/
|
||||
enum SymbolKind
|
||||
{
|
||||
SYMBOL_TYPE,
|
||||
SYMBOL_BUILTIN_TYPE,
|
||||
SYMBOL_NAMESPACE,
|
||||
SYMBOL_PACKAGE,
|
||||
SYMBOL_STRUCT,
|
||||
SYMBOL_CLASS,
|
||||
SYMBOL_INTERFACE,
|
||||
SYMBOL_ANNOTATION,
|
||||
SYMBOL_GLOBAL_VARIABLE,
|
||||
SYMBOL_FIELD,
|
||||
SYMBOL_FUNCTION,
|
||||
SYMBOL_METHOD,
|
||||
SYMBOL_ENUM,
|
||||
SYMBOL_ENUM_CONSTANT,
|
||||
SYMBOL_TYPEDEF,
|
||||
SYMBOL_TEMPLATE_PARAMETER,
|
||||
SYMBOL_TYPE_PARAMETER,
|
||||
SYMBOL_MACRO,
|
||||
SYMBOL_UNION,
|
||||
};
|
||||
|
||||
NodeKind symbolKindToNodeKind(SymbolKind v);
|
||||
}
|
||||
|
||||
#endif // SOURCETRAIL_SYMBOL_KIND_H
|
||||
@@ -0,0 +1,19 @@
|
||||
#ifndef SOURCETRAIL_UTILITY_H
|
||||
#define SOURCETRAIL_UTILITY_H
|
||||
|
||||
#include <string>
|
||||
#include <time.h>
|
||||
|
||||
namespace sourcetrail
|
||||
{
|
||||
namespace utility
|
||||
{
|
||||
bool getFileExists(const std::string& filePath);
|
||||
std::string getFileContent(const std::string& filePath);
|
||||
time_t getFileModificationTime(const std::string& filePath);
|
||||
std::string getDateTimeString(const time_t& time);
|
||||
int getLineCount(const std::string s);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // SOURCETRAIL_UTILITY_H
|
||||
@@ -0,0 +1,607 @@
|
||||
#include "DatabaseStorage.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "SourcetrailException.h"
|
||||
#include "NodeKind.h"
|
||||
#include "utility.h"
|
||||
#include "version.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
namespace sourcetrail
|
||||
{
|
||||
// --- Public Interface ---
|
||||
|
||||
int DatabaseStorage::getSupportedDatabaseVersion()
|
||||
{
|
||||
return DATABASE_VERSION;
|
||||
}
|
||||
|
||||
std::shared_ptr<DatabaseStorage> DatabaseStorage::openDatabase(const std::string& dbFilePath)
|
||||
{
|
||||
std::shared_ptr<DatabaseStorage> storage = std::shared_ptr<DatabaseStorage>(new DatabaseStorage());
|
||||
storage->m_database.open(dbFilePath.c_str());
|
||||
storage->executeStatement("PRAGMA foreign_keys=ON;");
|
||||
return storage;
|
||||
}
|
||||
|
||||
DatabaseStorage::~DatabaseStorage()
|
||||
{
|
||||
m_database.close();
|
||||
}
|
||||
|
||||
void DatabaseStorage::setupTables()
|
||||
{
|
||||
executeStatement("PRAGMA foreign_keys=ON;");
|
||||
|
||||
if (!isCompatible())
|
||||
{
|
||||
throw SourcetrailException("Unable to setup database tables because database is not compatible.");
|
||||
}
|
||||
|
||||
executeStatement(
|
||||
"CREATE TABLE IF NOT EXISTS meta("
|
||||
" id INTEGER, "
|
||||
" key TEXT, "
|
||||
" value TEXT, "
|
||||
" PRIMARY KEY(id)"
|
||||
");"
|
||||
);
|
||||
|
||||
executeStatement(
|
||||
"CREATE TABLE IF NOT EXISTS element("
|
||||
" id INTEGER, "
|
||||
" PRIMARY KEY(id)"
|
||||
");"
|
||||
);
|
||||
|
||||
executeStatement(
|
||||
"CREATE TABLE IF NOT EXISTS edge("
|
||||
" id INTEGER NOT NULL, "
|
||||
" type INTEGER NOT NULL, "
|
||||
" source_node_id INTEGER NOT NULL, "
|
||||
" target_node_id INTEGER NOT NULL, "
|
||||
" PRIMARY KEY(id), "
|
||||
" FOREIGN KEY(id) REFERENCES element(id) ON DELETE CASCADE, "
|
||||
" FOREIGN KEY(source_node_id) REFERENCES node(id) ON DELETE CASCADE, "
|
||||
" FOREIGN KEY(target_node_id) REFERENCES node(id) ON DELETE CASCADE"
|
||||
");"
|
||||
);
|
||||
|
||||
executeStatement(
|
||||
"CREATE TABLE IF NOT EXISTS node("
|
||||
" id INTEGER NOT NULL, "
|
||||
" type INTEGER NOT NULL, "
|
||||
" serialized_name TEXT, "
|
||||
" PRIMARY KEY(id), "
|
||||
" FOREIGN KEY(id) REFERENCES element(id) ON DELETE CASCADE"
|
||||
");"
|
||||
);
|
||||
|
||||
executeStatement(
|
||||
"CREATE TABLE IF NOT EXISTS symbol("
|
||||
" id INTEGER NOT NULL, "
|
||||
" definition_kind INTEGER NOT NULL, "
|
||||
" PRIMARY KEY(id), "
|
||||
" FOREIGN KEY(id) REFERENCES node(id) ON DELETE CASCADE"
|
||||
");"
|
||||
);
|
||||
|
||||
executeStatement(
|
||||
"CREATE TABLE IF NOT EXISTS file("
|
||||
" id INTEGER NOT NULL, "
|
||||
" path TEXT, "
|
||||
" modification_time TEXT, "
|
||||
" indexed INTEGER, "
|
||||
" complete INTEGER, "
|
||||
" line_count INTEGER, "
|
||||
" PRIMARY KEY(id), "
|
||||
" FOREIGN KEY(id) REFERENCES node(id) ON DELETE CASCADE"
|
||||
");"
|
||||
);
|
||||
|
||||
executeStatement(
|
||||
"CREATE TABLE IF NOT EXISTS filecontent("
|
||||
" id INTERGER, "
|
||||
" content TEXT, "
|
||||
" FOREIGN KEY(id) REFERENCES file(id)"
|
||||
" ON DELETE CASCADE "
|
||||
" ON UPDATE CASCADE"
|
||||
");"
|
||||
);
|
||||
|
||||
executeStatement(
|
||||
"CREATE TABLE IF NOT EXISTS local_symbol("
|
||||
" id INTEGER NOT NULL, "
|
||||
" name TEXT, "
|
||||
" PRIMARY KEY(id), "
|
||||
" FOREIGN KEY(id) REFERENCES element(id) ON DELETE CASCADE"
|
||||
");"
|
||||
);
|
||||
|
||||
executeStatement(
|
||||
"CREATE TABLE IF NOT EXISTS source_location("
|
||||
" id INTEGER NOT NULL, "
|
||||
" file_node_id INTEGER, "
|
||||
" start_line INTEGER, "
|
||||
" start_column INTEGER, "
|
||||
" end_line INTEGER, "
|
||||
" end_column INTEGER, "
|
||||
" type INTEGER, "
|
||||
" PRIMARY KEY(id), "
|
||||
" FOREIGN KEY(file_node_id) REFERENCES node(id) ON DELETE CASCADE"
|
||||
");"
|
||||
);
|
||||
|
||||
executeStatement(
|
||||
"CREATE TABLE IF NOT EXISTS occurrence("
|
||||
" element_id INTEGER NOT NULL, "
|
||||
" source_location_id INTEGER NOT NULL, "
|
||||
" PRIMARY KEY(element_id, source_location_id), "
|
||||
" FOREIGN KEY(element_id) REFERENCES element(id) ON DELETE CASCADE, "
|
||||
" FOREIGN KEY(source_location_id) REFERENCES source_location(id) ON DELETE CASCADE"
|
||||
");"
|
||||
);
|
||||
|
||||
executeStatement(
|
||||
"CREATE TABLE IF NOT EXISTS component_access("
|
||||
" node_id INTEGER NOT NULL, "
|
||||
" type INTEGER NOT NULL, "
|
||||
" PRIMARY KEY(node_id), "
|
||||
" FOREIGN KEY(node_id) REFERENCES node(id) ON DELETE CASCADE"
|
||||
");"
|
||||
);
|
||||
|
||||
executeStatement(
|
||||
"CREATE TABLE IF NOT EXISTS error("
|
||||
" id INTEGER NOT NULL, "
|
||||
" message TEXT, "
|
||||
" fatal INTEGER NOT NULL, "
|
||||
" indexed INTEGER NOT NULL, "
|
||||
" translation_unit TEXT, "
|
||||
" PRIMARY KEY(id), "
|
||||
" FOREIGN KEY(id) REFERENCES element(id) ON DELETE CASCADE"
|
||||
");"
|
||||
);
|
||||
|
||||
insertOrUpdateMetaValue("storage_version", std::to_string(getSupportedDatabaseVersion()));
|
||||
}
|
||||
|
||||
void DatabaseStorage::clearTables()
|
||||
{
|
||||
executeStatement("PRAGMA foreign_keys=OFF;");
|
||||
|
||||
const std::vector<std::string> tableNames = {
|
||||
"meta",
|
||||
"error"
|
||||
"component_access",
|
||||
"occurrence",
|
||||
"source_location",
|
||||
"local_symbol",
|
||||
"filecontent",
|
||||
"file",
|
||||
"symbol",
|
||||
"node",
|
||||
"edge",
|
||||
"element"
|
||||
};
|
||||
|
||||
for (const std::string& tableName : tableNames)
|
||||
{
|
||||
executeStatement("DROP TABLE IF EXISTS main." + tableName + ";");
|
||||
}
|
||||
|
||||
setupTables();
|
||||
}
|
||||
|
||||
bool DatabaseStorage::isEmpty() const
|
||||
{
|
||||
const std::string tableName = "meta";
|
||||
CppSQLite3Query q = executeQuery(
|
||||
"SELECT name FROM sqlite_master WHERE type='table' AND name='" + tableName + "';"
|
||||
);
|
||||
|
||||
if (!q.eof())
|
||||
{
|
||||
return q.getStringField(0, "") == tableName;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DatabaseStorage::isCompatible() const
|
||||
{
|
||||
if (isEmpty())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return getLoadedDatabaseVersion() == getSupportedDatabaseVersion();
|
||||
}
|
||||
|
||||
int DatabaseStorage::getLoadedDatabaseVersion() const
|
||||
{
|
||||
if (isEmpty())
|
||||
{
|
||||
throw SourcetrailException("Unable to determine version of an empty database.");
|
||||
}
|
||||
|
||||
CppSQLite3Query q = executeQuery("SELECT value FROM meta WHERE key = 'storage_version';");
|
||||
if (!q.eof())
|
||||
{
|
||||
return std::stoi(q.getStringField(0, "0"));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DatabaseStorage::beginTransaction()
|
||||
{
|
||||
executeStatement("BEGIN TRANSACTION;");
|
||||
}
|
||||
|
||||
void DatabaseStorage::commitTransaction()
|
||||
{
|
||||
executeStatement("COMMIT TRANSACTION;");
|
||||
}
|
||||
|
||||
void DatabaseStorage::rollbackTransaction()
|
||||
{
|
||||
executeStatement("ROLLBACK TRANSACTION;");
|
||||
}
|
||||
|
||||
void DatabaseStorage::optimizeDatabaseMemory()
|
||||
{
|
||||
executeStatement("VACUUM;");
|
||||
}
|
||||
|
||||
int DatabaseStorage::addNode(const std::string& serializedNameHierarchy)
|
||||
{
|
||||
int id = 0;
|
||||
|
||||
{
|
||||
CppSQLite3Statement stmt = m_database.compileStatement(
|
||||
"SELECT id FROM node WHERE serialized_name == ? LIMIT 1;"
|
||||
);
|
||||
stmt.bind(1, serializedNameHierarchy.c_str());
|
||||
CppSQLite3Query q = executeQuery(stmt);
|
||||
if (!q.eof())
|
||||
{
|
||||
id = q.getIntField(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (id == 0)
|
||||
{
|
||||
{
|
||||
CppSQLite3Statement stmt = m_database.compileStatement(
|
||||
"INSERT INTO element(id) VALUES(NULL);"
|
||||
);
|
||||
executeStatement(stmt);
|
||||
id = m_database.lastRowId();
|
||||
}
|
||||
{
|
||||
CppSQLite3Statement stmt = m_database.compileStatement(
|
||||
"INSERT INTO node(id, type, serialized_name) VALUES(?, ?, ?);"
|
||||
);
|
||||
stmt.bind(1, id);
|
||||
stmt.bind(2, nodeKindToInt(NODE_UNKNOWN));
|
||||
stmt.bind(3, serializedNameHierarchy.c_str());
|
||||
executeStatement(stmt);
|
||||
}
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
void DatabaseStorage::addSymbol(int nodeId, int definitionKind)
|
||||
{
|
||||
CppSQLite3Statement stmt = m_database.compileStatement(
|
||||
"INSERT OR IGNORE INTO symbol(id, definition_kind) VALUES(?, ?);"
|
||||
);
|
||||
stmt.bind(1, nodeId);
|
||||
stmt.bind(2, definitionKind);
|
||||
executeStatement(stmt);
|
||||
}
|
||||
|
||||
|
||||
void DatabaseStorage::addFile(int nodeId, const std::string& filePath)
|
||||
{
|
||||
std::string modificationTime = utility::getDateTimeString(0);
|
||||
const bool indexed = true;
|
||||
const bool complete = true;
|
||||
std::string content = "";
|
||||
if (utility::getFileExists(filePath))
|
||||
{
|
||||
modificationTime = utility::getDateTimeString(utility::getFileModificationTime(filePath));
|
||||
content = utility::getFileContent(filePath);
|
||||
}
|
||||
const int lineCount = utility::getLineCount(content);
|
||||
|
||||
{
|
||||
CppSQLite3Statement stmt = m_database.compileStatement(
|
||||
"INSERT OR IGNORE INTO file(id, path, modification_time, indexed, complete, line_count) VALUES(?, ?, ?, ?, ?, ?);"
|
||||
);
|
||||
stmt.bind(1, nodeId);
|
||||
stmt.bind(2, filePath.c_str());
|
||||
stmt.bind(3, modificationTime.c_str());
|
||||
stmt.bind(4, indexed);
|
||||
stmt.bind(5, complete);
|
||||
stmt.bind(6, lineCount);
|
||||
executeStatement(stmt);
|
||||
}
|
||||
|
||||
if (!content.empty())
|
||||
{
|
||||
CppSQLite3Statement stmt = m_database.compileStatement(
|
||||
"INSERT INTO filecontent(id, content) VALUES(?, ?);"
|
||||
);
|
||||
stmt.bind(1, nodeId);
|
||||
stmt.bind(2, content.c_str());
|
||||
executeStatement(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
int DatabaseStorage::addEdge(int sourceNodeId, int targetNodeId, int edgeKind)
|
||||
{
|
||||
int id = 0;
|
||||
|
||||
{
|
||||
CppSQLite3Statement stmt = m_database.compileStatement(
|
||||
"SELECT id FROM edge WHERE source_node_id == ? AND target_node_id == ? AND type == ? LIMIT 1;"
|
||||
);
|
||||
stmt.bind(1, sourceNodeId);
|
||||
stmt.bind(2, targetNodeId);
|
||||
stmt.bind(3, edgeKind);
|
||||
CppSQLite3Query q = executeQuery(stmt);
|
||||
if (!q.eof())
|
||||
{
|
||||
id = q.getIntField(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (id == 0)
|
||||
{
|
||||
{
|
||||
CppSQLite3Statement stmt = m_database.compileStatement(
|
||||
"INSERT INTO element(id) VALUES(NULL);"
|
||||
);
|
||||
executeStatement(stmt);
|
||||
id = m_database.lastRowId();
|
||||
}
|
||||
{
|
||||
CppSQLite3Statement stmt = m_database.compileStatement(
|
||||
"INSERT INTO edge(id, type, source_node_id, target_node_id) VALUES(?, ?, ?, ?);"
|
||||
);
|
||||
stmt.bind(1, id);
|
||||
stmt.bind(2, edgeKind);
|
||||
stmt.bind(3, sourceNodeId);
|
||||
stmt.bind(4, targetNodeId);
|
||||
executeStatement(stmt);
|
||||
}
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
int DatabaseStorage::addLocalSymbol(const std::string& name)
|
||||
{
|
||||
int id = 0;
|
||||
|
||||
{
|
||||
CppSQLite3Statement stmt = m_database.compileStatement(
|
||||
"SELECT id FROM local_symbol WHERE name == ? LIMIT 1;"
|
||||
);
|
||||
stmt.bind(1, name.c_str());
|
||||
CppSQLite3Query q = executeQuery(stmt);
|
||||
if (!q.eof())
|
||||
{
|
||||
id = q.getIntField(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (id == 0)
|
||||
{
|
||||
{
|
||||
CppSQLite3Statement stmt = m_database.compileStatement(
|
||||
"INSERT INTO element(id) VALUES(NULL);"
|
||||
);
|
||||
executeStatement(stmt);
|
||||
id = m_database.lastRowId();
|
||||
}
|
||||
{
|
||||
CppSQLite3Statement stmt = m_database.compileStatement(
|
||||
"INSERT INTO local_symbol(id, name) VALUES(?, ?);"
|
||||
);
|
||||
stmt.bind(1, id);
|
||||
stmt.bind(2, name.c_str());
|
||||
executeStatement(stmt);
|
||||
}
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
int DatabaseStorage::addSourceLocation(
|
||||
int fileId,
|
||||
int startLineNumber,
|
||||
int startColumnNumber,
|
||||
int endLineNumber,
|
||||
int endColumnNumber,
|
||||
int locationKind)
|
||||
{
|
||||
int id = 0;
|
||||
|
||||
{
|
||||
CppSQLite3Statement stmt = m_database.compileStatement(
|
||||
"SELECT id FROM source_location WHERE "
|
||||
"file_node_id = ? AND "
|
||||
"start_line = ? AND "
|
||||
"start_column = ? AND "
|
||||
"end_line = ? AND "
|
||||
"end_column = ? AND "
|
||||
"type = ? "
|
||||
"LIMIT 1;"
|
||||
);
|
||||
stmt.bind(1, fileId);
|
||||
stmt.bind(2, startLineNumber);
|
||||
stmt.bind(3, startColumnNumber);
|
||||
stmt.bind(4, endLineNumber);
|
||||
stmt.bind(5, endColumnNumber);
|
||||
stmt.bind(6, locationKind);
|
||||
CppSQLite3Query q = executeQuery(stmt);
|
||||
if (!q.eof())
|
||||
{
|
||||
id = q.getIntField(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (id == 0)
|
||||
{
|
||||
CppSQLite3Statement stmt = m_database.compileStatement(
|
||||
"INSERT INTO source_location(id, file_node_id, start_line, start_column, end_line, end_column, type) VALUES(NULL, ?, ?, ?, ?, ?, ?);"
|
||||
);
|
||||
stmt.bind(1, fileId);
|
||||
stmt.bind(2, startLineNumber);
|
||||
stmt.bind(3, startColumnNumber);
|
||||
stmt.bind(4, endLineNumber);
|
||||
stmt.bind(5, endColumnNumber);
|
||||
stmt.bind(6, locationKind);
|
||||
executeStatement(stmt);
|
||||
id = m_database.lastRowId();
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
void DatabaseStorage::addOccurrence(int elementId, int sourceLocationId)
|
||||
{
|
||||
CppSQLite3Statement stmt = m_database.compileStatement(
|
||||
"INSERT OR IGNORE INTO occurrence(element_id, source_location_id) VALUES(?, ?);"
|
||||
);
|
||||
stmt.bind(1, elementId);
|
||||
stmt.bind(2, sourceLocationId);
|
||||
executeStatement(stmt);
|
||||
}
|
||||
|
||||
int DatabaseStorage::addError(
|
||||
const std::string& message,
|
||||
bool fatal)
|
||||
{
|
||||
int id = 0;
|
||||
{
|
||||
CppSQLite3Statement stmt = m_database.compileStatement(
|
||||
"SELECT id FROM error WHERE "
|
||||
"message = ? AND "
|
||||
"fatal == ? "
|
||||
"LIMIT 1;"
|
||||
);
|
||||
stmt.bind(1, message.c_str());
|
||||
stmt.bind(2, fatal);
|
||||
CppSQLite3Query q = executeQuery(stmt);
|
||||
if (!q.eof() && q.numFields() > 0)
|
||||
{
|
||||
id = q.getIntField(0, -1);
|
||||
}
|
||||
}
|
||||
|
||||
if (id == 0)
|
||||
{
|
||||
{
|
||||
CppSQLite3Statement stmt = m_database.compileStatement(
|
||||
"INSERT INTO element(id) VALUES(NULL);"
|
||||
);
|
||||
executeStatement(stmt);
|
||||
id = m_database.lastRowId();
|
||||
}
|
||||
|
||||
CppSQLite3Statement stmt = m_database.compileStatement(
|
||||
"INSERT INTO error(id, message, fatal, indexed, translation_unit) "
|
||||
"VALUES(?, ?, ?, ?, ?);"
|
||||
);
|
||||
stmt.bind(1, id);
|
||||
stmt.bind(2, message.c_str());
|
||||
stmt.bind(3, fatal);
|
||||
stmt.bind(4, true);
|
||||
stmt.bind(5, "");
|
||||
executeStatement(stmt);
|
||||
id = m_database.lastRowId();
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
void DatabaseStorage::setNodeType(int nodeId, int nodeType)
|
||||
{
|
||||
CppSQLite3Statement stmt = m_database.compileStatement(
|
||||
"UPDATE node SET type = ? WHERE id == ?;"
|
||||
);
|
||||
stmt.bind(1, nodeType);
|
||||
stmt.bind(2, nodeId);
|
||||
executeStatement(stmt);
|
||||
}
|
||||
|
||||
// --- Private Interface ---
|
||||
|
||||
void DatabaseStorage::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);
|
||||
}
|
||||
|
||||
void DatabaseStorage::executeStatement(const std::string& statement) const
|
||||
{
|
||||
try
|
||||
{
|
||||
m_database.execDML(statement.c_str());
|
||||
}
|
||||
catch (CppSQLite3Exception e)
|
||||
{
|
||||
throw SourcetrailException("Failed to execute statement \"" + statement + "\" with message \"" + e.errorMessage() + "\".");
|
||||
}
|
||||
}
|
||||
|
||||
void DatabaseStorage::executeStatement(CppSQLite3Statement& statement) const
|
||||
{
|
||||
try
|
||||
{
|
||||
statement.execDML();
|
||||
}
|
||||
catch (CppSQLite3Exception e)
|
||||
{
|
||||
throw SourcetrailException("Failed to execute statement with message \"" + std::string(e.errorMessage()) + "\".");
|
||||
}
|
||||
}
|
||||
|
||||
CppSQLite3Query DatabaseStorage::executeQuery(const std::string& query) const
|
||||
{
|
||||
try
|
||||
{
|
||||
return m_database.execQuery(query.c_str());
|
||||
}
|
||||
catch (CppSQLite3Exception e)
|
||||
{
|
||||
throw SourcetrailException("Failed to execute query \"" + query + "\" with message \"" + e.errorMessage() + "\".");
|
||||
}
|
||||
}
|
||||
|
||||
CppSQLite3Query DatabaseStorage::executeQuery(CppSQLite3Statement& statement) const
|
||||
{
|
||||
try
|
||||
{
|
||||
return statement.execQuery();
|
||||
}
|
||||
catch (CppSQLite3Exception e)
|
||||
{
|
||||
throw SourcetrailException("Failed to execute query with message \"" + std::string(e.errorMessage()) + "\".");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#include "DefinitionKind.h"
|
||||
|
||||
namespace sourcetrail
|
||||
{
|
||||
int definitionKindToInt(DefinitionKind v)
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
DefinitionKind intToDefinitionKind(int v)
|
||||
{
|
||||
if (v == definitionKindToInt(DEFINITION_IMPLICIT))
|
||||
return DEFINITION_IMPLICIT;
|
||||
if (v == definitionKindToInt(DEFINITION_EXPLICIT))
|
||||
return DEFINITION_EXPLICIT;
|
||||
|
||||
return DEFINITION_EXPLICIT;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
#include "EdgeKind.h"
|
||||
|
||||
#include "ReferenceKind.h"
|
||||
|
||||
namespace sourcetrail
|
||||
{
|
||||
int edgeKindToInt(EdgeKind edgeKind)
|
||||
{
|
||||
return edgeKind;
|
||||
}
|
||||
|
||||
EdgeKind intToEdgeKind(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case EDGE_MEMBER:
|
||||
return EDGE_MEMBER;
|
||||
case EDGE_TYPE_USAGE:
|
||||
return EDGE_TYPE_USAGE;
|
||||
case EDGE_USAGE:
|
||||
return EDGE_USAGE;
|
||||
case EDGE_CALL:
|
||||
return EDGE_CALL;
|
||||
case EDGE_INHERITANCE:
|
||||
return EDGE_INHERITANCE;
|
||||
case EDGE_OVERRIDE:
|
||||
return EDGE_OVERRIDE;
|
||||
case EDGE_TEMPLATE_ARGUMENT:
|
||||
return EDGE_TEMPLATE_ARGUMENT;
|
||||
case EDGE_TYPE_ARGUMENT:
|
||||
return EDGE_TYPE_ARGUMENT;
|
||||
case EDGE_TEMPLATE_DEFAULT_ARGUMENT:
|
||||
return EDGE_TEMPLATE_DEFAULT_ARGUMENT;
|
||||
case EDGE_TEMPLATE_SPECIALIZATION:
|
||||
return EDGE_TEMPLATE_SPECIALIZATION;
|
||||
case EDGE_TEMPLATE_MEMBER_SPECIALIZATION:
|
||||
return EDGE_TEMPLATE_MEMBER_SPECIALIZATION;
|
||||
case EDGE_INCLUDE:
|
||||
return EDGE_INCLUDE;
|
||||
case EDGE_IMPORT:
|
||||
return EDGE_IMPORT;
|
||||
case EDGE_AGGREGATION:
|
||||
return EDGE_AGGREGATION;
|
||||
case EDGE_MACRO_USAGE:
|
||||
return EDGE_MACRO_USAGE;
|
||||
}
|
||||
|
||||
return EDGE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#include "LocationKind.h"
|
||||
|
||||
#include "SourcetrailException.h"
|
||||
|
||||
namespace sourcetrail
|
||||
{
|
||||
LocationKind intToLocationKind(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case LOCATION_TOKEN:
|
||||
return LOCATION_TOKEN;
|
||||
case LOCATION_SCOPE:
|
||||
return LOCATION_SCOPE;
|
||||
case LOCATION_QUALIFIER:
|
||||
return LOCATION_QUALIFIER;
|
||||
case LOCATION_LOCAL_SYMBOL:
|
||||
return LOCATION_LOCAL_SYMBOL;
|
||||
case LOCATION_SIGNATURE:
|
||||
return LOCATION_SIGNATURE;
|
||||
case LOCATION_COMMENT:
|
||||
return LOCATION_COMMENT;
|
||||
case LOCATION_ERROR:
|
||||
return LOCATION_ERROR;
|
||||
case LOCATION_FULLTEXT_SEARCH:
|
||||
return LOCATION_FULLTEXT_SEARCH;
|
||||
case LOCATION_SCREEN_SEARCH:
|
||||
return LOCATION_SCREEN_SEARCH;
|
||||
}
|
||||
throw SourcetrailException("Unable to convert integer \"" + std::to_string(i) + "\" to location kind.");
|
||||
}
|
||||
|
||||
int locationKindToInt(LocationKind locationKind)
|
||||
{
|
||||
return locationKind;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
#include "NameHierarchy.h"
|
||||
|
||||
#include "json/json.hpp"
|
||||
|
||||
namespace sourcetrail
|
||||
{
|
||||
std::string serializeNameHierarchyToJson(const NameHierarchy& nameHierarchy)
|
||||
{
|
||||
typedef nlohmann::json json;
|
||||
|
||||
nlohmann::json j;
|
||||
|
||||
j["name_delimiter"] = nameHierarchy.nameDelimiter;
|
||||
|
||||
for (const NameElement& nameElement : nameHierarchy.nameElements)
|
||||
{
|
||||
j["name_elements"].push_back(
|
||||
{
|
||||
{ "prefix", nameElement.prefix } ,
|
||||
{ "name", nameElement.name } ,
|
||||
{ "postfix", nameElement.postfix }
|
||||
});
|
||||
}
|
||||
|
||||
return j.dump(4);
|
||||
}
|
||||
|
||||
NameHierarchy deserializeNameHierarchyFromJson(const std::string& serializedNameHierarchy)
|
||||
{
|
||||
typedef nlohmann::json json;
|
||||
|
||||
NameHierarchy nameHierarchy;
|
||||
try
|
||||
{
|
||||
json j = nlohmann::json::parse(serializedNameHierarchy);
|
||||
{
|
||||
json jDelimiter = j["name_delimiter"];
|
||||
if (jDelimiter.is_string())
|
||||
{
|
||||
nameHierarchy.nameDelimiter = jDelimiter.get<std::string>();
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
json jNameElements = j["name_elements"];
|
||||
if (jNameElements.is_array())
|
||||
{
|
||||
for (json::iterator it = jNameElements.begin(); it != jNameElements.end(); ++it)
|
||||
{
|
||||
NameElement nameElement;
|
||||
{
|
||||
json jPrefix = it.value()["prefix"];
|
||||
if (jPrefix.is_string())
|
||||
{
|
||||
nameElement.prefix = jPrefix.get<std::string>();
|
||||
}
|
||||
}
|
||||
{
|
||||
json jName = it.value()["name"];
|
||||
if (jName.is_string())
|
||||
{
|
||||
nameElement.name = jName.get<std::string>();
|
||||
}
|
||||
}
|
||||
{
|
||||
json jPostfix = it.value()["postfix"];
|
||||
if (jPostfix.is_string())
|
||||
{
|
||||
nameElement.postfix = jPostfix.get<std::string>();
|
||||
}
|
||||
}
|
||||
nameHierarchy.nameElements.push_back(nameElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
return nameHierarchy;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#include "NodeKind.h"
|
||||
|
||||
namespace sourcetrail
|
||||
{
|
||||
int nodeKindToInt(NodeKind v)
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
NodeKind intToNodeKind(int v)
|
||||
{
|
||||
if (v == nodeKindToInt(NODE_UNKNOWN)) { return NODE_UNKNOWN; }
|
||||
if (v == nodeKindToInt(NODE_TYPE)) { return NODE_TYPE; }
|
||||
if (v == nodeKindToInt(NODE_BUILTIN_TYPE)) { return NODE_BUILTIN_TYPE; }
|
||||
if (v == nodeKindToInt(NODE_NAMESPACE)) { return NODE_NAMESPACE; }
|
||||
if (v == nodeKindToInt(NODE_PACKAGE)) { return NODE_PACKAGE; }
|
||||
if (v == nodeKindToInt(NODE_STRUCT)) { return NODE_STRUCT; }
|
||||
if (v == nodeKindToInt(NODE_CLASS)) { return NODE_CLASS; }
|
||||
if (v == nodeKindToInt(NODE_INTERFACE)) { return NODE_INTERFACE; }
|
||||
if (v == nodeKindToInt(NODE_ANNOTATION)) { return NODE_ANNOTATION; }
|
||||
if (v == nodeKindToInt(NODE_GLOBAL_VARIABLE)) { return NODE_GLOBAL_VARIABLE; }
|
||||
if (v == nodeKindToInt(NODE_FIELD)) { return NODE_FIELD; }
|
||||
if (v == nodeKindToInt(NODE_FUNCTION)) { return NODE_FUNCTION; }
|
||||
if (v == nodeKindToInt(NODE_METHOD)) { return NODE_METHOD; }
|
||||
if (v == nodeKindToInt(NODE_ENUM)) { return NODE_ENUM; }
|
||||
if (v == nodeKindToInt(NODE_ENUM_CONSTANT)) { return NODE_ENUM_CONSTANT; }
|
||||
if (v == nodeKindToInt(NODE_TYPEDEF)) { return NODE_TYPEDEF; }
|
||||
if (v == nodeKindToInt(NODE_TEMPLATE_PARAMETER)) { return NODE_TEMPLATE_PARAMETER; }
|
||||
if (v == nodeKindToInt(NODE_TYPE_PARAMETER)) { return NODE_TYPE_PARAMETER; }
|
||||
if (v == nodeKindToInt(NODE_FILE)) { return NODE_FILE; }
|
||||
if (v == nodeKindToInt(NODE_MACRO)) { return NODE_MACRO; }
|
||||
if (v == nodeKindToInt(NODE_UNION)) { return NODE_UNION; }
|
||||
return NODE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
#include "ReferenceKind.h"
|
||||
|
||||
#include "EdgeKind.h"
|
||||
|
||||
namespace sourcetrail
|
||||
{
|
||||
EdgeKind referenceKindToEdgeKind(ReferenceKind v)
|
||||
{
|
||||
switch (v)
|
||||
{
|
||||
case REFERENCE_TYPE_USAGE:
|
||||
return EDGE_TYPE_USAGE;
|
||||
case REFERENCE_USAGE:
|
||||
return EDGE_USAGE;
|
||||
case REFERENCE_CALL:
|
||||
return EDGE_CALL;
|
||||
case REFERENCE_INHERITANCE:
|
||||
return EDGE_INHERITANCE;
|
||||
case REFERENCE_OVERRIDE:
|
||||
return EDGE_OVERRIDE;
|
||||
case REFERENCE_TEMPLATE_ARGUMENT:
|
||||
return EDGE_TEMPLATE_ARGUMENT;
|
||||
case REFERENCE_TYPE_ARGUMENT:
|
||||
return EDGE_TYPE_ARGUMENT;
|
||||
case REFERENCE_TEMPLATE_DEFAULT_ARGUMENT:
|
||||
return EDGE_TEMPLATE_DEFAULT_ARGUMENT;
|
||||
case REFERENCE_TEMPLATE_SPECIALIZATION:
|
||||
return EDGE_TEMPLATE_SPECIALIZATION;
|
||||
case REFERENCE_TEMPLATE_MEMBER_SPECIALIZATION:
|
||||
return EDGE_TEMPLATE_MEMBER_SPECIALIZATION;
|
||||
case REFERENCE_INCLUDE:
|
||||
return EDGE_INCLUDE;
|
||||
case REFERENCE_IMPORT:
|
||||
return EDGE_IMPORT;
|
||||
case REFERENCE_MACRO_USAGE:
|
||||
return EDGE_MACRO_USAGE;
|
||||
case REFERENCE_ANNOTATION_USAGE:
|
||||
return EDGE_ANNOTATION_USAGE;
|
||||
}
|
||||
return EDGE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,722 @@
|
||||
#include "SourcetrailDBWriter.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
#include "sqlite/CppSQLite3.h"
|
||||
|
||||
#include "DatabaseStorage.h"
|
||||
#include "DefinitionKind.h"
|
||||
#include "EdgeKind.h"
|
||||
#include "LocationKind.h"
|
||||
#include "NameHierarchy.h"
|
||||
#include "NodeKind.h"
|
||||
#include "ReferenceKind.h"
|
||||
#include "SourceRange.h"
|
||||
#include "SourcetrailException.h"
|
||||
#include "SymbolKind.h"
|
||||
#include "version.h"
|
||||
|
||||
namespace sourcetrail
|
||||
{
|
||||
// --- Public Interface ---
|
||||
|
||||
SourcetrailDBWriter::SourcetrailDBWriter()
|
||||
: m_lastError("")
|
||||
{
|
||||
}
|
||||
|
||||
std::string SourcetrailDBWriter::getVersionString() const
|
||||
{
|
||||
return VERSION_STRING;
|
||||
}
|
||||
|
||||
int SourcetrailDBWriter::getSupportedDatabaseVersion() const
|
||||
{
|
||||
return DatabaseStorage::getSupportedDatabaseVersion();
|
||||
}
|
||||
|
||||
const std::string& SourcetrailDBWriter::getLastError() const
|
||||
{
|
||||
return m_lastError;
|
||||
}
|
||||
|
||||
void SourcetrailDBWriter::clearLastError()
|
||||
{
|
||||
m_lastError.clear();
|
||||
}
|
||||
|
||||
bool SourcetrailDBWriter::openProject(const std::string& projectDirectory, const std::string& projectName)
|
||||
{
|
||||
m_projectDirectory = projectDirectory;
|
||||
m_projectName = projectName;
|
||||
|
||||
try
|
||||
{
|
||||
openDatabase();
|
||||
}
|
||||
catch (const SourcetrailException e)
|
||||
{
|
||||
m_lastError = e.getMessage();
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
setupDatabaseTables();
|
||||
}
|
||||
catch (const SourcetrailException e)
|
||||
{
|
||||
m_lastError = e.getMessage();
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
bool projectFileExists = false;
|
||||
{
|
||||
std::ifstream f(getProjectFilePath().c_str());
|
||||
projectFileExists = f.good();
|
||||
f.close();
|
||||
}
|
||||
if (!projectFileExists)
|
||||
{
|
||||
try
|
||||
{
|
||||
createOrResetProjectFile();
|
||||
}
|
||||
catch (const SourcetrailException e)
|
||||
{
|
||||
m_lastError = e.getMessage();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SourcetrailDBWriter::closeProject()
|
||||
{
|
||||
try
|
||||
{
|
||||
closeDatabase();
|
||||
}
|
||||
catch (const SourcetrailException e)
|
||||
{
|
||||
m_lastError = e.getMessage();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SourcetrailDBWriter::clearProject()
|
||||
{
|
||||
try
|
||||
{
|
||||
clearDatabaseTables();
|
||||
}
|
||||
catch (const SourcetrailException e)
|
||||
{
|
||||
m_lastError = e.getMessage();
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
createOrResetProjectFile();
|
||||
}
|
||||
catch (const SourcetrailException e)
|
||||
{
|
||||
m_lastError = e.getMessage();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SourcetrailDBWriter::isEmpty() const
|
||||
{
|
||||
if (!m_storage)
|
||||
{
|
||||
m_lastError = "Unable to check if database is empty, because no database is currently open.";
|
||||
return true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return m_storage->isEmpty();
|
||||
}
|
||||
catch (const SourcetrailException e)
|
||||
{
|
||||
m_lastError = e.getMessage();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool SourcetrailDBWriter::isCompatible() const
|
||||
{
|
||||
if (!m_storage)
|
||||
{
|
||||
m_lastError = "Unable to check if database is compatible, because no database is currently open.";
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return m_storage->isCompatible();
|
||||
}
|
||||
catch (const SourcetrailException e)
|
||||
{
|
||||
m_lastError = e.getMessage();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int SourcetrailDBWriter::getLoadedDatabaseVersion() const
|
||||
{
|
||||
if (!m_storage)
|
||||
{
|
||||
m_lastError = "Unable to fetch database version, because no database is currently open.";
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return m_storage->getLoadedDatabaseVersion();
|
||||
}
|
||||
catch (const SourcetrailException e)
|
||||
{
|
||||
m_lastError = e.getMessage();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool SourcetrailDBWriter::beginTransaction()
|
||||
{
|
||||
if (!m_storage)
|
||||
{
|
||||
m_lastError = "Unable to begin transaction, because no database is currently open.";
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
m_storage->beginTransaction();
|
||||
}
|
||||
catch (const SourcetrailException e)
|
||||
{
|
||||
m_lastError = e.getMessage();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SourcetrailDBWriter::commitTransaction()
|
||||
{
|
||||
if (!m_storage)
|
||||
{
|
||||
m_lastError = "Unable to commit transaction, because no database is currently open.";
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
m_storage->commitTransaction();
|
||||
}
|
||||
catch (const SourcetrailException e)
|
||||
{
|
||||
m_lastError = e.getMessage();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SourcetrailDBWriter::rollbackTransaction()
|
||||
{
|
||||
if (!m_storage)
|
||||
{
|
||||
m_lastError = "Unable to rollback transaction, because no database is currently open.";
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
m_storage->rollbackTransaction();
|
||||
}
|
||||
catch (const SourcetrailException e)
|
||||
{
|
||||
m_lastError = e.getMessage();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SourcetrailDBWriter::optimizeDatabaseMemory()
|
||||
{
|
||||
if (!m_storage)
|
||||
{
|
||||
m_lastError = "Unable to optimize database memory, because no database is currently open.";
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
m_storage->optimizeDatabaseMemory();
|
||||
}
|
||||
catch (const SourcetrailException e)
|
||||
{
|
||||
m_lastError = e.getMessage();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int SourcetrailDBWriter::recordSymbol(const NameHierarchy& nameHierarchy)
|
||||
{
|
||||
if (!m_storage)
|
||||
{
|
||||
m_lastError = "Unable to record symbol, because no database is currently open.";
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return addNodeHierarchy(nameHierarchy);
|
||||
}
|
||||
catch (const SourcetrailException e)
|
||||
{
|
||||
m_lastError = e.getMessage();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool SourcetrailDBWriter::recordSymbolDefinitionKind(int symbolId, DefinitionKind definitionKind)
|
||||
{
|
||||
if (!m_storage)
|
||||
{
|
||||
m_lastError = "Unable to record symbol kind, because no database is currently open.";
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
m_storage->addSymbol(symbolId, definitionKindToInt(definitionKind));
|
||||
}
|
||||
catch (const SourcetrailException e)
|
||||
{
|
||||
m_lastError = e.getMessage();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SourcetrailDBWriter::recordSymbolKind(int symbolId, SymbolKind symbolKind)
|
||||
{
|
||||
if (!m_storage)
|
||||
{
|
||||
m_lastError = "Unable to record symbol kind, because no database is currently open.";
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
m_storage->setNodeType(symbolId, nodeKindToInt(symbolKindToNodeKind(symbolKind)));
|
||||
}
|
||||
catch (const SourcetrailException e)
|
||||
{
|
||||
m_lastError = e.getMessage();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SourcetrailDBWriter::recordSymbolLocation(int symbolId, const SourceRange& location)
|
||||
{
|
||||
if (!m_storage)
|
||||
{
|
||||
m_lastError = "Unable to record symbol location, because no database is currently open.";
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
addSourceLocation(symbolId, location, LOCATION_TOKEN);
|
||||
return true;
|
||||
}
|
||||
catch (const SourcetrailException e)
|
||||
{
|
||||
m_lastError = e.getMessage();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool SourcetrailDBWriter::recordSymbolScopeLocation(int symbolId, const SourceRange& location)
|
||||
{
|
||||
if (!m_storage)
|
||||
{
|
||||
m_lastError = "Unable to record symbol scope location, because no database is currently open.";
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
addSourceLocation(symbolId, location, LOCATION_SCOPE);
|
||||
return true;
|
||||
}
|
||||
catch (const SourcetrailException e)
|
||||
{
|
||||
m_lastError = e.getMessage();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool SourcetrailDBWriter::recordSymbolSignatureLocation(int symbolId, const SourceRange& location)
|
||||
{
|
||||
if (!m_storage)
|
||||
{
|
||||
m_lastError = "Unable to record symbol signature location, because no database is currently open.";
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
addSourceLocation(symbolId, location, LOCATION_SIGNATURE);
|
||||
return true;
|
||||
}
|
||||
catch (const SourcetrailException e)
|
||||
{
|
||||
m_lastError = e.getMessage();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int SourcetrailDBWriter::recordReference(int contextSymbolId, int referencedSymbolId, ReferenceKind referenceKind)
|
||||
{
|
||||
if (!m_storage)
|
||||
{
|
||||
m_lastError = "Unable to record reference, because no database is currently open.";
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return addEdge(contextSymbolId, referencedSymbolId, referenceKindToEdgeKind(referenceKind));
|
||||
}
|
||||
catch (const SourcetrailException e)
|
||||
{
|
||||
m_lastError = e.getMessage();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool SourcetrailDBWriter::recordReferenceLocation(int referenceId, const SourceRange& location)
|
||||
{
|
||||
if (!m_storage)
|
||||
{
|
||||
m_lastError = "Unable to record symbol signature location, because no database is currently open.";
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
addSourceLocation(referenceId, location, LOCATION_TOKEN);
|
||||
return true;
|
||||
}
|
||||
catch (const SourcetrailException e)
|
||||
{
|
||||
m_lastError = e.getMessage();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int SourcetrailDBWriter::recordFile(const std::string& filePath)
|
||||
{
|
||||
if (!m_storage)
|
||||
{
|
||||
m_lastError = "Unable to record file, because no database is currently open.";
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return addFile(filePath);
|
||||
}
|
||||
catch (const SourcetrailException e)
|
||||
{
|
||||
m_lastError = e.getMessage();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int SourcetrailDBWriter::recordLocalSymbol(const std::string& name)
|
||||
{
|
||||
if (!m_storage)
|
||||
{
|
||||
m_lastError = "Unable to record local symbol, because no database is currently open.";
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return m_storage->addLocalSymbol(name);
|
||||
}
|
||||
catch (const SourcetrailException e)
|
||||
{
|
||||
m_lastError = e.getMessage();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool SourcetrailDBWriter::recordLocalSymbolLocation(int localSymbolId, const SourceRange& location)
|
||||
{
|
||||
if (!m_storage)
|
||||
{
|
||||
m_lastError = "Unable to record local symbol location, because no database is currently open.";
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
addSourceLocation(localSymbolId, location, LOCATION_LOCAL_SYMBOL);
|
||||
return true;
|
||||
}
|
||||
catch (const SourcetrailException e)
|
||||
{
|
||||
m_lastError = e.getMessage();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool SourcetrailDBWriter::recordCommentLocation(const SourceRange& location)
|
||||
{
|
||||
if (!m_storage)
|
||||
{
|
||||
m_lastError = "Unable to record comment location, because no database is currently open.";
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
const int fileId = addFile(location.filePath);
|
||||
const int sourceLocationId = m_storage->addSourceLocation(
|
||||
fileId,
|
||||
location.startLine,
|
||||
location.startColumn,
|
||||
location.endLine,
|
||||
location.endColumn,
|
||||
LOCATION_COMMENT
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (const SourcetrailException e)
|
||||
{
|
||||
m_lastError = e.getMessage();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool SourcetrailDBWriter::recordError(const std::string& message, bool fatal, const SourceRange& location)
|
||||
{
|
||||
if (!m_storage)
|
||||
{
|
||||
m_lastError = "Unable to record error, because no database is currently open.";
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
const int errorId = m_storage->addError(message, fatal);
|
||||
addSourceLocation(errorId, location, LOCATION_ERROR);
|
||||
return true;
|
||||
}
|
||||
catch (const SourcetrailException e)
|
||||
{
|
||||
m_lastError = e.getMessage();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// --- Private Interface ---
|
||||
|
||||
std::string SourcetrailDBWriter::serializeNameHierarchy(const NameHierarchy& nameHierarchy)
|
||||
{
|
||||
static std::string META_DELIMITER = "\tm";
|
||||
static std::string NAME_DELIMITER = "\tn";
|
||||
static std::string PARTS_DELIMITER = "\ts";
|
||||
static std::string SIGNATURE_DELIMITER = "\tp";
|
||||
|
||||
std::string serialized = nameHierarchy.nameDelimiter + META_DELIMITER;
|
||||
for (size_t i = 0; i < nameHierarchy.nameElements.size(); i++)
|
||||
{
|
||||
if (i != 0)
|
||||
{
|
||||
serialized += NAME_DELIMITER;
|
||||
}
|
||||
const NameElement& nameElement = nameHierarchy.nameElements[i];
|
||||
serialized += nameElement.name + PARTS_DELIMITER + nameElement.prefix + SIGNATURE_DELIMITER + nameElement.postfix;
|
||||
}
|
||||
return serialized;
|
||||
}
|
||||
|
||||
std::string SourcetrailDBWriter::getProjectFilePath() const
|
||||
{
|
||||
return m_projectDirectory + "/" + m_projectName + ".srctrlprj";
|
||||
}
|
||||
std::string SourcetrailDBWriter::getDatabaseFilePath() const
|
||||
{
|
||||
return m_projectDirectory + "/" + m_projectName + ".srctrldb";
|
||||
}
|
||||
|
||||
void SourcetrailDBWriter::openDatabase()
|
||||
{
|
||||
if (m_storage)
|
||||
{
|
||||
closeDatabase();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
m_storage = DatabaseStorage::openDatabase(getDatabaseFilePath());
|
||||
}
|
||||
catch (CppSQLite3Exception e)
|
||||
{
|
||||
m_storage.reset();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
void SourcetrailDBWriter::closeDatabase()
|
||||
{
|
||||
if (!m_storage)
|
||||
{
|
||||
throw SourcetrailException("Unable to close database, because no database is currently open.");
|
||||
}
|
||||
m_storage.reset();
|
||||
}
|
||||
|
||||
void SourcetrailDBWriter::setupDatabaseTables()
|
||||
{
|
||||
if (!m_storage)
|
||||
{
|
||||
throw SourcetrailException("Unable to setup database tables, because no database is currently open.");
|
||||
}
|
||||
m_storage->setupTables();
|
||||
}
|
||||
|
||||
void SourcetrailDBWriter::clearDatabaseTables()
|
||||
{
|
||||
if (!m_storage)
|
||||
{
|
||||
throw SourcetrailException("Unable to setup database tables, because no database is currently open.");
|
||||
}
|
||||
m_storage->clearTables();
|
||||
}
|
||||
|
||||
void SourcetrailDBWriter::createOrResetProjectFile()
|
||||
{
|
||||
try
|
||||
{
|
||||
std::ofstream fileStream;
|
||||
fileStream.open(getProjectFilePath(), std::ios::out);
|
||||
fileStream << std::string(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <version>0</version>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
fileStream.close();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
throw SourcetrailException("Exception occurred while creating project file.");
|
||||
}
|
||||
}
|
||||
|
||||
int SourcetrailDBWriter::addNodeHierarchy(const NameHierarchy& nameHierarchy)
|
||||
{
|
||||
if (nameHierarchy.nameElements.size() == 0)
|
||||
{
|
||||
throw SourcetrailException("Unable to add nodes for an empty name hierarchy.");
|
||||
}
|
||||
|
||||
int parentNodeId = 0;
|
||||
|
||||
NameHierarchy currentNameHierarchy;
|
||||
currentNameHierarchy.nameDelimiter = nameHierarchy.nameDelimiter;
|
||||
|
||||
for (size_t i = 0; i < nameHierarchy.nameElements.size(); i++)
|
||||
{
|
||||
currentNameHierarchy.nameElements.push_back(nameHierarchy.nameElements[i]);
|
||||
|
||||
int nodeId = m_storage->addNode(serializeNameHierarchy(currentNameHierarchy));
|
||||
|
||||
if (parentNodeId != 0)
|
||||
{
|
||||
addEdge(parentNodeId, nodeId, EDGE_MEMBER);
|
||||
}
|
||||
|
||||
parentNodeId = nodeId;
|
||||
}
|
||||
return parentNodeId;
|
||||
}
|
||||
|
||||
int SourcetrailDBWriter::addFile(const std::string& filePath)
|
||||
{
|
||||
NameElement nameElement;
|
||||
nameElement.name = filePath;
|
||||
NameHierarchy nameHierarchy;
|
||||
nameHierarchy.nameDelimiter = "/";
|
||||
nameHierarchy.nameElements.push_back(nameElement);
|
||||
|
||||
const int nodeId = addNodeHierarchy(nameHierarchy);
|
||||
m_storage->setNodeType(nodeId, nodeKindToInt(NODE_FILE));
|
||||
m_storage->addFile(nodeId, filePath);
|
||||
|
||||
return nodeId;
|
||||
}
|
||||
|
||||
int SourcetrailDBWriter::addEdge(int sourceId, int targetId, EdgeKind edgeKind)
|
||||
{
|
||||
if (!m_storage)
|
||||
{
|
||||
throw SourcetrailException("Unable to add edge, because no database is currently open.");
|
||||
}
|
||||
if (!sourceId)
|
||||
{
|
||||
throw SourcetrailException("Unable to add edge, because source id is invalid.");
|
||||
}
|
||||
if (!targetId)
|
||||
{
|
||||
throw SourcetrailException("Unable to add edge, because target id is invalid.");
|
||||
}
|
||||
|
||||
return m_storage->addEdge(sourceId, targetId, edgeKindToInt(edgeKind));
|
||||
}
|
||||
|
||||
void SourcetrailDBWriter::addSourceLocation(int elementId, const SourceRange& location, LocationKind kind)
|
||||
{
|
||||
const int fileId = addFile(location.filePath);
|
||||
|
||||
const int sourceLocationId = m_storage->addSourceLocation(
|
||||
fileId,
|
||||
location.startLine,
|
||||
location.startColumn,
|
||||
location.endLine,
|
||||
location.endColumn,
|
||||
locationKindToInt(kind)
|
||||
);
|
||||
|
||||
m_storage->addOccurrence(
|
||||
elementId,
|
||||
sourceLocationId
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
#include "SymbolKind.h"
|
||||
|
||||
#include "NodeKind.h"
|
||||
|
||||
namespace sourcetrail
|
||||
{
|
||||
NodeKind symbolKindToNodeKind(SymbolKind v)
|
||||
{
|
||||
switch (v)
|
||||
{
|
||||
case SYMBOL_TYPE:
|
||||
return NODE_TYPE;
|
||||
case SYMBOL_BUILTIN_TYPE:
|
||||
return NODE_BUILTIN_TYPE;
|
||||
case SYMBOL_NAMESPACE:
|
||||
return NODE_NAMESPACE;
|
||||
case SYMBOL_PACKAGE:
|
||||
return NODE_PACKAGE;
|
||||
case SYMBOL_STRUCT:
|
||||
return NODE_STRUCT;
|
||||
case SYMBOL_CLASS:
|
||||
return NODE_CLASS;
|
||||
case SYMBOL_INTERFACE:
|
||||
return NODE_INTERFACE;
|
||||
case SYMBOL_ANNOTATION:
|
||||
return NODE_ANNOTATION;
|
||||
case SYMBOL_GLOBAL_VARIABLE:
|
||||
return NODE_GLOBAL_VARIABLE;
|
||||
case SYMBOL_FIELD:
|
||||
return NODE_FIELD;
|
||||
case SYMBOL_FUNCTION:
|
||||
return NODE_FUNCTION;
|
||||
case SYMBOL_METHOD:
|
||||
return NODE_METHOD;
|
||||
case SYMBOL_ENUM:
|
||||
return NODE_ENUM;
|
||||
case SYMBOL_ENUM_CONSTANT:
|
||||
return NODE_ENUM_CONSTANT;
|
||||
case SYMBOL_TYPEDEF:
|
||||
return NODE_TYPEDEF;
|
||||
case SYMBOL_TEMPLATE_PARAMETER:
|
||||
return NODE_TEMPLATE_PARAMETER;
|
||||
case SYMBOL_TYPE_PARAMETER:
|
||||
return NODE_TYPE_PARAMETER;
|
||||
case SYMBOL_MACRO:
|
||||
return NODE_MACRO;
|
||||
case SYMBOL_UNION:
|
||||
return NODE_UNION;
|
||||
}
|
||||
return NODE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
#include "utility.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <filesystem>
|
||||
|
||||
#include "SourcetrailException.h"
|
||||
|
||||
namespace sourcetrail
|
||||
{
|
||||
namespace utility
|
||||
{
|
||||
bool getFileExists(const std::string& filePath)
|
||||
{
|
||||
std::ifstream file(filePath);
|
||||
return file.good();
|
||||
}
|
||||
|
||||
std::string getFileContent(const std::string& filePath)
|
||||
{
|
||||
std::string content;
|
||||
|
||||
std::ifstream file;
|
||||
file.open(filePath);
|
||||
|
||||
if (file.fail())
|
||||
{
|
||||
throw SourcetrailException("Could not open file " + filePath);
|
||||
}
|
||||
|
||||
for (std::string line; std::getline(file, line); )
|
||||
{
|
||||
content += line + "\n";
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
time_t getFileModificationTime(const std::string& filePath)
|
||||
{
|
||||
std::experimental::filesystem::path p(filePath);
|
||||
auto ftime = std::experimental::filesystem::last_write_time(p);
|
||||
|
||||
// assuming system_clock for this demo
|
||||
// note: not true on MSVC; C++20 will allow portable output
|
||||
return decltype(ftime)::clock::to_time_t(ftime);
|
||||
}
|
||||
|
||||
std::string getDateTimeString(const time_t& time)
|
||||
{
|
||||
std::tm* ptm = std::localtime(&time);
|
||||
char buffer[32];
|
||||
std::strftime(buffer, 32, "%Y-%m-%d %H:%M:%S", ptm);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
int getLineCount(const std::string s)
|
||||
{
|
||||
return std::count(s.begin(), s.end(), '\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#ifndef SOURCETRAIL_VERSION_H
|
||||
#define SOURCETRAIL_VERSION_H
|
||||
|
||||
// This file is (re-)generated when running CMake on this project.
|
||||
|
||||
#define INTERFACE_VERSION @INTERFACE_VERSION@
|
||||
#define DATABASE_VERSION @DATABASE_VERSION@
|
||||
#define COMMIT_VERSION @COMMIT_VERSION@
|
||||
|
||||
#define VERSION_STRING "@VERSION_STRING@"
|
||||
|
||||
#endif // SOURCETRAIL_VERSION_H
|
||||
Reference in New Issue
Block a user