L'article est consacré aux versions alternatives des pilotes Qt pour travailler avec les bases de données. Dans l'ensemble, il n'y a pas tant de différences par rapport aux pilotes Qt natifs, juste quelques-unes : 1) prise en charge du type UUID ; 2) Travailler avec l'entité "Transaction" comme avec un objet indépendant. Mais ces différences ont conduit à une révision significative de l'implémentation du code des solutions Qt originales et ont changé l'approche de l'écriture de code fonctionnel.
Clé primaire : UUID ou entier ?
J'ai d'abord pris connaissance de l'idée d'utiliser l'UUID comme clé primaire en 2003, alors que je travaillais dans une équipe de dolphistes. Nous avons développé un programme pour l'automatisation des processus technologiques en production. Le SGBD a joué un rôle important dans le projet. A cette époque, c'était FireBird version 1.5. Au fur et à mesure que le projet devenait plus complexe, il devenait difficile d'utiliser des identifiants entiers comme clés primaires. Je vais décrire quelques difficultés :
Un problème d'architecture : de temps en temps, les clients envoient des données de référence afin de les inclure dans une nouvelle version du kit de distribution. Parfois, les répertoires contenaient les clés primaires déjà présentes dans notre base de données. J'ai dû éliminer les collisions dans le processus d'agrégation des données. Les problèmes ne s'arrêtaient pas là : lors du déploiement d'un nouveau kit de distribution, des collisions inverses se produisaient périodiquement.
: SELECT-, ( ). . . , , 2003 , - - .
UUID- , . UUID- , , SELECT- , . FireBird 1.5 UUID-, 32 ( UUID- ). , .
UUID- : 1) ; 2) . , . , , UUID-.
: UUID vs Integer MS SQL " – GUID ?"
FireBird
2012 FireBird. . QtFramework. FireBird 2.5 UUID-. : " Qt- FireBird QUuid?" Qt- UUID-. , , .
""
Qt- FireBird 2018 . . - , , ́ . . FireBird, . PostgreSQL, .
. Qt-FireBird . , Qt-, , : ( ) ( "" Driver). Qt- . , , : ( - ). Oracle, PostgreSQL, MS SQL ODBC. FireBird , API . , Qt-FireBird .
(2-3) , . . . , : , , , , sql- , . , . " - ". sql- .
"", , , . , "" , . , "" , , . , COMMIT ROLLBACK. , . Qt-.
, . (Driver) . , , . .
Qt-, :
- : " ?! ' - ', !" , , , , "" ODBC . , - , .
void function3(int value3)
{
db::firebird::Driver::Ptr dbcon = fbpool().connect();
db::firebird::Transaction::Ptr transact3 = dbcon->createTransact();
QSqlQuery q3 {db::firebird::createResult(transact3)};
if (!transact3->begin())
return;
if (!q3.prepare("INSERT INTO TABLE3 (VALUE3) VALUES (:VALUE3)"))
return;
sql::bindValue(q3, ":VALUE3" , value3);
if (!q3.exec())
return;
transact3->commit();
}
void function2(int value2)
{
db::firebird::Driver::Ptr dbcon = fbpool().connect();
db::firebird::Transaction::Ptr transact2 = dbcon->createTransact();
QSqlQuery q2 {db::firebird::createResult(transact2)};
if (!transact2->begin())
return;
if (!q2.prepare("SELECT * FROM TABLE2 WHERE VALUE2 = :VALUE2"))
return;
sql::bindValue(q2, ":VALUE2 " , value2);
if (!q2.exec())
return;
while (q2.next())
{
qint32 value3;
sql::assignValue(value3, q2.record(), "VALUE3");
function3(value3);
}
}
void function1()
{
db::firebird::Driver::Ptr dbcon = db::firebird::pool().connect();
db::firebird::Transaction::Ptr transact1 = dbcon->createTransact();
QSqlQuery q1 {db::firebird::createResult(transact1)};
if (!transact1->begin())
return;
if (!sql::exec(q1, "SELECT * FROM TABLE1"))
return;
while (q1.next())
{
QSqlRecord r = q1.record();
QUuidEx id;
qint32 value1;
qint32 value2;
sql::assignValue(id , r, "ID ");
sql::assignValue(value1 , r, "VALUE1 ");
sql::assignValue(value2 , r, "VALUE2 ");
...
function2(value2);
}
}
(1-3) . . QSqlQuery. ROLLBACK- SELECT- COMMIT- .
sql-. .
void function3(db::firebird::Transaction::Ptr transact, int value3)
{
QSqlQuery q3 {db::firebird::createResult(transact)};
// -
}
void function2(db::firebird::Transaction::Ptr transact, int value2)
{
QSqlQuery q2 {db::firebird::createResult(transact)};
// -
function3(transact, value3);
}
void function1()
{
db::firebird::Driver::Ptr dbcon = db::firebird::pool().connect();
db::firebird::Transaction::Ptr transact = dbcon->createTransact();
QSqlQuery q1 {db::firebird::createResult(transact)};
if (!transact->begin())
return;
while (q1.next())
{
// -
function2(transact, value2);
}
transact->commit();
}
PostgreSQL
2020 . : PostgreSQL. 18- , . PostgreSQL FireBird. Qt, , . Qt- : PREPARE EXECUTE. , , . , " ", PostgreSQL API. libpqxx , . " ". , . , . , , PostgreSQL . , . . singleConnect()
, . . singleConnect()
FALSE
. , . . , . .
MS SQL
MS SQL. , . MS SQL ODBC. PostgreSQL: - . , OLE DB MS SQL , ODBC . , "" . , NULL-. , .
Driver
Qt-. :
beginTransaction();
commitTransaction();
rollbackTransaction().
"" Qt-.
, , , . :
tables();
record();
primaryIndex();
formatValue();
escapeIdentifier().
. , , . , , .
, : "Forward Only". , , . , , SqlCachedResult
. - Qt-.
Driver
abortOperation()
, sql-, "" . Result
size2()
, sql-. size2()
, resultSize(const QSqlQuery&)
. .
GPL/LGPL 2.1. SqlCachedResult
, Qt . . PostgreSQL, , ( ). , : LGPL. , .
-
. : FireBird, PostgreSQL, MS SQL. , . SharedTools .
QtCreator, QBS. :
db_demo_project.qbs - ( 2-4);
db_demo_firebird.qbs - FireBird ( FireBird-);
db_demo_postgres.qbs - PostgreSQL ( libpq-dev);
db_demo_mssql.qbs - MS SQL.
Linux, . Windows FireBird- (), .
- :
/tmp/db-demo-firebird.log
/tmp/db-demo-mssql.log
/tmp/db-demo-postgres.log
, . , - .
, , , : ", , . ?!" , !
Une grande partie de mon travail et du travail de mes collègues a été investi dans la création de pilotes, beaucoup de vie a été dépensée. Connaissant l'aversion des programmeurs pour les dépendances externes, je n'ai aucune illusion que les solutions présentées seront utilisées "telles quelles". J'admets que quelqu'un décide de "brûler avec un fer chaud" ALog et de le remplacer par quelque chose qui lui est propre - cela ne me dérange pas (je le fais moi-même avec d'autres enregistreurs ;) En tout cas, si nos solutions font gagner du temps à quelqu'un, ou servir de point de départ à de nouvelles idées - ce sera bien !