关闭

dxi_hrwj实现代码

543人阅读 评论(0) 收藏 举报


/************************************************
 * Author: liujg
 * Date: 2012.3.28
 ************************************************/
#pragma once

#include "CQQBase.h"
#include "i_dd.h"
#include "TableRelation.h"
#include "DBSchema.h"


#define BUID_FILED_NAME "BUID"
#define INNER_TABLE_FMT "[table%d]"

struct CTaskCfgItem;
struct stDataSource;
////////////////////////////////////////////////////////////////////////////////
namespace ns_dxi_hrwj {
    struct CTaskKey {
        string field_name_; ///< 字段名称
        string field_val_; ///< 字段值
    };

    struct CTask {
        string id_; ///< 任务号
        string dest_; ///< 目的地
        string src_; ///< 来源地
        string type_; ///< 任务类型
        int status_; ///< 任务状态(0表示未同步,100表示已同步,99表示同步失败)
        int tries_; ///< 任务尝试次数
        string touch_time_; ///< 任务变更时间
        string launch_time_; ///< 任务产生日期

        CAutoVector<CTaskKey*> keys_; ///< 任务主键
        struct stRowsetInfo {
            string tbl_name_;
            CRowset *rs_;
        };
        CAutoMap<string,stRowsetInfo*> rss_; ///< 处理过程中记录表和CRowset的对应关系
        vector<string> delete_cmd_; ///< 删除原来数据的命令

        stDataSource *ds_;
        CTaskCfgItem *task_define_;

        int Run(); ///< 执行任务

        CTask():task_define_(0) {
        }
        ~CTask() {
        }

        int GenKeyCond(const char *tbl_name,string &cond); ///< 根据任务主键生成条件表达式
        int HandleTable(CTableRelationNode *node,CMsg *msg); ///< 处理指定节点的表(提取数据)

        CMsg* GetData(); ///< 提取数据生成UMX消息包
        int SyncData(CMsg *msg); ///< 同步数据到中间库

        int HandleDetail(CTableRelationNode *parent,CRecordset *prs,CMsg *msg);
    };

    struct CField {
        string name_;
        short type_;            ///< 字段类型 ///< 1-整数 2-带小数数值 5-字符串 9-日期 10-时间  11-日期时间

        bool flag_;                ///< 是否是抽取字段
        CField():type_(0),flag_(true) {
        }
    };
    struct CTable {
        string name_;
        CAutoVector<CField*> fields_;

        string fld_list_;
        string select_cmd_; ///< 查询命令模板
        string delete_cmd_; ///< 删除命令模板
    };
};

////////////////////////////////////////////////////////////////////////////////
struct CTaskCfgItem {
    string task_id_; ///< 任务类型
    CQQ_BILLTYPE sheet_type_; ///< 对应tb_change_log的单据类型

    CAutoVector<ns_dxi_hrwj::CTable*> tables_; ///< 表信息
    CTableRelationNode *relation_; ///< 表关系
    
    CTaskCfgItem():relation_(0),sheet_type_(0) {
    }
    ~CTaskCfgItem() {
    }

    ns_dxi_hrwj::CTable* find_table(const char *tbl_name); ///< 根据表名查表对象
};

////////////////////////////////////////////////////////////////////////////////
/// 数据源信息
struct stDataSource {
    string dbc_name_; ///< 数据库连接名
    map<string,stTableInfo*> tables_; ///< 数据库表元数据(保留)
    
    int buid_; ///< BUID
};
////////////////////////////////////////////////////////////////////////////////
class CDxiHRWJ
: public CQQBasePlugin
{
    typedef CQQBasePlugin parent;
    friend class ns_dxi_hrwj::CTask;
    friend ACE_THR_FUNC_RETURN TaskHandleProc(void *arg);

    static CDxiHRWJ* instance_;
    static MSG_FUNC_MAP func_[];    

    CAutoVector<stDataSource*> vss_db_;///< VSS源数据库(支持多个源)
    string schema_name_; ///< 模式名
    string tmp_vss_db_; ///< 保存同步数据的中间数据库
    short task_scan_interval_; ///< 任务记录表扫描间隔(单位:秒)
    map<string,CTaskCfgItem*> task_data_type_map_;  ///< 任务类型和数据类型映射关系

    ///< @note 目前假设所有源都是相同的数据库平台,否则每个数据源都有一套抽取源表的元数据。
    ///< 并且都与中间库相同
    map<string,stTableInfo*> tmp_vss_table_; ///< 中间库需要导入表的信息

    IDd *idd_;

    stTableInfo* FindTable(const char *tbl_name);
protected:
    CDxiHRWJ(void);
public:
    ~CDxiHRWJ(void);

    static CDxiHRWJ* instance() {
        if (instance_==0)
            instance_ = new CDxiHRWJ;
        return (CDxiHRWJ*)instance_;
    }    
protected:
    int ReadPrivateConfig();
    int Initialize();
    int Prepare();
    int CheckValid();
    int Activate();
    int OnActivate();
    int Deactivate();
    int Release();    

private:
    int HandleTask(stDataSource *ds); ///< 处理任务记录
};

