?? serverdb.c
字號:
/***********************************************************************//* 1. tpsvrinit : 初始化函數(shù) *//* 2. SERVERDB : 服務(wù)處理函數(shù) */ /* 3. tpsvrdone : 結(jié)束服務(wù) */ /***********************************************************************/#include <stdio.h>#include <ctype.h>#include <string.h>#include <unistd.h>#include <sys/time.h>#ifdef _AIX#include <sys/access.h>#endif/* Include OCI-specific headers. */#include <oratypes.h>#include <ocidfn.h>#ifdef __STDC__#include <ociapr.h>#else#include <ocikpr.h>#endif#include <ocidem.h>/* 用于BEA TUXEDO的包含文件 */#include <atmi.h>#define _DEBUG/* Constants used in this program. */#define MAX_BINDS 100#define MAX_ITEM_BUFFER_SIZE 100#define MAX_SELECT_LIST_SIZE 100#define MAX_SQL_IDENTIFIER 100#define MAX_OUT_LIST_SIZE 100#define PARSE_NO_DEFER 0#define PARSE_V7_LNG 2/* Define one logon data area and one cursor data area Also define a host data area for olog. (See ocidfn.h for declarations). */Lda_Def lda;Cda_Def cda;ub4 hda[HDA_SIZE/(sizeof(ub4))];void myuserlog(char *hdr, char *str);void DoCommit(Lda_Def *lda);void DoRollback(Lda_Def *lda);/* Declare structures for query information. */struct describe{ sb4 dbsize; sb2 dbtype; sb1 buf[MAX_ITEM_BUFFER_SIZE]; sb4 buflen; sb4 dsize; sb2 precision; sb2 scale; sb2 nullok;};struct define { ub1 buf[MAX_ITEM_BUFFER_SIZE]; float flt_buf; sword int_buf; sb2 indp; ub2 col_retlen, col_retcode;};struct outinfo{ ub2 ovrld; /* returns overloading info */ ub2 pos; /* returns the parameter position in the list */ ub2 level; /* returns the level for composite parameters */ text argnm[MAX_ITEM_BUFFER_SIZE]; /* returns parameter names */ ub2 arnlen; /* returns lengths of names */ ub2 dtype; /* returns ORACLE datatype code */ ub1 defsup; /* returns "default supplied" indicators */ ub1 mode; /* returns the mode(IN OUT/IN/OUT) info */ ub4 dtsize; /* returns lengths */ ub2 prec; /* returns precision, if a number */ ub2 scale; /* returns scale, if a number */ ub1 radix; /* returns the radix, if a number */ ub4 spare; /* reserved must be passed */};/* Define arrays of describe and define structs. */struct describe desc[MAX_SELECT_LIST_SIZE];struct define def[MAX_SELECT_LIST_SIZE];struct outinfo outs[MAX_OUT_LIST_SIZE];struct define outv[MAX_OUT_LIST_SIZE];text szOutNames[MAX_OUT_LIST_SIZE][MAX_SQL_IDENTIFIER];/* Declare an array of bind values. */text szOutValues[MAX_OUT_LIST_SIZE][MAX_ITEM_BUFFER_SIZE];sb2 sbNullFlag[MAX_OUT_LIST_SIZE];/* Declare this programs functions. */int tpsvrinit(int argc, char** argv);void SERVERDB(TPSVCINFO* svcinfo);void tpsvrdone(void);sword ReConnectSQLServer();sword ConnectSQLServer(text* szUserName,text* szPassword, text* szServerName);sword describe_define();sword do_prevbinds();sword do_postbinds();void oci_error();char ConvertDBType(sb2 dbtype);/* Globals */static sword numwidth = 8;static char *pszRcPath=NULL;static char *pszUserNameID="USERNAME";static char *pszPasswordID="PASSWORD";static char *pszServerNameID="SERVER";static text szOCISQL[16192]; /* OCI請求SQL */static sb2 nOCIErrNo; /* OCI錯誤碼 */static text szOCIErrMsg[512]; /* OCI錯誤信息 */static sword nOCIFunction; /* OCI函數(shù)號 */static int nOCIPacketNo; /* 當(dāng)前包序號 */static int nOCIFieldNum; /* 選擇字段數(shù)目*/static int nOCITranID=0; /* 事務(wù)ID */static int nOCIAffectedRow=0; /* 受操作影響的記錄數(shù) */static int nOCIRowLimits=0; /* 查詢操作可提取的最大行數(shù) */static int nOCIOutNum; /* 存儲過程輸出參數(shù) */#define ERROR_PACKET_FORMAT 20001 /* 數(shù)據(jù)包格式錯誤 */#define ERROR_UNSOLVED_VARIABLE 20002 /* SQL包含沒有未確定變量 */#define ERROR_SQL_FORMAT 20003 /* SQL包含初始化賦值錯誤 */#define DATA_SQL 0 /* SQL位 */#define DATA_RETCODE 1 /* 結(jié)果碼 */#define DATA_OUTDESC 2 /* Outs描述 */#define DATA_OUTDATA 3 /* Outs內(nèi)容 */#define DATA_FDDESC 4 /* 字段描述 */#define DATA_ROWS 5 /* 行內(nèi)容 *//* SQL請求類型 :Insert,Update,Delete,Procedure */#define ST_UNKNOWN 'X' /* 未定類型 */#define ST_INSERT 'I' /* 執(zhí)行Insert */#define ST_UPDATE 'U' /* 執(zhí)行Update */#define ST_DELETE 'D' /* 執(zhí)行Delete */#define ST_SELECT 'S' /* 執(zhí)行Select */#define ST_PROCEDURE 'P' /* 執(zhí)行存儲過程等 *//* 返回數(shù)據(jù)類型 */#define DBTYPE_STRING 'S' /* 字符串 */#define DBTYPE_INT 'I' /* 整數(shù) */#define DBTYPE_FLOAT 'F' /* 浮點數(shù) */#define DBTYPE_DATE 'D' /* 日期 */ #define DBTYPE_UNKNOWN 'U' /* 未確定 */#define LEN_BYTE_4 4#define LEN_BYTE_2 2#define LEN_BYTE_1 1typedef struct tagPacketQR { char PacketID[4]; /* 通信頭 */ /*int PacketLen; 數(shù)據(jù)包長度 */ char PacketLen[4]; /* 數(shù)據(jù)包長度 */ char UserID[4]; /* 用戶ID */ char TranID[4]; /* 事務(wù)ID */ char NextFlag; /* 后續(xù)標志 */ /*long RowLimits; 最大行數(shù) */ char RowLimits[4]; /* 最大行數(shù) */ char SQLType; /* SQL類型 */ char DataPart[6]; /* 數(shù)據(jù)部分 */} PacketQR;typedef struct tagPartDesc{ /*int PartLen; 該部分長度 */ char PartLen[2]; /* 該部分長度 */ /*int PartShift; 該部分位置 */ char PartShift[2]; /* 該部分位置 */} PartDesc;#define MAX_SENDBUF_LEN 8192#define PACKET_MIN_LEN sizeof(PacketQR)+6*sizeof(PartDesc)int UnpacketSQL(char* data, long len,char *szSQL);void DebugPrint(char* buf, long len);void DebugPrintHeader(PacketQR* hdr);int striequal(char* s1, char* s2);/*int isspace(char s);*/void TrimRight(char* p);void SetStrByte4(char* pbyte, int n);int GetStrByte4(char* pbyte);void SetStrByte2(char* pbyte, int n);int GetStrByte2(char* pbyte);/*void SetStrByte1(char* pbyte, int n);int GetStrByte1(char* pbyte);*//******************************************************//* 函數(shù):tpsvrinit *//* 用途:初始化TUXEDO服務(wù) *//* 原型:int tpsvrinit(int argc, char** argv); *//* 參數(shù):argc -- 命令行參數(shù)個數(shù) *//* argv -- 命令行參數(shù)清單 *//* 返回:0 -- 成功; -1 -- 失敗。 *//* 附注: *//* 這里,我們完成服務(wù)器到數(shù)據(jù)庫的注冊 *//******************************************************/int tpsvrinit(int argc, char** argv){ extern int optind; extern char *optarg; userlog("Starting SERVERDB...\n"); /* 配置文件名稱由命令行-P(p)給定 */ if(getopt(argc,argv,"Pp")!=EOF) { pszRcPath=argv[optind]; } if(pszRcPath==NULL) { userlog("Please configure the self-configuration file for serverdb\n"); return(-1); } if(access(pszRcPath,R_OK)==-1) { userlog("Please check self-configuration file %s to assure it has existed and can be accessed\n",pszRcPath); return(-1); } /* 從配置文件中讀取用戶名和密碼 */ if(ReConnectSQLServer()) { userlog("Cannot connect to databse SQL server\n"); return(-1); } #ifdef _USE_TRANS_ /* 打開事務(wù)管理器 */ if(tpopen()==-1) { userlog("Cannot my_open XA manager."); ologof(&lda); return(-1); } #endif return(0);}/******************************************************//* 函數(shù):tpsvrdone *//* 用途:退出TUXEDO服務(wù) *//* 原型:void tpsvrdone(void); *//* 參數(shù):無 *//* 返回:無 *//* 附注: *//* 這里,我們從數(shù)據(jù)庫退出 *//******************************************************/void tpsvrdone(void){ userlog("Stopping SERVERDB...\n"); #ifdef _USE_TRANS_ /* 關(guān)閉事務(wù)管理器 */ tpclose(); #endif /* 關(guān)閉數(shù)據(jù)庫連接 */ if(oclose(&cda)) userlog("Error closing cursor!\n"); if(ologof(&lda)) userlog("Error logging off!\n");}/******************************************************//* 函數(shù):ReConnectSQLServer *//* 用途:連接服務(wù)器 *//* 原型:sword ReConectSQLServer(); *//* 參數(shù):無 *//* 返回:integer. 0 -- 成功; -1 -- 非致命錯誤 *//* -2 -- 致命錯誤. *//* 附注: *//******************************************************/sword ReConnectSQLServer(){ text szUserName[40],szPassword[20],szServerName[40]; userlog("Connect to Oracle SQL Server...\n"); if((LoadEntryRcItem(pszUserNameID,szUserName)!=0) ||(LoadEntryRcItem(pszPasswordID,szPassword)!=0) ||(LoadEntryRcItem(pszServerNameID,szServerName)!=0)) { userlog("Bad contents in self_configuration file %s\n",pszRcPath); return(-2); } /* 從配置文件中讀取用戶名和密碼 */ if(ConnectSQLServer(szUserName,szPassword,szServerName)==-1) { userlog("Cannot connect to databse SQL server\n"); return(-1); } userlog("Connect to database SQL server ok\n"); /* 打開數(shù)據(jù)庫光標用于訪問 */ if(oopen(&cda, &lda, (text *) 0, -1, -1, (text *) 0, -1)) { userlog("Error opening cursor. Exiting...\n"); ologof(&lda); return(-2); } return(0);}/********************************************************** BEA TUXEDO中服務(wù)請求的結(jié)構(gòu) struct tpsvcinfo { char name[ 32]; // service name invoked long flags; // describes service attributes char *data; // pointer to data long len; // request data length int cd; // connection descriptor long appkey; // application authentication key CLIENTID cltid;// client identifier }; typedef struct struct tpsvcinfo TPSVCINFO;************************************************************//********************************************************************//* 函數(shù): SERVERDB *//* 用途: 服務(wù)處理 *//* 原型: void SERVERDB(TPSVCINFO* svcinfo); *//* 參數(shù): svcinfo -- 服務(wù)請求 *//* 返回: 無 *//********************************************************************/void SERVERDB(TPSVCINFO* svcinfo){ sword col, errno, n, nvars; text *cp; char *pszPacketErr="數(shù)據(jù)請求包格式錯誤"; char fdbuf[4096]; char rowbuf[MAX_SENDBUF_LEN]; char linebuf[MAX_SENDBUF_LEN]; char sendbuf[MAX_SENDBUF_LEN]; text szOCISQL2[16192]; /* OCI請求SQL */ int fdlen=0,rowlen=0,vallen=0,sendlen=0; char *tpbuf; char *rowpos; int rownum=0,trownum=0; long revent; int fdvallen; time_t tmStart; int retcode;RestartSQLProcess: nOCIFunction=0; nOCIAffectedRow=0; DebugPrint((char*)svcinfo->data,svcinfo->len); /* 檢查服務(wù)請求結(jié)構(gòu)是否合法 */ if(UnpacketSQL(svcinfo->data,svcinfo->len,(char*)szOCISQL)==-1) { nOCIErrNo=ERROR_PACKET_FORMAT; strcpy((char*)szOCIErrMsg,pszPacketErr); goto FailReturn; } /* 處理SQL請求 */ /* 1. 分析SQL語句:1.1 判定是否存儲過程;1.2 判定是否 */ if(do_prevbinds(szOCISQL)==-1) { goto FailReturn; } if(oparse(&cda, (text *) szOCISQL, (sb4) -1,(sword) PARSE_NO_DEFER, (ub4) PARSE_V7_LNG)) { if(strncasecmp((char*)szOCISQL,"begin\n",strlen("begin\n"))) { sprintf((char*)szOCISQL2,"begin\n%s;end;\n",szOCISQL); if(oparse(&cda, (text *) szOCISQL2, (sb4) -1,(sword) PARSE_NO_DEFER, (ub4) PARSE_V7_LNG)) { oci_error(&cda); goto FailReturn; } } else { oci_error(&cda); goto FailReturn; } } /* 2. 保存SQL函數(shù)編碼. */ nOCIFunction = cda.ft; /* 3. 綁定輸入變量(這里不能有輸入變量). */ if(do_postbinds(&cda)==-1) /* !=0) */ { goto FailReturn; } /* 4. 對于查詢, 描述和定義選擇項目 */ if(nOCIFunction==FT_SELECT) { if ((nOCIFieldNum = describe_define(&cda)) == -1) { goto FailReturn; } } /* 5. 執(zhí)行SQL語句. */ if(oexec(&cda)) { oci_error(&cda); goto FailReturn; } /* 6. 對于非查詢操作,直接返回結(jié)果. */ if(nOCIFunction!=FT_SELECT) { nOCIAffectedRow=cda.rpc; if(nOCIFunction==FT_UPDATE||nOCIFunction==FT_DELETE ||nOCIFunction==FT_INSERT) sprintf((char*)szOCIErrMsg,"成功處理了%d行記錄.",cda.rpc); else strcpy((char*)szOCIErrMsg,"處理成功."); nOCIErrNo=0; goto FailReturn; } /*else */ /* 6. 提取查詢記錄. */ nOCIPacketNo=0; /* 預(yù)打包字段清單 */ fdlen=PacketFDDesc(fdbuf); nOCIErrNo=0; *szOCIErrMsg='\0'; trownum=rownum=0; *rowbuf='\0'; rowpos=rowbuf+LEN_BYTE_2; rowlen=LEN_BYTE_2; for (;;) { /* 提取一行內(nèi)容. */ if(ofetch(&cda)) { if(cda.rc == NO_DATA_FOUND) { if(nOCITranID==0) { if(nOCIErrNo==0)
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -