mirror of
https://gitlab.com/spaceti-app/integrations/acs/colnod-connector.git
synced 2026-07-12 14:00:39 +02:00
244 lines
10 KiB
C++
244 lines
10 KiB
C++
#include "databasemanager.h"
|
|
|
|
DatabaseManager::DatabaseManager(const QString& host, const QString& dbName, const QString& user, const QString& password)
|
|
{
|
|
|
|
db = QSqlDatabase::addDatabase("QPSQL");
|
|
|
|
db.setDatabaseName(dbName);
|
|
db.setHostName(host);
|
|
db.setUserName(user);
|
|
// home-office stuff
|
|
//db.setPort(80);
|
|
//
|
|
db.setPassword(password);
|
|
|
|
if (!db.open())
|
|
{
|
|
qDebug() << "Opening error" + db.lastError().text();
|
|
}
|
|
query = QSqlQuery("query", db);
|
|
}
|
|
|
|
// add or update subject to db
|
|
void DatabaseManager::saveSubject(Subject* subject, const QString& table)
|
|
{
|
|
QString id = subject->idToStringWithoutBraces();
|
|
if (checkIfExists(id, table))
|
|
{
|
|
query.prepare(QString("UPDATE %1 SET id = :id, description = :description, last_update = last_update:, name = :name, pin = :pin"
|
|
"WHERE id = :id)").arg(table));
|
|
query.bindValue(":id", id);
|
|
query.bindValue(":description", subject->getDescription());
|
|
query.bindValue(":name", subject->getName());
|
|
query.bindValue(":last_update", QDateTime::fromMSecsSinceEpoch(subject->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz"));
|
|
query.bindValue(":pin", subject->getPin());
|
|
query.exec();
|
|
}
|
|
else
|
|
{
|
|
query.prepare(QString("INSERT INTO %1 (id, description, last_update, name, pin) "
|
|
"VALUES (:id, :description, :last_update, :name, :pin)").arg(table));
|
|
query.bindValue(":id", id);
|
|
query.bindValue(":description", subject->getDescription());
|
|
query.bindValue(":last_update", QDateTime::fromMSecsSinceEpoch(subject->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz"));
|
|
query.bindValue(":name", subject->getName());
|
|
query.bindValue(":pin", subject->getPin());
|
|
query.exec();
|
|
}
|
|
}
|
|
|
|
// add or update token to DB
|
|
void DatabaseManager::saveToken(Token* token, const QString& table)
|
|
{
|
|
QString id = token->idToStringWithoutBraces();
|
|
if (checkIfExists(id, table))
|
|
{
|
|
query.prepare(QString("UPDATE %1 SET id = :id, auth_errors = :auth_errors, description = :description, enabled = :enabled, name = :name, no_validity = :no_validity, time_to_live = :time_to_live, token_bits = :token_bits, token_data = :token_data, token_type = :token_type, subject_id = :subject_id, last_modified = :last_modified deleted = :deleted) "
|
|
"WHERE id = :id").arg(table));
|
|
query.bindValue(":id", id);
|
|
query.bindValue(":auth_errors", token->getAuthErrors());
|
|
query.bindValue(":description", token->getDescription());
|
|
query.bindValue(":enabled", token->getFlags().contains("Enabled"));
|
|
query.bindValue(":name", token->getName());
|
|
query.bindValue(":no_validity", token->getFlags().contains("NoValidity"));
|
|
query.bindValue(":time_to_live", token->getTimeToLive());
|
|
query.bindValue(":token_bits", token->getTokenBits());
|
|
query.bindValue(":token_data", token->getTokenData());
|
|
query.bindValue(":token_type", token->getTokenType());
|
|
query.bindValue(":subject_id", token->subjectIdToStringWithoutBraces());
|
|
query.bindValue(":last_modified", QDateTime::fromMSecsSinceEpoch(token->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz"));
|
|
query.bindValue(":deleted", token->getDeleted());
|
|
query.exec();
|
|
}
|
|
else
|
|
{
|
|
query.prepare(QString("INSERT INTO %1 (id, auth_errors, description, enabled, last_update, name, no_validity, time_to_live, token_bits, token_data, token_type, subject_id, last_modified, deleted) "
|
|
"VALUES (:id, :auth_errors, :description, :enabled, :last_update, :name, :no_validity, :time_to_live, :token_bits, :token_data, :token_type, :subject_id, :last_modified, :deleted)").arg(table));
|
|
query.bindValue(":id", id);
|
|
query.bindValue(":auth_errors", token->getAuthErrors());
|
|
query.bindValue(":description", token->getDescription());
|
|
query.bindValue(":enabled", token->getFlags().contains("Enabled"));
|
|
query.bindValue(":last_update", QDateTime::fromMSecsSinceEpoch(token->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz"));
|
|
query.bindValue(":name", token->getName());
|
|
query.bindValue(":no_validity", token->getFlags().contains("NoValidity"));
|
|
query.bindValue(":time_to_live", token->getTimeToLive());
|
|
query.bindValue(":token_bits", token->getTokenBits());
|
|
query.bindValue(":token_data", token->getTokenData());
|
|
query.bindValue(":token_type", token->getTokenType());
|
|
query.bindValue(":subject_id", token->subjectIdToStringWithoutBraces());
|
|
query.bindValue(":last_modified", QDateTime::fromMSecsSinceEpoch(token->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz"));
|
|
query.bindValue(":deleted", token->getDeleted());
|
|
query.exec();
|
|
}
|
|
}
|
|
|
|
// add of update subject attributes
|
|
void DatabaseManager::saveSubjectAttributes(Subject *subject, const QString& table)
|
|
{
|
|
auto attributes = subject->getAtr();
|
|
for (const auto& attribute : attributes){
|
|
QString id = subject->idToStringWithoutBraces() + " " + attribute.first;
|
|
if (checkIfExists(id, table)){
|
|
query.prepare(QString("UPDATE %1 SET id = :id, attribute_key = :key, attribute_value = :value, subject_id = :subject_id) "
|
|
"WHERE id = :id").arg(table));
|
|
query.bindValue(":id", id);
|
|
query.bindValue(":key", attribute.first);
|
|
query.bindValue(":value", attribute.second);
|
|
query.bindValue(":subject_id", subject->idToStringWithoutBraces());
|
|
query.exec();
|
|
}
|
|
else{
|
|
query.prepare(QString("INSERT INTO %1 (id, attribute_key, attribute_value, subject_id)"
|
|
"VALUES (:id, :key, :value, :subject_id)").arg(table));
|
|
query.bindValue(":id", id);
|
|
query.bindValue(":key", attribute.first);
|
|
query.bindValue(":value", attribute.second);
|
|
query.bindValue(":subject_id", subject->idToStringWithoutBraces());
|
|
query.exec();
|
|
}
|
|
}
|
|
}
|
|
|
|
// "delete" tokens from DB -> set deleted true
|
|
void DatabaseManager::setDeleted(const QString& id, const QString& table)
|
|
{
|
|
quint64 now = getNow();
|
|
QString nowString = QDateTime::fromMSecsSinceEpoch(now).toString("yyyy-MM-dd hh:mm:ss.zzz");
|
|
query.prepare(QString("UPDATE %1 SET deleted = true, last_update = :now, last_modified = :now WHERE id = :id").arg(table));
|
|
query.bindValue(":id", id);
|
|
query.bindValue(":now", nowString);
|
|
query.exec();
|
|
}
|
|
|
|
bool DatabaseManager::checkIfExists(const QString& id, const QString& table)
|
|
{
|
|
query.prepare(QString("SELECT EXISTS(SELECT 1 FROM %1 WHERE id = :id)").arg(table));
|
|
query.bindValue(":id", id);
|
|
query.exec();
|
|
query.first();
|
|
return query.value(0).toBool();
|
|
}
|
|
|
|
bool DatabaseManager::executeQuery(QSqlQuery &query) const
|
|
{
|
|
bool res = query.exec();
|
|
return res;
|
|
|
|
}
|
|
|
|
void DatabaseManager::dropTables()
|
|
{
|
|
query.exec("DROP TABLE IF EXISTS colnod_token, colnod_subject, colnod_subject_attribute");
|
|
}
|
|
|
|
// create table after deleting, it is used for full sync
|
|
void DatabaseManager::createTables()
|
|
{
|
|
query.exec("CREATE TABLE colnod_subject ("
|
|
"id character(36) primary key NOT NULL,"
|
|
"description character varying(255),"
|
|
"last_update timestamp NOT NULL,"
|
|
"name character varying(255),"
|
|
"pin character varying(255))");
|
|
|
|
query.exec("CREATE TABLE colnod_token ("
|
|
"id CHAR(36) primary key NOT NULL,"
|
|
"auth_errors INTEGER NOT NULL,"
|
|
"description VARCHAR(255),"
|
|
"enabled BOOLEAN NOT NULL,"
|
|
"last_update timestamp NOT NULL,"
|
|
"name VARCHAR(255),"
|
|
"no_validity BOOLEAN NOT NULL,"
|
|
"time_to_live INTEGER NOT NULL,"
|
|
"token_bits INTEGER,"
|
|
"token_data VARCHAR(255),"
|
|
"token_type VARCHAR(255),"
|
|
"subject_id CHAR(36),"
|
|
"last_modified timestamp,"
|
|
"deleted BOOLEAN)");
|
|
|
|
query.exec("CREATE TABLE colnod_subject_attribute ("
|
|
"id VARCHAR(255) primary key,"
|
|
"attribute_key VARCHAR(255),"
|
|
"attribute_value VARCHAR(255),"
|
|
"subject_id CHAR(36))");
|
|
}
|
|
|
|
// return last_sync time
|
|
uint64_t DatabaseManager::getLastSync()
|
|
{
|
|
query.exec("SELECT last_sync FROM config");
|
|
query.next();
|
|
quint64 temp = query.value(0).toULongLong();
|
|
return temp;
|
|
}
|
|
|
|
// on the very end of sync set new Last_sync time (begin of this sync)
|
|
void DatabaseManager::updateLastSync(quint64 lastSync)
|
|
{
|
|
query.prepare("UPDATE config SET last_sync = :last_sync");
|
|
query.bindValue(":last_sync", lastSync);
|
|
query.exec();
|
|
}
|
|
|
|
|
|
// return set of tokens to update form DB
|
|
QSqlQuery* DatabaseManager::getUpdatedTokens()
|
|
{
|
|
QSqlQuery* qry = new QSqlQuery;
|
|
qry->exec("SELECT id, auth_errors, description, enabled, last_update, name, no_validity, time_to_live, token_bits, token_data, token_type, subject_id, last_modified, deleted "
|
|
"FROM colnod_token WHERE EXTRACT(EPOCH FROM last_modified) * 1000 > EXTRACT(EPOCH FROM last_update) * 1000");
|
|
return qry;
|
|
}
|
|
|
|
QSqlQuery* DatabaseManager::getToken(const QString& id)
|
|
{
|
|
QSqlQuery* qry = new QSqlQuery;
|
|
qry->prepare("SELECT SELECT id, auth_errors, description, enabled, last_update, name, no_validity, time_to_live, token_bits, token_data, token_type, subject_id, last_modified, deleted "
|
|
"FROM colnod_token WHERE id = :id");
|
|
qry->bindValue(":id", id);
|
|
qry->exec();
|
|
if (qry->next()){
|
|
return qry;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
quint64 DatabaseManager::getNow()
|
|
{
|
|
query.exec("SELECT EXTRACT(EPOCH FROM NOW())*1000");
|
|
query.next();
|
|
return query.value(0).toULongLong();
|
|
}
|
|
|
|
// sync last update back to DB from Colnod after changes made to Colnod
|
|
void DatabaseManager::setLastUpdate(const QString& id, quint64 lastUpdate)
|
|
{
|
|
query.prepare("UPDATE colnod_token SET last_update = :lastUpdate WHERE id = :id");
|
|
query.bindValue(":id", id);
|
|
query.bindValue(":lastUpdate", lastUpdate);
|
|
query.exec();
|
|
}
|
|
|