Para aquellos familiarizados con Oracle Template Library (OTL), impulsar :: cualquiera y Loki biblioteca (el descrito en Modern C Diseño ++) aquí está la prueba de concepto de código TMP que le permite almacenar una fila de otl_stream en vector<boost::any>
contenedor y acceder a los datos por número de columna. Y 'Sí', voy a incorporarlo en el código de producción.
#include <iostream>
#include <vector>
#include <string>
#include <Loki/Typelist.h>
#include <Loki/TypeTraits.h>
#include <Loki/TypeManip.h>
#include <boost/any.hpp>
#define OTL_ORA10G_R2
#define OTL_ORA_UTF8
#include <otlv4.h>
using namespace Loki;
/* Auxiliary structs */
template <int T1, int T2>
struct IsIntTemplateEqualsTo{
static const int value = (T1 == T2);
};
template <int T1>
struct ZeroIntTemplateWorkaround{
static const int value = (0 == T1? 1 : T1);
};
/* Wrapper class for data row */
template <class TList>
class T_DataRow;
template <>
class T_DataRow<NullType>{
protected:
std::vector<boost::any> _data;
public:
void Populate(otl_stream&){};
};
/* Note the inheritance trick that enables to traverse Typelist */
template <class T, class U>
class T_DataRow< Typelist<T, U> >:public T_DataRow<U>{
public:
void Populate(otl_stream& aInputStream){
T value;
aInputStream >> value;
boost::any anyValue = value;
_data.push_back(anyValue);
T_DataRow<U>::Populate(aInputStream);
}
template <int TIdx>
/* return type */
Select<
IsIntTemplateEqualsTo<TIdx, 0>::value,
typename T,
typename TL::TypeAt<
U,
ZeroIntTemplateWorkaround<TIdx>::value - 1
>::Result
>::Result
/* sig */
GetValue(){
/* body */
return boost::any_cast<
Select<
IsIntTemplateEqualsTo<TIdx, 0>::value,
typename T,
typename TL::TypeAt<
U,
ZeroIntTemplateWorkaround<TIdx>::value - 1
>::Result
>::Result
>(_data[ TIdx ]);
}
};
int main(int argc, char* argv[])
{
db.rlogon("AMONRAWMS/[email protected]"); // connect to Oracle
std::cout<<"Connected to oracle DB"<<std::endl;
otl_stream o(1, "select * from blockstatuslist", db);
T_DataRow< TYPELIST_3(int, int, std::string)> c;
c.Populate(o);
typedef enum{ rcnum, id, name } e_fields;
/* After declaring enum you can actually acess columns by name */
std::cout << c.GetValue<rcnum>() << std::endl;
std::cout << c.GetValue<id>() << std::endl;
std::cout << c.GetValue<name>() << std::endl;
return 0;
};
Para aquellos que no estén familiarizados con las bibliotecas mencionadas.
El problema con containter otl_stream de comunicación cara a cara es que se puede acceder a las columnas de datos sólo en orden secuencial al declarar variables de tipo adecuado y la aplicación de la operator >>
a otl_stream objeto de la siguiente manera:
otl_stream o(1, "select * from blockstatuslist", db);
int rcnum;
int id;
std::string name;
o >> rcnum >> id >> name;
No siempre es conveniente . La solución consiste en escribir una clase contenedora y completarla con datos de otl_stream. El deseo es ser capaz de declarar la lista de tipos de columna y, a continuación:
- tomar el tipo T de la columna
- declaran variable de ese tipo
- aplican
olt_stream::operator >>(T&)
- tienda el resultado (en el vector de impulso :: hubiera)
- tomar el tipo de la columna siguiente y repetir hasta las todas las columnas se procesan
se puede hacer al Esto con la ayuda de la estructura Typelist
de Loki, la especialización de plantillas y la herencia.
Con la ayuda de las construcciones de biblioteca de Loki, también puede generar un montón de funciones de GetValue que devuelven valores del tipo apropiado deduciéndolo del número de columna (en realidad, número de tipo en Typelist
).
Prefiero mantener un analizador, personalmente, que mantener las plantillas anidadas de C++. –
No necesita un analizador. Use el sistema de meta-programación JetBrains. Puede definir un idioma, un editor y un generador de código. No necesita un analizador en absoluto porque está editando el árbol de sintaxis directamente. Y no es un anuncio, este programa es FOSS. – naeron84