int RecordToRowset(CRecordset *prs,CRowset *rs);
int RecordFieldToRowset(CRecordset *prs,CRowset *rs);
////////////////////////////////////////////////////////////////////////////////

/************************************************
 * Author: liujg
 * Date: 2012.3.28
 ************************************************/

#include "dxi_hrwj.h"
#include "stdtime.h"
#include "RecordsetBinder.h"
#include "DBhandle.h"
#include "stddb.h"
#include "ParamStrParser.h"


#ifdef _DEBUG
#pragma comment(lib,"xerces-c_2d.lib")
#pragma comment(lib,"aced.lib")
#else
#pragma comment(lib,"xerces-c_2.lib")
#pragma comment(lib,"ace.lib")
#endif

#pragma comment(lib,"lssdk.lib")


using namespace ns_dxi_hrwj;
////////////////////////////////////////////////////////////////////////////////
CDxiHRWJ* CDxiHRWJ::instance_ = NULL;
MSG_FUNC_MAP CDxiHRWJ::func_[] = {
        {0,MT_REQUEST,(MSGFUNC)0,true,"",""}, ///< @TODO: 增加协议处理函数映射
};

////////////////////////////////////////////////////////////////////////////////
CPluginModule* __stdcall CreateModule() {
    return CDxiHRWJ::instance();
}

////////////////////////////////////////////////////////////////////////////////
CDxiHRWJ::CDxiHRWJ(void) {
    task_scan_interval_ = 30;

    AddFuncMap(func_,sizeof(func_)/sizeof(func_[0]));    
}

