colnod-connector/src/colnod/databaseapi.cpp

459 lines
16 KiB
C++

#include "databaseapi.h"
#include "logger.h"
DatabaseAPI::DatabaseAPI(serversdk::DatabaseManager *dbMan)
:mDbMan(dbMan)
{
}
bool DatabaseAPI::open()
{
return mDbMan->openPostgres(QStringLiteral("192.168.1.94"), // move to databaseAPi
QStringLiteral("deloitte"),
QStringLiteral("postgres"),
QStringLiteral("34rjkciea12"),
QStringLiteral("postgres-connection"));
}
void DatabaseAPI::downloadData()
{
QSqlQuery updatedQuery = mDbMan->execPlainSql("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 AND deleted = false");
QSqlQuery deletedQuery = mDbMan->execPlainSql("SELECT id "
"FROM colnod_token WHERE EXTRACT(EPOCH FROM last_modified) * 1000 > EXTRACT(EPOCH FROM last_update) * 1000 AND deleted = true");
emit downloadDataFinished(composeData(updatedQuery, deletedQuery));
}
void DatabaseAPI::processData(std::shared_ptr<Data> data)
{
uploadTokens(data->updatedTokens);
uploadSubjects(data->updatedSubjects);
deleteTokens(data->deletedTokens);
deleteSubjects(data->deletedSubjects);
}
std::shared_ptr<Data> DatabaseAPI::composeData(QSqlQuery updatedQuery, QSqlQuery deletedQuery)
{
auto data = std::make_shared<Data>();
while (updatedQuery.next()) {
auto token = std::make_shared<Token>();
token->fromSQLRecord(updatedQuery);
data->updatedTokens.insert(token->getId(), token);
}
while (deletedQuery.next()) {
data->deletedTokens.append(deletedQuery.value(0).toString());
}
return data;
}
qint64 DatabaseAPI::getLastSync()
{
auto query = mDbMan->execPlainSql("SELECT last_sync FROM config");
if (query.next()){
return query.value(0).toLongLong();
}
else {
return -1;
}
}
void DatabaseAPI::setLastSync(qint64 timestamp)
{
QSqlQuery query;
query.prepare("UPDATE config SET last_sync = :last_sync");
query.bindValue(":last_sync", timestamp);
mDbMan->executeQuery(query);
}
void DatabaseAPI::setLastUpdate(QHash<QUuid, std::shared_ptr<Token>> tokens)
{
QSqlQuery query;
for (const auto &token : tokens){
query.prepare("UPDATE colnod_token SET last_update = :last_update WHERE id = :id");
query.bindValue(":last_update", QDateTime::fromMSecsSinceEpoch(token->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz"));
query.bindValue(":id", token->idToStringWithoutBraces());
mDbMan->executeQuery(query);
}
}
qint64 DatabaseAPI::getNow()
{
QSqlQuery query = mDbMan->execPlainSql("SELECT EXTRACT(EPOCH FROM NOW())*1000");
query.next();
return query.value(0).toLongLong();
}
void DatabaseAPI::initNewTokens()
{
QSqlQuery query = mDbMan->execPlainSql("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 name IS NULL");
QHash<QUuid, std::shared_ptr<Token>> tokensToInit;
while (query.next()){
auto token = std::make_shared<Token>();
token->fromSQLRecord(query);
qint16 num = getNumOfTokensOfSubject(token->subjectIdToStringWithoutBraces());
token->setName(getSubjectNameByTokenId(token->idToStringWithoutBraces()) + "_mobile_" + QString::number(num + 1));
token->setDescription("mobile");
tokensToInit.insert(token->getId(), token);
}
uploadTokens(tokensToInit);
}
void DatabaseAPI::uploadTokens(QHash<QUuid, std::shared_ptr<Token>> tokens)
{
// TODO:
}
void DatabaseAPI::uploadSubjects(QHash<QUuid, std::shared_ptr<Subject>> subjects)
{
// TODO:
}
void DatabaseAPI::deleteTokens(QList<QString> ids)
{
// TODO:
}
void DatabaseAPI::deleteSubjects(QList<QString> ids)
{
// TODO:
}
qint16 DatabaseAPI::getNumOfTokensOfSubject(const QString &id)
{
QSqlQuery query;
query.prepare("SELECT 1 FROM colnod_token WHERE subject_id = :id AND deleted = false");
query.bindValue(":id", id);
return static_cast<qint16>(mDbMan->executeQuery(query).size());
}
QString DatabaseAPI::getSubjectNameByTokenId(const QString &tokenId)
{
QSqlQuery query;
query.prepare("SELECT name FROM colnod_subject WHERE id = (SELECT subject_id FROM colnod_token WHERE id = :tokenId)");
query.bindValue(":tokenId", tokenId);
if (mDbMan->executeQuery(query).next())
return query.value(0).toString();
qWarning() << "Token:" << tokenId << "is not assigned to any subject";
return "(No subject)";
}
// OLD
//DatabaseAPI::DatabaseAPI(const QString& host, const QString& dbName, const QString& user, const QString& password, const bool &dryMode)
// :dryMode(dryMode)
//{
// 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())
// {
// opened = false;
// Logger::log("Opening error" + db.lastError().text());
// emit error();
// }
// else{
// opened = true;
// }
//}
//// add or update subject to db
//int DatabaseAPI::saveSubject(const std::shared_ptr<Subject>& subject, const QString& table)
//{
// QSqlQuery query;
// QString id = subject->idToStringWithoutBraces();
// int rtn;
// if (checkIfExists(id, table)){
// query.prepare(QString("UPDATE %1 SET id = :id, description = :description, last_update = :last_update, name = :name, pin = :pin, last_modified = :last_modified, deleted = :deleted "
// "WHERE id = :id").arg(table));
// rtn = -1;
// }else{
// query.prepare(QString("INSERT INTO %1 (id, description, last_update, name, pin, last_modified, deleted) "
// "VALUES (:id, :description, :last_update, :name, :pin, :last_modified, :deleted)").arg(table));
// rtn = 1;
// }
// 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.bindValue(":last_modified", QDateTime::fromMSecsSinceEpoch(subject->getLastUpdate()).toString("yyyy-MM-dd hh:mm:ss.zzz"));
// query.bindValue(":deleted", subject->getDeleted());
// executeQuery(query);
// return rtn;
//}
//QSqlQuery DatabaseAPI::getUpdatedTokens()
//{
// QSqlQuery query;
// executeQuery(query, "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 AND deleted = false");
// return query;
//}
//// add or update token to DB
//int DatabaseAPI::saveToken(const std::shared_ptr<Token>& token, const QString& table)
//{
// QSqlQuery query;
// QString id = token->idToStringWithoutBraces();
// int rtn;
// if (checkIfExists(id, table)){
// query.prepare(QString("UPDATE %1 SET id = :id, auth_errors = :auth_errors, description = :description, enabled = :enabled, last_update = :last_update, 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));
// rtn = -1;
// }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));
// rtn = 1;
// }
// 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());
// executeQuery(query);
// return rtn;
//}
//// add of update subject attributes
//void DatabaseAPI::saveSubjectAttributes(const std::shared_ptr<Subject>& subject, const QString& table)
//{
// QSqlQuery query;
// 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));
// }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());
// executeQuery(query);
// }
//}
//// "delete" tokens from DB -> set deleted true
//void DatabaseAPI::setDeleted(const QString& id, const QString& table, quint64 time)
//{
// QSqlQuery query;
// QString nowString = QDateTime::fromMSecsSinceEpoch(time).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);
// executeQuery(query);
//}
//bool DatabaseAPI::checkIfExists(const QString& id, const QString& table)
//{
// QSqlQuery query;
// query.prepare(QString("SELECT EXISTS(SELECT 1 FROM %1 WHERE id = :id)").arg(table));
// query.bindValue(":id", id);
// executeQuery(query);
// query.first();
// return query.value(0).toBool();
//}
//QString DatabaseAPI::getLastQuery(const QSqlQuery& query) const
//{
// QString str = query.lastQuery();
// QMapIterator<QString, QVariant> it(query.boundValues());
// while (it.hasNext())
// {
// it.next();
// str.replace(it.key(),it.value().toString());
// }
// return str;
//}
//bool DatabaseAPI::executeQuery(QSqlQuery &query, const QString &statement)
//{
// if (statement.isEmpty()){
// if (dryMode){
// QString sqlStatement = getLastQuery(query);
// qDebug() << sqlStatement;
// }
// if (!dryMode || getLastQuery(query).startsWith("SELECT")){
// if (!query.exec()){
// QString msg = QString("Source: Database Manager, Error: %1").arg(query.lastError().text());
// Logger::logToDb(QString(msg));
// emit error();
// }
// }
// return true;
// }
// if (dryMode){
// qDebug() << statement;
// }
// if (!dryMode || statement.startsWith("SELECT")){
// if (!query.exec(statement)){
// QString msg = QString("Source: Database Manager, Error: %1").arg(query.lastError().text());
// Logger::logToDb(QString(msg));
// emit error();
// }
// }
// return true;
//}
//void DatabaseAPI::dropTables()
//{
// QSqlQuery query;
// executeQuery(query, "DROP TABLE IF EXISTS colnod_token, colnod_subject, colnod_subject_attribute");
//}
//// create table after deleting, it is used for full sync
//void DatabaseAPI::createTables()
//{
// QSqlQuery query;
// executeQuery(query, "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),"
// "last_modified timestamp,"
// "deleted BOOLEAN)");
// executeQuery(query, "CREATE TABLE colnod_token ("
// "id CHAR(36) primary key NOT NULL,"
// "auth_errors INTEGER DEFAULT 255,"
// "description VARCHAR(255),"
// "enabled BOOLEAN DEFAULT true,"
// "last_update timestamp DEFAULT '1970-01-01 00:00:00'::timestamp without time zone,"
// "name VARCHAR(255),"
// "no_validity BOOLEAN DEFAULT true,"
// "time_to_live INTEGER DEFAULT 255,"
// "token_bits INTEGER DEFAULT 32,"
// "token_data VARCHAR(255),"
// "token_type VARCHAR(255) DEFAULT 'Token'::character varying,"
// "subject_id CHAR(36),"
// "last_modified timestamp NOT NULL,"
// "deleted BOOLEAN DEFAULT false)");
// executeQuery(query, "CREATE TABLE colnod_subject_attribute ("
// "id VARCHAR(255) primary key,"
// "attribute_key VARCHAR(255),"
// "attribute_value VARCHAR(255),"
// "subject_id CHAR(36))");
//}
//// on the very end of sync set new Last_sync time (begin of this sync)
//// return set of tokens to update form DB
//QSqlQuery DatabaseAPI::getToken(const QString& id)
//{
// QSqlQuery query;
// query.prepare("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");
// query.bindValue(":id", id);
// executeQuery(query);
// query.next();
// return query;
//}
//// sync last update back to DB from Colnod after changes made to Colnod
//void DatabaseAPI::log(const QString &msg)
//{
// QSqlQuery query;
// query.prepare("INSERT INTO logs (log_time, msg) VALUES (NOW(), :msg)");
// query.bindValue(":msg", msg);
// query.exec();
//}
//QString DatabaseAPI::getSubjectNameByTokenId(const QString &tokenId)
//{
// QSqlQuery query;
// query.prepare("SELECT name FROM colnod_subject WHERE id = (SELECT subject_id FROM colnod_token WHERE id = :tokenId)");
// query.bindValue(":tokenId", tokenId);
// executeQuery(query);
// if (query.next())
// return query.value(0).toString();
// qWarning() << "Token:" << tokenId << "is not assigned to any subject";
// return "(No subject)";
//}
//QString DatabaseAPI::getSubjectNameById(const QString &id)
//{
// QSqlQuery query;
// query.prepare("SELECT name FROM colnod_subject WHERE id = :id");
// query.bindValue(":id", id);
// executeQuery(query);
// if (query.next())
// return query.value(0).toString();
// qWarning() << "Subject:" << id << "doesn't exists";
// return "(No subject)";
//}
//bool DatabaseAPI::checkDeletedToken(const QString &id)
//{
// QSqlQuery query;
// query.prepare("SELECT deleted FROM colnod_token WHERE id = :id");
// query.bindValue(":id", id);
// executeQuery(query);
// query.next();
// return query.value(0).toBool();
//}
//bool DatabaseAPI::isOpen()
//{
// return opened;
//}