Bonjour,
QxOrm est une nouvelle librairie C++ open source de gestion de données :
[ Lien ]
A partir d'une simple
fonction de paramétrage (que l'on peut comparer 'modestement' avec un fichier de mapping xml Hibernate), vous aurez accès aux fonctionnalités suivantes :
*
Persistance (ORM) : communication avec de nombreuses bases de données (avec support des relations 1-1, 1-n, n-1 et n-n)
*
Serialization des données (flux binaire et xml)
*
Reflection pour accéder aux classes, attributs et invoquer des méthodes
QxOrm est dépendant des excellentes librairies
boost (compatible à partir de la version 1.38) et
Qt (compatible à partir de la version 4.5.0).
QxOrm a pour objectif de simplifier le code C++ tout en offrant un maximum de fonctionnalités.
Voici les principaux avantages de QxOrm :
*
non intrusif : la fonction de paramétrage se trouve à l'extérieur des classes. La signature des classes n'est donc pas modifiée. QxOrm peut donc être utilisé dans des projets existants
* aucune nécessité d'appartenir à une hiérarchie de classes : les classes n'ont pas besoin de dériver d'un 'super objet'
*
pas de génération automatique de code
*
pas de mapping xml
* 1 seul fichier <QxOrm.h> à inclure dans l'en-tête précompilé (precompiled-header nécessaire pour optimiser les temps de compilation)
* aucune nécessité d'utiliser le pré-compilateur 'moc' fourni par Qt
* vérification des types à la compilation (utilisation intensive de
méta-programmation)
* compatible avec
Visual C++ 2008 ou 2010 sous Windows et
GCC 4.4.1 sous Linux (d'autres environnements et plateformes seront testés prochainement : Mac, mobiles, etc...)
Un exemple rapide d'utilisation de QxOrm montrant les fonctionnalités de base de la librairie est disponible :
[ Lien ].
Un tutoriel plus complet montrant des fonctionnalités plus avancées de la librairie est également disponible à cette adresse :
[ Lien ].
Merci d'avance pour vos impressions, critiques, bugs détectés, évolutions souhaitées, etc...
QxOrm
_____________________________________________
Voici un exemple rapide d'utilisation de la librairie QxOrm :
* 1- fichier drug.h : définition d'une classe drug avec 3 attributs : id, name et description
* 2- fichier drug.cpp : implémentation de la 'fonction de paramétrage' : void qx::register_class()
* 3- fichier main.cpp : présentation des fonctionnalités de base de QxOrm avec la classe drug
* 4- exécution du programme de test et affichage des traces générées
* 5- contenu du fichier ./export_drugs.xml créé par le programme de test
* -----------------------------------------------------------------------------------------------------
* 1- fichier drug.h : définition d'une classe drug avec 3 attributs : id, name et description
* -----------------------------------------------------------------------------------------------------
Code C/C++ :
#ifndef _CLASS_DRUG_H_
#define _CLASS_DRUG_H_
class drug
{
public:
long id;
QString name;
QString description;
drug() : id(0) { ; }
virtual ~drug() { ; }
};
QX_REGISTER_HPP_MY_TEST_EXE(drug, qx::trait::no_base_class_defined, 1)
/* This macro is necessary to register 'drug' class in QxOrm context */
/* param 1 : the current class to register => 'drug' */
/* param 2 : the base class, if no base class, use the qx trait => 'qx::trait::no_base_class_defined' */
/* param 3 : the class version used by serialization to provide 'ascendant compatibility' */
#endif // _CLASS_DRUG_H_
* ----------------------------------------------------------------------------------------------------
* 2- fichier drug.cpp : implémentation de la 'fonction de paramétrage' : void qx::register_class()
* ----------------------------------------------------------------------------------------------------
Code C/C++ :
#include "precompiled.h" // Precompiled-header with '#include <QxOrm.h>' and '#include "export.h"'
#include "drug.h" // Class definition 'drug'
#include <QxMemLeak.h> // Automatic memory leak detection
QX_REGISTER_CPP_MY_TEST_EXE(drug) // This macro is necessary to register 'drug' class in QxOrm context
namespace qx {
template <> void register_class(QxClass<drug> & t)
{
t.id(& drug::id, "id"); // Register 'drug::id' <=> primary key in your database
t.data(& drug::name, "name", 1); // Register 'drug::name' property with key 'name' and version '1'
t.data(& drug::description, "desc"); // Register 'drug::description' property with key 'desc'
}}
* -----------------------------------------------------------------------------------------------
* 3- fichier main.cpp : présentation des fonctionnalités de base de QxOrm avec la classe drug
* -----------------------------------------------------------------------------------------------
Code C/C++ :
#include "precompiled.h"
#include "drug.h"
#include <QxMemLeak.h>
int main(int argc, char * argv[])
{
QApplication app(argc, argv); // Qt application
// Create 3 new drugs
// It is possible to use 'boost' and 'Qt' smart pointer : 'boost::shared_ptr', 'QSharedPointer', etc...
typedef boost::shared_ptr<drug> drug_ptr;
drug_ptr d1; d1.reset(new drug()); d1->name = "name1"; d1->description = "desc1";
drug_ptr d2; d2.reset(new drug()); d2->name = "name2"; d2->description = "desc2";
drug_ptr d3; d3.reset(new drug()); d3->name = "name3"; d3->description = "desc3";
// Insert drugs into container
// It is possible to use a lot of containers from 'std', 'boost', 'Qt' and 'qx::QxCollection<Key, Value>'
typedef std::vector<drug_ptr> type_lst_drug;
type_lst_drug lst_drug;
lst_drug.push_back(d1);
lst_drug.push_back(d2);
lst_drug.push_back(d3);
// Init parameters to communicate with a database
qx::QxSqlDatabase::getSingleton()->setDriverName("QSQLITE");
qx::QxSqlDatabase::getSingleton()->setDatabaseName("./test_qxorm.db");
qx::QxSqlDatabase::getSingleton()->setHostName("localhost");
qx::QxSqlDatabase::getSingleton()->setUserName("root");
qx::QxSqlDatabase::getSingleton()->setPassword("");
// Create table 'drug' into database to store drugs
QSqlError daoError = qx::dao::create_table<drug>();
// Insert drugs from container to database
// 'id' property of 'd1', 'd2' and 'd3' are auto-updated
daoError = qx::dao::insert(lst_drug);
// Modify and update the second drug into database
d2->name = "name2 modified";
d2->description = "desc2 modified";
daoError = qx::dao::update(d2);
// Delete the first drug from database
daoError = qx::dao::delete_by_id(d1);
// Count drugs into database
long lDrugCount = qx::dao::count<drug>();
// Fetch drug with id '3' into a new variable
drug_ptr d_tmp; d_tmp.reset(new drug());
d_tmp->id = 3;
daoError = qx::dao::fetch_by_id(d_tmp);
// Export drugs from container to a file under xml format (serialization)
qx::serialization::xml::to_file(lst_drug, "./export_drugs.xml");
// Import drugs from xml file into a new container
type_lst_drug lst_drug_tmp;
qx::serialization::xml::from_file(lst_drug_tmp, "./export_drugs.xml");
// Clone a drug
drug_ptr d_clone = qx::clone(* d1);
// Create a new drug by class name (factory)
boost::any d_any = qx::create("drug");
// Insert drugs container into 'qx::cache'
qx::cache::set("drugs", lst_drug);
// Remove all elements from 'qx::cache'
qx::cache::clear();
// Create a dummy memory leak
drug * pDummy = new drug();
return 0;
}
* -------------------------------------------------------------------------
* 4- exécution du programme de test et affichage des traces générées
* -------------------------------------------------------------------------
Code :
[QxOrm] qx::QxSqlDatabase : create new database connection in thread '3616' with key '{d315250c-b5c9-46e0-9402-f800368a6673}'
[QxOrm] sql query (78 ms) : CREATE TABLE drug (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name TEXT, desc TEXT)
[QxOrm] sql query (63 ms) : INSERT INTO drug (name, desc) VALUES (:name, :desc)
[QxOrm] sql query (62 ms) : UPDATE drug SET id = :id, name = :name, desc = :desc WHERE id = :id_bis
[QxOrm] sql query (63 ms) : DELETE FROM drug WHERE id = :id
[QxOrm] sql query (0 ms) : SELECT COUNT(*) FROM drug
[QxOrm] sql query (0 ms) : SELECT drug.id AS drug_id_0, drug.name AS drug_name_0, drug.desc AS drug_desc_0 FROM drug WHERE drug_id_0 = :id
[QxOrm] Leaked object at 0xf52ad8 (size 16, src\main.cpp:74)
[QxOrm] **** 1 memory leaks found ****
* ------------------------------------------------------------------------------
* 5- contenu du fichier ./export_drugs.xml créé par le programme de test
* ------------------------------------------------------------------------------
Code XML :
<std.vector-boost.shared_ptr-drug-- class_id="0" tracking_level="0" version="0">
<count>3</count>
<item_version>1</item_version>
<item class_id="1" tracking_level="0" version="1">
<px class_id="2" tracking_level="1" version="1" object_id="_0">
<id>1</id>
<name class_id="3" tracking_level="0" version="0">name1</name>
<desc>desc1</desc>
</px>
</item>
<item>
<px class_id_reference="2" object_id="_1">
<id>2</id>
<name>name2 modified</name>
<desc>desc2 modified</desc>
</px>
</item>
<item>
<px class_id_reference="2" object_id="_2">
<id>3</id>
<name>name3</name>
<desc>desc3</desc>
</px>
</item>
</std.vector-boost.shared_ptr-drug-->