////////////////////////////////////////////////////////////////////////////////
CDxiHRWJ::~CDxiHRWJ(void)
{
}
////////////////////////////////////////////////////////////////////////////////
int CDxiHRWJ::ReadPrivateConfig() {
    parent::ReadPrivateConfig();

    if (config_->Open(cf_.c_str())) {
        nlogger_->log(LO_STDOUT|LO_FILE,SEVERITY_ERROR,"打开配置文件%s失败.\n",cf_.c_str());
        return -1;
    }
    INode *root = config_->GetChildNodes()->GetChildNodes("config")->GetChildNode(0);
    INode *node,*attr;

    node = root->GetChildNodes()->GetChildNodes("vss_db")->GetChildNode(0);
    if (node==0) {
        nlogger_->log(LO_STDOUT|LO_FILE,SEVERITY_ERROR,"%s未配置VSS数据库连接信息<vss_db>.\n",cf_.c_str());
        return -1;
    }
    
    INodeList *nl = node->GetChildNodes()->GetChildNodes("item");
    int ds_num = nl->Count();
    for (int i=0;i<ds_num;i++) {
        INode *subnode = nl->GetChildNode(i);
        INode *name = subnode->GetChildNodes()->GetChildNodes("name")->GetChildNode(0);
        INode *buid = subnode->GetChildNodes()->GetChildNodes("buid")->GetChildNode(0);
        stDataSource *ds = new stDataSource;
        ds->dbc_name_ = (string)*name;
        ds->buid_ = (int)*buid;
        const char *dbc_name = ds->dbc_name_.c_str();
        if (!svr_info_->IsValidDBC(dbc_name)) {
            nlogger_->log(LO_STDOUT|LO_FILE,SEVERITY_ERROR,"%s配置VSS数据库连接名<vss_db>%s无效,请检查hotfox配置.\n",cf_.c_str(),dbc_name);
            return -1;
        }
        vss_db_.push_back(ds);
    }

    node = root->GetChildNodes()->GetChildNodes("schema_name")->GetChildNode(0);
    if (node) {
        schema_name_ = (string)*node;
    }

    node = root->GetChildNodes()->GetChildNodes("tmp_vss_db")->GetChildNode(0);
    if (node==0) {
        nlogger_->log(LO_STDOUT|LO_FILE,SEVERITY_ERROR,"%s未配置中间库连接名<tmp_vss_db>.\n",cf_.c_str());
        return -1;
    }
    tmp_vss_db_ = (string)*node;
    if (!svr_info_->IsValidDBC(tmp_vss_db_.c_str())) {
        nlogger_->log(LO_STDOUT|LO_FILE,SEVERITY_ERROR,"%s配置中间库连接名<tmp_vss_db>%s无效,请检查hotfox配置.\n",cf_.c_str(),tmp_vss_db_.c_str());
        return -1;
    }

    node = root->GetChildNodes()->GetChildNodes("task_data_map")->GetChildNode(0);
    if (node==0) {
        nlogger_->log(LO_STDOUT|LO_FILE,SEVERITY_WARNING,"%s未配置任务类型和单据类型的映射.\n",cf_.c_str());
    }
    nl = node->GetChildNodes()->GetChildNodes("item");
    unsigned int item_num = nl->Count();
    for (unsigned int i=0;i<item_num;i++) {
        INode *node = nl->GetChildNode(i);
        INode *task_id_node = node->GetChildNodes()->GetChildNodes("taskid")->GetChildNode(0);
        INode *data_type_node = node->GetChildNodes()->GetChildNodes("data_type")->GetChildNode(0);

        string task_id = (string)*task_id_node;
        CTaskCfgItem *item = new CTaskCfgItem;
        item->task_id_ = task_id;
        item->sheet_type_ = (int)*data_type_node;

        /// 写入时根据目标表的字段类型进行转换
        INode *subnode = node->GetChildNodes()->GetChildNodes("task_define")->GetChildNode(0);
        if (subnode==0) {
            nlogger_->log(LO_STDOUT|LO_FILE,SEVERITY_ERROR,"没有任务%s的定义信息.\n",task_id.c_str());
            return -1;
        }

        INode *tables_node = subnode->GetChildNodes()->GetChildNodes("tables")->GetChildNode(0);
        if (tables_node==0) {
            nlogger_->log(LO_STDOUT|LO_FILE,SEVERITY_ERROR,"没有任务%s的表信息.\n",task_id.c_str());
            return -1;
        }

        CTableRelationParser parser;
        INodeList *table_nl = tables_node->GetChildNodes()->GetChildNodes("table");
        int table_nl_num = table_nl->Count();
        for (int i=0;i<table_nl_num;i++) {
            INode *subnode = table_nl->GetChildNode(i);
            INode *name_node = subnode->GetChildNodes()->GetChildNodes("name")->GetChildNode(0);
            INode *field_node = subnode->GetChildNodes()->GetChildNodes("field")->GetChildNode(0);

            ns_dxi_hrwj::CTable *table = new ns_dxi_hrwj::CTable;
            table->name_ = (string)*name_node;
            string s = (string)*field_node;
            table->fld_list_ = s.empty() ? "*" : s; ///< 如果为空则查询所有列
            parser.AddNode(new CTableRelationNode(table->name_.c_str()));

            item->tables_.push_back(table);
        }

        ///< 读目标表的元数据信息(指定表的指定字段的类型信息)
        ///< 元数据

        ///< 读任务处理表的关联信息,单表则不需要
        INode *rs_node = subnode->GetChildNodes()->GetChildNodes("relations")->GetChildNode(0);
        if (rs_node) {
            INodeList *tnl = rs_node->GetChildNodes()->GetChildNodes("relation");
            int num = tnl->Count();
            vector<string> vs;

            for (int i=0;i<num;i++) {
                INode *subnode = tnl->GetChildNode(i);
                string s = (string)*subnode;
                if (!s.empty())
                    parser.AddExpr(s.c_str());
            }
            ///< 解析关系
            if (parser.Parse()) {
                nlogger_->log(LO_STDOUT|LO_FILE,SEVERITY_ERROR,"解析任务%s的表关系定义定义失败.\n",task_id.c_str());
                return -1;
            }

            item->relation_ = parser.GetRootNode();
        }
        task_data_type_map_[task_id] = item;
    }

    node = root->GetChildNodes()->GetChildNodes("task_scan_interval")->GetChildNode(0);
    if (node) {
        task_scan_interval_ = (int)*node;
    }
    
    config_->Close();
        
    return 0;
}
////////////////////////////////////////////////////////////////////////////////
int CDxiHRWJ::Initialize() {
    parent::Initialize();
    return 0;
}

////////////////////////////////////////////////////////////////////////////////
int CDxiHRWJ::Prepare() {
    parent::Prepare();
    return 0;
}
////////////////////////////////////////////////////////////////////////////////
int CDxiHRWJ::CheckValid() {
    parent::CheckValid();
    
    idd_ = ACE_reinterpret_cast(IDd*,container_->GetResource(DD_SHARE));

    return 0;        
}

////////////////////////////////////////////////////////////////////////////////
int CDxiHRWJ::Activate() {
    parent::Activate();

    vector<stDataSource*>::iterator it = vss_db_.begin();
    while(it!=vss_db_.end()) {
        stDataSource *ds = *it;
        const char* dbc_name = ds->dbc_name_.c_str();
        char task_name[32];
        sprintf(task_name,"TaskHandleProc_%s",dbc_name);
        IDeamonTask *task = deamon_mgr_->add(TaskHandleProc,task_name,(void*)ds);
        task->set_timer_strategy(task_scan_interval_);
        it++;
    }

    ///< 确定使用的中间库数据表,读中间库的元数据
    map<string,CTaskCfgItem*>::iterator iter = task_data_type_map_.begin();
    while(iter!=task_data_type_map_.end()) {
        CTaskCfgItem *ti = iter->second;
        int tbl_num = ti->tables_.size();
        for (int i=0;i<tbl_num;i++) {
            ns_dxi_hrwj::CTable *table = ti->tables_[i];
            map<string,stTableInfo*>::iterator it = tmp_vss_table_.find(table->name_);
            if (it==tmp_vss_table_.end()) {
                stTableInfo *t = new stTableInfo;
                ///< 读元数据
                if (QueryTableInfo(tmp_vss_db_.c_str(),table->name_.c_str(),t)) {
                    nlogger_->log(LO_STDOUT|LO_FILE,SEVERITY_ERROR,"CDxiHRWJ::Activate读%s.%s的模式信息失败.\n",tmp_vss_db_.c_str(),table->name_.c_str());
                    return -1;
                }
                tmp_vss_table_[table->name_] = t;
            }
            if (table->fld_list_[0]=='*') { ///< 如果查询所有字段
                ///<
            }

            ///< 确定每个表的查询条件
            CTableRelationNode *relation = ti->relation_->FindChild(table->name_.c_str(),true);
            if (relation) {
                string cond;
                relation->GetSQLWhereExpr(cond);
                table->select_cmd_ =  LogMsg("select %s from %s where %s",table->fld_list_.c_str(),table->name_.c_str(),cond.c_str());
                table->delete_cmd_ =  LogMsg("delete from %s where %s",table->name_.c_str(),cond.c_str());
            }
        }
        iter++;
    }

    return 0;
}

////////////////////////////////////////////////////////////////////////////////
int CDxiHRWJ::OnActivate() {
    parent::OnActivate();
    return 0;
}
////////////////////////////////////////////////////////////////////////////////
int CDxiHRWJ::Deactivate() {
    parent::Deactivate();
    return 0;
}

////////////////////////////////////////////////////////////////////////////////
int CDxiHRWJ::Release() {
    parent::Release();    

    map<string,CTaskCfgItem*>::iterator iter = task_data_type_map_.begin();
    while(iter!=task_data_type_map_.end()) {
        delete iter->second;
        iter++;
    }
    task_data_type_map_.clear();
    
            
    return 0;
}

////////////////////////////////////////////////////////////////////////////////
ACE_THR_FUNC_RETURN TaskHandleProc(void *arg) {
    return CDxiHRWJ::instance()->HandleTask((stDataSource*)arg);
}


