📄 serverdb.c
字号:
/***********************************************************************//* 1. tpsvrinit : 初始化函数 *//* 2. SERVERDB : 服务处理函数 */ /* 3. tpsvrdone : 结束服务 */ /***********************************************************************/#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函数号 */static int nOCIPacketNo; /* 当前包序号 */static int nOCIFieldNum; /* 选择字段数目*/static int nOCITranID=0; /* 事务ID */static int nOCIAffectedRow=0; /* 受操作影响的记录数 */static int nOCIRowLimits=0; /* 查询操作可提取的最大行数 */static int nOCIOutNum; /* 存储过程输出参数 */#define ERROR_PACKET_FORMAT 20001 /* 数据包格式错误 */#define ERROR_UNSOLVED_VARIABLE 20002 /* SQL包含没有未确定变量 */#define ERROR_SQL_FORMAT 20003 /* SQL包含初始化赋值错误 */#define DATA_SQL 0 /* SQL位 */#define DATA_RETCODE 1 /* 结果码 */#define DATA_OUTDESC 2 /* Outs描述 */#define DATA_OUTDATA 3 /* Outs内容 */#define DATA_FDDESC 4 /* 字段描述 */#define DATA_ROWS 5 /* 行内容 *//* SQL请求类型 :Insert,Update,Delete,Procedure */#define ST_UNKNOWN 'X' /* 未定类型 */#define ST_INSERT 'I' /* 执行Insert */#define ST_UPDATE 'U' /* 执行Update */#define ST_DELETE 'D' /* 执行Delete */#define ST_SELECT 'S' /* 执行Select */#define ST_PROCEDURE 'P' /* 执行存储过程等 *//* 返回数据类型 */#define DBTYPE_STRING 'S' /* 字符串 */#define DBTYPE_INT 'I' /* 整数 */#define DBTYPE_FLOAT 'F' /* 浮点数 */#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; 数据包长度 */ char PacketLen[4]; /* 数据包长度 */ char UserID[4]; /* 用户ID */ char TranID[4]; /* 事务ID */ char NextFlag; /* 后续标志 */ /*long RowLimits; 最大行数 */ char RowLimits[4]; /* 最大行数 */ char SQLType; /* SQL类型 */ char DataPart[6]; /* 数据部分 */} 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);*//******************************************************//* 函数:tpsvrinit *//* 用途:初始化TUXEDO服务 *//* 原型:int tpsvrinit(int argc, char** argv); *//* 参数:argc -- 命令行参数个数 *//* argv -- 命令行参数清单 *//* 返回:0 -- 成功; -1 -- 失败。 *//* 附注: *//* 这里,我们完成服务器到数据库的注册 *//******************************************************/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_ /* 打开事务管理器 */ if(tpopen()==-1) { userlog("Cannot my_open XA manager."); ologof(&lda); return(-1); } #endif return(0);}/******************************************************//* 函数:tpsvrdone *//* 用途:退出TUXEDO服务 *//* 原型:void tpsvrdone(void); *//* 参数:无 *//* 返回:无 *//* 附注: *//* 这里,我们从数据库退出 *//******************************************************/void tpsvrdone(void){ userlog("Stopping SERVERDB...\n"); #ifdef _USE_TRANS_ /* 关闭事务管理器 */ tpclose(); #endif /* 关闭数据库连接 */ if(oclose(&cda)) userlog("Error closing cursor!\n"); if(ologof(&lda)) userlog("Error logging off!\n");}/******************************************************//* 函数:ReConnectSQLServer *//* 用途:连接服务器 *//* 原型:sword ReConectSQLServer(); *//* 参数:无 *//* 返回: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"); /* 打开数据库光标用于访问 */ 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中服务请求的结构 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;************************************************************//********************************************************************//* 函数: SERVERDB *//* 用途: 服务处理 *//* 原型: void SERVERDB(TPSVCINFO* svcinfo); *//* 参数: svcinfo -- 服务请求 *//* 返回: 无 *//********************************************************************/void SERVERDB(TPSVCINFO* svcinfo){ sword col, errno, n, nvars; text *cp; char *pszPacketErr="数据请求包格式错误"; 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); /* 检查服务请求结构是否合法 */ 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函数编码. */ 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. 执行SQL语句. */ if(oexec(&cda)) { oci_error(&cda); goto FailReturn; } /* 6. 对于非查询操作,直接返回结果. */ 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; /* 预打包字段清单 */ fdlen=PacketFDDesc(fdbuf); nOCIErrNo=0; *szOCIErrMsg='\0'; trownum=rownum=0; *rowbuf='\0'; rowpos=rowbuf+LEN_BYTE_2; rowlen=LEN_BYTE_2; for (;;) { /* 提取一行内容. */ if(ofetch(&cda)) { if(cda.rc == NO_DATA_FOUND) { if(nOCITranID==0) { if(nOCIErrNo==0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -