1: void ReflectionFill( google::protobuf::Message* Msg, const google::protobuf::Descriptor* MsgDescriptor, mysqlpp::Row& RowData )
2: {
3: using namespace google::protobuf;
4:
5: // 遍历所有消息成员
6: for ( size_t i = 0;i < MsgDescriptor->field_count();i++ )
7: {
8: const FieldDescriptor* EachField = MsgDescriptor->field( i );
9:
10: // 这里假定optinal的是返回值
11: if ( !EachField->is_optional() )
12: continue;
13:
14: // sql的列
15: std::string FieldName = EachField->name();
16:
17: // 返回的CPP类型
18: switch ( EachField->cpp_type() )
19: {
20: case FieldDescriptor::CPPTYPE_STRING:
21: {
22: std::string Result = RowData[FieldName.c_str()];
23: Msg->GetReflection()->SetString( Msg, EachField, Result );
24: }
25: break;
26: case FieldDescriptor::CPPTYPE_INT64:
27: {
28: // 从列取值
29: __int64 Result = RowData[FieldName.c_str()];
30:
31: // 设置消息
32: Msg->GetReflection()->SetInt64( Msg, EachField, Result );
33: }
34: break;
35: }
36:
37: }
38: }
39:
40:
41:
42: void ParseMessage( mysqlpp::Connection& SQLConnection, const char* ProtoType, void* Data, size_t Size )
43: {
44: // 转载请注明来自 战魂小筑http://www.cppblog.com/sunicdavy
45: using namespace google::protobuf;
46:
47: Message* Msg = NULL;
48:
49: // 通过类型字符串查出消息类型信息
50: const Descriptor* MsgDescriptor = DescriptorPool::generated_pool()->FindMessageTypeByName(ProtoType);
51: if (MsgDescriptor == NULL )
52: return;
53:
54: // 取消息原型
55: const Message* MsgPrototype = MessageFactory::generated_factory()->GetPrototype(MsgDescriptor);
56: if (MsgPrototype == NULL )
57: return;
58:
59: // 不能用原型消息哦,要新的
60: Msg = MsgPrototype->New();
61:
62: // 解析数据
63: Msg->ParseFromArray( Data, Size );
64:
65: // 查找SQL指令
66: const FieldDescriptor* SQLField = MsgDescriptor->FindFieldByName("SQL");
67: if ( SQLField == NULL )
68: return;
69:
70: // 使用反射查出值
71: std::string SQLCmd = Msg->GetReflection()->GetString( *Msg, SQLField );
72:
73: // 进行SQL查询
74: mysqlpp::Query query = SQLConnection.query( SQLCmd.c_str() );
75:
76: // 确认查询有效
77: mysqlpp::StoreQueryResult res = query.store();
78:
79: if (!res)
80: return;
81:
82: // 这里只取第一个消息
83: mysqlpp::Row RowData = *res.begin();
84:
85: // 反射填充消息
86: ReflectionFill( Msg, MsgDescriptor, RowData );
87:
88: // 测试返回数据
89: dbsvc::QueryAccount* qamsg = dynamic_cast<dbsvc::QueryAccount*>( Msg );
90: __int64 i = qamsg->id();
91:
92: delete Msg;
93: }
94:
95:
96: int main(int argc, char* argv[])
97: {
98: mysqlpp::Connection con(false);
99:
100: con.set_option(new mysqlpp::SetCharsetNameOption("gbk"));
101:
102:
103: if (!con.connect("testdb", "localhost", "root", "123"))
104: {
105: return -1;
106: }
107: else
108: {
109:
110: dbsvc::QueryAccount Msg;
111: Msg.set_sql("select id from account where username = 'hello'");
112: std::string s;
113: Msg.SerializeToString( &s );
114:
115: ParseMessage( con, "dbsvc.QueryAccount", (void*)s.data(), s.size() );
116: }
117:
118: google::protobuf::ShutdownProtobufLibrary();
119: }