Đối với những người quen thuộc với Thư viện Oracle Template (OTL), đẩy mạnh :: bất kỳ và Loki thư viện (một trong những mô tả trong Modern C++ Thiết kế) đây là bằng chứng của khái niệm đang TMP cho phép bạn lưu trữ một dãy otl_stream trong vector<boost::any>
chứa và truy cập dữ liệu theo số cột. Và 'Có', tôi sẽ kết hợp nó trong mã sản xuất.
#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;
};
Đối với những người không quen thuộc với các thư viện được đề cập.
Vấn đề với containter otl_stream OTL là rằng người ta có thể truy cập vào các cột dữ liệu chỉ trong thứ tự tuần tự bằng cách tuyên bố biến của loại thích hợp và áp dụng các operator >>
để otl_stream đối tượng theo cách sau:
otl_stream o(1, "select * from blockstatuslist", db);
int rcnum;
int id;
std::string name;
o >> rcnum >> id >> name;
Nó không phải lúc nào cũng thuận . Cách giải quyết là viết một số lớp bao bọc và điền nó với dữ liệu từ otl_stream. Mong muốn là để có thể khai báo danh sách các loại cột và sau đó:
- có loại T của cột
- khai báo biến kiểu đó
- áp dụng
olt_stream::operator >>(T&)
- cửa hàng kết quả (trong vector của boost :: có)
- có loại của cột tiếp theo và lặp lại cho đến khi tất cả các cột được xử lý
Bạn có thể làm al l này với sự giúp đỡ của Loki Typelist
cấu trúc, mẫu chuyên môn và kế thừa.
Với sự trợ giúp của cấu trúc thư viện của Loki, bạn cũng có thể tạo ra các hàm GetValue trả về các giá trị của loại thích hợp suy ra từ số cột (thực tế là số kiểu trong Typelist
).
Tôi muốn duy trì một trình phân tích cú pháp, cá nhân hơn là duy trì các mẫu C++ lồng nhau. –
Bạn không cần một trình phân tích cú pháp. Sử dụng JetBrains Meta Programming System. Bạn có thể định nghĩa một ngôn ngữ, một trình soạn thảo và trình tạo mã. Bạn không cần một trình phân tích cú pháp nào cả bởi vì bạn đang chỉnh sửa trực tiếp cây cú pháp. Và nó không phải là một quảng cáo, chương trình này là FOSS. – naeron84