1 /******************************************************************************
2  * $Id: $
3  *
4  * Name:     oci_wrapper.cpp
5  * Project:  Oracle Spatial GeoRaster Driver
6  * Purpose:  Limited wrapper for OCI (Oracle Call Interfaces)
7  * Author:   Ivan Lucena [ivan.lucena at oracle.com]
8  *
9  ******************************************************************************
10  * Copyright (c) 2008, Ivan Lucena
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a
13  * copy of this software and associated documentation files (the "Software"),
14  * to deal in the Software without restriction, including without limitation
15  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16  * and/or sell copies of the Software, and to permit persons to whom the
17  * Software is furnished to do so, subject to the following conditions:
18  *
19  * The above copyright notice and this permission notice shall be included
20  * in all copies or substantial portions of the Software.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28  * DEALINGS IN THE SOFTWARE.
29  ****************************************************************************/
30 
31 #include "oci_wrapper.h"
32 
33 static const OW_CellDepth ahOW_CellDepth[] = {
34     {"8BIT_U",          GDT_Byte},
35     {"16BIT_U",         GDT_UInt16},
36     {"16BIT_S",         GDT_Int16},
37     {"32BIT_U",         GDT_UInt32},
38     {"32BIT_S",         GDT_Int32},
39     {"32BIT_REAL",      GDT_Float32},
40     {"64BIT_REAL",      GDT_Float64},
41     {"32BIT_COMPLEX",   GDT_CFloat32},
42     {"64BIT_COMPLEX",   GDT_CFloat64},
43     {"1BIT",            GDT_Byte},
44     {"2BIT",            GDT_Byte},
45     {"4BIT",            GDT_Byte}
46 };
47 
48 /*****************************************************************************/
49 /*                            OWConnection                                   */
50 /*****************************************************************************/
51 
OWConnection(const char * pszUserIn,const char * pszPasswordIn,const char * pszServerIn)52 OWConnection::OWConnection( const char* pszUserIn,
53                             const char* pszPasswordIn,
54                             const char* pszServerIn )
55 {
56     pszUser         = CPLStrdup( pszUserIn );
57     pszPassword     = CPLStrdup( pszPasswordIn );
58     pszServer       = CPLStrdup( pszServerIn );
59     hEnv            = NULL;
60     hError          = NULL;
61     hSvcCtx         = NULL;
62     hDescribe       = NULL;
63     hNumArrayTDO    = NULL;
64     hGeometryTDO    = NULL;
65     hGeoRasterTDO   = NULL;
66     hElemArrayTDO   = NULL;
67     hOrdnArrayTDO   = NULL;
68     bSuceeeded      = false;
69     nCharSize       = 1;
70 
71     // ------------------------------------------------------
72     //  Operational Systems's authentication option
73     // ------------------------------------------------------
74 
75     const char* pszUserId = "/";
76 
77     ub4 eCred = OCI_CRED_RDBMS;
78 
79     if( EQUAL(pszServer, "") &&
80         EQUAL(pszPassword, "") &&
81         EQUAL(pszUser, "") )
82     {
83         eCred = OCI_CRED_EXT;
84     }
85     else
86     {
87         pszUserId = pszUser;
88     }
89 
90     // ------------------------------------------------------
91     //  Initialize Environment handler
92     // ------------------------------------------------------
93 
94     if( OCIEnvCreate( &hEnv,
95         (ub4) ( OCI_DEFAULT | OCI_OBJECT | OCI_THREADED ),
96         (dvoid *) 0, (dvoid * (*)(dvoid *, size_t)) 0,
97         (dvoid * (*)(dvoid *, dvoid *, size_t)) 0,
98         (void (*)(dvoid *, dvoid *)) 0, (size_t) 0,
99         (dvoid **) 0), NULL )
100     {
101         return;
102     }
103 
104     // ------------------------------------------------------
105     //  Initialize Error handler
106     // ------------------------------------------------------
107 
108     if( CheckError( OCIHandleAlloc( (dvoid *) hEnv, (dvoid **) &hError,
109         OCI_HTYPE_ERROR, (size_t) 0, (dvoid **) 0), NULL ) )
110     {
111         return;
112     }
113 
114     // ------------------------------------------------------
115     //  Initialize Server Context
116     // ------------------------------------------------------
117 
118     if( CheckError( OCIHandleAlloc( (dvoid *) hEnv, (dvoid **) &hSvcCtx,
119         OCI_HTYPE_SVCCTX, (size_t) 0, (dvoid **) 0), hError ) )
120     {
121         return;
122     }
123 
124     // ------------------------------------------------------
125     //  Allocate Server and Authentication (Session) handler
126     // ------------------------------------------------------
127 
128     if( CheckError( OCIHandleAlloc( (dvoid *) hEnv, (dvoid **) &hServer,
129         (ub4) OCI_HTYPE_SERVER, (size_t) 0, (dvoid **) 0), hError ) )
130     {
131         return;
132     }
133 
134     if( CheckError( OCIHandleAlloc((dvoid *) hEnv, (dvoid **)&hSession,
135         (ub4) OCI_HTYPE_SESSION, (size_t) 0, (dvoid **) 0), hError ) )
136     {
137         return;
138     }
139 
140     // ------------------------------------------------------
141     //  Attach to the server
142     // ------------------------------------------------------
143 
144     if( CheckError( OCIServerAttach( hServer, hError, (text*) pszServer,
145         (sb4) strlen((char*) pszServer), (ub4) 0), hError ) )
146     {
147         return;
148     }
149 
150     if( CheckError( OCIAttrSet((dvoid *) hSession, (ub4) OCI_HTYPE_SESSION,
151         (dvoid *) pszUserId, (ub4) strlen( pszUserId),
152         (ub4) OCI_ATTR_USERNAME, hError), hError ) )
153     {
154         return;
155     }
156 
157     if( CheckError( OCIAttrSet((dvoid *) hSession, (ub4) OCI_HTYPE_SESSION,
158         (dvoid *) pszPassword, (ub4) strlen((char *) pszPassword),
159         (ub4) OCI_ATTR_PASSWORD, hError), hError ) )
160     {
161         return;
162     }
163 
164     if( CheckError( OCIAttrSet( (dvoid *) hSvcCtx, OCI_HTYPE_SVCCTX, (dvoid *)hServer,
165         (ub4) 0, OCI_ATTR_SERVER, (OCIError *) hError), hError ) )
166     {
167         return;
168     }
169 
170     // ------------------------------------------------------
171     //  Initialize Session
172     // ------------------------------------------------------
173 
174     if( CheckError( OCISessionBegin(hSvcCtx, hError, hSession, eCred,
175         (ub4) OCI_DEFAULT), hError ) )
176     {
177         return;
178     }
179 
180     // ------------------------------------------------------
181     //  Initialize Service
182     // ------------------------------------------------------
183 
184     if( CheckError( OCIAttrSet((dvoid *) hSvcCtx, (ub4) OCI_HTYPE_SVCCTX,
185         (dvoid *) hSession, (ub4) 0,
186         (ub4) OCI_ATTR_SESSION, hError), hError ) )
187     {
188         return;
189     }
190 
191     bSuceeeded = true;
192 
193     // ------------------------------------------------------
194     //  Get Character Size based on current Locale
195     // ------------------------------------------------------
196 
197     OCINlsNumericInfoGet( hEnv, hError,
198         &nCharSize, OCI_NLS_CHARSET_MAXBYTESZ );
199 
200     // ------------------------------------------------------
201     //  Get Server Version
202     // ------------------------------------------------------
203 
204     char szVersionTxt[OWTEXT];
205 
206     OCIServerVersion (
207         hSvcCtx,
208         hError,
209         (text*) szVersionTxt,
210         (ub4) OWTEXT,
211         (ub1) OCI_HTYPE_SVCCTX );
212 
213     nVersion = OWParseServerVersion( szVersionTxt );
214 
215     // ------------------------------------------------------
216     //  Initialize/Describe types
217     // ------------------------------------------------------
218 
219     CheckError( OCIHandleAlloc(
220         (dvoid*) hEnv,
221         (dvoid**) (dvoid*) &hDescribe,
222         (ub4) OCI_HTYPE_DESCRIBE,
223         (size_t) 0,
224         (dvoid**) NULL ), hError );
225 
226     hNumArrayTDO    = DescribeType( SDO_NUMBER_ARRAY );
227     hGeometryTDO    = DescribeType( SDO_GEOMETRY );
228     hGeoRasterTDO   = DescribeType( SDO_GEORASTER );
229     hElemArrayTDO   = DescribeType( SDO_ELEM_INFO_ARRAY);
230     hOrdnArrayTDO   = DescribeType( SDO_ORDINATE_ARRAY);
231 
232     if( nVersion > 10 )
233     {
234         hPCTDO      = DescribeType( SDO_PC );
235     }
236 }
237 
~OWConnection()238 OWConnection::~OWConnection()
239 {
240     OCIHandleFree( (dvoid*) hDescribe, (ub4) OCI_HTYPE_DESCRIBE);
241 
242     if( hSvcCtx && hError && hSession )
243         OCISessionEnd( hSvcCtx, hError, hSession, (ub4) 0);
244 
245     if( hSvcCtx && hError)
246         OCIServerDetach( hServer, hError, (ub4) OCI_DEFAULT);
247 
248     if( hServer )
249         OCIHandleFree((dvoid *) hServer, (ub4) OCI_HTYPE_SERVER);
250 
251     if( hSvcCtx )
252         OCIHandleFree((dvoid *) hSvcCtx, (ub4) OCI_HTYPE_SVCCTX);
253 
254     if( hError )
255         OCIHandleFree((dvoid *) hError, (ub4) OCI_HTYPE_ERROR);
256 
257     if( hSession )
258         OCIHandleFree((dvoid *) hSession, (ub4) OCI_HTYPE_SESSION);
259 }
260 
DescribeType(const char * pszTypeName)261 OCIType* OWConnection::DescribeType( const char *pszTypeName )
262 {
263     OCIParam* hParam    = NULL;
264     OCIRef*   hRef      = NULL;
265     OCIType*  hType     = NULL;
266 
267     CheckError( OCIDescribeAny(
268         hSvcCtx,
269         hError,
270         (text*) pszTypeName,
271         (ub4) strlen( pszTypeName ),
272         (ub1) OCI_OTYPE_NAME,
273         (ub1) OCI_DEFAULT,
274         (ub1) OCI_PTYPE_TYPE,
275         hDescribe ), hError );
276 
277     CheckError( OCIAttrGet(
278         hDescribe,
279         (ub4) OCI_HTYPE_DESCRIBE,
280         (dvoid*) &hParam,
281         (ub4*) NULL,
282         (ub4) OCI_ATTR_PARAM,
283         hError ), hError );
284 
285     CheckError( OCIAttrGet(
286         hParam,
287         (ub4) OCI_DTYPE_PARAM,
288         (dvoid*) &hRef,
289         (ub4*) NULL,
290         (ub4) OCI_ATTR_REF_TDO,
291         hError ), hError );
292 
293     CheckError( OCIObjectPin(
294         hEnv,
295         hError,
296         hRef,
297         (OCIComplexObject*) NULL,
298         (OCIPinOpt) OCI_PIN_ANY,
299         (OCIDuration) OCI_DURATION_SESSION,
300         (OCILockOpt) OCI_LOCK_NONE,
301         (dvoid**) (dvoid*) &hType ), hError );
302 
303     return hType;
304 }
305 
CreateType(sdo_geometry ** pphData)306 void OWConnection::CreateType( sdo_geometry** pphData )
307 {
308     CheckError( OCIObjectNew(
309         hEnv,
310         hError,
311         hSvcCtx,
312         OCI_TYPECODE_OBJECT,
313         hGeometryTDO,
314         (dvoid *) 0,
315         OCI_DURATION_CALL,
316         TRUE,
317         (dvoid **) pphData), hError );
318 }
319 
DestroyType(sdo_geometry ** pphData)320 void OWConnection::DestroyType( sdo_geometry** pphData )
321 {
322     CheckError( OCIObjectFree(
323         hEnv,
324         hError,
325         (dvoid*) *pphData,
326         (ub2) 0), NULL );
327 }
328 
CreateType(OCIArray ** phData,OCIType * otype)329 void OWConnection::CreateType( OCIArray** phData, OCIType* otype)
330 {
331     CheckError( OCIObjectNew(   hEnv,
332         hError,
333         hSvcCtx,
334         OCI_TYPECODE_VARRAY,
335         otype,
336         (dvoid *)NULL,
337         OCI_DURATION_SESSION,
338         FALSE,
339         (dvoid **)phData), hError );
340 }
341 
DestroyType(OCIArray ** phData)342 void OWConnection::DestroyType( OCIArray** phData )
343 {
344     CheckError( OCIObjectFree(
345         hEnv,
346         hError,
347         (OCIColl*) *phData,
348         (ub2) 0), NULL );
349 }
350 
CreateStatement(const char * pszStatement)351 OWStatement* OWConnection::CreateStatement( const char* pszStatement )
352 {
353     OWStatement* poStatement = new OWStatement( this, pszStatement );
354 
355     return poStatement;
356 }
357 
GetDescription(char * pszTable)358 OCIParam* OWConnection::GetDescription( char* pszTable )
359 {
360     OCIParam*    phParam    = NULL;
361     OCIParam*    phAttrs    = NULL;
362 
363     CheckError( OCIDescribeAny (
364         hSvcCtx,
365         hError,
366         (text*) pszTable,
367         (ub4) strlen( pszTable ),
368         (ub1) OCI_OTYPE_NAME,
369         (ub1) OCI_DEFAULT,
370         (ub1) OCI_PTYPE_TABLE,
371         hDescribe ), hError );
372 
373     CheckError( OCIAttrGet(
374         hDescribe,
375         (ub4) OCI_HTYPE_DESCRIBE,
376         (dvoid*) &phParam,
377         (ub4*) NULL,
378         (ub4) OCI_ATTR_PARAM,
379         hError ), hError );
380 
381     CheckError( OCIAttrGet(
382         phParam,
383         (ub4) OCI_DTYPE_PARAM,
384         (dvoid*) &phAttrs,
385         (ub4*) NULL,
386         (ub4) OCI_ATTR_LIST_COLUMNS,
387         hError ), hError );
388 
389     return phAttrs;
390 }
391 
GetNextField(OCIParam * phTable,int nIndex,char * pszName,int * pnType,int * pnSize,int * pnPrecision,signed short * pnScale)392 bool OWConnection::GetNextField( OCIParam* phTable,
393                                  int nIndex,
394                                  char* pszName,
395                                  int* pnType,
396                                  int* pnSize,
397                                  int* pnPrecision,
398                                  signed short* pnScale )
399 {
400     OCIParam* hParmDesc = NULL;
401 
402     sword nStatus = 0;
403 
404     nStatus = OCIParamGet(
405         phTable,
406         (ub4) OCI_DTYPE_PARAM,
407         hError,
408         (dvoid**) &hParmDesc,   //Warning
409         (ub4) nIndex + 1 );
410 
411     if( nStatus != OCI_SUCCESS )
412     {
413         return false;
414     }
415 
416     char* pszFieldName = NULL;
417     ub4 nNameLength = 0;
418 
419     CheckError( OCIAttrGet(
420         hParmDesc,
421         (ub4) OCI_DTYPE_PARAM,
422         (dvoid*) &pszFieldName,
423         (ub4*) &nNameLength,
424         (ub4) OCI_ATTR_NAME,
425         hError ), hError );
426 
427     ub2 nOCIType = 0;
428 
429     CheckError( OCIAttrGet(
430         hParmDesc,
431         (ub4) OCI_DTYPE_PARAM,
432         (dvoid*) &nOCIType,
433         (ub4*) NULL,
434         (ub4) OCI_ATTR_DATA_TYPE,
435         hError ), hError );
436 
437     ub2 nOCILen = 0;
438 
439     CheckError( OCIAttrGet(
440         hParmDesc,
441         (ub4) OCI_DTYPE_PARAM,
442         (dvoid*) &nOCILen,
443         (ub4*) NULL,
444         (ub4) OCI_ATTR_DATA_SIZE,
445         hError ), hError );
446 
447     unsigned short nOCIPrecision = 0;
448     sb1 nOCIScale = 0;
449 
450     if( nOCIType == SQLT_NUM )
451     {
452         CheckError( OCIAttrGet(
453             hParmDesc,
454             (ub4) OCI_DTYPE_PARAM,
455             (dvoid*) &nOCIPrecision,
456             (ub4*) 0,
457             (ub4) OCI_ATTR_PRECISION,
458             hError ), hError );
459 
460         CheckError( OCIAttrGet(
461             hParmDesc,
462             (ub4) OCI_DTYPE_PARAM,
463             (dvoid*) &nOCIScale,
464             (ub4*) 0,
465             (ub4) OCI_ATTR_SCALE,
466             hError ), hError );
467 
468         if( nOCIPrecision > 255 ) // Lesson learned from ogrocisession.cpp
469         {
470             nOCIPrecision = nOCIPrecision / 256;
471         }
472     }
473 
474     nNameLength = MIN( nNameLength, OWNAME );
475 
476     strncpy( pszName, pszFieldName, nNameLength);
477     pszName[nNameLength] = '\0';
478 
479     *pnType      = (int) nOCIType;
480     *pnSize      = (int) nOCILen;
481     *pnPrecision = (int) nOCIPrecision;
482     *pnScale     = (signed short) nOCIScale;
483 
484     return true;
485 
486 }
487 
StartTransaction()488 bool OWConnection::StartTransaction()
489 {
490     CheckError( OCITransStart (
491         hSvcCtx,
492         hError,
493         (uword) 30,
494         OCI_TRANS_NEW), hError );
495 
496     return true;
497 }
498 
Commit()499 bool OWConnection::Commit()
500 {
501     CheckError( OCITransCommit (
502         hSvcCtx,
503         hError,
504         OCI_DEFAULT), hError );
505 
506     return true;
507 }
508 
509 /*****************************************************************************/
510 /*                           OWStatement                                     */
511 /*****************************************************************************/
512 
OWStatement(OWConnection * pConnect,const char * pszStatement)513 OWStatement::OWStatement( OWConnection* pConnect, const char* pszStatement )
514 {
515     poConnection    = pConnect;
516     nStmtMode       = OCI_DEFAULT;
517     nNextCol        = 0;
518     nNextBnd        = 0;
519     hError          = poConnection->hError;
520 
521     //  -----------------------------------------------------------
522     //  Create Statement handler
523     //  -----------------------------------------------------------
524 
525     OCIStmt* hStatement;
526 
527     CheckError( OCIHandleAlloc( (dvoid*) poConnection->hEnv,
528         (dvoid**) (dvoid*) &hStatement,
529         (ub4) OCI_HTYPE_STMT,
530         (size_t) 0,
531         (dvoid**) NULL), hError );
532 
533     hStmt = hStatement;   // Save Statement Handle
534 
535     //  -----------------------------------------------------------
536     //  Prepare Statement
537     //  -----------------------------------------------------------
538 
539     CheckError( OCIStmtPrepare( hStmt,
540         hError,
541         (text*) pszStatement,
542         (ub4) strlen(pszStatement),
543         (ub4) OCI_NTV_SYNTAX,
544         (ub4) OCI_DEFAULT ), hError );
545 
546     //  -----------------------------------------------------------
547     //  Get Statement type
548     //  -----------------------------------------------------------
549 
550     ub2 nStmtType;
551 
552     CheckError( OCIAttrGet( (dvoid*) hStmt,
553         (ub4) OCI_HTYPE_STMT,
554         (dvoid*) &nStmtType,
555         (ub4*) 0,
556         (ub4) OCI_ATTR_STMT_TYPE,
557         hError ), hError );
558 
559     //  -----------------------------------------------------------
560     //  Set Statement mode
561     //  -----------------------------------------------------------
562 
563     if( nStmtType != OCI_STMT_SELECT )
564     {
565         nStmtMode = OCI_DEFAULT;
566     }
567 
568     CPLDebug("PL/SQL","\n%s\n", pszStatement);
569 }
570 
~OWStatement()571 OWStatement::~OWStatement()
572 {
573     OCIHandleFree( (dvoid*) hStmt, (ub4) OCI_HTYPE_STMT);
574 }
575 
Execute(int nRows)576 bool OWStatement::Execute( int nRows )
577 {
578     sword nStatus = OCIStmtExecute( poConnection->hSvcCtx,
579         hStmt,
580         hError,
581         (ub4) nRows,
582         (ub4) 0,
583         (OCISnapshot*) NULL,
584         (OCISnapshot*) NULL,
585         nStmtMode );
586 
587     if( CheckError( nStatus, hError ) )
588     {
589         return false;
590     }
591 
592 
593     if( nStatus == OCI_SUCCESS_WITH_INFO || nStatus == OCI_NO_DATA )
594     {
595         return false;
596     }
597 
598     return true;
599 }
600 
Fetch(int nRows)601 bool OWStatement::Fetch( int nRows )
602 {
603     sword nStatus = 0;
604 
605     nStatus = OCIStmtFetch2 (
606         (OCIStmt*) hStmt,
607         (OCIError*) poConnection->hError,
608         (ub4) nRows,
609         (ub2) OCI_FETCH_NEXT,
610         (sb4) 0,
611         (ub4) OCI_DEFAULT );
612 
613     if( nStatus == OCI_NO_DATA )
614     {
615         return false;
616     }
617 
618     if( CheckError( nStatus, poConnection->hError ) )
619     {
620         return false;
621     }
622 
623     return true;
624 }
625 
Bind(int * pnData)626 void OWStatement::Bind( int* pnData )
627 {
628     OCIBind* hBind = NULL;
629 
630     nNextBnd++;
631 
632     CheckError( OCIBindByPos(
633         hStmt,
634         &hBind,
635         hError,
636         (ub4) nNextBnd,
637         (dvoid*) pnData,
638         (sb4) sizeof(int),
639         (ub2) SQLT_INT,
640         (void*) NULL,
641         (ub2*) NULL,
642         (ub2*) NULL,
643         (ub4) NULL,
644         (ub4) NULL,
645         (ub4) OCI_DEFAULT ),
646         hError );
647 }
648 
Bind(long * pnData)649 void OWStatement::Bind( long* pnData )
650 {
651     OCIBind* hBind = NULL;
652 
653     nNextBnd++;
654 
655     CheckError( OCIBindByPos(
656         hStmt,
657         &hBind,
658         hError,
659         (ub4) nNextBnd,
660         (dvoid*) pnData,
661         (sb4) sizeof(long),
662         (ub2) SQLT_INT,
663         (void*) NULL,
664         (ub2*) NULL,
665         (ub2*) NULL,
666         (ub4) NULL,
667         (ub4) NULL,
668         (ub4) OCI_DEFAULT ),
669         hError );
670 }
671 
Bind(double * pnData)672 void OWStatement::Bind( double* pnData )
673 {
674     OCIBind* hBind = NULL;
675 
676     nNextBnd++;
677 
678     CheckError( OCIBindByPos(
679         hStmt,
680         &hBind,
681         hError,
682         (ub4) nNextBnd,
683         (dvoid*) pnData,
684         (sb4) sizeof(double),
685         (ub2) SQLT_BDOUBLE,
686         (void*) NULL,
687         (ub2*) NULL,
688         (ub2*) NULL,
689         (ub4) NULL,
690         (ub4) NULL,
691         (ub4) OCI_DEFAULT ),
692         hError );
693 }
694 
Bind(char * pData,long nData)695 void OWStatement::Bind( char* pData, long nData )
696 {
697     OCIBind* hBind = NULL;
698 
699     nNextBnd++;
700 
701     CheckError( OCIBindByPos(
702         hStmt,
703         &hBind,
704         hError,
705         (ub4) nNextBnd,
706         (dvoid*) pData,
707         (sb4) nData,
708         (ub2) SQLT_LBI,
709         (void*) NULL,
710         (ub2*) NULL,
711         (ub2*) NULL,
712         (ub4) NULL,
713         (ub4) NULL,
714         (ub4) OCI_DEFAULT ),
715         hError );
716 }
717 
Bind(sdo_geometry ** pphData)718 void OWStatement::Bind( sdo_geometry** pphData )
719 {
720     OCIBind* hBind = NULL;
721 
722     nNextBnd++;
723 
724     CheckError( OCIBindByPos(
725         hStmt,
726         &hBind,
727         hError,
728         (ub4) nNextBnd,
729         (dvoid*) NULL,
730         (sb4) 0,
731         (ub2) SQLT_NTY,
732         (void*) NULL,
733         (ub2*) NULL,
734         (ub2*) NULL,
735         (ub4) 0,
736         (ub4) 0,
737         (ub4) OCI_DEFAULT ),
738         hError );
739 
740     CheckError( OCIBindObject(
741         hBind,
742         hError,
743         poConnection->hGeometryTDO,
744     (dvoid**) pphData,
745         (ub4*) 0,
746     (dvoid**) 0,
747         (ub4*) 0),
748         hError );
749 
750 }
751 
Bind(OCILobLocator ** pphLocator)752 void OWStatement::Bind( OCILobLocator** pphLocator )
753 {
754     OCIBind* hBind = NULL;
755 
756     nNextBnd++;
757 
758     CheckError( OCIBindByPos(
759         hStmt,
760         &hBind,
761         hError,
762         (ub4) nNextBnd,
763         (dvoid*) pphLocator,
764         (sb4) -1,
765         (ub2) SQLT_CLOB,
766         (void*) NULL,
767         (ub2*) NULL,
768         (ub2*) NULL,
769         (ub4) NULL,
770         (ub4) NULL,
771         (ub4) OCI_DEFAULT ),
772         hError );
773 }
774 
Bind(OCIArray ** pphData,OCIType * type)775 void OWStatement::Bind( OCIArray** pphData, OCIType* type )
776 {
777     OCIBind* hBind = NULL;
778 
779     nNextBnd++;
780 
781     CheckError( OCIBindByPos(
782         hStmt,
783         &hBind,
784         hError,
785         (ub4) nNextBnd,
786         (dvoid*) 0,
787         (sb4) 0,
788         (ub2) SQLT_NTY,
789         (void*) NULL,
790         (ub2*) NULL,
791         (ub2*) NULL,
792         (ub4) NULL,
793         (ub4) NULL,
794         (ub4) OCI_DEFAULT ),
795         hError );
796 
797     CheckError( OCIBindObject(
798         hBind,
799         hError,
800         type,
801         (dvoid **)pphData,
802         (ub4 *)0,
803         (dvoid **)0,
804         (ub4 *)0 ),
805         hError);
806 
807 }
808 
Bind(char * pszData,int nSize)809 void OWStatement::Bind( char* pszData, int nSize )
810 {
811     OCIBind* hBind = NULL;
812 
813     nNextBnd++;
814 
815     CheckError( OCIBindByPos(
816         hStmt,
817         &hBind,
818         hError,
819         (ub4) nNextBnd,
820         (dvoid*) pszData,
821         (sb4) nSize,
822         (ub2) SQLT_STR,
823         (void*) NULL,
824         (ub2*) NULL,
825         (ub2*) NULL,
826         (ub4) NULL,
827         (ub4) NULL,
828         (ub4) OCI_DEFAULT ),
829         hError );
830 }
831 
Define(int * pnData)832 void OWStatement::Define( int* pnData )
833 {
834     OCIDefine* hDefine = NULL;
835 
836     nNextCol++;
837 
838     CheckError( OCIDefineByPos( hStmt,
839         &hDefine,
840         hError,
841         (ub4) nNextCol,
842         (dvoid*) pnData,
843         (sb4) sizeof(int),
844         (ub2) SQLT_INT,
845         (void*) NULL,
846         (ub2*) NULL,
847         (ub2*) NULL,
848         (ub4) OCI_DEFAULT ), hError );
849 }
850 
Define(long * pnData)851 void OWStatement::Define( long* pnData )
852 {
853     OCIDefine* hDefine = NULL;
854 
855     nNextCol++;
856 
857     CheckError( OCIDefineByPos( hStmt,
858         &hDefine,
859         hError,
860         (ub4) nNextCol,
861         (dvoid*) pnData,
862         (sb4) sizeof(long int),
863         (ub2) SQLT_INT,
864         (void*) NULL,
865         (ub2*) NULL,
866         (ub2*) NULL,
867         (ub4) OCI_DEFAULT ), hError );
868 }
869 
Define(double * pfdData)870 void OWStatement::Define( double* pfdData )
871 {
872     OCIDefine* hDefine = NULL;
873 
874     nNextCol++;
875 
876     CheckError( OCIDefineByPos( hStmt,
877         &hDefine,
878         hError,
879         (ub4) nNextCol,
880         (dvoid*) pfdData,
881         (sb4) sizeof(double),
882         (ub2) SQLT_BDOUBLE,
883         (void*) NULL,
884         (ub2*) NULL,
885         (ub2*) NULL,
886         (ub4) OCI_DEFAULT ), hError );
887 }
888 
Define(char * pszData,int nSize)889 void OWStatement::Define( char* pszData, int nSize )
890 {
891     OCIDefine* hDefine = NULL;
892 
893     nNextCol++;
894 
895     CheckError( OCIDefineByPos(
896         hStmt,
897         &hDefine,
898         hError,
899         (ub4) nNextCol,
900         (dvoid*) pszData,
901         (sb4) nSize,
902         (ub2) SQLT_STR,
903         (void*) NULL,
904         (ub2*) NULL,
905         (ub2*) NULL,
906         (ub4) OCI_DEFAULT ),
907         hError );
908 }
909 
Define(OCILobLocator ** pphLocator)910 void OWStatement::Define( OCILobLocator** pphLocator )
911 {
912     OCIDefine*  hDefine = NULL;
913 
914     nNextCol++;
915 
916     CheckError( OCIDescriptorAlloc(
917         poConnection->hEnv,
918         (void**) pphLocator,
919         OCI_DTYPE_LOB,
920         0,
921         0),
922         hError );
923 
924     CheckError( OCIDefineByPos(
925         hStmt,
926         &hDefine,
927         hError,
928         (ub4) nNextCol,
929         (dvoid*) pphLocator,
930         (sb4) 0,
931         (ub2) SQLT_BLOB,
932         (void*) NULL,
933         (ub2*) NULL,
934         (ub2*) NULL,
935         (ub4) OCI_DEFAULT ),
936         hError );
937 }
938 
WriteCLob(OCILobLocator ** pphLocator,char * pszData)939 void OWStatement::WriteCLob( OCILobLocator** pphLocator, char* pszData )
940 {
941     nNextCol++;
942 
943     CheckError( OCIDescriptorAlloc(
944         poConnection->hEnv,
945         (void**) pphLocator,
946         OCI_DTYPE_LOB,
947         (size_t) 0,
948         (dvoid **) 0),
949         hError );
950 
951     CheckError( OCILobCreateTemporary(
952         poConnection->hSvcCtx,
953         poConnection->hError,
954         (OCILobLocator*) *pphLocator,
955         (ub4) OCI_DEFAULT,
956         (ub1) OCI_DEFAULT,
957         (ub1) OCI_TEMP_CLOB,
958         false,
959         OCI_DURATION_SESSION ),
960         hError );
961 
962     ub4 nAmont = (ub4) strlen(pszData);
963 
964     CheckError( OCILobWrite(
965         poConnection->hSvcCtx,
966         hError,
967         *pphLocator,
968         (ub4*) &nAmont,
969         (ub4) 1,
970         (dvoid*) pszData,
971         (ub4) strlen(pszData),
972         (ub1) OCI_ONE_PIECE,
973         (dvoid*) NULL,
974         NULL,
975         (ub2) 0,
976         (ub1) SQLCS_IMPLICIT ),
977         hError );
978 }
979 
Define(OCIArray ** pphData)980 void OWStatement::Define( OCIArray** pphData )
981 {
982     OCIDefine* hDefine = NULL;
983 
984     nNextCol++;
985 
986     CheckError( OCIDefineByPos( hStmt,
987         &hDefine,
988         hError,
989         (ub4) nNextCol,
990         (dvoid*) NULL,
991         (sb4) 0,
992         (ub2) SQLT_NTY,
993         (void*) NULL,
994         (ub2*) NULL,
995         (ub2*) NULL,
996         (ub4) OCI_DEFAULT ), hError );
997 
998     CheckError( OCIDefineObject( hDefine,
999         hError,
1000         poConnection->hNumArrayTDO,
1001         (dvoid**) pphData,
1002         (ub4*) NULL,
1003         (dvoid**) NULL,
1004         (ub4*) NULL ), hError );
1005 }
1006 
Define(sdo_georaster ** pphData)1007 void OWStatement::Define( sdo_georaster** pphData )
1008 {
1009     OCIDefine* hDefine = NULL;
1010 
1011     nNextCol++;
1012 
1013     CheckError( OCIDefineByPos( hStmt,
1014         &hDefine,
1015         hError,
1016         (ub4) nNextCol,
1017         (dvoid*) NULL,
1018         (sb4) 0,
1019         (ub2) SQLT_NTY,
1020         (void*) NULL,
1021         (ub2*) NULL,
1022         (ub2*) NULL,
1023         (ub4) OCI_DEFAULT ), hError );
1024 
1025     CheckError( OCIDefineObject( hDefine,
1026         hError,
1027         poConnection->hGeoRasterTDO,
1028         (dvoid**) pphData,
1029         (ub4*) NULL,
1030         (dvoid**) NULL,
1031         (ub4*) NULL ), hError );
1032 }
1033 
Define(sdo_geometry ** pphData)1034 void OWStatement::Define( sdo_geometry** pphData )
1035 {
1036     OCIDefine* hDefine = NULL;
1037 
1038     nNextCol++;
1039 
1040     CheckError( OCIDefineByPos( hStmt,
1041         &hDefine,
1042         hError,
1043         (ub4) nNextCol,
1044         (dvoid*) NULL,
1045         (sb4) 0,
1046         (ub2) SQLT_NTY,
1047         (void*) NULL,
1048         (ub2*) NULL,
1049         (ub2*) NULL,
1050         (ub4) OCI_DEFAULT ), hError );
1051 
1052     CheckError( OCIDefineObject( hDefine,
1053         hError,
1054         poConnection->hGeometryTDO,
1055         (dvoid**) pphData,
1056         (ub4*) NULL,
1057         (dvoid**) NULL,
1058         (ub4*) NULL ), hError );
1059 }
1060 
Define(sdo_pc ** pphData)1061 void OWStatement::Define( sdo_pc** pphData )
1062 {
1063     OCIDefine* hDefine = NULL;
1064 
1065     nNextCol++;
1066 
1067     CheckError( OCIDefineByPos( hStmt,
1068         &hDefine,
1069         hError,
1070         (ub4) nNextCol,
1071         (dvoid*) NULL,
1072         (sb4) 0,
1073         (ub2) SQLT_NTY,
1074         (void*) NULL,
1075         (ub2*) NULL,
1076         (ub2*) NULL,
1077         (ub4) OCI_DEFAULT ), hError );
1078 
1079     CheckError( OCIDefineObject( hDefine,
1080         hError,
1081         poConnection->hPCTDO,
1082         (dvoid**) pphData,
1083         (ub4*) NULL,
1084         (dvoid**) NULL,
1085         (ub4*) NULL ), hError );
1086 }
1087 
Define(OCILobLocator ** pphLocator,long nIterations)1088 void OWStatement::Define( OCILobLocator** pphLocator, long nIterations )
1089 {
1090     OCIDefine* hDefine = NULL;
1091 
1092     nNextCol++;
1093 
1094     long i;
1095 
1096     for (i = 0; i < nIterations; i++)
1097     {
1098         OCIDescriptorAlloc(
1099             poConnection->hEnv,
1100             (void**) &pphLocator[i],
1101             OCI_DTYPE_LOB, (size_t) 0, (void**) 0);
1102     }
1103 
1104     CheckError( OCIDefineByPos( hStmt,
1105         &hDefine,
1106         hError,
1107         (ub4) nNextCol,
1108         (dvoid*) pphLocator,
1109         (sb4) -1,
1110         (ub2) SQLT_BLOB,
1111         (void*) 0,
1112         (ub2*) 0,
1113         (ub2*) 0,
1114         (ub4) OCI_DEFAULT ), hError );
1115 }
1116 
GetInteger(OCINumber * ppoData)1117 int OWStatement::GetInteger( OCINumber* ppoData )
1118 {
1119     sb4 nRetVal;
1120 
1121     CheckError( OCINumberToInt(
1122         hError,
1123         ppoData,
1124         (uword) sizeof(sb4),
1125         OCI_NUMBER_SIGNED,
1126         (dvoid *) &nRetVal ),
1127         hError );
1128 
1129     return nRetVal;
1130 }
1131 
GetDouble(OCINumber * ppoData)1132 double OWStatement::GetDouble( OCINumber* ppoData )
1133 {
1134     double dfRetVal = 0.0;
1135 
1136     CheckError( OCINumberToReal(
1137         hError,
1138         ppoData,
1139         (uword) sizeof(dfRetVal),
1140         (dvoid*) &dfRetVal ),
1141         hError );
1142 
1143     return dfRetVal;
1144 }
1145 
GetString(OCIString * ppoData)1146 char* OWStatement::GetString( OCIString* ppoData )
1147 {
1148     return (char*) OCIStringPtr(
1149         poConnection->hEnv,
1150         ppoData );
1151 }
1152 
Free(OCILobLocator ** pphLocator,int nCount)1153 void OWStatement::Free( OCILobLocator** pphLocator, int nCount )
1154 {
1155     if( nCount > 0 && pphLocator != NULL )
1156     {
1157         int i = 0;
1158         for (i = 0; i < nCount; i++)
1159         {
1160             if( pphLocator[i] != NULL )
1161             {
1162                 OCIDescriptorFree(&pphLocator[i], OCI_DTYPE_LOB);
1163             }
1164         }
1165     }
1166 }
1167 
GetElement(OCIArray ** ppoData,int nIndex,int * pnResult)1168 int OWStatement::GetElement( OCIArray** ppoData, int nIndex, int* pnResult )
1169 {
1170     boolean        exists;
1171     OCINumber      *oci_number;
1172     ub4            element_type;
1173 
1174     *pnResult = 0;
1175 
1176     if( CheckError( OCICollGetElem(
1177         poConnection->hEnv,
1178         hError,
1179         (OCIColl*) *ppoData,
1180         (sb4) nIndex,
1181         (boolean*) &exists,
1182         (dvoid**) (dvoid*) &oci_number,
1183         (dvoid**) NULL ), hError ) )
1184     {
1185         return *pnResult;
1186     }
1187 
1188     if( CheckError( OCINumberToInt(
1189         hError,
1190         oci_number,
1191         (uword) sizeof(ub4),
1192         OCI_NUMBER_UNSIGNED,
1193         (dvoid *) &element_type ), hError ) )
1194     {
1195         return *pnResult;
1196     }
1197 
1198     *pnResult = (int) element_type;
1199 
1200     return *pnResult;
1201 }
1202 
GetElement(OCIArray ** ppoData,int nIndex,double * pdfResult)1203 double OWStatement::GetElement( OCIArray** ppoData,
1204                                int nIndex, double* pdfResult )
1205 {
1206     boolean        exists;
1207     OCINumber      *oci_number;
1208     double         element_type;
1209 
1210     *pdfResult = 0.0;
1211 
1212     if( CheckError( OCICollGetElem(
1213         poConnection->hEnv,
1214         hError,
1215         (OCIColl*) *ppoData,
1216         (sb4) nIndex,
1217         (boolean*) &exists,
1218         (dvoid**) (dvoid*) &oci_number, NULL ), hError ) )
1219     {
1220         return *pdfResult;
1221     }
1222 
1223     if( CheckError( OCINumberToReal(
1224         hError,
1225         oci_number,
1226         (uword) sizeof(double),
1227         (dvoid *) &element_type ), hError ) )
1228     {
1229         return *pdfResult;
1230     }
1231 
1232     *pdfResult = (double) element_type;
1233 
1234     return *pdfResult;
1235 }
1236 
AddElement(OCIArray * poData,int nValue)1237 void OWStatement::AddElement( OCIArray* poData,
1238                               int nValue )
1239 {
1240     OCINumber      oci_number;
1241 
1242     CheckError(OCINumberFromInt(hError,
1243         (dvoid*) &nValue,
1244         (uword) sizeof(ub4),
1245         OCI_NUMBER_UNSIGNED,
1246         (OCINumber*) &oci_number), hError);
1247 
1248     CheckError(OCICollAppend(poConnection->hEnv,
1249         hError,
1250         (OCINumber*) &oci_number,
1251         (dvoid*) 0,
1252         (OCIColl*) poData), hError);
1253 }
1254 
AddElement(OCIArray * poData,double dfValue)1255 void OWStatement::AddElement( OCIArray* poData,
1256                               double dfValue )
1257 {
1258     OCINumber      oci_number;
1259 
1260     CheckError(OCINumberFromReal(hError,
1261         (dvoid*) &dfValue,
1262         (uword) sizeof(double),
1263         (OCINumber*) &oci_number), hError);
1264 
1265     CheckError(OCICollAppend(poConnection->hEnv,
1266         hError,
1267         (OCINumber*) &oci_number,
1268         (dvoid*) 0,
1269         (OCIColl*) poData), hError);
1270 }
1271 
ReadBlob(OCILobLocator * phLocator,void * pBuffer,int nSize)1272 unsigned long OWStatement::ReadBlob( OCILobLocator* phLocator,
1273                                      void* pBuffer,
1274                                      int nSize )
1275 {
1276     ub4 nAmont      = (ub4) 0;
1277 
1278     if( CheckError( OCILobRead(
1279         poConnection->hSvcCtx,
1280         hError,
1281         phLocator,
1282         (ub4*) &nAmont,
1283         (ub4) 1,
1284         (dvoid*) pBuffer,
1285         (ub4) nSize,
1286         (dvoid *) 0,
1287         (OCICallbackLobRead) 0,
1288         (ub2) 0,
1289         (ub1) SQLCS_IMPLICIT), hError ) )
1290     {
1291         return 0;
1292     }
1293 
1294     return nAmont;
1295 }
1296 
WriteBlob(OCILobLocator * phLocator,void * pBuffer,int nSize)1297 bool OWStatement::WriteBlob( OCILobLocator* phLocator,
1298                              void* pBuffer,
1299                              int nSize )
1300 {
1301     ub4 nAmont  = (ub4) nSize;
1302 
1303     if( CheckError( OCILobWrite(
1304         poConnection->hSvcCtx,
1305         hError,
1306         phLocator,
1307         (ub4*) &nAmont,
1308         (ub4) 1,
1309         (dvoid*) pBuffer,
1310         (ub4) nSize,
1311         (ub1) OCI_ONE_PIECE,
1312         (dvoid*) NULL,
1313         NULL,
1314         (ub2) 0,
1315         (ub1) SQLCS_IMPLICIT ),
1316         hError ) )
1317     {
1318         return false;
1319     }
1320 
1321     return ( nAmont == (ub4) nSize );
1322 }
1323 
ReadCLob(OCILobLocator * phLocator)1324 char* OWStatement::ReadCLob( OCILobLocator* phLocator )
1325 {
1326     ub4 nSize  = 0;
1327     ub4 nAmont = 0;
1328 
1329     char* pszBuffer = NULL;
1330 
1331     if( CheckError( OCILobGetLength (
1332         poConnection->hSvcCtx,
1333         hError,
1334         phLocator,
1335         (ub4*) &nSize ),
1336         hError ) )
1337     {
1338         return NULL;
1339     }
1340 
1341     nSize *= this->poConnection->nCharSize;
1342 
1343     pszBuffer = (char*) VSIMalloc( sizeof(char*) * nSize );
1344 
1345     if( pszBuffer == NULL)
1346     {
1347         return NULL;
1348     }
1349 
1350     if( CheckError( OCILobRead(
1351         poConnection->hSvcCtx,
1352         hError,
1353         phLocator,
1354         (ub4*) &nAmont,
1355         (ub4) 1,
1356         (dvoid*) pszBuffer,
1357         (ub4) nSize,
1358         (dvoid*) NULL,
1359         NULL,
1360         (ub2) 0,
1361         (ub1) SQLCS_IMPLICIT ),
1362         hError ) )
1363     {
1364         CPLFree( pszBuffer );
1365         return NULL;
1366     }
1367 
1368     pszBuffer[nAmont] = '\0';
1369 
1370     return pszBuffer;
1371 }
1372 
BindName(const char * pszName,int * pnData)1373 void OWStatement::BindName( const char* pszName, int* pnData )
1374 {
1375     OCIBind* hBind = NULL;
1376 
1377     CheckError( OCIBindByName(
1378         (OCIStmt*) hStmt,
1379         (OCIBind**) &hBind,
1380         (OCIError*) hError,
1381         (text*) pszName,
1382         (sb4) -1,
1383         (dvoid*) pnData,
1384         (sb4) sizeof(int),
1385         (ub2) SQLT_INT,
1386         (dvoid*) NULL,
1387         (ub2*) NULL,
1388         (ub2*) NULL,
1389         (ub4) 0,
1390         (ub4*) NULL,
1391         (ub4) OCI_DEFAULT ),
1392         hError );
1393 }
1394 
BindName(const char * pszName,double * pnData)1395 void OWStatement::BindName( const char* pszName, double* pnData )
1396 {
1397     OCIBind* hBind = NULL;
1398 
1399     CheckError( OCIBindByName(
1400         (OCIStmt*) hStmt,
1401         (OCIBind**) &hBind,
1402         (OCIError*) hError,
1403         (text*) pszName,
1404         (sb4) -1,
1405         (dvoid*) pnData,
1406         (sb4) sizeof(double),
1407         (ub2) SQLT_BDOUBLE,
1408         (dvoid*) NULL,
1409         (ub2*) NULL,
1410         (ub2*) NULL,
1411         (ub4) 0,
1412         (ub4*) NULL,
1413         (ub4) OCI_DEFAULT ),
1414         hError );
1415 }
1416 
BindName(const char * pszName,char * pszData,int nSize)1417 void OWStatement::BindName( const char* pszName, char* pszData, int nSize )
1418 {
1419     OCIBind* hBind = NULL;
1420 
1421     CheckError( OCIBindByName(
1422         (OCIStmt*) hStmt,
1423         (OCIBind**) &hBind,
1424         (OCIError*) hError,
1425         (text*) pszName,
1426         (sb4) -1,
1427         (dvoid*) pszData,
1428         (sb4) nSize,
1429         (ub2) SQLT_STR,
1430         (dvoid*) NULL,
1431         (ub2*) NULL,
1432         (ub2*) NULL,
1433         (ub4) 0,
1434         (ub4*) NULL,
1435         (ub4) OCI_DEFAULT ),
1436         hError );
1437 }
1438 
BindName(const char * pszName,OCILobLocator ** pphLocator)1439 void OWStatement::BindName( const char* pszName, OCILobLocator** pphLocator )
1440 {
1441     OCIBind* hBind = NULL;
1442 
1443     CheckError( OCIDescriptorAlloc(
1444         poConnection->hEnv,
1445         (void**) pphLocator,
1446         OCI_DTYPE_LOB,
1447         0,
1448         0),
1449         hError );
1450 
1451     CheckError( OCIBindByName(
1452         (OCIStmt*) hStmt,
1453         (OCIBind**) &hBind,
1454         (OCIError*) hError,
1455         (text*) pszName,
1456         (sb4) -1,
1457         (dvoid*) pphLocator,
1458         (sb4) -1,
1459         (ub2) SQLT_CLOB,
1460         (dvoid*) NULL,
1461         (ub2*) NULL,
1462         (ub2*) NULL,
1463         (ub4) 0,
1464         (ub4*) NULL,
1465         (ub4) OCI_DEFAULT ),
1466         hError );
1467 }
1468 
BindArray(void * pData,long nSize)1469 void OWStatement::BindArray( void* pData, long nSize )
1470 {
1471     OCIBind* hBind = NULL;
1472 
1473     nNextBnd++;
1474 
1475     CheckError( OCIBindByPos(
1476         hStmt,
1477         &hBind,
1478         hError,
1479         (ub4) nNextBnd,
1480         (dvoid*) pData,
1481         (sb4) nSize * sizeof(double),
1482         (ub2) SQLT_BIN,
1483         (void*) NULL,
1484         (ub2*) NULL,
1485         (ub2*) NULL,
1486         (ub4) NULL,
1487         (ub4) NULL,
1488         (ub4) OCI_DEFAULT ), hError );
1489 
1490     CheckError( OCIBindArrayOfStruct(
1491         hBind,
1492         hError,
1493         (ub4) nSize * sizeof(double),
1494         (ub4) 0,
1495         (ub4) 0,
1496         (ub4) 0), hError );
1497 }
1498 
1499 /*****************************************************************************/
1500 /*               Check for valid integer number in a string                  */
1501 /*****************************************************************************/
1502 
OWIsNumeric(const char * pszText)1503 bool OWIsNumeric( const char *pszText )
1504 {
1505     if( pszText == NULL )
1506     {
1507         return false;
1508     }
1509 
1510     const char* pszPos = pszText;
1511 
1512     while( *pszPos != '\0' )
1513     {
1514         if( *pszPos < '0' ||
1515             *pszPos > '9' )
1516             return false;
1517         pszPos++;
1518     }
1519 
1520     return true;
1521 }
1522 
1523 /*****************************************************************************/
1524 /*                     Parse Value after a Hint on a string                  */
1525 /*****************************************************************************/
1526 
OWParseValue(const char * pszText,const char * pszSeparators,const char * pszHint,int nOffset)1527 const char *OWParseValue( const char* pszText,
1528                           const char* pszSeparators,
1529                           const char* pszHint,
1530                           int nOffset )
1531 {
1532     if( pszText == NULL ) return 0;
1533 
1534     int i       = 0;
1535     int nCount  = 0;
1536 
1537     char **papszTokens = CSLTokenizeString2( pszText, pszSeparators,
1538         CSLT_PRESERVEQUOTES );
1539 
1540     nCount = CSLCount( papszTokens );
1541     const char* pszResult = "";
1542 
1543     for( i = 0; ( i + nOffset ) < nCount; i++ )
1544     {
1545         if( EQUAL( papszTokens[i], pszHint ) )
1546         {
1547             pszResult = CPLStrdup( papszTokens[i + nOffset] );
1548             break;
1549         }
1550     }
1551 
1552     CSLDestroy( papszTokens );
1553 
1554     return pszResult;
1555 }
1556 
1557 /*****************************************************************************/
1558 /*                            Parse SDO_GEOR.INIT entries                    */
1559 /*****************************************************************************/
1560 
1561 /* Input Examples:
1562  *
1563  * "ID, RASTER, NAME VALUES (102, SDO_GEOR.INIT('RDT_80', 80), 'Nashua')"
1564  *
1565  */
1566 
OWParseSDO_GEOR_INIT(const char * pszInsert,int nField)1567 const char* OWParseSDO_GEOR_INIT( const char* pszInsert, int nField )
1568 {
1569     char  szUpcase[OWTEXT];
1570     char* pszIn = NULL;
1571 
1572     strcpy( szUpcase, pszInsert );
1573 
1574     for( pszIn = szUpcase; *pszIn != '\0'; pszIn++ )
1575     {
1576         *pszIn = (char) toupper( *pszIn );
1577     }
1578 
1579     char* pszStart = strstr( szUpcase, "SDO_GEOR.INIT" );
1580 
1581     if( pszStart == NULL )
1582     {
1583         return "";
1584     }
1585 
1586     char* pszEnd   = strstr( pszStart, ")" );
1587 
1588     if( pszEnd == NULL )
1589     {
1590         return "";
1591     }
1592 
1593     pszStart += strlen("SDO_GEOR.");
1594 
1595     pszEnd++;
1596 
1597     int nLength = pszEnd - pszStart + 1;
1598 
1599     char szBuffer[OWTEXT];
1600 
1601     strncpy( szBuffer, pszStart, nLength );
1602     szBuffer[nLength] = '\0';
1603 
1604     const char* pszValue = OWParseValue( szBuffer, " (,)", "INIT", nField );
1605 
1606     return EQUAL( pszValue, "" ) ? "NULL" : pszValue;
1607 }
1608 
1609 /*****************************************************************************/
1610 /*                            Parse Release Version                          */
1611 /*****************************************************************************/
1612 
1613 /* Input Examples:
1614  *
1615  * "Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - Production
1616  * With the Partitioning, OLAP, Data Mining and Real Application Testing options"
1617  *
1618  */
1619 
OWParseServerVersion(const char * pszText)1620 int OWParseServerVersion( const char* pszText )
1621 {
1622     const char* pszValue = OWParseValue( pszText, " .", "Release", 1 );
1623 
1624     return pszValue == NULL ? 0 : atoi( pszValue );
1625 }
1626 
1627 /*****************************************************************************/
1628 /*                            Parse EPSG Codes                               */
1629 /*****************************************************************************/
1630 
1631 /* Input Examples:
1632 *
1633 *      DATUM["World Geodetic System 1984 (EPSG ID 6326)",
1634 *      SPHEROID["WGS 84 (EPSG ID 7030)",6378137,298.257223563]],
1635 *      PROJECTION["UTM zone 50N (EPSG OP 16050)"],
1636 */
1637 
OWParseEPSG(const char * pszText)1638 int OWParseEPSG( const char* pszText )
1639 {
1640     const char* pszValue = OWParseValue( pszText, " ()", "EPSG", 2 );
1641 
1642     return pszValue == NULL ? 0 : atoi( pszValue );
1643 }
1644 
1645 /*****************************************************************************/
1646 /*                            Convert Data type description                  */
1647 /*****************************************************************************/
1648 
OWGetDataType(const char * pszCellDepth)1649 const GDALDataType OWGetDataType( const char* pszCellDepth )
1650 {
1651     unsigned int i;
1652 
1653     for( i = 0;
1654         i < (sizeof(ahOW_CellDepth) / sizeof(OW_CellDepth));
1655         i++ )
1656     {
1657         if( EQUAL( ahOW_CellDepth[i].pszValue, pszCellDepth ) )
1658         {
1659             return ahOW_CellDepth[i].eDataType;
1660         }
1661     }
1662 
1663     return GDT_Unknown;
1664 }
1665 
1666 /*****************************************************************************/
1667 /*                            Convert Data type description                  */
1668 /*****************************************************************************/
1669 
OWSetDataType(const GDALDataType eType)1670 const char* OWSetDataType( const GDALDataType eType )
1671 
1672 {
1673     unsigned int i;
1674 
1675     for( i = 0;
1676         i < (sizeof(ahOW_CellDepth) / sizeof(OW_CellDepth));
1677         i++ )
1678     {
1679         if( ahOW_CellDepth[i].eDataType == eType )
1680         {
1681             return ahOW_CellDepth[i].pszValue;
1682         }
1683     }
1684 
1685     return "Unknown";
1686 }
1687 
1688 /*****************************************************************************/
1689 /*                            Check for Failure                              */
1690 /*****************************************************************************/
1691 
CheckError(sword nStatus,OCIError * hError)1692 bool CheckError( sword nStatus, OCIError* hError )
1693 {
1694     text    szMsg[OWTEXT];
1695     sb4     nCode = 0;
1696 
1697     switch ( nStatus )
1698     {
1699     case OCI_SUCCESS:
1700         return false;
1701         break;
1702     case OCI_NEED_DATA:
1703         CPLError( CE_Failure, CPLE_AppDefined, "OCI_NEED_DATA\n" );
1704         break;
1705     case OCI_NO_DATA:
1706         CPLError( CE_Failure, CPLE_AppDefined, "OCI_NODATA\n" );
1707         break;
1708     case OCI_INVALID_HANDLE:
1709         CPLError( CE_Failure, CPLE_AppDefined, "OCI_INVALID_HANDLE" );
1710         break;
1711     case OCI_STILL_EXECUTING:
1712         CPLError( CE_Failure, CPLE_AppDefined, "OCI_STILL_EXECUTE\n" );
1713         break;
1714     case OCI_CONTINUE:
1715         CPLError( CE_Failure, CPLE_AppDefined, "OCI_CONTINUE\n" );
1716         break;
1717     case OCI_ERROR: case OCI_SUCCESS_WITH_INFO:
1718 
1719         if( hError == NULL)
1720         {
1721             CPLError( CE_Failure, CPLE_AppDefined,
1722                 "OCI_ERROR with no error handler" );
1723         }
1724 
1725         OCIErrorGet( (dvoid *) hError, (ub4) 1,
1726             (text *) NULL, &nCode, szMsg,
1727             (ub4) sizeof(szMsg), OCI_HTYPE_ERROR);
1728 
1729         if( nCode == 1405 ) // Null field
1730         {
1731             return false;
1732         }
1733 
1734         CPLError( CE_Failure, CPLE_AppDefined, "%.*s",
1735             static_cast<int>(sizeof(szMsg)), szMsg );
1736         break;
1737 
1738     default:
1739 
1740             if( hError == NULL)
1741             {
1742                 CPLError( CE_Failure, CPLE_AppDefined,
1743                     "OCI_ERROR with no error handler" );
1744             }
1745 
1746             OCIErrorGet( (dvoid *) hError, (ub4) 1,
1747                 (text *) NULL, &nCode, szMsg,
1748                 (ub4) sizeof(szMsg), OCI_HTYPE_ERROR);
1749 
1750             CPLError( CE_Failure, CPLE_AppDefined, "%.*s",
1751                 static_cast<int>(sizeof(szMsg)), szMsg );
1752             break;
1753 
1754     }
1755 
1756     return true;
1757 }
1758