vendredi 6 mars 2009

Un binder en C++ pour libpqxx

Une fois de trop, je me suis retrouvé à écrire un horrible bout de code spécifique pour extraire mes données de ma belle base postgresql. Quand j'ai l'impression d'écrire plusieurs fois la même chose, j'essaie d'en faire un utilitaire. J'ai donc commencé à balancer quelques templates pour faire le gros du boulot pour moi, et voilà ce que ça donne, le tout tenant dans un petit en-tête (si vous voulez l'utiliser, n'oubliez pas d'ajouter les #include pour libpqxx et boost::optional, et probablement de virer mon support pour les StrongId).

L'utilisation du bazar est fort simple. Tout d'abord, définir une classe qui contiendra les données de la base, et qui possède une méthode statique qui passe les champs au binder, dans l'ordre de la requête:


struct PropertyListBinder
{
PropertyListId m_listId;
std::string m_key;
std::string m_valueType;
std::string m_accessType;
boost::optional m_intValue;
boost::optional m_doubleValue;
boost::optional m_stringValue;

static void bind(DbBinder & binder)
{
binder.bind(&PropertyListBinder::m_listId);
binder.bind(&PropertyListBinder::m_key);
binder.bind(&PropertyListBinder::m_valueType);
binder.bind(&PropertyListBinder::m_accessType);
binder.bind(&PropertyListBinder::m_intValue);
binder.bind(&PropertyListBinder::m_doubleValue);
binder.bind(&PropertyListBinder::m_stringValue);
}
};


L'on peut passer directement les boost::optional, qui seront interprétés comme des champs pouvant être nuls. Une valeur nulle sur un champ non optionnel lèvera une exception.

Pour l'appel, l'on créé un binder, un vecteur de notre structure qui contiendra les données, et l'on combine tout ça avec un résultat de libpqxx.


pqxx::result result = ...

DbBinder binder;

std::vector propertyListBinders;
binder.extract(propertyListBinders, result);


Le vecteur est rempli! C'est quand même plus facile que de se trimballer avec les appels à as et les is_null, non?

Aucun commentaire: