mirror of
https://github.com/chris2511/xca.git
synced 2026-09-12 19:51:05 +05:00
Support concurrent database access.
If a database is modified by another instance of XCA the passive instance reloads and displays the changed parts.
This commit is contained in:
parent
ced0995862
commit
f43e7520db
@ -29,7 +29,7 @@
|
||||
#endif
|
||||
|
||||
#define C_FILE ((strrchr(__FILE__, '/') ? : __FILE__- 1) + 1)
|
||||
#define TRACE qDebug("File: %s Func: %s Line: %d\n",C_FILE,__func__,__LINE__);
|
||||
#define TRACE qDebug("File: %s Func: %s Line: %d", C_FILE, __func__, __LINE__);
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
|
||||
#define nativeSeparator(s) QDir::toNativeSeparators(s)
|
||||
|
||||
@ -141,6 +141,27 @@ void db_base::loadContainer()
|
||||
emit columnsContentChanged();
|
||||
}
|
||||
|
||||
void db_base::reloadContainer(const QList<enum pki_type> &typelist)
|
||||
{
|
||||
bool match = false;
|
||||
QList<enum pki_type> all_types = pkitype + pkitype_depends;
|
||||
foreach(enum pki_type t, typelist) {
|
||||
if (all_types.contains(t)) {
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!match)
|
||||
return;
|
||||
qDebug() << "RELOAD" << class_name << all_types << typelist;
|
||||
beginResetModel();
|
||||
delete rootItem;
|
||||
rootItem = newPKI();
|
||||
endResetModel();
|
||||
|
||||
loadContainer();
|
||||
}
|
||||
|
||||
void db_base::updateHeaders()
|
||||
{
|
||||
QString s = allHeaders.toData();
|
||||
@ -288,6 +309,7 @@ void db_base::deletePKI(QModelIndex idx)
|
||||
TransDone(e);
|
||||
if (!e.isValid())
|
||||
remFromCont(idx);
|
||||
AffectedItems(pki->getSqlItemId());
|
||||
mainwin->dbSqlError(e);
|
||||
}
|
||||
} catch (errorEx &err) {
|
||||
@ -336,7 +358,7 @@ void db_base::inToCont(pki_base *pki)
|
||||
pki_base *db_base::getByName(QString desc)
|
||||
{
|
||||
QList<pki_base*> list = sqlSELECTpki<pki_base>(
|
||||
QString("SELECT id FROM items WHERE name=? AND ") +
|
||||
QString("SELECT id FROM items WHERE name=? AND del=0 AND ") +
|
||||
sqlItemSelector(),
|
||||
QList<QVariant>() << QVariant(desc));
|
||||
return list.isEmpty() ? NULL : list[0];
|
||||
|
||||
@ -44,6 +44,7 @@ class db_base: public QAbstractItemModel
|
||||
void _removePKI(pki_base *pki );
|
||||
void removeItem(QString k);
|
||||
QList<enum pki_type> pkitype;
|
||||
QList<enum pki_type> pkitype_depends;
|
||||
MainWindow *mainwin;
|
||||
QString class_name;
|
||||
/* Sql table containing the 'hash' of this items */
|
||||
@ -60,7 +61,7 @@ class db_base: public QAbstractItemModel
|
||||
bool isValidCol(int col) const;
|
||||
static XSqlQuery sqlSELECTpki(QString query,
|
||||
QList<QVariant> values = QList<QVariant>());
|
||||
void timerEvent(QTimerEvent * event);
|
||||
void timerEvent(QTimerEvent *event);
|
||||
void restart_timer();
|
||||
|
||||
public:
|
||||
@ -110,6 +111,7 @@ class db_base: public QAbstractItemModel
|
||||
pki_base *getByReference(pki_base *refpki);
|
||||
pki_base *getByPtr(void *);
|
||||
virtual void loadContainer();
|
||||
void reloadContainer(const QList<enum pki_type> &typelist);
|
||||
template <class T> QList<T *> getAll()
|
||||
{
|
||||
return sqlSELECTpki<T>(
|
||||
|
||||
@ -23,6 +23,7 @@ db_crl::db_crl(MainWindow *mw)
|
||||
class_name = "crls";
|
||||
sqlHashTable = "crls";
|
||||
pkitype << revocation;
|
||||
pkitype_depends << x509;
|
||||
updateHeaders();
|
||||
loadContainer();
|
||||
}
|
||||
|
||||
@ -31,13 +31,15 @@ db_x509::db_x509(MainWindow *mw)
|
||||
class_name = "certificates";
|
||||
sqlHashTable = "certs";
|
||||
pkitype << x509;
|
||||
pkitype_depends << x509_req;
|
||||
updateHeaders();
|
||||
loadContainer();
|
||||
dereferenceIssuer();
|
||||
}
|
||||
|
||||
void db_x509::dereferenceIssuer()
|
||||
void db_x509::loadContainer()
|
||||
{
|
||||
db_x509super::loadContainer();
|
||||
|
||||
XSqlQuery q("SELECT item, issuer FROM certs WHERE issuer is NOT NULL");
|
||||
while (q.next()) {
|
||||
pki_base *root = rootItem;
|
||||
@ -56,6 +58,7 @@ void db_x509::dereferenceIssuer()
|
||||
insertChild(root, cert);
|
||||
}
|
||||
}
|
||||
emit columnsContentChanged();
|
||||
}
|
||||
|
||||
dbheaderList db_x509::getHeaders()
|
||||
|
||||
@ -34,6 +34,7 @@ class db_x509: public db_x509super
|
||||
db_x509(MainWindow *mw);
|
||||
pki_base *newPKI(enum pki_type type = none);
|
||||
pki_x509 *findIssuer(pki_x509 *client);
|
||||
virtual void loadContainer();
|
||||
|
||||
bool updateView();
|
||||
void updateViewAll();
|
||||
|
||||
@ -20,6 +20,7 @@ db_x509req::db_x509req(MainWindow *mw)
|
||||
class_name = "requests";
|
||||
sqlHashTable = "requests";
|
||||
pkitype << x509_req;
|
||||
pkitype_depends << x509;
|
||||
updateHeaders();
|
||||
loadContainer();
|
||||
}
|
||||
|
||||
@ -34,6 +34,7 @@ dbheaderList db_x509name::getHeaders()
|
||||
db_x509super::db_x509super(MainWindow *mw)
|
||||
:db_x509name(mw)
|
||||
{
|
||||
pkitype_depends << asym_key << smartCard;
|
||||
}
|
||||
|
||||
void db_x509super::loadContainer()
|
||||
|
||||
@ -195,7 +195,7 @@ QSqlError pki_base::deleteSql()
|
||||
e = deleteSqlData();
|
||||
if (e.isValid())
|
||||
return e;
|
||||
SQL_PREPARE(q, "DELETE FROM items WHERE id=?");
|
||||
SQL_PREPARE(q, "UPDATE items SET del=1 WHERE id=?");
|
||||
q.bindValue(0, sqlItemId);
|
||||
q.exec();
|
||||
return q.lastError();
|
||||
|
||||
@ -17,7 +17,7 @@ int DbTransaction::error;
|
||||
bool DbTransaction::hasTransaction;
|
||||
QList<quint64> DbTransaction::items;
|
||||
|
||||
quint64 DatabaseStamp;
|
||||
quint64 DbTransaction::DatabaseStamp;
|
||||
|
||||
void DbTransaction::debug(const char *func, const char *file, int line)
|
||||
{
|
||||
|
||||
@ -34,6 +34,7 @@ class DbTransaction
|
||||
bool commit(const char *file, int line);
|
||||
bool rollback(const char *file, int line);
|
||||
bool done(QSqlError e, const char *file, int line);
|
||||
static quint64 DatabaseStamp;
|
||||
static bool active()
|
||||
{
|
||||
return mutex > 0;
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
|
||||
QSqlError MainWindow::initSqlDB()
|
||||
{
|
||||
QStringList schemas[6];
|
||||
QStringList schemas[7];
|
||||
|
||||
#include "database_schema.cpp"
|
||||
|
||||
@ -274,6 +274,8 @@ int MainWindow::init_database(QString dbName)
|
||||
certs = new db_x509(this);
|
||||
temps = new db_temp(this);
|
||||
crls = new db_crl(this);
|
||||
check_oom(keys && reqs && certs && temps && crls);
|
||||
models << keys << reqs << certs << temps << crls;
|
||||
}
|
||||
catch (errorEx &err) {
|
||||
Error(err);
|
||||
@ -325,9 +327,42 @@ int MainWindow::init_database(QString dbName)
|
||||
}
|
||||
dbindex->setText(tr("Database") + ": " + dbName);
|
||||
currentDB = dbName;
|
||||
dbTimer = startTimer(1500);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void MainWindow::timerEvent(QTimerEvent *event)
|
||||
{
|
||||
quint64 stamp;
|
||||
if (event->timerId() != dbTimer)
|
||||
return;
|
||||
XSqlQuery q;
|
||||
SQL_PREPARE(q, "SELECT MAX(stamp) from items");
|
||||
q.exec();
|
||||
if (!q.first())
|
||||
return;
|
||||
stamp = q.value(0).toULongLong();
|
||||
q.finish();
|
||||
qDebug() << "Stamp" << stamp
|
||||
<< "DatabaseStamp" << DbTransaction::DatabaseStamp;
|
||||
|
||||
if (stamp > DbTransaction::DatabaseStamp) {
|
||||
SQL_PREPARE(q, "SELECT DISTINCT type FROM items WHERE stamp=?");
|
||||
q.bindValue(0, stamp);
|
||||
q.exec();
|
||||
|
||||
QList<enum pki_type> typelist;
|
||||
while (q.next())
|
||||
typelist << (enum pki_type)q.value(0).toInt();
|
||||
|
||||
q.finish();
|
||||
qDebug() << "CHANGED" << typelist;
|
||||
foreach(db_base *model, models)
|
||||
model->reloadContainer(typelist);
|
||||
}
|
||||
DbTransaction::DatabaseStamp = stamp;
|
||||
}
|
||||
|
||||
void MainWindow::dump_database()
|
||||
{
|
||||
QString dirname = QFileDialog::getExistingDirectory(
|
||||
@ -464,6 +499,7 @@ void MainWindow::close_database()
|
||||
Settings.clear();
|
||||
return;
|
||||
}
|
||||
killTimer(dbTimer);
|
||||
qDebug("Closing database: %s", QString2filename(currentDB));
|
||||
Settings["mw_geometry"] = QString("%1,%2,%3")
|
||||
.arg(size().width())
|
||||
@ -480,16 +516,8 @@ void MainWindow::close_database()
|
||||
tempView->setModel();
|
||||
crlView->setModel();
|
||||
|
||||
if (crls)
|
||||
delete(crls);
|
||||
if (reqs)
|
||||
delete(reqs);
|
||||
if (certs)
|
||||
delete(certs);
|
||||
if (temps)
|
||||
delete(temps);
|
||||
if (keys)
|
||||
delete(keys);
|
||||
qDeleteAll(models.begin(), models.end());
|
||||
models.clear();
|
||||
|
||||
db_base::flushLookup();
|
||||
reqs = NULL;
|
||||
|
||||
@ -915,16 +915,13 @@ void MainWindow::generateDHparam()
|
||||
void MainWindow::changeEvent(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::LanguageChange) {
|
||||
QList<db_base*> models;
|
||||
retranslateUi(this);
|
||||
dn_translations_setup();
|
||||
init_menu();
|
||||
update_history_menu();
|
||||
models << keys << reqs << certs << crls << temps;
|
||||
foreach(db_base *model, models) {
|
||||
if (model)
|
||||
model->updateHeaders();
|
||||
}
|
||||
foreach(db_base *model, models)
|
||||
model->updateHeaders();
|
||||
|
||||
if (!currentDB.isEmpty())
|
||||
dbindex->setText(tr("Database") + ": " + currentDB);
|
||||
searchEdit->setPlaceholderText(tr("Search"));
|
||||
|
||||
@ -76,7 +76,7 @@ class MainWindow: public QMainWindow, public Ui::MainWindow
|
||||
void checkDB();
|
||||
QSqlError initSqlDB();
|
||||
QString openSqlDB(QString dbName);
|
||||
QTimer *eachSecond;
|
||||
QList<db_base*> models;
|
||||
|
||||
protected:
|
||||
void init_images();
|
||||
@ -87,6 +87,8 @@ class MainWindow: public QMainWindow, public Ui::MainWindow
|
||||
QString homedir;
|
||||
int changeDB(QString fname);
|
||||
void keyPressEvent(QKeyEvent *e);
|
||||
int dbTimer;
|
||||
void timerEvent(QTimerEvent *event);
|
||||
|
||||
public:
|
||||
static db_x509 *certs;
|
||||
|
||||
@ -210,7 +210,6 @@ void Options::on_searchPkcs11_clicked(void)
|
||||
|
||||
void Options::Pkcs11ItemChanged(QListWidgetItem *item)
|
||||
{
|
||||
TRACE
|
||||
pkcs11List->blockSignals(true);
|
||||
pkcs11_lib *l = pkcs11::get_libs().get_lib(item->text());
|
||||
qDebug() << item->text() << item->checkState() << l->isEnabled() << l->isLoaded();
|
||||
|
||||
@ -310,6 +310,12 @@
|
||||
<< "UPDATE settings SET value='6' WHERE key_='schema'"
|
||||
;
|
||||
|
||||
schemas[6]
|
||||
<< "ALTER TABLE items ADD del SMALLINT NOT NULL DEFAULT 0"
|
||||
<< "CREATE INDEX i_items_del ON items (del)"
|
||||
<< "UPDATE settings SET value='7' 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