////////////////////////////////////////////////////////////////////////////////
int ns_dxi_hrwj::CTask::GenKeyCond(const char *tbl_name,string &cond) {
    USEDBC(pdbor,ds_->dbc_name_.c_str());
    string s;
    stTableInfo *ti = CDxiHRWJ::instance()->FindTable(tbl_name);
    CAutoVector<CTaskKey*>::iterator iter = keys_.begin();
    while(iter!=keys_.end()) {
        CTaskKey *key = *iter;
        stFieldInfo *fi = ti->FindField(key->field_name_.c_str());
        switch(fi->type2_) {
            case 1:
            case 2:
                s += LogMsg("%s=%s",key->field_name_.c_str(),key->field_val_.c_str());
                break;
            case 9:
                s += LogMsg("%s='%s'",pdbor->GetDBExt()->DateToChar(key->field_name_.c_str(),2).c_str(),key->field_val_.c_str());
                break;
            case 10:
                s += LogMsg("%s='%s'",pdbor->GetDBExt()->TimeToChar(key->field_name_.c_str(),2).c_str(),key->field_val_.c_str());
                break;
            case 11:
                ///< 日期时间字段只取日期
                s += LogMsg("%s='%s'",pdbor->GetDBExt()->DateToChar(key->field_name_.c_str(),2).c_str(),key->field_val_.c_str());
                break;
            default:
                s += LogMsg("%s='%s'",key->field_name_.c_str(),key->field_val_.c_str());
                break;

        }
        s += " and ";

        iter++;
    }
    if (s.length()>0) {
        s.erase(s.length()-5,5);
    }
    cond = s;
    return 0;
}



////////////////////////////////////////////////////////////////////////////////
ns_dxi_hrwj::CTable* CTaskCfgItem::find_table(const char *tbl_name) {
    CAutoVector<ns_dxi_hrwj::CTable*>::iterator iter = tables_.begin();
    while(iter!=tables_.end()) {
        ns_dxi_hrwj::CTable *table = *iter;
        if (stricmp(table->name_.c_str(),tbl_name)==0)
            return table;
        iter++;
    }
    return 0;
}

////////////////////////////////////////////////////////////////
int ns_dxi_hrwj::CTask::HandleDetail(CTableRelationNode *parent,CRecordset *prs,CMsg *msg) {
    int result = 0;
    IDbAccessor *pdbor = prs->GetAccessor();
    int sub_node_num = parent->ChildCount();
    for (int i=0;i<sub_node_num;i++) {
        CTableRelationNode *sub_node = (CTableRelationNode*)parent->GetChild(i);
        ns_dxi_hrwj::CTable *table = task_define_->find_table(sub_node->GetName());
        ///< 确定对应表的抽取语句(参数化SQL)
        ///< 确定参数(父表对应字段的值)
        char *select_cmd,*delete_cmd;
        struct stA {
            const char *p;
            char **buffer;
        } va[] = {
            { table->select_cmd_.c_str(),&select_cmd},
            { table->delete_cmd_.c_str(),&delete_cmd},
        };
        for (int k=0;k<sizeof(va)/sizeof(va[0]);k++) {
            stA  &a = va[k];
            CParamStrParser parser;
            parser.Parse(a.p);
            int para_num = parser.GetParamNum();
            for (int k=0;k<para_num;k++) {
                stParamPair *pp = parser.GetParam(k);
                _variant_t vtVal;
                prs->GetFieldValue(pp->name_.c_str(),vtVal);
                stTableInfo *ti = CDxiHRWJ::instance()->FindTable(table->name_.c_str());
                stFieldInfo *fi = ti->FindField(pp->name_.c_str());
                string val = ExVariantToString(vtVal);
                if (CvtFieldConstValueString(pdbor,fi->type2_,val.c_str(),pp->value_))
                    return -1;
            }
            ///< 生成最终执行的SQL语句
            parser.Instance(a.buffer);
        }
        string sql = *va[0].buffer;
        delete []*va[0].buffer;
        delete_cmd_.push_back(*va[1].buffer);
        delete []*va[1].buffer;

        AUTO_QUERY_RECORDSET(CRecordset,prs2,pdbor);
        prs2 = pdbor->Query(adCmdText,sql.c_str());
        if (prs2==0) {
            return -2;
        }
        CRowset *rs = 0;
        CAutoMap<string,stRowsetInfo*>::iterator iter = rss_.find(table->name_.c_str());
        if (rs==0) {
            int rs_num = msg->GetRowsets();
            string para_name = LogMsg(INNER_TABLE_FMT,rs_num+1);
            msg->AddParam(para_name.c_str(),table->name_.c_str());
            rs = new CRowset;
            msg->AddRowset(rs);
            
            stRowsetInfo *ri = new stRowsetInfo;
            ri->rs_ = rs;
            ri->tbl_name_ = table->name_;
            rss_[table->name_] = ri;
            if (RecordFieldToRowset(prs2,rs))
                return -3;
        }
        unsigned long ulDetailCount = 0;
        while(!prs2->IsEof()) {
            if (RecordToRowset(prs2,rs))
                return -4;

            if (HandleDetail(sub_node,prs2,msg)) {
                result = -5;
                break;
            }
            if (!prs2->Move()) {
                return -6;
            }
        }
    }

    return 0;
}


