mirror of
https://github.com/chris2511/xca.git
synced 2026-09-12 19:51:05 +05:00
Add table prefix to be prepended to each table
This allows multiple independent xca databases in one database
This commit is contained in:
parent
468f7e43e2
commit
64c9c5ccab
46
lib/sql.cpp
46
lib/sql.cpp
@ -9,6 +9,7 @@
|
||||
#include <QDebug>
|
||||
#include "base.h"
|
||||
#include "sql.h"
|
||||
#include "settings.h"
|
||||
|
||||
int DbTransaction::mutex;
|
||||
int DbTransaction::error;
|
||||
@ -99,12 +100,48 @@ bool DbTransaction::done(QSqlError e, const char *file, int line)
|
||||
return e.isValid() ? rollback(file, line) : commit(file, line);
|
||||
}
|
||||
|
||||
QString XSqlQuery::table_prefix;
|
||||
|
||||
int XSqlQuery::schemaVersion()
|
||||
{
|
||||
qDebug() << "table_prefix:" << table_prefix;;
|
||||
return QSqlDatabase::database().tables()
|
||||
.contains(table_prefix + "settings") ?
|
||||
Settings["schema"] : 0;
|
||||
}
|
||||
|
||||
QString XSqlQuery::rewriteQuery(QString _q)
|
||||
{
|
||||
QStringList tables; tables <<
|
||||
"items" << "crls" << "private_keys" << "public_keys" <<
|
||||
"tokens" << "token_mechanism" << "templates" << "certs" <<
|
||||
"authority" << "revocations" << "requests" << "x509super" <<
|
||||
"settings" << "revocations" <<
|
||||
|
||||
"view_public_keys" << "view_certs" << "view_requests" <<
|
||||
"view_crls" << "view_templates" << "view_private" ;
|
||||
|
||||
lastq = query = _q;
|
||||
if (table_prefix.isEmpty())
|
||||
return query;
|
||||
|
||||
QString m = tables.join("|") + "|i_" + tables.join("|i_");
|
||||
m = QString("\\b(%1)").arg(m);
|
||||
query = query.replace(QRegExp(m), table_prefix + "\\1");
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
QString XSqlQuery::query_details()
|
||||
{
|
||||
QString lq = lastq;
|
||||
QList<QVariant> list = boundValues().values();
|
||||
QStringList sl;
|
||||
|
||||
if (query != lastq) {
|
||||
lq = QString("%1 (PREFIX[%2]: %3)").arg(lastq)
|
||||
.arg(table_prefix).arg(query);
|
||||
}
|
||||
for (int i = 0; i < list.size(); ++i)
|
||||
sl << list.at(i).toString();
|
||||
if (sl.size())
|
||||
@ -126,15 +163,14 @@ XSqlQuery::XSqlQuery() : QSqlQuery()
|
||||
{
|
||||
}
|
||||
|
||||
XSqlQuery::XSqlQuery(QString q) : QSqlQuery(q)
|
||||
XSqlQuery::XSqlQuery(QString q) : QSqlQuery()
|
||||
{
|
||||
file = ""; line = 0;
|
||||
lastq = q;
|
||||
exec(q);
|
||||
}
|
||||
|
||||
bool XSqlQuery::exec(QString q)
|
||||
{
|
||||
lastq = q;
|
||||
q = rewriteQuery(q);
|
||||
file = ""; line = 0;
|
||||
return QSqlQuery::exec(q);
|
||||
}
|
||||
@ -159,7 +195,7 @@ bool XSqlQuery::exec()
|
||||
|
||||
bool XSqlQuery::prepare(QString q)
|
||||
{
|
||||
lastq = q;
|
||||
q = rewriteQuery(q);
|
||||
setForwardOnly(true);
|
||||
return QSqlQuery::prepare(q);
|
||||
}
|
||||
|
||||
13
lib/sql.h
13
lib/sql.h
@ -56,13 +56,24 @@ class DbTransaction
|
||||
class XSqlQuery: public QSqlQuery
|
||||
{
|
||||
private:
|
||||
QString lastq;
|
||||
QString lastq, query;
|
||||
const char *file;
|
||||
int line;
|
||||
QString rewriteQuery(QString query);
|
||||
static QString table_prefix;
|
||||
public:
|
||||
XSqlQuery();
|
||||
XSqlQuery(QString q);
|
||||
|
||||
static int schemaVersion();
|
||||
static void setTablePrefix(QString p)
|
||||
{
|
||||
table_prefix = p;
|
||||
}
|
||||
static void clearTablePrefix()
|
||||
{
|
||||
table_prefix.clear();
|
||||
}
|
||||
QString query_details();
|
||||
QSqlError lastError();
|
||||
bool exec(QString q);
|
||||
|
||||
15
ui/OpenDb.ui
15
ui/OpenDb.ui
@ -7,12 +7,9 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>441</width>
|
||||
<height>325</height>
|
||||
<height>292</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="_2">
|
||||
@ -149,6 +146,16 @@
|
||||
<item row="4" column="1">
|
||||
<widget class="QLineEdit" name="dbName"/>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Table prefix</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLineEdit" name="prefix"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
|
||||
@ -32,24 +32,18 @@ QSqlError MainWindow::initSqlDB()
|
||||
XSqlQuery q;
|
||||
QSqlDatabase db = QSqlDatabase::database();
|
||||
QStringList tables;
|
||||
unsigned i = 0;
|
||||
|
||||
unsigned int i;
|
||||
if (!db.isOpen())
|
||||
return QSqlError();
|
||||
|
||||
tables = db.tables();
|
||||
|
||||
if (tables.contains("settings")) {
|
||||
i = Settings["schema"];
|
||||
}
|
||||
Transaction;
|
||||
if (!TransBegin())
|
||||
return db.lastError();
|
||||
|
||||
for (; i < ARRAY_SIZE(schemas); i++) {
|
||||
for (i = XSqlQuery::schemaVersion(); i < ARRAY_SIZE(schemas); i++) {
|
||||
foreach(QString sql, schemas[i]) {
|
||||
qDebug("EXEC[%d]: '%s'", i, CCHAR(sql));
|
||||
if (!q.exec(sql)) {
|
||||
if (!q.exec(sql) || q.lastError().isValid()) {
|
||||
TransRollback();
|
||||
return q.lastError();
|
||||
}
|
||||
@ -66,13 +60,14 @@ QString MainWindow::openSqlDB(QString dbName)
|
||||
close_database();
|
||||
opendb->openDatabase();
|
||||
QSqlError e = initSqlDB();
|
||||
qDebug() << "DB-DESC:" << opendb->getDescriptor();
|
||||
if (e.isValid()) {
|
||||
dbSqlError();
|
||||
dbSqlError(e);
|
||||
QSqlDatabase::database().close();
|
||||
dbName = QString();
|
||||
} else {
|
||||
dbName = opendb->getDescriptor();
|
||||
}
|
||||
qDebug() << "DB-DESC:" << opendb->getDescriptor() << dbName << e;
|
||||
}
|
||||
delete opendb;
|
||||
return dbName;
|
||||
@ -258,7 +253,7 @@ int MainWindow::init_database(QString dbName)
|
||||
}
|
||||
Entropy::seed_rng();
|
||||
dbName = openSqlDB(dbName);
|
||||
if (!QSqlDatabase::database().isOpen()) {
|
||||
if (!QSqlDatabase::database().isOpen() || dbName.isEmpty()) {
|
||||
/* Error already printed */
|
||||
return 1;
|
||||
}
|
||||
@ -513,6 +508,7 @@ void MainWindow::close_database()
|
||||
QSqlDatabase::removeDatabase(connName);
|
||||
currentDB.clear();
|
||||
Settings.clear();
|
||||
XSqlQuery::clearTablePrefix();
|
||||
}
|
||||
|
||||
void MainWindow::load_history()
|
||||
|
||||
@ -15,6 +15,9 @@
|
||||
#include "PwDialog.h"
|
||||
#include "lib/base.h"
|
||||
|
||||
#define NUM_PARAM 6
|
||||
#define NUM_PARAM_LEAST 5
|
||||
|
||||
DbMap OpenDb::getDatabases()
|
||||
{
|
||||
QStringList list = QSqlDatabase::drivers();
|
||||
@ -46,17 +49,21 @@ bool OpenDb::hasRemoteDrivers()
|
||||
|
||||
DbMap OpenDb::splitRemoteDbName(QString db)
|
||||
{
|
||||
static const char * const names[] =
|
||||
{ "all", "user", "host", "type", "dbname" };
|
||||
static const char * const names[NUM_PARAM] =
|
||||
{ "all", "user", "host", "type", "dbname", "prefix" };
|
||||
DbMap map;
|
||||
QRegExp rx("(.*)@(.*)/(.*):(.*)");
|
||||
QRegExp rx("(.*)@(.*)/(.*):([^#]*)#?([^#]*)");
|
||||
int i, pos = rx.indexIn(db);
|
||||
QStringList list = rx.capturedTexts();
|
||||
|
||||
if (pos != -1 && list.size() == 5) {
|
||||
for (i=0; i<5; i++) {
|
||||
if (pos != -1 && list.size() >= NUM_PARAM_LEAST) {
|
||||
if (list.size() == NUM_PARAM_LEAST)
|
||||
list[NUM_PARAM_LEAST] = "";
|
||||
list[NUM_PARAM_LEAST] = list[NUM_PARAM_LEAST].toLower();
|
||||
for (i=0; i < NUM_PARAM; i++) {
|
||||
map[names[i]] = list[i];
|
||||
}
|
||||
qDebug() << "SPLIT DB:" << map;
|
||||
}
|
||||
return map;
|
||||
}
|
||||
@ -64,7 +71,7 @@ DbMap OpenDb::splitRemoteDbName(QString db)
|
||||
bool OpenDb::isRemoteDB(QString db)
|
||||
{
|
||||
DbMap remote_param = splitRemoteDbName(db);
|
||||
return remote_param.size() == 5;
|
||||
return remote_param.size() == NUM_PARAM;
|
||||
}
|
||||
|
||||
OpenDb::OpenDb(QWidget *parent, QString db)
|
||||
@ -77,11 +84,12 @@ OpenDb::OpenDb(QWidget *parent, QString db)
|
||||
setWindowTitle(XCA_TITLE);
|
||||
|
||||
remote_param = splitRemoteDbName(db);
|
||||
if (remote_param.size() == 5) {
|
||||
if (remote_param.size() == NUM_PARAM) {
|
||||
userName->setText(remote_param["user"]);
|
||||
hostName->setText(remote_param["host"]);
|
||||
dbTypeName = remote_param["type"];
|
||||
dbName->setText(remote_param["dbname"]);
|
||||
prefix->setText(remote_param["prefix"]);
|
||||
sqlite = false;
|
||||
show_connection_settings = false;
|
||||
} else if (hasSqLite() && !db.isEmpty()) {
|
||||
@ -183,26 +191,31 @@ bool OpenDb::_openDatabase(QString connName, QString pass) const
|
||||
db.setPort(hostport[1].toInt());
|
||||
db.setUserName(userName->text());
|
||||
db.setPassword(pass);
|
||||
XSqlQuery::setTablePrefix(prefix->text().toLower());
|
||||
|
||||
db.open();
|
||||
QSqlError e = db.lastError();
|
||||
if (!e.isValid() || e.type() != QSqlError::ConnectionError ||
|
||||
db.isOpen())
|
||||
return true;
|
||||
|
||||
XSqlQuery::clearTablePrefix();
|
||||
db.close();
|
||||
return false;
|
||||
};
|
||||
|
||||
QString OpenDb::getDescriptor() const
|
||||
{
|
||||
QString pref = prefix->text();
|
||||
if (!pref.isEmpty())
|
||||
pref = QString("#%1").arg(pref.toLower());
|
||||
return sqlite ?
|
||||
dbName->text() :
|
||||
QString("%1@%2/%3:%4")
|
||||
QString("%1@%2/%3:%4%5")
|
||||
.arg(userName->text())
|
||||
.arg(hostName->text())
|
||||
.arg(getDbType())
|
||||
.arg(dbName->text());
|
||||
.arg(dbName->text())
|
||||
.arg(pref);
|
||||
}
|
||||
|
||||
int OpenDb::exec()
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
#define __OPENDB_H
|
||||
|
||||
#include "ui_OpenDb.h"
|
||||
#include <QDialog>
|
||||
#include <QSqlDatabase>
|
||||
|
||||
typedef QMap<QString, QString> DbMap;
|
||||
|
||||
@ -294,3 +294,7 @@
|
||||
<< "CREATE INDEX i_items_stamp ON items (stamp)"
|
||||
<< "UPDATE settings SET value='5' WHERE key_='schema'"
|
||||
;
|
||||
|
||||
/* When adding new tables or views, also add them to the list
|
||||
* in XSqlQuery::rewriteQuery(QString) in lib/sql.cpp
|
||||
*/
|
||||
|
||||
Loading…
Reference in New Issue
Block a user