www.pudn.com > xml2db.rar > truncate_data.cpp


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "xml2db.h"

#include "config.h"
#include "clog.h"
#include "local_log.h"


using namespace std;
using namespace oracle::occi ;
	

#ifdef XML_LARGE_SIZE
#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400
#define XML_FMT_INT_MOD "I64"
#else
#define XML_FMT_INT_MOD "ll"
#endif
#else
#define XML_FMT_INT_MOD "l"
#endif

#define BUFFSIZE    1024*5000

static void (*tracer_log)(int type,int sev,int msg_id,const char * msg)=NULL;
#define TRACE_ERROR(msg,msgid)  if(tracer_log != NULL) (*tracer_log)(X2D_ERROR_TYPE,X2D_CRITICAL,msgid,msg)
#define TRACE_WARNING(msg,msgid) if(tracer_log != NULL) (*tracer_log)(X2D_ERROR_TYPE,X2D_WARNNING,msgid,msg)
#define TRACE_INFO(msg,msgid) if(tracer_log != NULL) (*tracer_log)(X2D_INFO_TYPE,X2D_INFOR,msgid,msg)


static char Buff[BUFFSIZE];
static int Depth;

//string row_val[1000];
static int row_count=0;

static string field_name[200];
static int field_count=0;

static string col_val[200];
static int col_count=0;

static string table_name;

static string field_list;//用于生成sql的insert语句
static string value_list;//
static string str_sql;
static string str_sql_truncate;

//_flag 说明:初始false ,遇到<>为true,读到 为false 

static bool obj_flag=false;
static bool row_flag=false;
static bool data_flag=false;

static Environment *env =NULL;
static Connection *conn =NULL;
static Statement *stmt =NULL;
static Statement *stmt_truncate =NULL;

static int read_rows = 0 ;

bool open_db(const char *config_file_name)
{
    try
    {     	
	    load_config(config_file_name);
	}
	catch(string &xs)	
	{
	    string error_str = "Fail to load config file :";
	    error_str += config_file_name;
	    error_str += ". ";
	    error_str += xs;
	    TRACE_ERROR(error_str.c_str(),13);
	    return false;
	}
	
	const char * db_user_name=get_config_value("DB_USER_NAME");
	const char * db_passwd=get_config_value("DB_PASSWD");
	const char * db_connect_string=get_config_value("DB_CONNECT_STRING");
	
	bool has_error = false;	
	try
	{
 	    env=Environment::createEnvironment();        
        if(db_user_name == NULL || db_passwd == NULL)
   	    {
   	        string error_str = "Fail to call get_config_value from the config file : ";
   	        error_str += config_file_name;
   	        error_str += ". ";   	        
   		    TRACE_ERROR(error_str.c_str(),1);
   		    return false;
   	    }   			   			   			
    
   	    if(db_connect_string != NULL)
	    {
	        conn = env->createConnection(db_user_name,db_passwd,db_connect_string);
        }
	    else
	    {
	        conn = env->createConnection(db_user_name,db_passwd);
	    }
	}
	catch(SQLException ex)
	{
	    string errstr("Fail to open connect to ORACLE. ");
        errstr += ex.getMessage();
        TRACE_ERROR(errstr.c_str(),2);
        has_error = true;
	}	
	catch(...)
	{
	    string errstr("Fail to open connect to ORACLE. unkown error happen. ");
	    TRACE_ERROR(errstr.c_str(),3);
	    has_error = true;
	}
	
	if( has_error )
	{
	    if(conn != NULL)
	    {
	        env->terminateConnection(conn);
	        conn = NULL;
	    }
	    if(env !=NULL)
	    {
	        Environment::terminateEnvironment(env);
	        env = NULL;
	    }
	    TRACE_ERROR("fail to connect datebase.",4);
	    return false;
	}	    	
   	
   	return true;
}

void quit_db()
{
    if(stmt !=NULL)
    {
	    conn->terminateStatement(stmt);
	    stmt = NULL;
	}
	
	if(conn != NULL)
	{
	    env->terminateConnection(conn);
	    conn = NULL;
	}
	
	if(env != NULL)
	{
   	    Environment::terminateEnvironment(env);
   	    env = NULL;
   	}
   	return ;
} 



