EVOLUTION-MANAGER
Edit File: oci_wrapper.cpp
/****************************************************************************** * * Name: oci_wrapper.cpp * Project: Oracle Spatial GeoRaster Driver * Purpose: Limited wrapper for OCI (Oracle Call Interfaces) * Author: Ivan Lucena [ivan.lucena at oracle.com] * ****************************************************************************** * Copyright (c) 2008, Ivan Lucena * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************/ #include "oci_wrapper.h" CPL_CVSID("$Id: oci_wrapper.cpp 40616 2017-11-02 12:40:51Z ilucena $") static const OW_CellDepth ahOW_CellDepth[] = { {"8BIT_U", GDT_Byte}, {"16BIT_U", GDT_UInt16}, {"16BIT_S", GDT_Int16}, {"32BIT_U", GDT_UInt32}, {"32BIT_S", GDT_Int32}, {"32BIT_REAL", GDT_Float32}, {"64BIT_REAL", GDT_Float64}, {"32BIT_COMPLEX", GDT_CFloat32}, {"64BIT_COMPLEX", GDT_CFloat64}, {"1BIT", GDT_Byte}, {"2BIT", GDT_Byte}, {"4BIT", GDT_Byte} }; /*****************************************************************************/ /* OWConnection */ /*****************************************************************************/ OWConnection::OWConnection( OCIExtProcContext* poWithContext ) { pszUser = CPLStrdup( "" ); pszPassword = CPLStrdup( "" ); pszServer = CPLStrdup( "" ); hEnv = NULL; hError = NULL; hSvcCtx = NULL; hSession = NULL; hDescribe = NULL; hNumArrayTDO = NULL; hGeometryTDO = NULL; hGeoRasterTDO = NULL; hElemArrayTDO = NULL; hOrdnArrayTDO = NULL; bSuceeeded = false; nCharSize = 1; bExtProc = false; if( ! poWithContext ) { return; } // ------------------------------------------------------ // Retrieve connection handlers // ------------------------------------------------------ if( CheckError( OCIExtProcGetEnv( poWithContext, &hEnv, &hSvcCtx, &hError ), NULL ) ) { return; } // ------------------------------------------------------------------- // Get User Name and Schema from SYS_CONTEXT on EXTPROC // ------------------------------------------------------------------- char szUser[OWTEXT]; char szSchema[OWTEXT]; szUser[0] = '\0'; szSchema[0] = '\0'; OWStatement* poStmt = CreateStatement( "select sys_context('userenv','session_user'),\n" " sys_context('userenv','current_schema') || '.'\n" "from dual\n" ); poStmt->Define(szUser); poStmt->Define(szSchema); poStmt->Execute(); pszExtProcSchema = CPLStrdup( szSchema ); pszExtProcUser = CPLStrdup( szUser ); CPLDebug("GEOR","User from sys_context = %s", pszExtProcUser); delete poStmt; QueryVersion(); bSuceeeded = true; bExtProc = true; } OWConnection::OWConnection( const char* pszUserIn, const char* pszPasswordIn, const char* pszServerIn ) { pszUser = CPLStrdup( pszUserIn ); pszPassword = CPLStrdup( pszPasswordIn ); pszServer = CPLStrdup( pszServerIn ); hEnv = NULL; hError = NULL; hSvcCtx = NULL; hSession = NULL; hDescribe = NULL; hNumArrayTDO = NULL; hGeometryTDO = NULL; hGeoRasterTDO = NULL; hElemArrayTDO = NULL; hOrdnArrayTDO = NULL; bSuceeeded = false; nCharSize = 1; bExtProc = false; // ------------------------------------------------------ // Operational Systems's authentication option // ------------------------------------------------------ const char* pszUserId = "/"; ub4 eCred = OCI_CRED_RDBMS; if( EQUAL(pszServer, "") && EQUAL(pszPassword, "") && EQUAL(pszUser, "") ) { eCred = OCI_CRED_EXT; } else { pszUserId = pszUser; } // ------------------------------------------------------ // Initialize Environment handler // ------------------------------------------------------ if( CheckError( OCIEnvCreate( &hEnv, (ub4) ( OCI_DEFAULT | OCI_OBJECT | OCI_THREADED ), (dvoid *) 0, (dvoid * (*)(dvoid *, size_t)) 0, (dvoid * (*)(dvoid *, dvoid *, size_t)) 0, (void (*)(dvoid *, dvoid *)) 0, (size_t) 0, (dvoid **) 0), NULL ) ) { return; } // ------------------------------------------------------ // Initialize Error handler // ------------------------------------------------------ if( CheckError( OCIHandleAlloc( (dvoid *) hEnv, (dvoid **) &hError, OCI_HTYPE_ERROR, (size_t) 0, (dvoid **) 0), NULL ) ) { return; } // ------------------------------------------------------ // Initialize Server Context // ------------------------------------------------------ if( CheckError( OCIHandleAlloc( (dvoid *) hEnv, (dvoid **) &hSvcCtx, OCI_HTYPE_SVCCTX, (size_t) 0, (dvoid **) 0), hError ) ) { return; } // ------------------------------------------------------ // Allocate Server and Authentication (Session) handler // ------------------------------------------------------ if( CheckError( OCIHandleAlloc( (dvoid *) hEnv, (dvoid **) &hServer, (ub4) OCI_HTYPE_SERVER, (size_t) 0, (dvoid **) 0), hError ) ) { return; } if( CheckError( OCIHandleAlloc((dvoid *) hEnv, (dvoid **) &hSession, (ub4) OCI_HTYPE_SESSION, (size_t) 0, (dvoid **) 0), hError ) ) { return; } // ------------------------------------------------------ // Attach to the server // ------------------------------------------------------ if( CheckError( OCIServerAttach( hServer, hError, (text*) pszServer, (sb4) strlen((char*) pszServer), (ub4) 0), hError ) ) { return; } if( CheckError( OCIAttrSet((dvoid *) hSession, (ub4) OCI_HTYPE_SESSION, (dvoid *) pszUserId, (ub4) strlen((char*) pszUserId), (ub4) OCI_ATTR_USERNAME, hError), hError ) ) { return; } if( CheckError( OCIAttrSet((dvoid *) hSession, (ub4) OCI_HTYPE_SESSION, (dvoid *) pszPassword, (ub4) strlen((char *) pszPassword), (ub4) OCI_ATTR_PASSWORD, hError), hError ) ) { return; } if( CheckError( OCIAttrSet( (dvoid *) hSvcCtx, OCI_HTYPE_SVCCTX, (dvoid *) hServer, (ub4) 0, OCI_ATTR_SERVER, (OCIError *) hError), hError ) ) { return; } // ------------------------------------------------------ // Initialize Session // ------------------------------------------------------ if( CheckError( OCISessionBegin(hSvcCtx, hError, hSession, eCred, (ub4) OCI_DEFAULT), hError ) ) { return; } // ------------------------------------------------------ // Initialize Service // ------------------------------------------------------ if( CheckError( OCIAttrSet((dvoid *) hSvcCtx, (ub4) OCI_HTYPE_SVCCTX, (dvoid *) hSession, (ub4) 0, (ub4) OCI_ATTR_SESSION, hError), hError ) ) { return; } QueryVersion(); bSuceeeded = true; // ------------------------------------------------------ // Initialize/Describe types // ------------------------------------------------------ CheckError( OCIHandleAlloc( (dvoid*) hEnv, (dvoid**) (dvoid*) &hDescribe, (ub4) OCI_HTYPE_DESCRIBE, (size_t) 0, (dvoid**) NULL ), hError ); hNumArrayTDO = DescribeType( SDO_NUMBER_ARRAY ); hGeometryTDO = DescribeType( SDO_GEOMETRY ); hGeoRasterTDO = DescribeType( SDO_GEORASTER ); hElemArrayTDO = DescribeType( SDO_ELEM_INFO_ARRAY); hOrdnArrayTDO = DescribeType( SDO_ORDINATE_ARRAY); if( nVersion > 10 ) { hPCTDO = DescribeType( SDO_PC ); } } void OWConnection::QueryVersion() { // ------------------------------------------------------ // Get Character Size based on current Locale // ------------------------------------------------------ OCINlsNumericInfoGet( hEnv, hError, &nCharSize, OCI_NLS_CHARSET_MAXBYTESZ ); // ------------------------------------------------------ // Get Server Version // ------------------------------------------------------ char szVersionTxt[OWTEXT]; OCIServerVersion ( hSvcCtx, hError, (text*) szVersionTxt, (ub4) OWTEXT, (ub1) OCI_HTYPE_SVCCTX ); nVersion = OWParseServerVersion( szVersionTxt ); } OWConnection::~OWConnection() { CPLFree( pszUser ); CPLFree( pszPassword ); CPLFree( pszServer ); DestroyType( hNumArrayTDO ); DestroyType( hGeometryTDO ); DestroyType( hGeoRasterTDO ); DestroyType( hElemArrayTDO ); DestroyType( hOrdnArrayTDO ); OCIHandleFree( (dvoid*) hDescribe, (ub4) OCI_HTYPE_DESCRIBE); // ------------------------------------------------------ // Do not free OCI handles from a external procedure // ------------------------------------------------------ if( bExtProc ) { return; } // ------------------------------------------------------ // Terminate session and free OCI handles // ------------------------------------------------------ if( hSvcCtx && hError && hSession ) { OCISessionEnd( hSvcCtx, hError, hSession, (ub4) 0); } if( hSvcCtx && hError) { OCIServerDetach( hServer, hError, (ub4) OCI_DEFAULT); } if( hServer ) { OCIHandleFree((dvoid *) hServer, (ub4) OCI_HTYPE_SERVER); } if( hSvcCtx ) { OCIHandleFree((dvoid *) hSvcCtx, (ub4) OCI_HTYPE_SVCCTX); } if( hError ) { OCIHandleFree((dvoid *) hError, (ub4) OCI_HTYPE_ERROR); } if( hSession ) { OCIHandleFree((dvoid *) hSession, (ub4) OCI_HTYPE_SESSION); } } OCIType* OWConnection::DescribeType( const char *pszTypeName ) { OCIParam* hParam = NULL; OCIRef* hRef = NULL; OCIType* hType = NULL; CheckError( OCIDescribeAny( hSvcCtx, hError, (text*) pszTypeName, (ub4) strlen( pszTypeName ), (ub1) OCI_OTYPE_NAME, (ub1) OCI_DEFAULT, (ub1) OCI_PTYPE_TYPE, hDescribe ), hError ); CheckError( OCIAttrGet( hDescribe, (ub4) OCI_HTYPE_DESCRIBE, (dvoid*) &hParam, (ub4*) NULL, (ub4) OCI_ATTR_PARAM, hError ), hError ); CheckError( OCIAttrGet( hParam, (ub4) OCI_DTYPE_PARAM, (dvoid*) &hRef, (ub4*) NULL, (ub4) OCI_ATTR_REF_TDO, hError ), hError ); CheckError( OCIObjectPin( hEnv, hError, hRef, (OCIComplexObject*) NULL, (OCIPinOpt) OCI_PIN_ANY, (OCIDuration) OCI_DURATION_SESSION, (OCILockOpt) OCI_LOCK_NONE, (dvoid**) (dvoid*) &hType ), hError ); /* OCIType* hType = NULL; CheckError( OCITypeByName( hEnv, hError, hSvcCtx, (text*) TYPE_OWNER, (ub4) strlen(TYPE_OWNER), (text*) pszTypeName, (ub4) strlen(pszTypeName), (text*) 0, (ub4) 0, OCI_DURATION_SESSION, OCI_TYPEGET_HEADER, &hType), hError ); */ return hType; } void OWConnection::CreateType( sdo_geometry** pphData ) { CheckError( OCIObjectNew( hEnv, hError, hSvcCtx, OCI_TYPECODE_OBJECT, hGeometryTDO, (dvoid *) 0, OCI_DURATION_CALL, TRUE, (dvoid **) pphData), hError ); } void OWConnection::DestroyType( OCIType* phType ) { if( phType == NULL ) { return; } CheckError( OCIObjectUnpin( hEnv, hError, (dvoid*) phType ), hError ); } void OWConnection::DestroyType( sdo_geometry** pphData ) { CheckError( OCIObjectFree( hEnv, hError, (dvoid*) *pphData, (ub2) 0), NULL ); } void OWConnection::CreateType( OCIArray** phData, OCIType* otype) { CheckError( OCIObjectNew( hEnv, hError, hSvcCtx, OCI_TYPECODE_VARRAY, otype, (dvoid *)NULL, OCI_DURATION_SESSION, FALSE, (dvoid **)phData), hError ); } void OWConnection::DestroyType( OCIArray** phData ) { CheckError( OCIObjectFree( hEnv, hError, (OCIColl*) *phData, (ub2) 0), NULL ); } OWStatement* OWConnection::CreateStatement( const char* pszStatement ) { OWStatement* poStatement = new OWStatement( this, pszStatement ); return poStatement; } OCIParam* OWConnection::GetDescription( char* pszTable ) { OCIParam* phParam = NULL; OCIParam* phAttrs = NULL; CheckError( OCIDescribeAny ( hSvcCtx, hError, (text*) pszTable, (ub4) strlen( pszTable ), (ub1) OCI_OTYPE_NAME, (ub1) OCI_DEFAULT, (ub1) OCI_PTYPE_TABLE, hDescribe ), hError ); CheckError( OCIAttrGet( hDescribe, (ub4) OCI_HTYPE_DESCRIBE, (dvoid*) &phParam, (ub4*) NULL, (ub4) OCI_ATTR_PARAM, hError ), hError ); CheckError( OCIAttrGet( phParam, (ub4) OCI_DTYPE_PARAM, (dvoid*) &phAttrs, (ub4*) NULL, (ub4) OCI_ATTR_LIST_COLUMNS, hError ), hError ); return phAttrs; } bool OWConnection::GetNextField( OCIParam* phTable, int nIndex, char* pszName, int* pnType, int* pnSize, int* pnPrecision, signed short* pnScale ) { OCIParam* hParmDesc = NULL; sword nStatus = 0; nStatus = OCIParamGet( phTable, (ub4) OCI_DTYPE_PARAM, hError, (dvoid**) &hParmDesc, //Warning (ub4) nIndex + 1 ); if( nStatus != OCI_SUCCESS ) { return false; } char* pszFieldName = NULL; ub4 nNameLength = 0; CheckError( OCIAttrGet( hParmDesc, (ub4) OCI_DTYPE_PARAM, (dvoid*) &pszFieldName, (ub4*) &nNameLength, (ub4) OCI_ATTR_NAME, hError ), hError ); ub2 nOCIType = 0; CheckError( OCIAttrGet( hParmDesc, (ub4) OCI_DTYPE_PARAM, (dvoid*) &nOCIType, (ub4*) NULL, (ub4) OCI_ATTR_DATA_TYPE, hError ), hError ); ub2 nOCILen = 0; CheckError( OCIAttrGet( hParmDesc, (ub4) OCI_DTYPE_PARAM, (dvoid*) &nOCILen, (ub4*) NULL, (ub4) OCI_ATTR_DATA_SIZE, hError ), hError ); unsigned short nOCIPrecision = 0; sb1 nOCIScale = 0; if( nOCIType == SQLT_NUM ) { CheckError( OCIAttrGet( hParmDesc, (ub4) OCI_DTYPE_PARAM, (dvoid*) &nOCIPrecision, (ub4*) 0, (ub4) OCI_ATTR_PRECISION, hError ), hError ); CheckError( OCIAttrGet( hParmDesc, (ub4) OCI_DTYPE_PARAM, (dvoid*) &nOCIScale, (ub4*) 0, (ub4) OCI_ATTR_SCALE, hError ), hError ); if( nOCIPrecision > 255 ) // Lesson learned from ogrocisession.cpp { nOCIPrecision = nOCIPrecision / 256; } } nNameLength = MIN( nNameLength, OWNAME ); strncpy( pszName, pszFieldName, nNameLength); pszName[nNameLength] = '\0'; *pnType = (int) nOCIType; *pnSize = (int) nOCILen; *pnPrecision = (int) nOCIPrecision; *pnScale = (signed short) nOCIScale; return true; } bool OWConnection::StartTransaction() { CheckError( OCITransStart ( hSvcCtx, hError, (uword) 30, OCI_TRANS_NEW), hError ); return true; } bool OWConnection::Commit() { CheckError( OCITransCommit ( hSvcCtx, hError, OCI_DEFAULT), hError ); return true; } /*****************************************************************************/ /* OWStatement */ /*****************************************************************************/ OWStatement::OWStatement( OWConnection* pConnect, const char* pszStatement ) { poConnection = pConnect; nStmtMode = OCI_DEFAULT; nNextCol = 0; nNextBnd = 0; hError = poConnection->hError; nFetchCount = 0; // ----------------------------------------------------------- // Create Statement handler // ----------------------------------------------------------- OCIStmt* hStatement = NULL; CheckError( OCIHandleAlloc( (dvoid*) poConnection->hEnv, (dvoid**) (dvoid*) &hStatement, (ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid**) NULL), hError ); hStmt = hStatement; // Save Statement Handle // ----------------------------------------------------------- // Prepare Statement // ----------------------------------------------------------- CheckError( OCIStmtPrepare( hStmt, hError, (text*) pszStatement, (ub4) strlen(pszStatement), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT ), hError ); // ----------------------------------------------------------- // Get Statement type // ----------------------------------------------------------- ub2 nStmtType; CheckError( OCIAttrGet( (dvoid*) hStmt, (ub4) OCI_HTYPE_STMT, (dvoid*) &nStmtType, (ub4*) 0, (ub4) OCI_ATTR_STMT_TYPE, hError ), hError ); // ----------------------------------------------------------- // Set Statement mode // ----------------------------------------------------------- if( nStmtType != OCI_STMT_SELECT ) { nStmtMode = OCI_DEFAULT; } CPLDebug("PL/SQL","\n%s\n", pszStatement); } OWStatement::~OWStatement() { OCIHandleFree( (dvoid*) hStmt, (ub4) OCI_HTYPE_STMT); } bool OWStatement::Execute( int nRows ) { sword nStatus = OCIStmtExecute( poConnection->hSvcCtx, hStmt, hError, (ub4) nRows, (ub4) 0, (OCISnapshot*) NULL, (OCISnapshot*) NULL, nStmtMode ); if( CheckError( nStatus, hError ) ) { return false; } if( nStatus == OCI_SUCCESS_WITH_INFO || nStatus == OCI_NO_DATA ) { return false; } return true; } bool OWStatement::Fetch( int nRows ) { sword nStatus = 0; nStatus = OCIStmtFetch2 ( (OCIStmt*) hStmt, (OCIError*) poConnection->hError, (ub4) nRows, (ub2) OCI_FETCH_NEXT, (sb4) 0, (ub4) OCI_DEFAULT ); if( nStatus == OCI_NO_DATA ) { return false; } if( CheckError( nStatus, poConnection->hError ) ) { return false; } return true; } void OWStatement::Bind( int* pnData ) { OCIBind* hBind = NULL; nNextBnd++; CheckError( OCIBindByPos( hStmt, &hBind, hError, (ub4) nNextBnd, (dvoid*) pnData, (sb4) sizeof(int), (ub2) SQLT_INT, (void*) NULL, (ub2*) NULL, (ub2*) NULL, (ub4) 0, (ub4*) NULL, (ub4) OCI_DEFAULT ), hError ); } void OWStatement::Bind( long* pnData ) { OCIBind* hBind = NULL; nNextBnd++; CheckError( OCIBindByPos( hStmt, &hBind, hError, (ub4) nNextBnd, (dvoid*) pnData, (sb4) sizeof(long), (ub2) SQLT_INT, (void*) NULL, (ub2*) NULL, (ub2*) NULL, (ub4) 0, (ub4*) NULL, (ub4) OCI_DEFAULT ), hError ); } void OWStatement::Bind( long long* pnData ) { OCIBind* hBind = NULL; nNextBnd++; CheckError( OCIBindByPos( hStmt, &hBind, hError, (ub4) nNextBnd, (dvoid*) pnData, (sb4) sizeof(long long), (ub2) SQLT_INT, (void*) NULL, (ub2*) NULL, (ub2*) NULL, (ub4) 0, (ub4*) NULL, (ub4) OCI_DEFAULT ), hError ); } void OWStatement::Bind( double* pnData ) { OCIBind* hBind = NULL; nNextBnd++; CheckError( OCIBindByPos( hStmt, &hBind, hError, (ub4) nNextBnd, (dvoid*) pnData, (sb4) sizeof(double), (ub2) SQLT_BDOUBLE, (void*) NULL, (ub2*) NULL, (ub2*) NULL, (ub4) 0, (ub4*) NULL, (ub4) OCI_DEFAULT ), hError ); } void OWStatement::Bind( char* pData, long nData ) { OCIBind* hBind = NULL; nNextBnd++; CheckError( OCIBindByPos( hStmt, &hBind, hError, (ub4) nNextBnd, (dvoid*) pData, (sb4) nData, (ub2) SQLT_LBI, (void*) NULL, (ub2*) NULL, (ub2*) NULL, (ub4) 0, (ub4*) NULL, (ub4) OCI_DEFAULT ), hError ); } void OWStatement::Bind( sdo_geometry** pphData ) { OCIBind* hBind = NULL; nNextBnd++; CheckError( OCIBindByPos( hStmt, &hBind, hError, (ub4) nNextBnd, (dvoid*) NULL, (sb4) 0, (ub2) SQLT_NTY, (void*) NULL, (ub2*) NULL, (ub2*) NULL, (ub4) 0, (ub4*) NULL, (ub4) OCI_DEFAULT ), hError ); CheckError( OCIBindObject( hBind, hError, poConnection->hGeometryTDO, (dvoid**) pphData, (ub4*) 0, (dvoid**) 0, (ub4*) 0), hError ); } void OWStatement::Bind( OCILobLocator** pphLocator ) { OCIBind* hBind = NULL; nNextBnd++; CheckError( OCIBindByPos( hStmt, &hBind, hError, (ub4) nNextBnd, (dvoid*) pphLocator, (sb4) -1, (ub2) SQLT_CLOB, (void*) NULL, (ub2*) NULL, (ub2*) NULL, (ub4) 0, (ub4*) NULL, (ub4) OCI_DEFAULT ), hError ); } void OWStatement::Bind( OCIArray** pphData, OCIType* type ) { OCIBind* hBind = NULL; nNextBnd++; CheckError( OCIBindByPos( hStmt, &hBind, hError, (ub4) nNextBnd, (dvoid*) 0, (sb4) 0, (ub2) SQLT_NTY, (void*) NULL, (ub2*) NULL, (ub2*) NULL, (ub4) 0, (ub4*) NULL, (ub4) OCI_DEFAULT ), hError ); CheckError( OCIBindObject( hBind, hError, type, (dvoid **)pphData, (ub4 *)0, (dvoid **)0, (ub4 *)0 ), hError); } void OWStatement::Bind( char* pszData, int nSize ) { OCIBind* hBind = NULL; nNextBnd++; CheckError( OCIBindByPos( hStmt, &hBind, hError, (ub4) nNextBnd, (dvoid*) pszData, (sb4) nSize, (ub2) SQLT_STR, (void*) NULL, (ub2*) NULL, (ub2*) NULL, (ub4) 0, (ub4*) NULL, (ub4) OCI_DEFAULT ), hError ); } void OWStatement::Define( int* pnData ) { OCIDefine* hDefine = NULL; nNextCol++; CheckError( OCIDefineByPos( hStmt, &hDefine, hError, (ub4) nNextCol, (dvoid*) pnData, (sb4) sizeof(int), (ub2) SQLT_INT, (void*) NULL, (ub2*) NULL, (ub2*) NULL, (ub4) OCI_DEFAULT ), hError ); } void OWStatement::Define( long* pnData ) { OCIDefine* hDefine = NULL; nNextCol++; CheckError( OCIDefineByPos( hStmt, &hDefine, hError, (ub4) nNextCol, (dvoid*) pnData, (sb4) sizeof(long int), (ub2) SQLT_INT, (void*) NULL, (ub2*) NULL, (ub2*) NULL, (ub4) OCI_DEFAULT ), hError ); } void OWStatement::Define( long long* pnData ) { OCIDefine* hDefine = NULL; nNextCol++; CheckError( OCIDefineByPos( hStmt, &hDefine, hError, (ub4) nNextCol, (dvoid*) pnData, (sb4) sizeof(long long), (ub2) SQLT_INT, (void*) NULL, (ub2*) NULL, (ub2*) NULL, (ub4) OCI_DEFAULT ), hError ); } void OWStatement::Define( double* pfdData ) { OCIDefine* hDefine = NULL; nNextCol++; CheckError( OCIDefineByPos( hStmt, &hDefine, hError, (ub4) nNextCol, (dvoid*) pfdData, (sb4) sizeof(double), (ub2) SQLT_BDOUBLE, (void*) NULL, (ub2*) NULL, (ub2*) NULL, (ub4) OCI_DEFAULT ), hError ); } void OWStatement::Define( char* pszData, int nSize ) { OCIDefine* hDefine = NULL; nNextCol++; CheckError( OCIDefineByPos( hStmt, &hDefine, hError, (ub4) nNextCol, (dvoid*) pszData, (sb4) nSize, (ub2) SQLT_STR, (void*) NULL, (ub2*) NULL, (ub2*) NULL, (ub4) OCI_DEFAULT ), hError ); } void OWStatement::Define( OCILobLocator** pphLocator ) { OCIDefine* hDefine = NULL; nNextCol++; CheckError( OCIDescriptorAlloc( poConnection->hEnv, (void**) pphLocator, OCI_DTYPE_LOB, 0, 0), hError ); CheckError( OCIDefineByPos( hStmt, &hDefine, hError, (ub4) nNextCol, (dvoid*) pphLocator, (sb4) 0, (ub2) SQLT_BLOB, (void*) NULL, (ub2*) NULL, (ub2*) NULL, (ub4) OCI_DEFAULT ), hError ); } void OWStatement::WriteCLob( OCILobLocator** pphLocator, char* pszData ) { nNextCol++; CheckError( OCIDescriptorAlloc( poConnection->hEnv, (void**) pphLocator, OCI_DTYPE_LOB, (size_t) 0, (dvoid **) 0), hError ); CheckError( OCILobCreateTemporary( poConnection->hSvcCtx, poConnection->hError, (OCILobLocator*) *pphLocator, (ub4) OCI_DEFAULT, (ub1) OCI_DEFAULT, (ub1) OCI_TEMP_CLOB, false, OCI_DURATION_SESSION ), hError ); ub4 nAmont = (ub4) strlen(pszData); CheckError( OCILobWrite( poConnection->hSvcCtx, hError, *pphLocator, (ub4*) &nAmont, (ub4) 1, (dvoid*) pszData, (ub4) strlen(pszData), (ub1) OCI_ONE_PIECE, (dvoid*) NULL, NULL, (ub2) 0, (ub1) SQLCS_IMPLICIT ), hError ); } void OWStatement::Define( OCIArray** pphData ) { OCIDefine* hDefine = NULL; nNextCol++; CheckError( OCIDefineByPos( hStmt, &hDefine, hError, (ub4) nNextCol, (dvoid*) NULL, (sb4) 0, (ub2) SQLT_NTY, (void*) NULL, (ub2*) NULL, (ub2*) NULL, (ub4) OCI_DEFAULT ), hError ); CheckError( OCIDefineObject( hDefine, hError, poConnection->hNumArrayTDO, (dvoid**) pphData, (ub4*) NULL, (dvoid**) NULL, (ub4*) NULL ), hError ); } void OWStatement::Define( sdo_georaster** pphData ) { OCIDefine* hDefine = NULL; nNextCol++; CheckError( OCIDefineByPos( hStmt, &hDefine, hError, (ub4) nNextCol, (dvoid*) NULL, (sb4) 0, (ub2) SQLT_NTY, (void*) NULL, (ub2*) NULL, (ub2*) NULL, (ub4) OCI_DEFAULT ), hError ); CheckError( OCIDefineObject( hDefine, hError, poConnection->hGeoRasterTDO, (dvoid**) pphData, (ub4*) NULL, (dvoid**) NULL, (ub4*) NULL ), hError ); } void OWStatement::Define( sdo_geometry** pphData ) { OCIDefine* hDefine = NULL; nNextCol++; CheckError( OCIDefineByPos( hStmt, &hDefine, hError, (ub4) nNextCol, (dvoid*) NULL, (sb4) 0, (ub2) SQLT_NTY, (void*) NULL, (ub2*) NULL, (ub2*) NULL, (ub4) OCI_DEFAULT ), hError ); CheckError( OCIDefineObject( hDefine, hError, poConnection->hGeometryTDO, (dvoid**) pphData, (ub4*) NULL, (dvoid**) NULL, (ub4*) NULL ), hError ); } void OWStatement::Define( sdo_pc** pphData ) { OCIDefine* hDefine = NULL; nNextCol++; CheckError( OCIDefineByPos( hStmt, &hDefine, hError, (ub4) nNextCol, (dvoid*) NULL, (sb4) 0, (ub2) SQLT_NTY, (void*) NULL, (ub2*) NULL, (ub2*) NULL, (ub4) OCI_DEFAULT ), hError ); CheckError( OCIDefineObject( hDefine, hError, poConnection->hPCTDO, (dvoid**) pphData, (ub4*) NULL, (dvoid**) NULL, (ub4*) NULL ), hError ); } void OWStatement::Define( OCILobLocator** pphLocator, long nIterations ) { OCIDefine* hDefine = NULL; nNextCol++; long i; for (i = 0; i < nIterations; i++) { OCIDescriptorAlloc( poConnection->hEnv, (void**) &pphLocator[i], OCI_DTYPE_LOB, (size_t) 0, (void**) 0); } CheckError( OCIDefineByPos( hStmt, &hDefine, hError, (ub4) nNextCol, (dvoid*) pphLocator, (sb4) -1, (ub2) SQLT_BLOB, (void*) 0, (ub2*) 0, (ub2*) 0, (ub4) OCI_DEFAULT ), hError ); } int OWStatement::GetInteger( OCINumber* ppoData ) { sb4 nRetVal; CheckError( OCINumberToInt( hError, ppoData, (uword) sizeof(sb4), OCI_NUMBER_SIGNED, (dvoid *) &nRetVal ), hError ); return nRetVal; } double OWStatement::GetDouble( OCINumber* ppoData ) { double dfRetVal = 0.0; CheckError( OCINumberToReal( hError, ppoData, (uword) sizeof(dfRetVal), (dvoid*) &dfRetVal ), hError ); return dfRetVal; } char* OWStatement::GetString( OCIString* ppoData ) { return (char*) OCIStringPtr( poConnection->hEnv, ppoData ); } void OWStatement::Free( OCILobLocator** pphLocator, int nCount ) { if( nCount > 0 && pphLocator != NULL ) { int i = 0; for (i = 0; i < nCount; i++) { if( pphLocator[i] != NULL ) { OCIDescriptorFree(&pphLocator[i], OCI_DTYPE_LOB); } } } } int OWStatement::GetElement( OCIArray** ppoData, int nIndex, int* pnResult ) { boolean exists; OCINumber *oci_number = NULL; ub4 element_type; *pnResult = 0; if( CheckError( OCICollGetElem( poConnection->hEnv, hError, (OCIColl*) *ppoData, (sb4) nIndex, (boolean*) &exists, (dvoid**) (dvoid*) &oci_number, (dvoid**) NULL ), hError ) ) { return *pnResult; } if( CheckError( OCINumberToInt( hError, oci_number, (uword) sizeof(ub4), OCI_NUMBER_UNSIGNED, (dvoid *) &element_type ), hError ) ) { return *pnResult; } *pnResult = (int) element_type; return *pnResult; } double OWStatement::GetElement( OCIArray** ppoData, int nIndex, double* pdfResult ) { boolean exists; OCINumber *oci_number = NULL; double element_type; *pdfResult = 0.0; if( CheckError( OCICollGetElem( poConnection->hEnv, hError, (OCIColl*) *ppoData, (sb4) nIndex, (boolean*) &exists, (dvoid**) (dvoid*) &oci_number, NULL ), hError ) ) { return *pdfResult; } if( CheckError( OCINumberToReal( hError, oci_number, (uword) sizeof(double), (dvoid *) &element_type ), hError ) ) { return *pdfResult; } *pdfResult = (double) element_type; return *pdfResult; } void OWStatement::AddElement( OCIArray* poData, int nValue ) { OCINumber oci_number; CheckError(OCINumberFromInt(hError, (dvoid*) &nValue, (uword) sizeof(ub4), OCI_NUMBER_UNSIGNED, (OCINumber*) &oci_number), hError); CheckError(OCICollAppend(poConnection->hEnv, hError, (OCINumber*) &oci_number, (dvoid*) 0, (OCIColl*) poData), hError); } void OWStatement::AddElement( OCIArray* poData, double dfValue ) { OCINumber oci_number; CheckError(OCINumberFromReal(hError, (dvoid*) &dfValue, (uword) sizeof(double), (OCINumber*) &oci_number), hError); CheckError(OCICollAppend(poConnection->hEnv, hError, (OCINumber*) &oci_number, (dvoid*) 0, (OCIColl*) poData), hError); } unsigned long OWStatement::GetBlobLength( OCILobLocator* phLocator ) { ub8 nSize = (ub8) 0; if( CheckError( OCILobGetLength2( poConnection->hSvcCtx, poConnection->hError, phLocator, (ub8*) &nSize), hError ) ) { return 0; } return nSize; } unsigned long OWStatement::ReadBlob( OCILobLocator* phLocator, void* pBuffer, unsigned long nSize ) { return ReadBlob( phLocator, pBuffer, (unsigned long) 1, nSize ); } unsigned long OWStatement::ReadBlob( OCILobLocator* phLocator, void* pBuffer, unsigned long nOffset, unsigned long nSize ) { ub8 nAmont = (ub8) nSize; if( CheckError( OCILobRead2( poConnection->hSvcCtx, hError, phLocator, (ub8*) &nAmont, (ub8*) 0, (ub8) nOffset, (void*) pBuffer, (ub8) nSize, (ub1) OCI_ONE_PIECE, (dvoid*) 0, (OCICallbackLobRead2) 0, (ub2) 0, (ub1) SQLCS_IMPLICIT), hError ) ) { return 0; } return (unsigned long) nAmont; } bool OWStatement::WriteBlob( OCILobLocator* phLocator, void* pBuffer, unsigned long nSize ) { ub8 nAmont = WriteBlob( phLocator, pBuffer, (unsigned long) 1, nSize ); return ( nAmont == (ub8) nSize ); } unsigned long OWStatement::WriteBlob( OCILobLocator* phLocator, void* pBuffer, unsigned long nOffset, unsigned long nSize ) { ub8 nAmont = (ub8) nSize; if( CheckError( OCILobWrite2( poConnection->hSvcCtx, hError, phLocator, (ub8*) &nAmont, (ub8*) 0, (ub8) nOffset, (dvoid*) pBuffer, (ub8) nSize, (ub1) OCI_ONE_PIECE, (dvoid *) 0, (OCICallbackLobWrite2) 0, (ub2) 0, (ub1) SQLCS_IMPLICIT ), hError ) ) { return (unsigned long) 0; } return nAmont; } char* OWStatement::ReadCLob( OCILobLocator* phLocator ) { ub4 nSize = 0; ub4 nAmont = 0; char* pszBuffer = NULL; if( CheckError( OCILobGetLength ( poConnection->hSvcCtx, hError, phLocator, (ub4*) &nSize ), hError ) ) { return NULL; } nSize *= this->poConnection->nCharSize; pszBuffer = (char*) VSIMalloc( sizeof(char*) * nSize ); if( pszBuffer == NULL) { return NULL; } if( CheckError( OCILobRead( poConnection->hSvcCtx, hError, phLocator, (ub4*) &nAmont, (ub4) 1, (dvoid*) pszBuffer, (ub4) nSize, (dvoid*) NULL, NULL, (ub2) 0, (ub1) SQLCS_IMPLICIT ), hError ) ) { CPLFree( pszBuffer ); return NULL; } pszBuffer[nAmont] = '\0'; return pszBuffer; } void OWStatement::BindName( const char* pszName, int* pnData ) { OCIBind* hBind = NULL; CheckError( OCIBindByName( (OCIStmt*) hStmt, (OCIBind**) &hBind, (OCIError*) hError, (text*) pszName, (sb4) -1, (dvoid*) pnData, (sb4) sizeof(int), (ub2) SQLT_INT, (dvoid*) NULL, (ub2*) NULL, (ub2*) NULL, (ub4) 0, (ub4*) NULL, (ub4) OCI_DEFAULT ), hError ); } void OWStatement::BindName( const char* pszName, long* pnData ) { OCIBind* hBind = NULL; CheckError( OCIBindByName( (OCIStmt*) hStmt, (OCIBind**) &hBind, (OCIError*) hError, (text*) pszName, (sb4) -1, (dvoid*) pnData, (sb4) sizeof(long), (ub2) SQLT_INT, (dvoid*) NULL, (ub2*) NULL, (ub2*) NULL, (ub4) 0, (ub4*) NULL, (ub4) OCI_DEFAULT ), hError ); } void OWStatement::BindName( const char* pszName, long long* pnData ) { OCIBind* hBind = NULL; CheckError( OCIBindByName( (OCIStmt*) hStmt, (OCIBind**) &hBind, (OCIError*) hError, (text*) pszName, (sb4) -1, (dvoid*) pnData, (sb4) sizeof(long long), (ub2) SQLT_INT, (dvoid*) NULL, (ub2*) NULL, (ub2*) NULL, (ub4) 0, (ub4*) NULL, (ub4) OCI_DEFAULT ), hError ); } void OWStatement::BindName( const char* pszName, double* pnData ) { OCIBind* hBind = NULL; CheckError( OCIBindByName( (OCIStmt*) hStmt, (OCIBind**) &hBind, (OCIError*) hError, (text*) pszName, (sb4) -1, (dvoid*) pnData, (sb4) sizeof(double), (ub2) SQLT_BDOUBLE, (dvoid*) NULL, (ub2*) NULL, (ub2*) NULL, (ub4) 0, (ub4*) NULL, (ub4) OCI_DEFAULT ), hError ); } void OWStatement::BindName( const char* pszName, char* pszData, int nSize ) { OCIBind* hBind = NULL; CheckError( OCIBindByName( (OCIStmt*) hStmt, (OCIBind**) &hBind, (OCIError*) hError, (text*) pszName, (sb4) -1, (dvoid*) pszData, (sb4) nSize, (ub2) SQLT_STR, (dvoid*) NULL, (ub2*) NULL, (ub2*) NULL, (ub4) 0, (ub4*) NULL, (ub4) OCI_DEFAULT ), hError ); } void OWStatement::BindName( const char* pszName, OCILobLocator** pphLocator ) { OCIBind* hBind = NULL; CheckError( OCIDescriptorAlloc( poConnection->hEnv, (void**) pphLocator, OCI_DTYPE_LOB, 0, 0), hError ); CheckError( OCIBindByName( (OCIStmt*) hStmt, (OCIBind**) &hBind, (OCIError*) hError, (text*) pszName, (sb4) -1, (dvoid*) pphLocator, (sb4) -1, (ub2) SQLT_CLOB, (dvoid*) NULL, (ub2*) NULL, (ub2*) NULL, (ub4) 0, (ub4*) NULL, (ub4) OCI_DEFAULT ), hError ); } void OWStatement::BindArray( void* pData, long nSize ) { OCIBind* hBind = NULL; nNextBnd++; CheckError( OCIBindByPos( hStmt, &hBind, hError, (ub4) nNextBnd, (dvoid*) pData, (sb4) nSize * sizeof(double), (ub2) SQLT_BIN, (void*) NULL, (ub2*) NULL, (ub2*) NULL, (ub4) 0, (ub4*) NULL, (ub4) OCI_DEFAULT ), hError ); CheckError( OCIBindArrayOfStruct( hBind, hError, (ub4) nSize * sizeof(double), (ub4) 0, (ub4) 0, (ub4) 0), hError ); } /*****************************************************************************/ /* Check for valid integer number in a string */ /*****************************************************************************/ bool OWIsNumeric( const char *pszText ) { if( pszText == NULL ) { return false; } const char* pszPos = pszText; while( *pszPos != '\0' ) { if( *pszPos < '0' || *pszPos > '9' ) return false; pszPos++; } return true; } /*****************************************************************************/ /* Remove quotes */ /*****************************************************************************/ char *OWRemoveQuotes( const char* pszText ) { const size_t nSize = strlen(pszText); if( nSize > 2 && pszText[0] != '"' && pszText[nSize - 1] != '"' ) { return CPLStrdup( pszText ); } char *pszResult = reinterpret_cast<char*>( CPLMalloc(nSize - 1) ); CPLStrlcpy( pszResult, &pszText[1], nSize - 1); return pszResult; } /*****************************************************************************/ /* To upper if there is no quotes */ /*****************************************************************************/ void OWUpperIfNoQuotes( char* pszText ) { const size_t nSize = strlen( pszText ); if( nSize > 2 && pszText[0] == '"' && pszText[nSize - 1] == '"' ) { return; } for( size_t i = 0; i < nSize; i++ ) { pszText[i] = toupper( pszText[i] ); } } /*****************************************************************************/ /* Parse Value after a Hint on a string */ /*****************************************************************************/ static const char *OWParseValue( const char* pszText, const char* pszSeparators, const char* pszHint, int nOffset ) { if( pszText == NULL ) return 0; int i = 0; int nCount = 0; char **papszTokens = CSLTokenizeString2( pszText, pszSeparators, CSLT_PRESERVEQUOTES ); nCount = CSLCount( papszTokens ); const char* pszResult = ""; for( i = 0; ( i + nOffset ) < nCount; i++ ) { if( EQUAL( papszTokens[i], pszHint ) ) { pszResult = CPLStrdup( papszTokens[i + nOffset] ); break; } } CSLDestroy( papszTokens ); return pszResult; } /*****************************************************************************/ /* Parse SDO_GEOR.INIT entries */ /*****************************************************************************/ /* Input Examples: * * "ID, RASTER, NAME VALUES (102, SDO_GEOR.INIT('RDT_80', 80), 'Nashua')" * */ const char* OWParseSDO_GEOR_INIT( const char* pszInsert, int nField ) { char szUpcase[OWTEXT]; char* pszIn = NULL; strcpy( szUpcase, pszInsert ); for( pszIn = szUpcase; *pszIn != '\0'; pszIn++ ) { *pszIn = (char) toupper( *pszIn ); } char* pszStart = strstr( szUpcase, "SDO_GEOR.INIT" ); if( pszStart == NULL ) { return ""; } char* pszEnd = strstr( pszStart, ")" ); if( pszEnd == NULL ) { return ""; } pszStart += strlen("SDO_GEOR."); pszEnd++; int nLength = static_cast<int>(pszEnd - pszStart + 1); char szBuffer[OWTEXT]; strncpy( szBuffer, pszStart, nLength ); szBuffer[nLength] = '\0'; const char* pszValue = OWParseValue( szBuffer, " (,)", "INIT", nField ); return EQUAL( pszValue, "" ) ? "NULL" : pszValue; } /*****************************************************************************/ /* Parse Release Version */ /*****************************************************************************/ /* Input Examples: * * "Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - Production * With the Partitioning, OLAP, Data Mining and Real Application Testing options" * */ int OWParseServerVersion( const char* pszText ) { const char* pszValue = OWParseValue( pszText, " .", "Release", 1 ); return pszValue == NULL ? 0 : atoi( pszValue ); } /*****************************************************************************/ /* Parse EPSG Codes */ /*****************************************************************************/ /* Input Examples: * * DATUM["World Geodetic System 1984 (EPSG ID 6326)", * SPHEROID["WGS 84 (EPSG ID 7030)",6378137,298.257223563]], * PROJECTION["UTM zone 50N (EPSG OP 16050)"], */ int OWParseEPSG( const char* pszText ) { const char* pszValue = OWParseValue( pszText, " ()", "EPSG", 2 ); return pszValue == NULL ? 0 : atoi( pszValue ); } /*****************************************************************************/ /* Convert Data type description */ /*****************************************************************************/ GDALDataType OWGetDataType( const char* pszCellDepth ) { unsigned int i; for( i = 0; i < (sizeof(ahOW_CellDepth) / sizeof(OW_CellDepth)); i++ ) { if( EQUAL( ahOW_CellDepth[i].pszValue, pszCellDepth ) ) { return ahOW_CellDepth[i].eDataType; } } return GDT_Unknown; } /*****************************************************************************/ /* Convert Data type description */ /*****************************************************************************/ const char* OWSetDataType( const GDALDataType eType ) { unsigned int i; for( i = 0; i < (sizeof(ahOW_CellDepth) / sizeof(OW_CellDepth)); i++ ) { if( ahOW_CellDepth[i].eDataType == eType ) { return ahOW_CellDepth[i].pszValue; } } return "Unknown"; } /*****************************************************************************/ /* Check for Failure */ /*****************************************************************************/ bool CheckError( sword nStatus, OCIError* hError ) { text szMsg[OWTEXT]; sb4 nCode = 0; switch ( nStatus ) { case OCI_SUCCESS: return false; break; case OCI_NEED_DATA: CPLError( CE_Failure, CPLE_AppDefined, "OCI_NEED_DATA\n" ); break; case OCI_NO_DATA: CPLError( CE_Failure, CPLE_AppDefined, "OCI_NODATA\n" ); break; case OCI_INVALID_HANDLE: CPLError( CE_Failure, CPLE_AppDefined, "OCI_INVALID_HANDLE" ); break; case OCI_STILL_EXECUTING: CPLError( CE_Failure, CPLE_AppDefined, "OCI_STILL_EXECUTE\n" ); break; case OCI_CONTINUE: CPLError( CE_Failure, CPLE_AppDefined, "OCI_CONTINUE\n" ); break; case OCI_ERROR: case OCI_SUCCESS_WITH_INFO: if( hError == NULL) { CPLError( CE_Failure, CPLE_AppDefined, "OCI_ERROR with no error handler" ); } OCIErrorGet( (dvoid *) hError, (ub4) 1, (text *) NULL, &nCode, szMsg, (ub4) sizeof(szMsg), OCI_HTYPE_ERROR); if( nCode == 1405 ) // Null field { return false; } CPLError( CE_Failure, CPLE_AppDefined, "%s", szMsg ); break; default: if( hError == NULL) { CPLError( CE_Failure, CPLE_AppDefined, "OCI_ERROR with no error handler" ); } OCIErrorGet( (dvoid *) hError, (ub4) 1, (text *) NULL, &nCode, szMsg, (ub4) sizeof(szMsg), OCI_HTYPE_ERROR); CPLError( CE_Failure, CPLE_AppDefined, "%s", szMsg ); break; } return true; }