diff --git a/Makefile b/Makefile index 4f381fa4..58a8e775 100644 --- a/Makefile +++ b/Makefile @@ -162,7 +162,7 @@ xca-portable-$(VERSION): xca$(SUFFIX).signed do.doc do.lang do.misc $(patsubst %,"$(QTDIR)/translations/qt_%.qm", de es pl pt ru fr sk it ja) \ "$(TOPDIR)"/COPYRIGHT "${TOPDIR}/../sql/"*.dll $@ cp "$(QTDIR)/plugins/platforms/qwindows.dll" $@/platforms - cp $(patsubst %,"$(QTDIR)/plugins/sqldrivers/%.dll", qsqlite qsqlmysql qsqlpsql) $@/sqldrivers + cp $(patsubst %,"$(QTDIR)/plugins/sqldrivers/%.dll", qsqlite qsqlmysql qsqlpsql qsqlodbc) $@/sqldrivers xca-portable.zip: xca-portable-$(VERSION).zip diff --git a/lib/pki_key.cpp b/lib/pki_key.cpp index 1bdc147f..3ae1a5e9 100644 --- a/lib/pki_key.cpp +++ b/lib/pki_key.cpp @@ -487,7 +487,7 @@ QSqlError pki_key::insertSqlData() } q.finish(); - SQL_PREPARE(q, "INSERT INTO public_keys (item, type, hash, len, public) " + SQL_PREPARE(q, "INSERT INTO public_keys (item, type, hash, len, \"public\") " "VALUES (?, ?, ?, ?, ?)"); q.bindValue(0, sqlItemId); q.bindValue(1, getKeyTypeString()); diff --git a/ui/OpenDb.ui b/ui/OpenDb.ui index d509d2ee..354f24d4 100644 --- a/ui/OpenDb.ui +++ b/ui/OpenDb.ui @@ -137,7 +137,7 @@ - + Database name diff --git a/widgets/MW_database.cpp b/widgets/MW_database.cpp index b4c082c9..b3f27a5e 100644 --- a/widgets/MW_database.cpp +++ b/widgets/MW_database.cpp @@ -25,14 +25,17 @@ QSqlError MainWindow::initSqlDB() { - QStringList schemas[7]; +#define MAX_SCHEMAS 7 +#define SCHEMA_VERSION "7" + + QStringList schemas[MAX_SCHEMAS]; #include "database_schema.cpp" XSqlQuery q; QSqlDatabase db = QSqlDatabase::database(); QStringList tables; - unsigned int i; + if (!db.isOpen()) return QSqlError(); @@ -40,7 +43,10 @@ QSqlError MainWindow::initSqlDB() if (!TransBegin()) return db.lastError(); - for (i = XSqlQuery::schemaVersion(); i < ARRAY_SIZE(schemas); i++) { + for (;;) { + unsigned int i = XSqlQuery::schemaVersion(); + if (i >= ARRAY_SIZE(schemas)) + break; foreach(QString sql, schemas[i]) { qDebug("EXEC[%d]: '%s'", i, CCHAR(sql)); if (!q.exec(sql) || q.lastError().isValid()) { @@ -49,6 +55,7 @@ QSqlError MainWindow::initSqlDB() } } } + TransCommit(); return QSqlError(); } diff --git a/widgets/OpenDb.cpp b/widgets/OpenDb.cpp index dff59ec0..fe3b6fb6 100644 --- a/widgets/OpenDb.cpp +++ b/widgets/OpenDb.cpp @@ -27,7 +27,7 @@ DbMap OpenDb::getDatabases() databases["QPSQL7"] = "PostgreSQL"; databases["QMYSQL3"] = "MySQL / MariaDB"; - //databases["QODBC3"] = "Open Database Connectivity (ODBC)"; + databases["QODBC3"] = "Open Database Connectivity (ODBC)"; foreach (QString driver, databases.keys()) { if (!list.contains(driver)) @@ -50,6 +50,14 @@ bool OpenDb::hasRemoteDrivers() return getDatabases().size() > 0; } +void OpenDb::driver_selected() +{ + if (getDbType() == "QODBC3") + dbName_label->setText("DSN"); + else + dbName_label->setText(tr("Database name")); +} + DbMap OpenDb::splitRemoteDbName(QString db) { static const char * const names[NUM_PARAM] = @@ -125,13 +133,13 @@ OpenDb::OpenDb(QWidget *parent, QString db) sqlite = false; show_connection_settings = true; } + driver_selected(); + connect(dbType, SIGNAL(currentIndexChanged(int)), + this, SLOT(driver_selected())); } QString OpenDb::getDbType() const { - qDebug() << "OpenDb::getDbType: " - << dbType->itemData(dbType->currentIndex()).toString(); - return sqlite ? hasSqLite() ? QString("QSQLITE") : QString("") : dbType->itemData(dbType->currentIndex()).toString(); } @@ -219,6 +227,10 @@ bool OpenDb::_openDatabase(QString connName, QString pass) const if (!hasTrans) { XCA_WARN(tr("The database driver does not support transactions. This may happen if the client and server have different versions. Continue with care.")); } + /* This is MySQL specific. Execute it always, because + * dbType() could return "ODBC" but connect to MariaDB + */ + XSqlQuery q("SET SESSION SQL_MODE='ANSI'"); return true; } XSqlQuery::clearTablePrefix(); diff --git a/widgets/OpenDb.h b/widgets/OpenDb.h index a41653b3..d936f3e0 100644 --- a/widgets/OpenDb.h +++ b/widgets/OpenDb.h @@ -39,6 +39,7 @@ class OpenDb: public QDialog, public Ui::OpenDb public slots: int exec(); + void driver_selected(); }; #endif diff --git a/widgets/database_schema.cpp b/widgets/database_schema.cpp index 48b0be75..9f46498d 100644 --- a/widgets/database_schema.cpp +++ b/widgets/database_schema.cpp @@ -4,10 +4,10 @@ * Collisions are of course possible. * * All binaries are stored Base64 encoded in a column of type - * " B64_BLOB " It is defined here as "VARCHAR(10000)" + * " B64_BLOB " It is defined here as "VARCHAR(8000)" */ -#define B64_BLOB "VARCHAR(10000)" +#define B64_BLOB "VARCHAR(8000)" /* * The B64(DER(something)) function means DER encode something @@ -30,8 +30,8 @@ << "CREATE TABLE settings (" "key_ CHAR(20) UNIQUE, " /* mySql does not like "key" or "option" */ - "value VARCHAR(1024))" -<< "INSERT INTO settings (key_, value) VALUES ('schema', '1')" + "value " B64_BLOB ")" +<< "INSERT INTO settings (key_, value) VALUES ('schema', '" SCHEMA_VERSION "')" /* * All items (keys, tokens, requests, certs, crls, templates) @@ -45,7 +45,9 @@ "type INTEGER, " /* enum pki_type */ "source INTEGER, " /* enum pki_source */ "date " DB_DATE ", " /* Time of insertion (creation/import) */ - "comment VARCHAR(2048))" + "comment VARCHAR(2048), " + "stamp INTEGER NOT NULL DEFAULT 0, " /* indicate concurrent access */ + "del SMALLINT NOT NULL DEFAULT 0)" /* * Storage of public keys. Private keys and tokens also store @@ -56,7 +58,7 @@ "type CHAR(4), " /* RSA DSA EC (as text) */ "hash INTEGER, " /* 32 bit hash */ "len INTEGER, " /* key size in bits */ - "public " B64_BLOB ", " /* B64(DER(public key)) */ + "\"public\" " B64_BLOB ", " /* B64(DER(public key)) */ "FOREIGN KEY (item) REFERENCES items (id))" /* @@ -185,15 +187,11 @@ "template " B64_BLOB ", " /* The base64 encoded template */ "FOREIGN KEY (item) REFERENCES items (id))" - ; -/* Schema Version 2: Views added to quickly load the data */ - schemas[1] - /* Views */ << "CREATE VIEW view_public_keys AS SELECT " "items.id, items.name, items.type AS item_type, items.date, " "items.source, items.comment, " - "public_keys.type as key_type, public_keys.len, public_keys.public, " + "public_keys.type as key_type, public_keys.len, public_keys.\"public\", " "private_keys.ownPass, " "tokens.card_manufacturer, tokens.card_serial, tokens.card_model, " "tokens.card_label, tokens.slot_label, tokens.object_id " @@ -236,12 +234,10 @@ "templates.version, templates.template " "FROM templates LEFT JOIN items ON templates.item = items.id" +<< "CREATE VIEW view_private AS SELECT " + "name, private FROM private_keys JOIN items ON " + "items.id = private_keys.item" -<< "UPDATE settings SET value='2' WHERE key_='schema'" - - ; -/* Schema Version 3: Add indexes over hashes and primary, foreign keys */ - schemas[2] << "CREATE INDEX i_settings_key_ ON settings (key_)" << "CREATE INDEX i_items_id ON items (id)" @@ -269,9 +265,14 @@ << "CREATE INDEX i_crls_issuer ON crls (issuer)" << "CREATE INDEX i_revocations_caId_serial ON revocations (caId, serial)" << "CREATE INDEX i_templates_item ON templates (item)" -<< "UPDATE settings SET value='3' WHERE key_='schema'" +<< "CREATE INDEX i_items_stamp ON items (stamp)" ; + +/* Schema Version 2: Views added to quickly load the data */ + +/* Schema Version 3: Add indexes over hashes and primary, foreign keys */ + /* Schema Version 4: Add private key view to extract a private key with: mysql: mysql -sNp -u xca xca_msq -e or sqlite: sqlite3 ~/sqlxdb.xdb @@ -281,21 +282,8 @@ * First mysql/psql will ask for a password and then OpenSSL will ask for * the database password. */ - schemas[3] -<< "CREATE VIEW view_private AS SELECT " - "name, private FROM private_keys JOIN items ON " - "items.id = private_keys.item" -<< "UPDATE settings SET value='4' WHERE key_='schema'" - ; - - schemas[4] -<< "ALTER TABLE items ADD stamp INTEGER NOT NULL DEFAULT 0" -<< "CREATE INDEX i_items_stamp ON items (stamp)" -<< "UPDATE settings SET value='5' WHERE key_='schema'" - ; - -/* Extend settings value size from 1024 to B64_BLOB +/* Schema Version 5: Extend settings value size from 1024 to B64_BLOB * SQLite does not support "ALTER TABLE settings MODIFY ..." */ schemas[5]