📄 ifmxdb.c
字号:
SetDbNulls(DbInfo_t *pDbInfo){ if(pDbInfo->rlen==SQL_NULL_DATA && pDbInfo->pValue) { DebugHTML(__FILE__,__LINE__,3,"Fetched a Null"); memset(pDbInfo->pValue,0,pDbInfo->iLen); } switch (pDbInfo->iColType) { case SQL_DECIMAL: case SQL_DOUBLE: case SQL_REAL: case SQL_INTEGER: case SQL_SMALLINT: if((pDbInfo->iScale)==0) { char *p; for(p=pDbInfo->pValue;*p;p++)if(*p=='.')*p=0; } } return(eTrue);}/*/* Get the Next Available CursorIndex from/* the gaCDA array. */static eBoolean_tGetCursorIndex(int *piCursorIndex){ static int siCursorIndex; int iStart, i; for(i=0, iStart=siCursorIndex ;i==0 || (iStart != siCursorIndex && i>0) ;i++, siCursorIndex = (siCursorIndex+1)%MAX_CURSORS) { /* the gbaOpen array simply lets me know when /* a cursor has been opened or closed so that /* in this routine I can re-use cursors! */ if( gbaOpen[siCursorIndex]==eFalse ) { (*piCursorIndex) = siCursorIndex; return(eTrue); } } MsgPush("Exceeded Maximum Cursors"); return(eFalse);}/*/* Describe the BIND Variables.../* this is much simplified since the parsing of the SQL/* string itself is handled in the PrepareParameters() function/* which was a hack of the origional decrbindvars... */static eBoolean_tDescribeBindVars(SQLWEB_CURSOR *pCursor){ int iParamCnt=1; DbInfo_t *pDbInfo; for( pDbInfo=l_ffirst(pCursor->lBind); pDbInfo; pDbInfo=l_fnext(pCursor->lBind)) { RETCODE rc; if( !pDbInfo->pValue) { pDbInfo->pValue = DupBuf(""); pDbInfo->rlen = SQL_NULL_DATA; } else if( !*pDbInfo->pValue) { pDbInfo->rlen = SQL_NULL_DATA; } else pDbInfo->rlen = SQL_NTS; /* bug fix ... */ pDbInfo->rlen = SQL_NTS; /* bug fix ... */ rc=SQLBindParameter( gaCDA[pCursor->iCursorIndex] ,iParamCnt++ ,SQL_PARAM_INPUT ,SQL_C_CHAR /* SQL_C_CHAR */ ,SQL_CHAR /* SQL_CHAR */ ,pDbInfo->iLen+1 ,0 ,pDbInfo->pValue /* &pDbInfo->pValue[0] */ ,pDbInfo->iLen+1 ,&pDbInfo->rlen ); if(rc!=SQL_SUCCESS && rc!=SQL_SUCCESS_WITH_INFO) { PushDBErr(gaLDA[pCursor->pLDA->iLdaIndex] ,gaCDA[pCursor->iCursorIndex] ,"SQLBindParameter failed." ); MsgPush("s='?',b=%x",pDbInfo->pValue); return(eFalse); } DebugHTML(__FILE__,__LINE__,2,"Describe:Bound(%d: %s)",iParamCnt-1,pDbInfo->pValue); } return(eTrue);}/*/* Describe the SELECT Variables... */static eBoolean_tDescribeSelectVars(SQLWEB_CURSOR *pCursor){ SWORD NumCols, Col; RETCODE rc; UCHAR sColName [ MAX_ITEM_BUFFER_SIZE ]; SWORD iColNameSize = sizeof(sColName) ,iColType ,iScale ,iNullable ; UDWORD iLength; char *pBuf; DbInfo_t *pDbInfo; rc=SQLNumResultCols(gaCDA[pCursor->iCursorIndex], &NumCols); if(rc!=SQL_SUCCESS && rc!=SQL_SUCCESS_WITH_INFO) { PushDBErr(gaLDA[pCursor->pLDA->iLdaIndex] ,gaCDA[pCursor->iCursorIndex] ,"SQLNumResultCols failed." ); return(eFalse); } if(NumCols!=0) { gbaOpen[pCursor->iCursorIndex]=pCursor->bOpen=eTrue; } /* Describe each select-list item. */ for(Col=1;Col<=NumCols;Col++) { rc=SQLDescribeCol(gaCDA[pCursor->iCursorIndex] ,Col ,sColName ,(SWORD)sizeof(sColName) ,&iColNameSize ,&iColType ,&iLength ,&iScale ,&iNullable ); if(rc!=SQL_SUCCESS && rc!=SQL_SUCCESS_WITH_INFO) { PushDBErr(gaLDA[pCursor->pLDA->iLdaIndex] ,gaCDA[pCursor->iCursorIndex] ,"SQLDescribe failed." ); return(eFalse); } sColName[iColNameSize]=0; DebugHTML(__FILE__,__LINE__,2,"DbOpen:Desc:%s:Len=%d:Scale=%d:T=%d" ,sColName ,iLength ,iScale ,iColType ); switch (iColType) { case SQL_LONGVARBINARY: case SQL_LONGVARCHAR: iLength = 65533; break; case SQL_DATE: case SQL_TIMESTAMP: case SQL_DECIMAL: case SQL_DOUBLE: case SQL_INTEGER: case SQL_REAL: case SQL_SMALLINT: iLength=44; break; case SQL_CHAR: case SQL_VARCHAR: /* iLength set by Describe */ break; default: iLength = 32768; break; } /* /* Build a "DB" Symbol */ pDbInfo = NewDbInfo(); if(!pDbInfo){ MsgPush("malloc failed"); return(eFalse); } pDbInfo->pValue =(char*)malloc(iLength+1); pDbInfo->iLen =iLength+1; pDbInfo->iScale =iScale; pDbInfo->iColType=iColType; if(!pDbInfo->pValue) { /* Impossible occured! */ MsgPush("malloc failed"); return(eFalse); } memset(pDbInfo->pValue,0,iLength+1); ENQ(pCursor->lSelect,pDbInfo); /* For NULL Processing */ if(ISeTrue(GetSymbolValueREF((char*)sColName,&pBuf)) && strlen(pBuf)<=iLength) { strcpy(pDbInfo->pValue,pBuf); /* Don't assume a symbol was malloc'd, (you hosehead) /* Add Symbol will take care of memory leakage... */ } if(! *pDbInfo->pValue) pDbInfo->rlen = SQL_NULL_DATA; else pDbInfo->rlen = SQL_NTS; RETeFalse2(AddSymbol(SEL_SYMBOL ,DupBuf((const char*)sColName) ,pDbInfo->pValue ,eTrue ,(long)iLength+1 ) ,"AddSymbol(SEL,%s) Failed." ,(char*)sColName ); DebugHTML(__FILE__,__LINE__,2,"DbOpen:AddS(%s)",sColName); /* Let Informix Convert everything to STRING */ rc=SQLBindCol( gaCDA[pCursor->iCursorIndex] ,Col ,SQL_C_CHAR ,&pDbInfo->pValue[0] ,iLength+1 ,&pDbInfo->rlen ); if(rc!=SQL_SUCCESS && rc!=SQL_SUCCESS_WITH_INFO) { PushDBErr(gaLDA[pCursor->pLDA->iLdaIndex] ,gaCDA[pCursor->iCursorIndex] ,"SQLBindCol failed." ); return(eFalse); } } return(eTrue);}static DbInfo_t *NewDbInfo(){ DbInfo_t *pDbInfo; if(!glDbInfoList){ glDbInfoList=l_create("STACK"); if(!glDbInfoList) { MsgPush("NewDbInfo:l_create failed"); return(0); } } if(l_size(glDbInfoList)>0) { DebugHTML(__FILE__,__LINE__,3,"NewDbInfo:POP(%d)",l_size(glDbInfoList)); pDbInfo=(DbInfo_t*)POP(glDbInfoList); } else { pDbInfo=(DbInfo_t*)malloc(sizeof(DbInfo_t)); } if(!pDbInfo) { MsgPush("NewDbInfo:malloc or POP failed"); return(0); } (void)memset(pDbInfo,0,sizeof(DbInfo_t)); pDbInfo->rlen = SQL_NTS; return(pDbInfo);}static eBoolean_tFreeDbInfo(DbInfo_t *pDbInfo){ DebugHTML(__FILE__,__LINE__,3,"FreeDbInfo[%x]",pDbInfo); if(!glDbInfoList) { glDbInfoList=l_create("STACK"); if(!glDbInfoList) { MsgPush("FreeDbInfo:l_create failed"); return(eFalse); } } /* /* Free pValue.... Free(pDbInfo->pValue); */ /* /* Store This PI on the FreeLIst */ DebugHTML(__FILE__,__LINE__,3,"FreeDbInfo:PUSH(%d)",l_size(glDbInfoList)); PUSH(glDbInfoList,pDbInfo); return(eTrue);}/*/* New function for Informix prot. change the /* symbol references in the sql string to /* informix's '?' parameters so something like:/* select * from dual where a = :a/* becomes/* select * from dual where a = ?/* each symbol is converted into a ? parameter and the/* DbInfo is stuffed onto the lBind list for the/* cursor. */static eBoolean_tPrepareParameters(SQLWEB_CURSOR *pCursor){ char *pNewStmt, *cpNew; int i, n; eBoolean_t bLiteral; char *cp; /* New stmt will always be at at most the same size /* as the origional because any symbol reference is /* requires a ':' and a symbol name and the parameter /* is a single '?' */ cpNew = pNewStmt = malloc(strlen(pCursor->pStmt)+1); if(!pNewStmt) { MsgPush("Malloc Failed in PrepareParameters"); return(eFalse); } /* Find and bind input variables for placeholders. */ for (i=0, bLiteral=eFalse, cp=pCursor->pStmt; *cp; ) { DbInfo_t *pDbInfo; /* Single Quoted Strings are SQL literals */ if (*cp == '\'') { bLiteral = ISeTrue(bLiteral)?eFalse:eTrue; /* Toggle */ } /* Oh, boy, we've got a live one! */ /* if(*cp == ':' && ISeFalse(bLiteral) && *(cp+1) != '=') */ if(*cp == ':' && ISeFalse(bLiteral)) { char buf[MAX_SQL_IDENTIFIER]; for ( ++cp, n=0; *cp && (isalnum(*cp) || *cp == '_') && n < MAX_SQL_IDENTIFIER; cp++, n++ ) { buf[n]=*cp; } buf[n]=0; /* NULL the 'buf' Buffer */ /* if(! *cp) --cp; /* If this the end of the buffer, there /* is a problem because the outer loop */ /* increments the cp pointer again, /* BEYOND THE END OF THIS STRING!!! */ /* /* buf now points to the SYMBOL NAME /* so... go-n-get it! */ pDbInfo = NewDbInfo(); if(!pDbInfo){ MsgPush("malloc failed"); return(eFalse); } ENQ(pCursor->lBind,pDbInfo); if(ISeFalse(GetSymbolValueREF(buf,&pDbInfo->pValue))){ /* There is no symbol by that name, stick in NULL /* WARNING? */ pDbInfo->pValue=0; /* should have been done by Get.. */ /* pDbInfo->rlen = SQL_NULL_DATA; */ } DebugHTML(__FILE__,__LINE__,2 ,"DbOpen:GetS(%s:%s)" ,buf ,pDbInfo->pValue? pDbInfo->pValue: "" ); pDbInfo->iLen = pDbInfo->pValue ? strlen(pDbInfo->pValue) : 0; /* pDbInfo->ind = pDbInfo->iLen>0 ? 0 : -1; */ i++; /* Install the Informix place holder */ *cpNew++ = '?'; /* *cpNew++ = ' '; */ } /* end if (*cp == ':') */ else { /* Update the Modified SQLStmt */ *cpNew++ = *cp++; } } /* end for () */ /* NULL terminate the newly processed SQL stmt */ *cpNew=0; /* Update the pCursor Structure */ pCursor->pStmt = pNewStmt; DebugHTML(__FILE__,__LINE__,3,"DbSQL(%s) OK!",pNewStmt); return(eTrue);}#define ErrMsgLen 200static voidPushDBErr(HENV pLDA ,HSTMT pCDA ,char *pErrMsg ){ RETCODE rc = SQL_NO_DATA_FOUND; SWORD pcbErrorMsgLen = 0; SDWORD pfNativeError; UCHAR ErrMsg[ErrMsgLen]; char SqlState[6]; HENV henv = (HENV)0; HDBC hdbc = (HDBC)0; HSTMT hstmt = pCDA; if(pErrMsg) MsgPush("%s",pErrMsg); if(hstmt) { rc=SQLError(NULL,NULL,hstmt ,(UCHAR *)SqlState ,&pfNativeError ,(UCHAR *)ErrMsg ,ErrMsgLen ,&pcbErrorMsgLen ); } else if(hdbc) { rc=SQLError(NULL,hdbc,NULL ,(UCHAR *)SqlState ,&pfNativeError ,(UCHAR *)ErrMsg ,ErrMsgLen ,&pcbErrorMsgLen ); } else if (henv) { rc=SQLError(henv,NULL,NULL ,(UCHAR *)SqlState ,&pfNativeError ,(UCHAR *)ErrMsg ,ErrMsgLen ,&pcbErrorMsgLen ); } if(rc==SQL_SUCCESS || rc==SQL_SUCCESS_WITH_INFO) { MsgPush("DBERROR:IFMX:%d:%s:%s",pfNativeError,SqlState,ErrMsg); } else if (rc== SQL_NO_DATA_FOUND ) { MsgPush("DBERROR:IFMX:?:?:Unknown error"); } else { MsgPush("DBERROR:IFMX:?:?:Unknown error rc=%d",rc); } return;}static eBoolean_tFreeStmt(SQLWEB_CURSOR *pCursor){ RETCODE rc; rc=SQLFreeStmt( gaCDA[pCursor->iCursorIndex], SQL_CLOSE ); if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO ) { PushDBErr(gaLDA[pCursor->pLDA->iLdaIndex] ,gaCDA[pCursor->iCursorIndex] ,"oclose failed." ); return(eFalse); } gbaOpen[pCursor->iCursorIndex]=eFalse; return(eTrue);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -