• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            戰(zhàn)魂小筑

            討論群:309800774 知乎關(guān)注:http://zhihu.com/people/sunicdavy 開(kāi)源項(xiàng)目:https://github.com/davyxu

               :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
              257 隨筆 :: 0 文章 :: 506 評(píng)論 :: 0 Trackbacks

            protobuf反射代碼借鑒自陳碩的blog一種自動(dòng)反射消息類(lèi)型的 Google Protobuf 網(wǎng)絡(luò)傳輸方案  在此表示感謝

            這里是proto文件

            message QueryAccount
            {    
                // in
                required string SQL = 1;
                
                // out
                optional int64 id = 2;
            }
             
            C++實(shí)現(xiàn)
               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類(lèi)型
              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:                  // 設(shè)置消息
              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:      // 轉(zhuǎn)載請(qǐng)注明來(lái)自 戰(zhàn)魂小筑http://www.shnenglu.com/sunicdavy
              45:      using namespace google::protobuf;
              46:   
              47:      Message* Msg = NULL;
              48:   
              49:      // 通過(guò)類(lèi)型字符串查出消息類(lèi)型信息
              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:      // 解析數(shù)據(jù)
              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:      // 進(jìn)行SQL查詢(xún)
              74:      mysqlpp::Query query = SQLConnection.query( SQLCmd.c_str() );
              75:   
              76:      // 確認(rèn)查詢(xún)有效
              77:      mysqlpp::StoreQueryResult res = query.store();
              78:   
              79:      if (!res)
              80:          return;
              81:   
              82:      // 這里只取第一個(gè)消息
              83:      mysqlpp::Row RowData = *res.begin();
              84:   
              85:      // 反射填充消息
              86:      ReflectionFill( Msg, MsgDescriptor, RowData );
              87:   
              88:      // 測(cè)試返回?cái)?shù)據(jù)
              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:  }
            posted on 2011-12-14 17:48 戰(zhàn)魂小筑 閱讀(4875) 評(píng)論(3)  編輯 收藏 引用 所屬分類(lèi): 網(wǎng)絡(luò) 服務(wù)器技術(shù)

            評(píng)論

            # re: ProtocolBuffer + MySQL++實(shí)現(xiàn)消息反射查詢(xún)返回?cái)?shù)據(jù) 2012-03-15 21:56 aya
            sql語(yǔ)句+protobuf入?yún)⒌男问剑€是不夠通用啊。
            存儲(chǔ)過(guò)程+protobuf入?yún)?protobuf出參封裝成一個(gè)數(shù)據(jù)庫(kù)邏輯層,底層用odbc,mysql之類(lèi)的api, 上層用lua寫(xiě)邏輯,可以寫(xiě)個(gè)自動(dòng)映射的數(shù)據(jù)庫(kù)的服務(wù)器就好了。  回復(fù)  更多評(píng)論
              

            # re: ProtocolBuffer + MySQL++實(shí)現(xiàn)消息反射查詢(xún)返回?cái)?shù)據(jù) 2012-04-27 17:50 YU_YU
            這里也有一篇和你一樣精神的文章 http://geek.renren.com/?p=71
            其實(shí),最好就是連proto文件都不需要,有好多數(shù)據(jù)庫(kù)查詢(xún)都是聯(lián)合語(yǔ)句,很復(fù)雜,不可能把所有的proto都定義出來(lái)  回復(fù)  更多評(píng)論
              

            # re: ProtocolBuffer + MySQL++實(shí)現(xiàn)消息反射查詢(xún)返回?cái)?shù)據(jù) 2012-05-12 10:24 戰(zhàn)魂小筑
            @YU_YU
            感謝分享.
            這套機(jī)制與我們項(xiàng)目使用的技術(shù)類(lèi)似.   回復(fù)  更多評(píng)論
              

            一本久久久久久久| 亚洲国产精品成人AV无码久久综合影院| 久久www免费人成看国产片| 久久久久国色AV免费看图片| 思思久久99热免费精品6| 中文字幕无码精品亚洲资源网久久| 综合久久国产九一剧情麻豆| 国产精品久久毛片完整版| 午夜视频久久久久一区 | 亚洲精品视频久久久| 久久亚洲私人国产精品| 精品久久人人妻人人做精品| 欧美精品乱码99久久蜜桃| 国产精品无码久久四虎| 国内精品人妻无码久久久影院导航| A狠狠久久蜜臀婷色中文网| 国产伊人久久| 久久精品国产亚洲AV麻豆网站| 国产伊人久久| 香港aa三级久久三级| 久久夜色精品国产噜噜亚洲AV| 青青青青久久精品国产h久久精品五福影院1421 | 国产A级毛片久久久精品毛片| 777午夜精品久久av蜜臀| 久久97久久97精品免视看| 国产99精品久久| 亚洲人成网亚洲欧洲无码久久 | 久久久久无码精品国产| 无码8090精品久久一区| 国产精品日韩欧美久久综合| 成人资源影音先锋久久资源网| 亚洲日韩欧美一区久久久久我| 国产AV影片久久久久久| 国产精品美女久久久久AV福利| 久久福利青草精品资源站免费| 精品国产VA久久久久久久冰| 久久人人妻人人爽人人爽| 婷婷久久香蕉五月综合加勒比| 7777久久久国产精品消防器材| 狠狠色综合网站久久久久久久高清| 亚洲午夜久久久久妓女影院|