mirror of
https://gitlab.com/spaceti-app/integrations/common/server-sdk.git
synced 2026-07-12 11:50:42 +02:00
229 lines
6.0 KiB
C++
229 lines
6.0 KiB
C++
#include "databaseutils.h"
|
|
#include "databasemanager.h"
|
|
#include "databasetable.h"
|
|
#include "logger.h"
|
|
|
|
#include <QMetaProperty>
|
|
|
|
|
|
namespace serversdk {
|
|
|
|
/**
|
|
* @brief DatabaseUtils::createTableSQL
|
|
* @param table
|
|
* @return
|
|
*
|
|
* @code{sql}
|
|
* "CREATE TABLE colsunod_bject ("
|
|
"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)"
|
|
* @endcode
|
|
*
|
|
* Default types:
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
DatabaseUtils::DatabaseUtils(DatabaseManager *manager, const QString type)
|
|
: mDatabaseManager(manager), mSqlType(type)
|
|
{
|
|
Q_ASSERT(mDatabaseManager);
|
|
}
|
|
|
|
|
|
QString DatabaseUtils::createTableText(const DatabaseTable *table, const QString table_name) const
|
|
{
|
|
QString userData;
|
|
|
|
if (table_name.isEmpty()) {
|
|
return QString();
|
|
}
|
|
|
|
// out: "CREATE TABLE colnod_subject ( "
|
|
QString sql = QString("CREATE TABLE %1 ( ").arg(table_name);
|
|
|
|
const QMetaObject *metaObj = table->metaObject();
|
|
int total = metaObj->propertyCount();
|
|
int first = true;
|
|
for (int i = metaObj->propertyOffset(); i < total; ++i) {
|
|
QMetaProperty prop = metaObj->property(i);
|
|
// Skip non USER so -> ( Q_PROPERTY( ...... USER false ) only
|
|
if (!prop.isUser())
|
|
continue;
|
|
|
|
QString name = fromCamelCase(prop.name());
|
|
QVariant::Type type = prop.type();
|
|
QString textType;
|
|
|
|
|
|
// Getting correct type based on QVariant
|
|
if (sqlType() == "SQLITE") {
|
|
textType = table->textSQLIteType(type);
|
|
} else if (sqlType() == "PSQL") {
|
|
textType = table->textSQLIteType(type);
|
|
//return QString();
|
|
} else {
|
|
qCDebug(sdkdb) << "Implemented only for SQLITE";
|
|
return QString();
|
|
}
|
|
|
|
// in: id TEXT
|
|
// out: "CREATE TABLE colnod_subject ( id TEXT "
|
|
sql += QString("%1 %2").arg(name,textType);
|
|
|
|
// in: PRIMARY KEY
|
|
// out: "CREATE TABLE colnod_subject ( id TEXT PRIMARY KEY"
|
|
if (first) { // first row
|
|
sql += " PRIMARY KEY NOT NULL";
|
|
first = false;
|
|
}
|
|
|
|
// in: NOT NULL
|
|
// out: "CREATE TABLE colnod_subject ( id TEXT PRIMARY KEY NOT NULL"
|
|
if (!userData.isEmpty()) {
|
|
sql += " " + userData;
|
|
}
|
|
|
|
// out: "CREATE TABLE colnod_subject ( id TEXT PRIMARY KEY NOT NULL,"
|
|
if (i < (total-1)) { // second last
|
|
sql += ", ";
|
|
}
|
|
}
|
|
|
|
// out: ".. subject_id TEXT)"
|
|
sql+= " )";
|
|
|
|
return sql;
|
|
}
|
|
|
|
QSqlQuery DatabaseUtils::createTable(const DatabaseTable *table, const QString tableName) const
|
|
{
|
|
// CREATE TABLE ...
|
|
QString sql = createTableText(table, tableName);
|
|
qCDebug(sdkdb) << "SQL:" << sql;
|
|
return mDatabaseManager->execPlainSql(sql);
|
|
}
|
|
|
|
/**
|
|
* @brief DatabaseUtils::insertIntoTable
|
|
* @param table
|
|
* @param table_name
|
|
* @return
|
|
*
|
|
* @todo Loop VariantMap change to Loop over propertiess
|
|
*/
|
|
QSqlQuery DatabaseUtils::insertIntoTable(const DatabaseTable *table, const QString table_name) const
|
|
{
|
|
QString columns;
|
|
QString values;
|
|
|
|
QVariantMap valueMap = table->toVariantMap();
|
|
|
|
// in: id / 23233
|
|
// out: columns: id
|
|
// out: values: :id
|
|
auto keys = valueMap.keys();
|
|
for (auto _key : keys) {
|
|
QString key = fromCamelCase(_key);
|
|
if (!columns.isEmpty()) {
|
|
columns += ", ";
|
|
values += ", ";
|
|
}
|
|
columns += key;
|
|
values += ":" + key;
|
|
}
|
|
|
|
QSqlQuery query(mDatabaseManager->database());
|
|
QString queryText = QString("INSERT INTO %1 ( %2 ) VALUES ( %3 );").arg(table_name).arg(columns).arg(values);
|
|
query.prepare(queryText);
|
|
|
|
for (auto _key : keys ) {
|
|
QString key = fromCamelCase(_key);
|
|
auto value = valueMap.value(_key);
|
|
query.bindValue(":"+key, value);
|
|
}
|
|
|
|
QSqlQuery res = mDatabaseManager->executeQuery(query);
|
|
return res;
|
|
}
|
|
|
|
|
|
QSqlQuery DatabaseUtils::updateTable(const DatabaseTable *table, const QString table_name) const
|
|
{
|
|
QString columnsAndValues;
|
|
QString primaryKeyCondition;
|
|
|
|
QVariantMap valueMap = table->toVariantMap();
|
|
auto keys = valueMap.keys();
|
|
|
|
Q_ASSERT(!keys.isEmpty());
|
|
// Primary key is first user property ( first VariantMap item )
|
|
// in ( primary key ): id
|
|
// out: id = :id
|
|
const QString primaryKey = table->primaryKey();
|
|
primaryKeyCondition = primaryKey + " = :" + primaryKey;
|
|
|
|
for (auto _key : keys) {
|
|
QString key = fromCamelCase(_key);
|
|
if (!columnsAndValues.isEmpty()) {
|
|
columnsAndValues += ", ";
|
|
}
|
|
columnsAndValues += key + " = :" + key;
|
|
}
|
|
|
|
QSqlQuery query(mDatabaseManager->database());
|
|
QString queryText = QString("UPDATE %1 SET %2 WHERE %3;").arg(table_name).arg(columnsAndValues).arg(primaryKeyCondition);
|
|
query.prepare(queryText);
|
|
|
|
for (auto _key : keys ) {
|
|
QString key = fromCamelCase(_key);
|
|
auto value = valueMap.value(_key);
|
|
query.bindValue(":"+key, value);
|
|
}
|
|
|
|
QSqlQuery res = mDatabaseManager->executeQuery(query);
|
|
return res;
|
|
}
|
|
|
|
|
|
|
|
QString DatabaseUtils::sqlType() const
|
|
{
|
|
return mSqlType;
|
|
}
|
|
|
|
void DatabaseUtils::setSqlType(const QString &sqlType)
|
|
{
|
|
mSqlType = sqlType;
|
|
}
|
|
|
|
QString DatabaseUtils::fromCamelCase(const QString &s)
|
|
{
|
|
static QRegularExpression regExp1 {"(.)([A-Z][a-z]+)"};
|
|
static QRegularExpression regExp2 {"([a-z0-9])([A-Z])"};
|
|
|
|
QString result = s;
|
|
result.replace(regExp1, "\\1_\\2");
|
|
result.replace(regExp2, "\\1_\\2");
|
|
|
|
return result.toLower();
|
|
}
|
|
|
|
QString serversdk::DatabaseUtils::toCamelCase(const QString &s)
|
|
{
|
|
QStringList parts = s.split('_', QString::SkipEmptyParts);
|
|
for (int i=1; i<parts.size(); ++i)
|
|
parts[i].replace(0, 1, parts[i][0].toUpper());
|
|
|
|
return parts.join("");
|
|
}
|
|
|
|
|
|
|
|
} // namespace serversdk
|