* -------------------------------------------------------------------------
* This file is part of the MindStudio project.
* Copyright (c) 2025 Huawei Technologies Co.,Ltd.
*
* MindStudio is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* -------------------------------------------------------------------------
*/
#ifndef DATA_INSIGHT_CORE_MODULE_CORE_DATABASE_BASE_H
#define DATA_INSIGHT_CORE_MODULE_CORE_DATABASE_BASE_H
#include <vector>
#include <string>
#include <mutex>
#include "ServerLog.h"
#include "sqlite3.h"
#include "BaseDomain.h"
#include "TryOpt.h"
#include "SqlitePreparedStatement.h"
namespace Dic {
namespace Module {
class DatabaseException : public std::exception {
public:
explicit DatabaseException(const char *message) : message(message) {};
DatabaseException(const char *message, bool isError) : isError(isError), message(message) {};
const char *What() const { return message; };
void Log(std::string prefix) const {
if (isError) {
Server::ServerLog::Error(prefix, message);
} else {
Server::ServerLog::Warn(prefix, message);
}
}
private:
bool isError = true;
const char *message;
};
class Database {
public:
explicit Database(std::recursive_mutex &sqlMutex) : mutex(sqlMutex) {};
virtual ~Database();
virtual bool CreateDbIfNotExist(const std::string &dbPath);
virtual bool OpenDb(const std::string &dbPath, bool clearAllTable);
virtual bool AttachDb(const std::string &dbPath);
virtual bool IsOpen() const;
void CloseDb();
virtual bool StartTransaction();
virtual bool RollbackTransaction();
virtual bool EndTransaction();
virtual std::string GetDbPath();
virtual void SetDbPath(const std::string &dbPath);
virtual bool GetTableList(std::vector<std::string> &tableList) const;
virtual std::unique_ptr<SqlitePreparedStatement> CreatPreparedStatement(const std::string &sql);
virtual std::unique_ptr<SqlitePreparedStatement> CreatPreparedStatement();
bool ExecSql(const std::string &sql) const;
bool DropSomeTables(const std::vector<std::string> &tableNames) const;
bool DropAllTable();
bool IsDatabaseVersionChange() const;
bool QueryMetaVersion();
std::string GetMetaVersion() const;
bool SetDataBaseVersion(const std::string &targetVersion = "");
std::string QueryValueFromMetaDataByName(const std::string &name);
bool CheckTableExist(const std::string &tableName);
bool CheckTablesExist(const std::vector<std::string> &tablesName);
bool CheckColumnExist(const std::string &tableName, const std::string &columnName);
bool CheckStringInColumn(
const std::string &tableName, const std::string &columnName, const std::string &searchString);
bool ExtendColumns(const std::string &tableName, const std::vector<std::string> &columns);
bool CreateMetaDataTableForText();
bool UpdateMetaDataTable(const std::string &name, const std::string &value);
bool UpdateMetaDataTableWithNoPrimaryKey(const std::string &name, const std::string &value);
virtual std::vector<ColumnAtt> QueryTableInfoByName(const std::string &tableName);
virtual uint64_t QueryCountByTableName(const PageQuery &query, const std::vector<ColumnAtt> &columns);
virtual std::vector<std::map<std::string, std::string>> QueryDataByPage(
const PageQuery &query, const std::vector<ColumnAtt> &columns);
std::vector<LinkInfo> QueryTableNameAndCol(const std::string &linkName);
* 查询所有符合前缀的表名
* @param prefix 表名前缀
* @return 所有符合前缀的表名
*/
std::vector<std::string> QueryTableNamesByPrefix(const std::string &prefix);
bool CheckValueFromStatusInfoTable(const std::string &key, const std::string &refValue);
bool UpdateValueIntoStatusInfoTable(const std::string &key, const std::string &value);
std::unordered_map<std::string, std::string> QueryTranslate(bool isZh);
std::string QueryDatabaseVersion() const;
static std::string GetCompileDataBaseVersion();
protected:
bool CheckTableContainData(const std::string &tableName);
virtual bool SetConfig();
static std::string CheckSqlString(const std::string &src);
static std::string sqlite3_column_string(sqlite3_stmt *stmt, int iCol);
void FastGetString(sqlite3_stmt *stmt, int iCol, std::string &output);
static std::string Sqlite3ColumnConvertStr(int colType, sqlite3_stmt *stmt, int iCol);
std::string Sqlite3ColumnConvertStrReturnNull(int colType, sqlite3_stmt *stmt, int iCol);
std::string GetLastError();
sqlite3 *db = nullptr;
std::recursive_mutex &mutex;
bool isOpen = false;
std::string path;
const int bindStartIndex = 1;
const int resultStartIndex = 0;
const int timeoutMs = 50000;
const std::string infoTable = "status_info";
bool isLowCamel = false;
std::string metaVersion;
const std::string metaDataTable = "META_DATA";
std::unordered_map<std::string, std::string> rankToDeviceMap;
std::string GetValueFromMetaDataTable(const std::string &name);
bool CreateStatusInfoTable();
std::string GetValueFromStatusInfoTable(const std::string &key);
bool CheckAndResetDatabaseOnVersionChange();
template <typename... Args>
static inline std::unique_ptr<SqliteResultSet> ExecuteQuery(
std::unique_ptr<SqlitePreparedStatement> &stmt, const std::string &sql, Args &&...args) {
if (stmt == nullptr) {
throw DatabaseException("Failed to prepare sql.");
}
if (!stmt->Prepare(sql)) {
throw DatabaseException("Failed to prepare sql.");
}
stmt->Reset();
stmt->BindParams(std::forward<Args>(args)...);
auto result = stmt->ExecuteQuery();
if (result == nullptr) {
throw DatabaseException("Failed to ExecuteQuery.");
}
return result;
};
static std::string ComputeDataPageSql(const PageQuery &query, std::vector<std::string> &columnName);
static std::string ComputeConditionSql(const PageQuery &query, std::vector<std::string> &columnName);
static std::string BuildQueryFiltersConditionSql(const std::map<std::string, std::string> &filters);
static std::string BuildQueryRangeFiltersConditionSql(
const std::map<std::string, std::pair<double, double>> &rangeFilters);
static std::string BuildQueryOrderSql(const std::string &orderBy, bool desc);
static void CommonBindFiltersParams(
const std::map<std::string, std::string> &filters, sqlite3_stmt *stmt, int &bindIdx);
static void CommonBindRangeFiltersParams(
const std::map<std::string, std::pair<double, double>> &rangeFilters, sqlite3_stmt *stmt, int &bindIdx);
static void CommonBindPaginationParams(int64_t pageSize, int64_t currentPage, sqlite3_stmt *stmt, int &bindIdx);
private:
size_t maxDbFileSize = 50ULL * 1024 * 1024 * 1024;
};
}
}
#endif