static void XMLCALL start(void *data, const char *el, const char **attr)
{
    
   int i;    
   
    if(strcmp(el,"OBJECT")==0)
    {
        obj_flag=true;
        
        row_count=0;
        col_count=0;
        //set a flag of xml file type   
        //找数据库中对应的表名,在getText中实现。               
    }
   
    if(strcmp(el,"DATA")==0)
    {
        data_flag=true;
     		
    }
   
    if(strcmp(el,"ROW")==0)
    {
       
        row_flag=true;      
        row_count++;
        col_count=0;
        field_count=0;
      
    }
        
    //得到表中的字段名称
    if(data_flag==true && row_flag == true && (strcmp(el,"ROW")!=0))
    {
        col_count++;
        field_count++;           
        field_name[field_count]=el;
        if(field_name[field_count].length()>=30)
        {
     	    field_name[field_count].erase(30);        
        }
        string::iterator p_;
        for(p_ = field_name[field_count].begin();
            p_ != field_name[field_count].end();
            p_ ++)
        {
            *p_ = toupper(*p_);
        }
        field_name[field_count].insert(0,"\"");
        field_name[field_count].append("\"");
                            
    }   
    Depth++;
}


static void XMLCALL getText(void *userData, const XML_Char *s,int len)
{
    int k=1;
    int i=0;
  
    if(data_flag==true&&row_flag==true&&field_count>=1)
    {
        //for(i=0;i=1&&field_count>=1)
   {
           
     if(Depth==7)
     //在之间的表数据,Depth值为7,
     //必须有此判断,否则解析中Depth=6时候,取到空值
     {
        col_val[col_count]=ss;
        //cout<<"  ("<createStatement(str_sql_truncate); 	
  	  	    stmt_truncate->executeUpdate();
            //conn->commit();

        }
        catch(SQLException ex)
	    {
	        string errstr("Fail to execute sql:  '");
	        errstr += str_sql;
	        errstr += "'. ";
            errstr += ex.getMessage();
            if(stmt !=NULL)
            {
	            conn->terminateStatement(stmt);
	            stmt = NULL;
	        }
	        TRACE_ERROR(errstr.c_str(),5);
	    }
	    catch(...)
	    {
	        if(stmt !=NULL)
            {
	            conn->terminateStatement(stmt);
	            stmt = NULL;
	        }
	        string errstr("Fail to execute sql. unkown error.");
	        errstr += str_sql;
	        TRACE_ERROR(errstr.c_str(),6);
	    }
	    
	    if(stmt !=NULL)
        {
	        conn->terminateStatement(stmt);
	        stmt = NULL;
	    }	    
        //数据处理完,col_count,field_count归零
        col_count=0;
        field_count=0;
   }
   
   if(strcmp(el,"DATA")==0)
   {
       data_flag=false;            
       string log_info("truncate  table :");
       log_info += table_name;
       log_info += ". ";
       TRACE_INFO(log_info.c_str(),7);       
       //完成入库,断开数据库连接
       //quit_db();
   }
                       
}

//#ifdef AMIGA_SHARED_LIB
//#include 

//单个xml文件的入库
int xml2db_one(const char * config_file_name, const char *xml_file) 
{ 
    read_rows = 0;     						
    //open the *.xml file
    FILE *file;
    if(!(file=fopen(xml_file,"rt")))
    {
        string errstr("truncate Can NOT open the xml file. file name = ");
        errstr += xml_file;
        errstr += ". Hint: ";
        errstr += strerror(errno);
        TRACE_ERROR(errstr.c_str(),13);
        return -1;        
    };
    
  
    XML_Parser p = XML_ParserCreate(NULL);
    if (! p) 
    {    
        //fprintf(stderr, "Couldn't allocate memory for parser\n");
        TRACE_ERROR("Couldn't allocate memory for parser",8);
        return(-1);
    } 
    
 
 		/*是设置处理元素头尾的函数*/
    XML_SetElementHandler(p, start, end);
    /*设置一个共享的数据结构给各各处理函数使用*/
    XML_SetUserData(p, &Depth);
    /*设置元素内文本的处理函数*/
    XML_SetCharacterDataHandler(p,getText); 
       
	for (;;) 
	{
        int done;
        int len;

        len = fread(Buff, 1, BUFFSIZE, file);
        
        if (ferror(file)) 
        {      
            //fprintf(stderr, "Read error\n");
            TRACE_ERROR("Couldn't read file",9);
            return(-1);
        }
        done = feof(file);

						/*主处理函数*/
        if (XML_Parse(p, Buff, len, done) == XML_STATUS_ERROR) 
        {        
            //出错处理,写入日志              
            //fprintf(stderr, "Parse error at line %" XML_FMT_INT_MOD "u:\n%s\n",
            //        XML_GetCurrentLineNumber(p),
            //        XML_ErrorString(XML_GetErrorCode(p)));
            stringstream err_os;
            err_os<<"Parser error at line "<