////////////////////////////////////////////////////////////////////////////////
int RecordFieldToRowset(CRecordset *prs,CRowset *rs) {
    unsigned long fld_num = prs->GetFieldCount();
    for (int i=0;i<fld_num;i++) {
        FieldInfo fldInfo;
        if (!prs->GetFieldInfo(i,&fldInfo))    {
            return -2;
        }
        rs->AddField(fldInfo.m_strName);
    }

    return 0;
}
////////////////////////////////////////////////////////////////////////////////
///< 把CRecordset的一条记录追加到CRowset中
int RecordToRowset(CRecordset *prs,CRowset *rs) {
    assert(!prs->IsEof());
    rs->AddRecord();
    unsigned long fld_num = prs->GetFieldCount();
    for (int i=0; i<fld_num; i++) {
        _variant_t varFld;
        string strFld;
        string strFldName;
        if (!prs->GetFieldValue(i,varFld))
            return -1;
        strFld = ExVariantToString(varFld);

        FieldInfo fldInfo;
        if (!prs->GetFieldInfo(i,&fldInfo))
            return -2;
        strFldName = fldInfo.m_strName;

        rs->SetFieldValueByName(strFldName.c_str(),(char*)strFld.c_str());
    }

    return 0;
}

////////////////////////////////////////////////////////////////////////////////
int ns_dxi_hrwj::CTask::HandleTable(CTableRelationNode *node,CMsg *msg) {
    string tbl_name = node->GetName();
    string fld_list = task_define_->find_table(tbl_name.c_str())->fld_list_;
    string schema_name = CDxiHRWJ::instance()->schema_name_;
    if (!schema_name.empty()) {
        schema_name += ".";
    }
    string cond;
    GenKeyCond(tbl_name.c_str(),cond);
    string sql = LogMsg("select %s from %s%s where %s",fld_list.c_str(),schema_name.c_str(),tbl_name.c_str(),cond.c_str());
    string delete_sql = LogMsg("delete from %s%s where %s",schema_name.c_str(),tbl_name.c_str(),cond.c_str());
    delete_cmd_.push_back(delete_sql);

    USEDBC(pdbor,ds_->dbc_name_.c_str());
    AUTO_QUERY_RECORDSET(CRecordset,prs,pdbor);
    prs = pdbor->Query(adCmdText,sql.c_str());
    if (prs==0) {
        return -1;
    }    
    int rs_num = msg->GetRowsets();
    string para_name = LogMsg(INNER_TABLE_FMT,rs_num+1);
    msg->AddParam(para_name.c_str(),tbl_name.c_str());
    CRowset *rs = new CRowset;
    msg->AddRowset(rs);
    stRowsetInfo *ri = new stRowsetInfo;
    ri->rs_ = rs;
    ri->tbl_name_ = tbl_name;
    rss_[tbl_name] = ri;

    if (RecordFieldToRowset(prs,rs))
        return -2;

    while(!prs->IsEof()) {
        if (RecordToRowset(prs,rs))
            return -4;
        if (HandleDetail(node,prs,msg))
            return -5;

        prs->Move();
    }

    return 0;
}
////////////////////////////////////////////////////////////////////////////////
CMsg* ns_dxi_hrwj::CTask::GetData() {
    CMsg *msg = new CMsg; ///< 内部数据结构使用,无需设置消息ID等属性
    CTableRelationNode *root = task_define_->relation_; ///< 从根表开始处理

    if (HandleTable(root,msg)) {
        msg->Release();
        return 0;
    }

    return msg;
}
////////////////////////////////////////////////////////////////////////////////
int ns_dxi_hrwj::CTask::SyncData(CMsg *msg) {
    CTableRelationNode *root = task_define_->relation_; ///< 从根表开始处理
    ///< 先删除后新增
    int rs_num = msg->GetRowsets();
    USEDBC(pdbor,CDxiHRWJ::instance()->tmp_vss_db_.c_str());
    pdbor->BeginTrans();

    for (int i=0;i<rs_num;i++) {
        CRowset *rs = msg->GetRowset(i);
        int fld_num = rs->GetRSMeta(RST_FLD_NUM);
        string fld_list;
        fld_list = BUID_FILED_NAME;
        fld_list += ",";
        for (int col=0;col<fld_num;col++) {
            FieldDescriptor *fd = rs->GetFieldInfo(col);
            fld_list += LogMsg("%s,",fd->name);
        }
        if (!fld_list.empty())
            fld_list.erase(fld_list.length()-1,1);
        int row_num = rs->GetRSMeta(RST_ROW_CNT);
        string para_name = LogMsg(INNER_TABLE_FMT,i+1);
        const char *tbl_name = msg->GetParam(para_name.c_str());
        stTableInfo *ti = CDxiHRWJ::instance()->FindTable(tbl_name);
        CLargeStringArray vs;
        for (int row=0;row<row_num;row++) {
            ///< 生成insert语句
            string sql;
            string val_list;
            val_list += LogMsg("%d,",ds_->buid_);
            for (int col=0;col<fld_num;col++) {
                FieldDescriptor *fd = rs->GetFieldInfo(col);
                const char *val = rs->GetFieldValue(row,col); ///< @todo 很大的性能提升空间
                stFieldInfo *fi = ti->FindField(fd->name);
                string ret_val;
                if (ISEMPTY_STR(val)) {
                    GetFieldDefaultValue(0,fi->type2_,ret_val);
                }
                else {
                    if (CvtFieldConstValueString(pdbor,fi->type2_,val,ret_val)) {
                        pdbor->RollbackTrans();
                        return -1;
                    }
                }
                val_list += ret_val;
                val_list += ",";
            }
            val_list.erase(val_list.length()-1,1);
            char *buffer = 0;
            FormatString(2048,&buffer,"%s",val_list.c_str());
            vs.Add(buffer);
        }
        if (pdbor->GetDBExt()->BatchInsert(tbl_name,fld_list.c_str(),vs,BATCH_INSERT_NUM)) {
            pdbor->RollbackTrans();
            return -1;
        }
    }
    if (!pdbor->CommitTrans())
        return -1;

    return 0;
}

////////////////////////////////////////////////////////////////////////////////
int ns_dxi_hrwj::CTask::Run() {
    ///< 根据任务定义信息抽取数据
    ///< 生成UMX数据包
    CMsg *msg = GetData();
    if (msg==0)
        return -1;

    USEDBC(pdbor,CDxiHRWJ::instance()->tmp_vss_db_.c_str());
    pdbor->BeginTrans();
    vector<string>::reverse_iterator iter = delete_cmd_.rbegin();
    while(iter!=delete_cmd_.rend()) {
        string cmd = *iter;
        if (!pdbor->Execute(adCmdText,cmd.c_str())) {
            pdbor->RollbackTrans();
            return -2;
        }
        iter++;
    }
    ///< 从UMX数据包导入到中间库
    if (SyncData(msg)) {
        msg->Release();
        return -2;
    }
    msg->Release();
    if (!pdbor->CommitTrans())
        return -3;



    return 0;
}

////////////////////////////////////////////////////////////////////////////////
stTableInfo* CDxiHRWJ::FindTable(const char *tbl_name) {
    map<string,stTableInfo*>::iterator iter = tmp_vss_table_.find(tbl_name);
    return iter==tmp_vss_table_.end() ? 0 : iter->second;
}

////////////////////////////////////////////////////////////////////////////////
int CDxiHRWJ::HandleTask(stDataSource *ds) {
    GETDBC(pdbor,ds->dbc_name_.c_str());
    string sql = "select a.taskid,a.destination,a.source,a.topic,b.field,b.value from MSCMTASKLIST a left join MSCMTASKKEY b on a.taskid=b.taskid where a.STATUS<>100 order by LAUNCHDATE,taskid";

    AUTO_QUERY_RECORDSET(CRecordset,prs,pdbor);
    prs = pdbor->Query(adCmdText,sql.c_str());
    if (prs==0) {
        nlogger_->log(LO_STDOUT|LO_FILE,SEVERITY_ERROR,"CDxiHRWJ::HandleTask执行%s失败,错误:%s.\n",sql.c_str(),pdbor->GetLastError());
        return -1;
    }
    if (prs->IsEof())
        return 0;

    nlogger_->log(LO_STDOUT|LO_FILE,SEVERITY_DEBUG,"CDxiHRWJ::HandleTask开始处理任务记录...\n");
    clock_t beg = clock();
    unsigned long handle_rec = 0; ///< 处理任务记录数
    _variant_t vtTaskId,vtTopic,vtField,vtValue;
    string strTaskId,strTopic,strField,strValue;
    do {
        if (!prs->GetFieldValue("taskid",vtTaskId)
            ||!prs->GetFieldValue("topic",vtTopic)
            ||!prs->GetFieldValue("field",vtField)
            ||!prs->GetFieldValue("value",vtValue)) {
                return -2;
        }            
        strTaskId = ExVariantToString(vtTaskId);
        strTopic = ExVariantToString(vtTopic);
        strField = ExVariantToString(vtField);
        strValue = ExVariantToString(vtValue);

        CTask task;
        task.id_ = strTaskId;
        task.ds_ = ds;
        task.type_ = ExVariantToString(vtTopic);
        while(!prs->IsEof()) {
            _variant_t vtTaskId,vtField,vtValue;
            prs->GetFieldValue("taskid",vtTaskId);
            prs->GetFieldValue("field",vtField);
            prs->GetFieldValue("value",vtValue);
            string t_task_id = ExVariantToString(vtTaskId);
            if (stricmp(t_task_id.c_str(),strTaskId.c_str())) {
                break;
            }
            if (!strField.empty()) {
                CTaskKey *key = new CTaskKey;
                key->field_name_ = strField;
                key->field_val_ = strValue;
                task.keys_.push_back(key);
            }
            prs->Move();
        }
        ///< 处理任务
        map<string,CTaskCfgItem*>::iterator iter = task_data_type_map_.find(task.type_);
        if (iter==task_data_type_map_.end()) {
            continue;
        }
        CTaskCfgItem *item = iter->second;
        task.task_define_ = item;
        CQQ_BILLTYPE data_type = item->sheet_type_;
        string app_key;
        CAutoVector<CTaskKey*>::iterator it_key = task.keys_.begin();
        while(it_key!=task.keys_.end()) {
            CTaskKey *key = *it_key;
            app_key += LogMsg("%s=C[%s],",key->field_name_.c_str(),key->field_val_.c_str());
            it_key++;
        }
        if (!app_key.empty()) {
            app_key.erase(app_key.length()-1,1);
        }

        string update_sql = LogMsg("update MSCMTASKLIST set status=99 ,tries=tries+1 where taskid='%s'",task.id_.c_str());
        bool has_error = false;
        if (task.Run()) {
            nlogger_->log(LO_STDOUT|LO_FILE,SEVERITY_ERROR,"CDxiHRWJ::HandleTask处理任务%s失败.\n",task.id_.c_str());
            has_error = true;
        }
        else {
            char now[32];
            sens::CDateTime::GetDateTime(now);
            GETDBC(p,tmp_vss_db_.c_str());
            string sql = LogMsg("insert into tb_change_log(datatype,app_pk,logtime,optype,logflag) values(%d,'%s',%s,1,0)",
                data_type,app_key.c_str(),p->GetDBExt()->ToDateTime(now,1).c_str());
            bool bFlag = p->Execute(adCmdText,sql.c_str());
            if (bFlag) {
                update_sql = LogMsg("update MSCMTASKLIST set status=100 where taskid='%s'",task.id_.c_str());
            }
            else {
                nlogger_->log(LO_STDOUT|LO_FILE,SEVERITY_ERROR,"CDxiHRWJ::HandleTask执行%s失败,错误:%s.\n",sql.c_str(),p->GetLastError());
            }
        }
        pdbor->Execute(adCmdText,update_sql.c_str()); ///< 不需要检查是否成功.如果失败,下次会重复做一次
        
        if (has_error)
            return -3;

        handle_rec++;

    } while(!prs->IsEof());

    nlogger_->log(LO_STDOUT|LO_FILE,SEVERITY_DEBUG,"CDxiHRWJ::HandleTask处理任务记录结束,处理记录数:%d,耗时:%.2f(秒).\n",handle_rec,(double)(clock()-beg)/CLOCKS_PER_SEC);

    return 0;
}
////////////////////////////////////////////////////////////////////////////////



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:156398次
    • 积分:3524
    • 等级:
    • 排名:第7959名
    • 原创:194篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章分类
    最新评论