1 /******************************************************************************
2 * Project: MapServer
3 * Purpose: Native access to Oracle Spatial (SDO) data.
4 * Author: Fernando Simon (fsimon@univali.br)
5 * Rodrigo Becke Cabral
6 * Adriana Gomes Alves
7 *
8 * Notes: Developed under several funding agreements:
9 *
10 * 1) n.45/00 between CTTMAR/UNIVALI (www.cttmar.univali.br)
11 * and CEPSUL/IBAMA (www.ibama.gov.br)
12 *
13 * 2) CNPq (www.cnpq.br) under process 401263.03-7
14 *
15 * 3) FUNCITEC (www.funcitec.rct-sc.br) under process FCTP1523-031
16 *
17 ******************************************************************************
18 * Copyright (c) 1996-2008 Regents of the University of Minnesota.
19 *
20 * Permission is hereby granted, free of charge, to any person obtaining a
21 * copy of this software and associated documentation files (the "Software"),
22 * to deal in the Software without restriction, including without limitation
23 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
24 * and/or sell copies of the Software, and to permit persons to whom the
25 * Software is furnished to do so, subject to the following conditions:
26 *
27 * The above copyright notice and this permission notice shall be included in
28 * all copies of this Software or works derived from this Software.
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
31 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
32 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
33 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
34 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
35 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
36 * DEALINGS IN THE SOFTWARE.
37 *****************************************************************************/
38
39 #include "mapserver.h"
40 #include "maptime.h"
41 #include "mapows.h"
42 #include <assert.h>
43
44
45
46 #if defined(USE_ORACLESPATIAL) || defined(USE_ORACLE_PLUGIN)
47
48 #include <oci.h>
49 #include <ctype.h>
50
51 #define ARRAY_SIZE 1024
52 #define QUERY_SIZE 1
53 #define TEXT_SIZE 4000 /* ticket #2260 */
54 #define TYPE_OWNER "MDSYS"
55 #define SDO_GEOMETRY TYPE_OWNER".SDO_GEOMETRY"
56 #define SDO_ORDINATE_ARRAY TYPE_OWNER".SDO_ORDINATE_ARRAY"
57 #define SDO_GEOMETRY_LEN strlen( SDO_GEOMETRY )
58 #define FUNCTION_FILTER 1
59 #define FUNCTION_RELATE 2
60 #define FUNCTION_GEOMRELATE 3
61 #define FUNCTION_NONE 4
62 #define VERSION_8i 1
63 #define VERSION_9i 2
64 #define VERSION_10g 3
65 #define TOLERANCE 0.001
66 #define NULLERRCODE 1405
67 #define TABLE_NAME_SIZE 2000
68
69 typedef
70 struct {
71 OCINumber x;
72 OCINumber y;
73 OCINumber z;
74 } SDOPointObj;
75
76 typedef
77 struct {
78 OCINumber gtype;
79 OCINumber srid;
80 SDOPointObj point;
81 OCIArray *elem_info;
82 OCIArray *ordinates;
83 } SDOGeometryObj;
84
85 typedef
86 struct {
87 OCIInd _atomic;
88 OCIInd x;
89 OCIInd y;
90 OCIInd z;
91 } SDOPointInd;
92
93 typedef
94 struct {
95 OCIInd _atomic;
96 OCIInd gtype;
97 OCIInd srid;
98 SDOPointInd point;
99 OCIInd elem_info;
100 OCIInd ordinates;
101 } SDOGeometryInd;
102
103 typedef
104 text item_text[TEXT_SIZE];
105
106 typedef
107 item_text item_text_array[ARRAY_SIZE];
108
109 typedef
110 item_text item_text_array_query[QUERY_SIZE];
111
112 typedef
113 ub2 query_dtype[ARRAY_SIZE];
114
115 typedef
116 struct {
117 /*Oracle handlers (global to connection)*/
118 OCIEnv *envhp;
119 OCIError *errhp;
120 OCISvcCtx *svchp;
121 int last_oci_status;
122 text last_oci_error[2048];
123 /* This references counter is to avoid the cache freed if there are other layers that could use it */
124 int ref_count;
125 } msOracleSpatialHandler;
126
127 typedef
128 struct {
129 /* Oracle data handlers (global to connection) */
130 OCIDescribe *dschp;
131 OCIType *tdo;
132 } msOracleSpatialDataHandler;
133
134 typedef
135 struct {
136 OCIStmt *stmthp;
137
138 /* fetch data buffer */
139 ub4 rows_count; /* total number of rows (so far) within cursor */
140 ub4 row_num; /* current row index within cursor results */
141 ub4 rows_fetched; /* total number of rows fetched into our buffer */
142 ub4 row; /* current row index within our buffer */
143
144 item_text_array *items; /* items buffer */
145 item_text_array_query *items_query; /* items buffer */
146 SDOGeometryObj *obj[ARRAY_SIZE]; /* spatial object buffer */
147 SDOGeometryInd *ind[ARRAY_SIZE]; /* object indicator (null) buffer */
148
149 int uniqueidindex; /*allows to keep whic attribute id index is used as unique id*/
150
151
152 } msOracleSpatialStatement;
153
154 typedef
155 struct {
156 /* oracle handlers */
157 msOracleSpatialHandler *orahandlers;
158
159 /* oracle data handlers */
160 msOracleSpatialDataHandler *oradatahandlers;
161 msOracleSpatialStatement *orastmt;
162
163 /* Following items are setup by WhichShapes
164 * used by NextShape, ResultGetShape
165 * disposed by CloseLayer (if set)
166 */
167 msOracleSpatialStatement *orastmt2;
168 /* Driver handling of pagination, enabled by default */
169 int paging;
170
171 } msOracleSpatialLayerInfo;
172
173 static OCIType *ordinates_tdo = NULL;
174 static OCIArray *ordinates;
175
176
177
178
179
180 /* local prototypes */
181 static int TRY( msOracleSpatialHandler *hand, sword status );
182 static int ERROR( char *routine, msOracleSpatialHandler *hand, msOracleSpatialDataHandler *dthand );
183 static void msSplitLogin( char *connection, mapObj *map, char **username, char **password, char **dblink );
184 static int msSplitData( char *data, char **geometry_column_name, char **table_name, char **unique, char **srid, char **indexfield, int *function, int * version);
185 static void msOCICloseConnection( void *layerinfo );
186 static msOracleSpatialHandler *msOCISetHandlers( char *username, char *password, char *dblink );
187 static int msOCISetDataHandlers( msOracleSpatialHandler *hand, msOracleSpatialDataHandler *dthand );
188 static void msOCICloseDataHandlers ( msOracleSpatialDataHandler *dthand );
189 static void msOCICloseHandlers( msOracleSpatialHandler *hand );
190 static void msOCIClearLayerInfo( msOracleSpatialLayerInfo *layerinfo );
191 static int msOCIOpenStatement( msOracleSpatialHandler *hand, msOracleSpatialStatement *sthand );
192 static void msOCIFinishStatement( msOracleSpatialStatement *sthand );
193 static int msOCIGet2DOrdinates( msOracleSpatialHandler *hand, SDOGeometryObj *obj, int s, int e, pointObj *pt );
194 static int msOCIGet3DOrdinates( msOracleSpatialHandler *hand, SDOGeometryObj *obj, int s, int e, pointObj *pt );
195 static int msOCIGet4DOrdinates( msOracleSpatialHandler *hand, SDOGeometryObj *obj, int s, int e, pointObj *pt );
196 static int msOCIConvertCircle( pointObj *pt );
197 static void osFilteritem(layerObj *layer, int function, char *query_str, size_t size, int mode);
198 static void osAggrGetExtent(layerObj *layer, char *query_str, size_t size, char *geom_column_name, char *table_name);
199 static void osConvexHullGetExtent(layerObj *layer, char *query_str, size_t size, char *geom_column_name, char *table_name);
200 static void osGeodeticData(int function, int version, char *query_str, size_t size, char *geom_column_name, char *index_column_name, char *srid, rectObj rect);
201 static void osNoGeodeticData(int function, int version, char *query_str, size_t size, char *geom_column_name, char *index_column_name, char *srid, rectObj rect);
202 static double osCalculateArcRadius(pointObj *pnt);
203 static void osCalculateArc(pointObj *pnt, int data3d, int data4d, double area, double radius, double npoints, int side, lineObj arcline, shapeObj *shape);
204 static void osGenerateArc(shapeObj *shape, lineObj arcline, lineObj points, int i, int n, int data3d, int data4d);
205 static void osShapeBounds ( shapeObj *shp );
206 static void osCloneShape(shapeObj *shape, shapeObj *newshape, int data3d, int data4d);
207 static void osPointCluster(msOracleSpatialHandler *hand, shapeObj *shape, SDOGeometryObj *obj, int start, int end, lineObj points, int interpretation, int data3d, int data4d);
208 static void osPoint(msOracleSpatialHandler *hand, shapeObj *shape, SDOGeometryObj *obj, int start, int end, lineObj points, pointObj *pnt, int data3d, int data4d);
209 static void osClosedPolygon(msOracleSpatialHandler *hand, shapeObj *shape, SDOGeometryObj *obj, int start, int end, lineObj points, int elem_type, int data3d, int data4d);
210 static void osRectangle(msOracleSpatialHandler *hand, shapeObj *shape, SDOGeometryObj *obj, int start, int end, lineObj points, pointObj *pnt, int data3d, int data4d);
211 static void osCircle(msOracleSpatialHandler *hand, shapeObj *shape, SDOGeometryObj *obj, int start, int end, lineObj points, pointObj *pnt, int data3d, int data4d);
212 static void osArcPolygon(msOracleSpatialHandler *hand, shapeObj *shape, SDOGeometryObj *obj, int start, int end, lineObj arcpoints,int elem_type,int data3d, int data4d);
213 static int osGetOrdinates(msOracleSpatialDataHandler *dthand, msOracleSpatialHandler *hand, shapeObj *shape, SDOGeometryObj *obj, SDOGeometryInd *ind);
214 static int osCheck2DGtype(int pIntGtype);
215 static int osCheck3DGtype(int pIntGtype);
216 static int osCheck4DGtype(int pIntGtype);
217
218
219
220 /******************************************************************************
221 * Local Helper Functions *
222 ******************************************************************************/
223
224
225 /* if an error ocurred call msSetError, sets last_oci_status to MS_FAILURE and return 0;
226 * otherwise returns 1 */
TRY(msOracleSpatialHandler * hand,sword status)227 static int TRY( msOracleSpatialHandler *hand, sword status )
228 {
229 sb4 errcode = 0;
230
231 if (hand->last_oci_status == MS_FAILURE)
232 return 0; /* error from previous call */
233
234 switch (status) {
235 case OCI_SUCCESS_WITH_INFO:
236 case OCI_ERROR:
237 OCIErrorGet((dvoid *)hand->errhp, (ub4)1, (text *)NULL, &errcode, hand->last_oci_error, (ub4)sizeof(hand->last_oci_error), OCI_HTYPE_ERROR );
238 if (errcode == NULLERRCODE) {
239 hand->last_oci_error[0] = (text)'\0';
240 return 1;
241 }
242 hand->last_oci_error[sizeof(hand->last_oci_error)-1] = 0; /* terminate string!? */
243 break;
244 case OCI_NEED_DATA:
245 strlcpy( (char *)hand->last_oci_error, "OCI_NEED_DATA", sizeof(hand->last_oci_error));
246 break;
247 case OCI_INVALID_HANDLE:
248 strlcpy( (char *)hand->last_oci_error, "OCI_INVALID_HANDLE", sizeof(hand->last_oci_error));
249 break;
250 case OCI_STILL_EXECUTING:
251 ((char*)hand->last_oci_error)[sizeof(hand->last_oci_error)-1] = 0;
252 break;
253 case OCI_CONTINUE:
254 strlcpy( (char *)hand->last_oci_error, "OCI_CONTINUE", sizeof(hand->last_oci_error));
255 break;
256 default:
257 return 1; /* no error */
258 }
259
260 /* if I got here, there was an error */
261 hand->last_oci_status = MS_FAILURE;
262
263 return 0; /* error! */
264 }
265
get_tdo(char * typename,msOracleSpatialHandler * hand,msOracleSpatialDataHandler * dthand)266 OCIType *get_tdo(char *typename, msOracleSpatialHandler *hand, msOracleSpatialDataHandler *dthand )
267 {
268 OCIParam *paramp = NULL;
269 OCIRef *type_ref = NULL;
270 OCIType *tdoe = NULL;
271 int success = 0;
272
273
274 success = TRY( hand, OCIDescribeAny(hand->svchp, hand->errhp, (text *)typename, (ub4)strlen((char *)typename), OCI_OTYPE_NAME, (ub1)1, (ub1)OCI_PTYPE_TYPE, dthand->dschp))
275 &&TRY( hand, OCIAttrGet((dvoid *)dthand->dschp, (ub4)OCI_HTYPE_DESCRIBE, (dvoid *)¶mp, (ub4 *)0, (ub4)OCI_ATTR_PARAM, hand->errhp))
276 &&TRY( hand, OCIAttrGet((dvoid *)paramp, (ub4)OCI_DTYPE_PARAM, (dvoid *)&type_ref, (ub4 *)0, (ub4)OCI_ATTR_REF_TDO, hand->errhp))
277 &&TRY( hand, OCIObjectPin(hand->envhp, hand->errhp, type_ref, (OCIComplexObject *)0, OCI_PIN_ANY, OCI_DURATION_SESSION, OCI_LOCK_NONE, (dvoid **)&tdoe));
278 if (success)
279 return tdoe;
280
281 /* if failure, return NULL*/
282 return NULL;
283 }
284
285
286 /* check last_oci_status for MS_FAILURE (set by TRY()) if an error ocurred return 1;
287 * otherwise, returns 0 */
ERROR(char * routine,msOracleSpatialHandler * hand,msOracleSpatialDataHandler * dthand)288 static int ERROR( char *routine, msOracleSpatialHandler *hand, msOracleSpatialDataHandler *dthand )
289 {
290 if (hand->last_oci_status == MS_FAILURE) {
291 /* there was an error */
292 msSetError( MS_ORACLESPATIALERR, "OracleSpatial server returned an error, check logs for more details", routine );
293 msDebug("OracleSpatial server returned an error in funtion (%s): %s.\n", routine, (char*)hand->last_oci_error );
294
295 /* reset error flag */
296 hand->last_oci_status = MS_SUCCESS;
297
298 return 1; /* error processed */
299 } else
300 return 0; /* no error */
301 }
302
303 /* break layer->connection (username/password@dblink) into username, password and dblink */
msSplitLogin(char * connection,mapObj * map,char ** username,char ** password,char ** dblink)304 static void msSplitLogin( char *connection, mapObj *map, char **username, char **password, char **dblink )
305 {
306 char *src, *tgt, *conn_decrypted;
307 size_t buffer_size = 0;
308
309 /* bad 'connection' */
310 if (connection == NULL) return;
311
312 buffer_size = strlen(connection)+1;
313 *username = (char*)malloc(buffer_size);
314 *password = (char*)malloc(buffer_size);
315 *dblink = (char*)malloc(buffer_size);
316
317 /* clearup */
318 **username = **password = **dblink = 0;
319
320 /* Decrypt any encrypted token */
321 conn_decrypted = msDecryptStringTokens(map, connection);
322 if (conn_decrypted == NULL) return;
323
324 /* ok, split connection */
325 for( tgt=*username, src=conn_decrypted; *src; src++, tgt++ )
326 if (*src=='/' || *src=='@')
327 break;
328 else
329 *tgt = *src;
330 *tgt = 0;
331 if (*src == '/') {
332 for( tgt=*password, ++src; *src; src++, tgt++ )
333 if (*src == '@')
334 break;
335 else
336 *tgt = *src;
337 *tgt = 0;
338 }
339 if (*src == '@') {
340 strlcpy( *dblink, ++src, buffer_size);
341 }
342
343 msFree(conn_decrypted);
344 }
345
346 /* break layer->data into geometry_column_name, table_name and srid */
msSplitData(char * data,char ** geometry_column_name,char ** table_name,char ** unique,char ** srid,char ** indexfield,int * function,int * version)347 static int msSplitData( char *data, char **geometry_column_name, char **table_name, char **unique, char **srid, char **indexfield, int *function, int *version )
348 {
349 char *tok_from = "from";
350 char *tok_using = "using";
351 char *tok_unique = "unique";
352 char *tok_srid = "srid";
353 char *tok_indexfield="indexfield";
354 char *tok_version = "version";
355 char data_version[4] = "";
356 char tok_function[11] = "";
357 int parenthesis, i;
358 char *src = data, *tgt;
359 int table_name_size = TABLE_NAME_SIZE;
360 size_t buffer_size = 0;
361
362 /* bad 'data' */
363 if (data == NULL)
364 return 0;
365
366 buffer_size = strlen(data)+1;
367 *geometry_column_name = (char*)malloc(buffer_size);
368 *unique = (char*)malloc(buffer_size);
369 *srid = (char*)malloc(buffer_size);
370 *indexfield=(char*)malloc(buffer_size);
371
372
373 /* clearup */
374 **geometry_column_name = **table_name = 0;
375
376 /* parsing 'geometry_column_name' */
377 for( ; *src && isspace( *src ); src++ ); /* skip blanks */
378 for( tgt=*geometry_column_name; *src; src++, tgt++ )
379 if (isspace( *src ))
380 break;
381 else
382 *tgt = *src;
383 *tgt = 0;
384
385 /* parsing 'from' */
386 for( ; *src && isspace( *src ); src++ ) ; /* skip blanks */
387 for( ; *src && *tok_from && tolower(*src)==*tok_from; src++, tok_from++ );
388 if (*tok_from != '\0')
389 return 0;
390
391 /* parsing 'table_name' or '(SELECT stmt)' */
392 i = 0;
393 for( ; *src && isspace( *src ); src++ ); /* skip blanks */
394 for( tgt=*table_name, parenthesis=0; *src; src++, tgt++, ++i ) {
395 if (*src == '(')
396 parenthesis++;
397 else if (*src == ')')
398 parenthesis--;
399 else if (parenthesis==0 && isspace( *src ))
400 break; /* stop on spaces */
401 /* double the size of the table_name array if necessary */
402 if (i == table_name_size) {
403 size_t tgt_offset = tgt - *table_name;
404 table_name_size *= 2;
405 *table_name = (char *) realloc(*table_name,sizeof(char *) * table_name_size);
406 tgt = *table_name + tgt_offset;
407 }
408 *tgt = *src;
409 }
410 *tgt = 0;
411
412 strlcpy( *unique, "", buffer_size);
413 strlcpy( *srid, "NULL", buffer_size);
414 strlcpy( *indexfield, "", buffer_size);
415
416 *function = -1;
417 *version = -1;
418
419 /* parsing 'unique' */
420 for( ; *src && isspace( *src ); src++ ) ; /* skip blanks */
421 if (*src != '\0') {
422 /* parse 'using' */
423 for( ; *src && *tok_using && tolower(*src)==*tok_using; src++, tok_using++ );
424 if (*tok_using != '\0')
425 return 0;
426
427 /* parsing 'unique' */
428 for( ; *src && isspace( *src ); src++ ); /* skip blanks */
429 for( ; *src && *tok_unique && tolower(*src)==*tok_unique; src++, tok_unique++ );
430
431 if (*tok_unique == '\0') {
432 for( ; *src && isspace( *src ); src++ ); /* skip blanks */
433 if (*src == '\0')
434 return 0;
435 for( tgt=*unique; *src; src++, tgt++ )
436 if (isspace( *src ))
437 break;
438 else
439 *tgt = *src;
440 *tgt = 0;
441
442 if (*tok_unique != '\0')
443 return 0;
444 }
445
446 /* parsing 'srid' */
447 for( ; *src && isspace( *src ); src++ ); /* skip blanks */
448 for( ; *src && *tok_srid && tolower(*src)==*tok_srid; src++, tok_srid++ );
449 if (*tok_srid == '\0') {
450 for( ; *src && isspace( *src ); src++ ); /* skip blanks */
451 if (*src == '\0')
452 return 0;
453 for( tgt=*srid; *src; src++, tgt++ )
454 if (isspace( *src ))
455 break;
456 else
457 *tgt = *src;
458 *tgt = 0;
459
460 if (*tok_srid != '\0')
461 return 0;
462 }
463
464 /* parsing 'indexfield' */
465 for( ; *src && isspace( *src ); src++ ); /* skip blanks */
466 for( ; *src && *tok_indexfield && tolower(*src)==*tok_indexfield; src++, tok_indexfield++ );
467
468 if (*tok_indexfield == '\0') {
469 for( ; *src && isspace( *src ); src++ ); /* skip blanks */
470 if (*src == '\0')
471 return 0;
472 for( tgt=*indexfield; *src; src++, tgt++ )
473 if (isspace( *src ))
474 break;
475 else
476 *tgt = *src;
477 *tgt = 0;
478
479 if (*tok_indexfield != '\0')
480 return 0;
481 }
482
483 /*parsing function/version */
484 for( ; *src && isspace( *src ); src++ );
485 if (*src != '\0') {
486 for( tgt=tok_function; *src; src++, tgt++ )
487 if (isspace( *src ))
488 break;
489 else
490 *tgt = *src;
491 *tgt = 0;
492 }
493
494 /*Upcase conversion for the FUNCTION/VERSION token*/
495 for (i=0; tok_function[i] != '\0'; i++)
496 tok_function[i] = toupper(tok_function[i]);
497
498 if (strcmp(tok_function, "VERSION")) {
499 if (!strcmp(tok_function, "FILTER") || !strcmp(tok_function, ""))
500 *function = FUNCTION_FILTER;
501 else if(!strcmp(tok_function, "RELATE"))
502 *function = FUNCTION_RELATE;
503 else if (!strcmp(tok_function,"GEOMRELATE"))
504 *function = FUNCTION_GEOMRELATE;
505 else if (!strcmp(tok_function,"NONE"))
506 *function = FUNCTION_NONE;
507 else {
508 *function = -1;
509 return 0;
510 }
511
512 /*parsing VERSION token when user defined one function*/
513 for( ; *src && isspace( *src ); src++ );
514 for( ; *src && *tok_version && tolower(*src)==*tok_version; src++, tok_version++ );
515 } else {
516 for(tgt = "VERSION"; *tgt && *tok_version && toupper(*tgt)==toupper(*tok_version); tgt++, tok_version++ );
517 *function = FUNCTION_FILTER;
518 }
519
520 /*parsing version*/
521 if (*tok_version == '\0') {
522 for( ; *src && isspace( *src ); src++ ); /* skip blanks */
523 for( tgt=data_version; *src; src++, tgt++ )
524 if (isspace( *src ))
525 break;
526 else
527 *tgt = *src;
528 *tgt = 0;
529
530 for (i=0; data_version[i] != '\0'; i++)
531 data_version[i] = tolower(data_version[i]);
532
533 if (!strcmp(data_version, "8i"))
534 *version = VERSION_8i;
535 else if(!strcmp(data_version, "9i"))
536 *version = VERSION_9i;
537 else if (!strcmp(data_version, "10g"))
538 *version = VERSION_10g;
539 else
540 return 0;
541
542 }
543
544 }
545 /* finish parsing */
546 for( ; *src && isspace( *src ); src++ ); /* skip blanks */
547
548 return (*src == '\0');
549 }
550
551
552 /******************************************************************************
553 * OCI Helper Functions *
554 ******************************************************************************/
555
556 /* create statement handle from database connection */
msOCIOpenStatement(msOracleSpatialHandler * hand,msOracleSpatialStatement * sthand)557 static int msOCIOpenStatement( msOracleSpatialHandler *hand, msOracleSpatialStatement *sthand)
558 {
559 int success = 0;
560 char * cmd = "";
561
562 /* allocate stmthp */
563 success = TRY( hand, OCIHandleAlloc( (dvoid *)hand->envhp, (dvoid **)&sthand->stmthp, (ub4)OCI_HTYPE_STMT, (size_t)0, (dvoid **)0 ) );
564
565 sthand->rows_count = 0;
566 sthand->row_num = 0;
567 sthand->rows_fetched = 0;
568 sthand->row = 0;
569 sthand->items = NULL;
570 sthand->items_query = NULL;
571
572 /* setting environment values to enable time parsing */
573
574 cmd = "alter session set NLS_DATE_FORMAT='yyyy-mm-dd hh24:mi:ss'";
575 success = TRY(hand, OCIStmtPrepare( sthand->stmthp, hand->errhp, (const OraText*)cmd, (ub4) strlen(cmd), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT));
576 success = TRY(hand, OCIStmtExecute( hand->svchp, sthand->stmthp, hand->errhp, (ub4)ARRAY_SIZE, (ub4)0, (OCISnapshot *)NULL, (OCISnapshot *)NULL, (ub4)OCI_DEFAULT ) );
577
578 cmd = "alter session set NLS_TIMESTAMP_TZ_FORMAT='yyyy-mm-dd hh24:mi:ss'";
579 success = TRY(hand, OCIStmtPrepare( sthand->stmthp, hand->errhp, (const OraText*)cmd, (ub4) strlen(cmd), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT));
580 success = TRY(hand, OCIStmtExecute( hand->svchp, sthand->stmthp, hand->errhp, (ub4)ARRAY_SIZE, (ub4)0, (OCISnapshot *)NULL, (OCISnapshot *)NULL, (ub4)OCI_DEFAULT ) );
581
582 cmd = "alter session set NLS_TIMESTAMP_FORMAT = 'yyyy-mm-dd hh24:mi:ss'";
583 success = TRY(hand, OCIStmtPrepare( sthand->stmthp, hand->errhp, (const OraText*)cmd, (ub4) strlen(cmd), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT));
584 success = TRY(hand, OCIStmtExecute( hand->svchp, sthand->stmthp, hand->errhp, (ub4)ARRAY_SIZE, (ub4)0, (OCISnapshot *)NULL, (OCISnapshot *)NULL, (ub4)OCI_DEFAULT ) );
585
586 cmd = "alter session set time_zone = 'GMT'";
587 success = TRY(hand, OCIStmtPrepare( sthand->stmthp, hand->errhp, (const OraText*)cmd, (ub4) strlen(cmd), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT));
588 success = TRY(hand, OCIStmtExecute( hand->svchp, sthand->stmthp, hand->errhp, (ub4)ARRAY_SIZE, (ub4)0, (OCISnapshot *)NULL, (OCISnapshot *)NULL, (ub4)OCI_DEFAULT ) );
589
590
591 /* fprintf(stderr, "Creating statement handle at %p\n", sthand->stmthp); */
592
593 return success;
594 }
595
596 /* create statement handle from database connection */
msOCIFinishStatement(msOracleSpatialStatement * sthand)597 static void msOCIFinishStatement( msOracleSpatialStatement *sthand )
598 {
599 if(sthand != NULL) {
600 /* fprintf(stderr, "Freeing statement handle at %p\n", sthand->stmthp); */
601
602 if (sthand->stmthp != NULL)
603 OCIHandleFree( (dvoid *)sthand->stmthp, (ub4)OCI_HTYPE_STMT );
604 if (sthand->items != NULL)
605 free( sthand->items );
606 if (sthand->items_query != NULL)
607 free( sthand->items_query );
608 memset(sthand, 0, sizeof( msOracleSpatialStatement ) );
609 free(sthand);
610 }
611 }
612
msOCISetDataHandlers(msOracleSpatialHandler * hand,msOracleSpatialDataHandler * dthand)613 static int msOCISetDataHandlers(msOracleSpatialHandler *hand, msOracleSpatialDataHandler *dthand)
614 {
615 int success = 0;
616 OCIParam *paramp = NULL;
617 OCIRef *type_ref = NULL;
618
619 success = TRY( hand,
620 /* allocate dschp */
621 OCIHandleAlloc( hand->envhp, (dvoid **)&dthand->dschp, (ub4)OCI_HTYPE_DESCRIBE, (size_t)0, (dvoid **)0 ) )
622 && TRY( hand,
623 /* describe SDO_GEOMETRY in svchp (dschp) */
624 OCIDescribeAny( hand->svchp, hand->errhp, (text *)SDO_GEOMETRY, (ub4)SDO_GEOMETRY_LEN, OCI_OTYPE_NAME, (ub1)1, (ub1)OCI_PTYPE_TYPE, dthand->dschp ) )
625 && TRY( hand,
626 /* get param for SDO_GEOMETRY */
627 OCIAttrGet( (dvoid *)dthand->dschp, (ub4)OCI_HTYPE_DESCRIBE, (dvoid *)¶mp, (ub4 *)0, (ub4)OCI_ATTR_PARAM, hand->errhp ) )
628 && TRY( hand,
629 /* get type_ref for SDO_GEOMETRY */
630 OCIAttrGet( (dvoid *)paramp, (ub4)OCI_DTYPE_PARAM, (dvoid *)&type_ref, (ub4 *)0, (ub4)OCI_ATTR_REF_TDO, hand->errhp ) )
631 && TRY( hand,
632 /* get TDO for SDO_GEOMETRY */
633 OCIObjectPin( hand->envhp, hand->errhp, type_ref, (OCIComplexObject *)0, OCI_PIN_ANY, OCI_DURATION_SESSION, OCI_LOCK_NONE, (dvoid **)&dthand->tdo ) );
634
635 return success;
636 }
637
638 /* connect to database */
msOCISetHandlers(char * username,char * password,char * dblink)639 static msOracleSpatialHandler *msOCISetHandlers( char *username, char *password, char *dblink )
640 {
641 int success;
642
643 msOracleSpatialHandler *hand = NULL;
644
645 hand = (msOracleSpatialHandler *) malloc( sizeof(msOracleSpatialHandler));
646 if (hand == NULL) {
647 msSetError(MS_MEMERR, NULL, "msOCISetHandlers()");
648 return NULL;
649 }
650 memset( hand, 0, sizeof(msOracleSpatialHandler) );
651
652 hand->ref_count = 1;
653 hand->last_oci_status = MS_SUCCESS;
654 hand->last_oci_error[0] = (text)'\0';
655
656 success = TRY( hand,
657 /* allocate envhp */
658 #ifdef USE_THREAD
659 OCIEnvCreate( &hand->envhp, OCI_OBJECT|OCI_THREADED, (dvoid *)0, 0, 0, 0, (size_t) 0, (dvoid **)0 ) )
660 #else
661 OCIEnvCreate( &hand->envhp, OCI_OBJECT, (dvoid *)0, 0, 0, 0, (size_t) 0, (dvoid **)0 ) )
662 #endif
663 && TRY( hand,
664 /* allocate errhp */
665 OCIHandleAlloc( (dvoid *)hand->envhp, (dvoid **)&hand->errhp, (ub4)OCI_HTYPE_ERROR, (size_t)0, (dvoid **)0 ) )
666 && TRY( hand,
667 /* logon */
668 OCILogon( hand->envhp, hand->errhp, &hand->svchp, (text *)username, strlen(username), (text *)password, strlen(password), (text *)dblink, strlen(dblink) ) );
669
670 if ( !success ) {
671 msDebug( "Cannot create OCI Handlers. "
672 "Connection failure."
673 "Error: %s."
674 "msOracleSpatialLayerOpen()\n", hand->last_oci_error);
675 msSetError( MS_ORACLESPATIALERR,
676 "Cannot create OCI Handlers. "
677 "Connection failure. Check your logs and the connection string. ",
678 "msOracleSpatialLayerOpen()");
679
680 msOCICloseHandlers(hand);
681 return NULL;
682 }
683
684 return hand;
685
686 }
687
688 /* disconnect from database */
msOCICloseHandlers(msOracleSpatialHandler * hand)689 static void msOCICloseHandlers( msOracleSpatialHandler *hand )
690 {
691 if (hand->svchp != NULL)
692 OCILogoff( hand->svchp, hand->errhp );
693 if (hand->errhp != NULL)
694 OCIHandleFree( (dvoid *)hand->errhp, (ub4)OCI_HTYPE_ERROR );
695 if (hand->envhp != NULL)
696 OCIHandleFree( (dvoid *)hand->envhp, (ub4)OCI_HTYPE_ENV );
697 if (hand != NULL)
698 memset( hand, 0, sizeof (msOracleSpatialHandler));
699 free(hand);
700 }
701
msOCICloseDataHandlers(msOracleSpatialDataHandler * dthand)702 static void msOCICloseDataHandlers( msOracleSpatialDataHandler *dthand )
703 {
704 if (dthand->dschp != NULL)
705 OCIHandleFree( (dvoid *)dthand->dschp, (ub4)OCI_HTYPE_DESCRIBE );
706 if (dthand != NULL)
707 memset( dthand, 0, sizeof (msOracleSpatialDataHandler));
708 free(dthand);
709 }
710
msOCIClearLayerInfo(msOracleSpatialLayerInfo * layerinfo)711 static void msOCIClearLayerInfo( msOracleSpatialLayerInfo *layerinfo )
712 {
713 if (layerinfo != NULL) {
714 memset( layerinfo, 0, sizeof( msOracleSpatialLayerInfo ) );
715 free(layerinfo);
716 }
717 }
718
719 /*function that creates the correct sql for geoditical srid for version 9i*/
osGeodeticData(int function,int version,char * query_str,size_t size,char * geom_column_name,char * index_column_name,char * srid,rectObj rect)720 static void osGeodeticData(int function, int version, char *query_str, size_t size, char *geom_column_name, char *index_column_name, char *srid, rectObj rect)
721 {
722 char *filter_field=index_column_name[0]=='\0' ? geom_column_name : index_column_name;
723 switch (function) {
724 case FUNCTION_FILTER: {
725 snprintf( query_str + strlen(query_str), size-strlen(query_str),
726 "SDO_FILTER( %s, SDO_CS.VIEWPORT_TRANSFORM(MDSYS.SDO_GEOMETRY("
727 "2003, 0, NULL,"
728 "MDSYS.SDO_ELEM_INFO_ARRAY(1,1003,3),"
729 ":ordinates ), :srid),"
730 "'querytype=window') = 'TRUE'",
731 filter_field);
732 break;
733 }
734 case FUNCTION_RELATE: {
735 snprintf( query_str + strlen(query_str), size-strlen(query_str),
736 "SDO_RELATE( %s, SDO_CS.VIEWPORT_TRANSFORM(MDSYS.SDO_GEOMETRY("
737 "2003, 0, NULL,"
738 "MDSYS.SDO_ELEM_INFO_ARRAY(1,1003,3),"
739 ":ordinates ), :srid),"
740 "'mask=anyinteract querytype=window') = 'TRUE'",
741 filter_field);
742 break;
743 }
744 case FUNCTION_GEOMRELATE: {
745 snprintf( query_str + strlen(query_str), size-strlen(query_str),
746 "SDO_GEOM.RELATE( %s, 'anyinteract', SDO_CS.VIEWPORT_TRANSFORM(MDSYS.SDO_GEOMETRY("
747 "2003, 0, NULL,"
748 "MDSYS.SDO_ELEM_INFO_ARRAY(1,1003,3),"
749 ":ordinates), :srid),"
750 "%f) = 'TRUE' AND %s IS NOT NULL",
751 index_column_name, TOLERANCE, geom_column_name );
752 break;
753 }
754 case FUNCTION_NONE: {
755 break;
756 }
757 default: {
758 snprintf( query_str + strlen(query_str), size-strlen(query_str),
759 "SDO_FILTER( %s, SDO_CS.VIEWPORT_TRANSFORM(MDSYS.SDO_GEOMETRY("
760 "2003, 0, NULL,"
761 "MDSYS.SDO_ELEM_INFO_ARRAY(1,1003,3),"
762 ":ordinates), :srid),"
763 "'querytype=window') = 'TRUE'",
764 filter_field );
765 }
766 }
767 }
768
769 /*function that generate the correct sql for no geoditic srid's*/
osNoGeodeticData(int function,int version,char * query_str,size_t size,char * geom_column_name,char * index_column_name,char * srid,rectObj rect)770 static void osNoGeodeticData(int function, int version, char *query_str, size_t size, char *geom_column_name, char *index_column_name, char *srid, rectObj rect)
771 {
772 char *filter_field= index_column_name[0]=='\0' ? geom_column_name : index_column_name;
773 switch (function) {
774 case FUNCTION_FILTER: {
775 snprintf( query_str + strlen(query_str), size-strlen(query_str),
776 "SDO_FILTER( %s, MDSYS.SDO_GEOMETRY("
777 "2003, :srid, NULL,"
778 "MDSYS.SDO_ELEM_INFO_ARRAY(1,1003,3),"
779 /* "MDSYS.SDO_ORDINATE_ARRAY(%.9g,%.9g,%.9g,%.9g)" */
780 ":ordinates"
781 " ),'querytype=window') = 'TRUE'",
782 filter_field);
783 break;
784 }
785 case FUNCTION_RELATE: {
786 if (version == VERSION_10g) {
787 snprintf( query_str + strlen(query_str), size-strlen(query_str),
788 "SDO_ANYINTERACT( %s, MDSYS.SDO_GEOMETRY("
789 "2003, :srid, NULL,"
790 "MDSYS.SDO_ELEM_INFO_ARRAY(1,1003,3),"
791 ":ordinates)) = 'TRUE'",
792 filter_field);
793 } else {
794 snprintf( query_str + strlen(query_str), size-strlen(query_str),
795 "SDO_RELATE( %s, MDSYS.SDO_GEOMETRY("
796 "2003, :srid, NULL,"
797 "MDSYS.SDO_ELEM_INFO_ARRAY(1,1003,3),"
798 ":ordinates),"
799 "'mask=anyinteract querytype=window') = 'TRUE'",
800 geom_column_name);
801 }
802 break;
803 }
804 case FUNCTION_GEOMRELATE: {
805 snprintf( query_str + strlen(query_str), size-strlen(query_str),
806 "SDO_GEOM.RELATE( %s, 'anyinteract', MDSYS.SDO_GEOMETRY("
807 "2003, :srid, NULL,"
808 "MDSYS.SDO_ELEM_INFO_ARRAY(1,1003,3),"
809 ":ordinates),"
810 "%f) = 'TRUE' AND %s IS NOT NULL",
811 index_column_name, TOLERANCE, geom_column_name );
812 break;
813 }
814 case FUNCTION_NONE: {
815 break;
816 }
817 default: {
818 snprintf( query_str + strlen(query_str), size-strlen(query_str),
819 "SDO_FILTER( %s, MDSYS.SDO_GEOMETRY("
820 "2003, :srid, NULL,"
821 "MDSYS.SDO_ELEM_INFO_ARRAY(1,1003,3),"
822 ":ordinates),"
823 "'querytype=window') = 'TRUE'",
824 filter_field);
825 }
826 }
827 }
828
829 /* get ordinates from SDO buffer */
msOCIGet2DOrdinates(msOracleSpatialHandler * hand,SDOGeometryObj * obj,int s,int e,pointObj * pt)830 static int msOCIGet2DOrdinates( msOracleSpatialHandler *hand, SDOGeometryObj *obj, int s, int e, pointObj *pt )
831 {
832 double x, y;
833 int i, n, success = 1;
834 boolean exists;
835 OCINumber *oci_number;
836
837 for( i=s, n=0; i < e && success; i+=2, n++ ) {
838 success = TRY( hand,
839 OCICollGetElem( hand->envhp, hand->errhp, (OCIColl *)obj->ordinates, (sb4)i, (boolean *)&exists, (dvoid *)&oci_number, (dvoid **)0 ) )
840 && TRY( hand,
841 OCINumberToReal( hand->errhp, oci_number, (uword)sizeof(double), (dvoid *)&x ) )
842 && TRY( hand,
843 OCICollGetElem( hand->envhp, hand->errhp, (OCIColl *)obj->ordinates, (sb4)i+1, (boolean *)&exists, (dvoid *)&oci_number, (dvoid **)0 ) )
844 && TRY( hand,
845 OCINumberToReal( hand->errhp, oci_number, (uword)sizeof(double), (dvoid *)&y ) );
846
847 if (success) {
848 pt[n].x = x;
849 pt[n].y = y;
850 }
851 }
852
853 return success ? n : 0;
854 }
855
msOCIGet3DOrdinates(msOracleSpatialHandler * hand,SDOGeometryObj * obj,int s,int e,pointObj * pt)856 static int msOCIGet3DOrdinates( msOracleSpatialHandler *hand, SDOGeometryObj *obj, int s, int e, pointObj *pt )
857 {
858 double x, y;
859 int i, n, success = 1;
860 boolean exists;
861 #ifdef USE_POINT_Z_M
862 double z;
863 boolean numnull;
864 #endif /* USE_POINT_Z_M */
865 OCINumber *oci_number;
866
867 for( i=s, n=0; i < e && success; i+=3, n++ ) {
868 success = TRY( hand,
869 OCICollGetElem( hand->envhp, hand->errhp, (OCIColl *)obj->ordinates, (sb4)i, (boolean *)&exists, (dvoid *)&oci_number, (dvoid **)0 ) )
870 && TRY( hand,
871 OCINumberToReal( hand->errhp, oci_number, (uword)sizeof(double), (dvoid *)&x ) )
872 && TRY( hand,
873 OCICollGetElem( hand->envhp, hand->errhp, (OCIColl *)obj->ordinates, (sb4)i+1, (boolean *)&exists, (dvoid *)&oci_number, (dvoid **)0 ) )
874 && TRY( hand,
875 OCINumberToReal( hand->errhp, oci_number, (uword)sizeof(double), (dvoid *)&y ) )
876 #ifdef USE_POINT_Z_M
877 && TRY( hand,
878 OCICollGetElem( hand->envhp, hand->errhp, (OCIColl *)obj->ordinates, (sb4)i+2, (boolean *)&exists, (dvoid *)&oci_number, (dvoid **)0 ) )
879 #endif /* USE_POINT_Z_M */
880 ;
881 #ifdef USE_POINT_Z_M
882 if (success) {
883 success = TRY(hand, OCINumberIsZero( hand->errhp, oci_number, (boolean *)&numnull));
884 if (success) {
885 success = TRY( hand, OCINumberToReal( hand->errhp, oci_number, (uword)sizeof(double), (dvoid *)&z ) );
886 } else {
887 hand->last_oci_status = MS_SUCCESS;
888 strlcpy( (char *)hand->last_oci_error, "Retrieve z value, but NULL value for z. Setting z to 0.", sizeof(hand->last_oci_error));
889 z = 0;
890 success = 1;
891 }
892 }
893 #endif /* USE_POINT_Z_M */
894 if (success) {
895 pt[n].x = x;
896 pt[n].y = y;
897 #ifdef USE_POINT_Z_M
898 pt[n].z = z;
899 #endif /* USE_POINT_Z_M */
900 }
901 }
902
903 return success ? n : 0;
904 }
905
msOCIGet4DOrdinates(msOracleSpatialHandler * hand,SDOGeometryObj * obj,int s,int e,pointObj * pt)906 static int msOCIGet4DOrdinates( msOracleSpatialHandler *hand, SDOGeometryObj *obj, int s, int e, pointObj *pt )
907 {
908 double x, y;
909 int i, n, success = 1;
910 boolean exists;
911 #ifdef USE_POINT_Z_M
912 double z;
913 boolean numnull;
914 #endif /* USE_POINT_Z_M */
915 OCINumber *oci_number;
916
917 for( i=s, n=0; i < e && success; i+=4, n++ ) {
918 success = TRY( hand,
919 OCICollGetElem( hand->envhp, hand->errhp, (OCIColl *)obj->ordinates, (sb4)i, (boolean *)&exists, (dvoid *)&oci_number, (dvoid **)0 ) )
920 && TRY( hand,
921 OCINumberToReal( hand->errhp, oci_number, (uword)sizeof(double), (dvoid *)&x ) )
922 && TRY( hand,
923 OCICollGetElem( hand->envhp, hand->errhp, (OCIColl *)obj->ordinates, (sb4)i+1, (boolean *)&exists, (dvoid *)&oci_number, (dvoid **)0 ) )
924 && TRY( hand,
925 OCINumberToReal( hand->errhp, oci_number, (uword)sizeof(double), (dvoid *)&y ) )
926 #ifdef USE_POINT_Z_M
927 && TRY( hand,
928 OCICollGetElem( hand->envhp, hand->errhp, (OCIColl *)obj->ordinates, (sb4)i+2, (boolean *)&exists, (dvoid *)&oci_number, (dvoid **)0 ) )
929
930 #endif /* USE_POINT_Z_M */
931 ;
932 #ifdef USE_POINT_Z_M
933 if (success) {
934 success = TRY(hand, OCINumberIsZero( hand->errhp, oci_number, (boolean *)&numnull));
935 if (success) {
936 success = TRY( hand, OCINumberToReal( hand->errhp, oci_number, (uword)sizeof(double), (dvoid *)&z ) );
937 } else {
938 hand->last_oci_status = MS_SUCCESS;
939 strlcpy( (char *)hand->last_oci_error, "Retrieve z value, but NULL value for z. Setting z to 0.", sizeof(hand->last_oci_error));
940 z = 0;
941 success = 1;
942 }
943 }
944 #endif /* USE_POINT_Z_M */
945 if (success) {
946 pt[n].x = x;
947 pt[n].y = y;
948 #ifdef USE_POINT_Z_M
949 pt[n].z = z;
950
951 #endif /* USE_POINT_Z_M */
952 }
953 }
954 return success ? n : 0;
955 }
956
957 /* convert three-point circle to two-point rectangular bounds */
msOCIConvertCircle(pointObj * pt)958 static int msOCIConvertCircle( pointObj *pt )
959 {
960 pointObj ptaux;
961 double dXa, dXb;
962 double ma, mb;
963 double cx, cy, r;
964 int success;
965
966 dXa = pt[1].x - pt[0].x;
967 success = (fabs( dXa ) > 1e-8);
968 if (!success) {
969 /* switch points 1 & 2 */
970 ptaux = pt[1];
971 pt[1] = pt[2];
972 pt[2] = ptaux;
973 dXa = pt[1].x - pt[0].x;
974 success = (fabs( dXa ) > 1e-8);
975 }
976 if (success) {
977 dXb = pt[2].x - pt[1].x;
978 success = (fabs( dXb ) > 1e-8);
979 if (!success) {
980 /* insert point 2 before point 0 */
981 ptaux = pt[2];
982 pt[2] = pt[1];
983 pt[1] = pt[0];
984 pt[0] = ptaux;
985 dXb = dXa; /* segment A has become B */
986 dXa = pt[1].x - pt[0].x; /* recalculate new segment A */
987 success = (fabs( dXa ) > 1e-8);
988 }
989 }
990 if (success) {
991 ma = (pt[1].y - pt[0].y)/dXa;
992 mb = (pt[2].y - pt[1].y)/dXb;
993 success = (fabs( mb - ma ) > 1e-8);
994 }
995 if (!success)
996 return 0;
997
998 /* calculate center and radius */
999 cx = (ma*mb*(pt[0].y - pt[2].y) + mb*(pt[0].x + pt[1].x) - ma*(pt[1].x + pt[2].x))/(2*(mb - ma));
1000 cy = (fabs( ma ) > 1e-8)
1001 ? ((pt[0].y + pt[1].y)/2 - (cx - (pt[0].x + pt[1].x)/2)/ma)
1002 : ((pt[1].y + pt[2].y)/2 - (cx - (pt[1].x + pt[2].x)/2)/mb);
1003
1004 r = sqrt( pow( pt[0].x - cx, 2 ) + pow( pt[0].y - cy, 2 ) );
1005
1006 /* update pt buffer with rectangular bounds */
1007 pt[0].x = cx - r;
1008 pt[0].y = cy - r;
1009 pt[1].x = cx + r;
1010 pt[1].y = cy + r;
1011
1012 return 1;
1013 }
1014
1015 /*function that creates the correct sql for filter and filteritem*/
osFilteritem(layerObj * layer,int function,char * query_str,size_t size,int mode)1016 static void osFilteritem(layerObj *layer, int function, char *query_str, size_t size, int mode)
1017 {
1018 char *native_filter;
1019 if (layer->filter.native_string != NULL) {
1020 if (mode == 1)
1021 strlcat( query_str, " WHERE ", size);
1022 else
1023 strlcat( query_str, " AND ", size);
1024
1025 /* if (layer->filteritem != NULL) {
1026 snprintf (query_str + strlen(query_str), size-strlen(query_str), " %s = ", layer->filteritem); */
1027 /* snprintf (query_str + strlen(query_str), " %s = ", layer->filteritem); */
1028 /* } */
1029
1030 snprintf (query_str + strlen(query_str), size-strlen(query_str), " %s ", layer->filter.native_string);
1031 /* snprintf(buffer, n, "gfdg %s %s %s", layer->filter.native_string, (layer->filteritem != NULL ? layer->filteritem : ""), ); */
1032
1033 if (function != FUNCTION_NONE)
1034 snprintf (query_str + strlen(query_str), size-strlen(query_str), " AND ");
1035 } else {
1036 if (function != FUNCTION_NONE)
1037 strlcat( query_str, " WHERE ", size);
1038 }
1039
1040 /* Handle a native filter set as a PROCESSING option (#5001). */
1041 if ( msLayerGetProcessingKey(layer, "NATIVE_FILTER") != NULL ) {
1042 if ((function == FUNCTION_NONE)&&(layer->filter.native_string == NULL)) {
1043 strlcat( query_str, " WHERE ", size);
1044 }
1045 if ((function == FUNCTION_NONE)&&(layer->filter.native_string != NULL)) {
1046 strlcat( query_str, " AND ", size);
1047 }
1048 native_filter = msLayerGetProcessingKey(layer, "NATIVE_FILTER");
1049 snprintf(query_str + strlen(query_str) , size-strlen(query_str), " %s ", native_filter);
1050 if (function != FUNCTION_NONE) {
1051 strlcat( query_str, " AND ", size);
1052 }
1053
1054 }
1055
1056
1057 }
1058
osAggrGetExtent(layerObj * layer,char * query_str,size_t size,char * geom_column_name,char * table_name)1059 static void osAggrGetExtent(layerObj *layer, char *query_str, size_t size, char *geom_column_name, char *table_name)
1060 {
1061 char query_str2[6000];
1062 int i = 0;
1063
1064 snprintf( query_str2, sizeof(query_str2), "(SELECT");
1065 for( i = 0; i < layer->numitems; ++i )
1066 snprintf( query_str2 + strlen(query_str2), sizeof(query_str2)-strlen(query_str2), " %s,", layer->items[i] );
1067
1068 snprintf( query_str2 + strlen(query_str2), sizeof(query_str2)-strlen(query_str2), " %s FROM %s", geom_column_name, table_name);
1069
1070 osFilteritem(layer, FUNCTION_NONE, query_str2, sizeof(query_str2), 1);
1071
1072 snprintf( query_str, size, "SELECT SDO_AGGR_MBR(%s) AS GEOM from %s)", geom_column_name, query_str2);
1073
1074 if (layer->debug)
1075 msDebug("osAggrGetExtent was called: %s.\n", query_str);
1076 }
1077
osConvexHullGetExtent(layerObj * layer,char * query_str,size_t size,char * geom_column_name,char * table_name)1078 static void osConvexHullGetExtent(layerObj *layer, char *query_str, size_t size, char *geom_column_name, char *table_name)
1079 {
1080 char query_str2[6000];
1081 int i = 0;
1082
1083 snprintf( query_str2, sizeof(query_str2), "(SELECT");
1084 for( i = 0; i < layer->numitems; ++i )
1085 snprintf( query_str2 + strlen(query_str2), sizeof(query_str2)-strlen(query_str2), " %s,", layer->items[i] );
1086
1087 snprintf( query_str2 + strlen(query_str2), sizeof(query_str2)-strlen(query_str2), " %s FROM %s", geom_column_name, table_name);
1088
1089 osFilteritem(layer, FUNCTION_NONE, query_str2, sizeof(query_str2), 1);
1090
1091
1092 snprintf( query_str, size, "SELECT SDO_GEOM.SDO_CONVEXHULL(%s, %f) AS GEOM from %s)", geom_column_name, TOLERANCE, query_str2);
1093 }
1094
osCalculateArcRadius(pointObj * pnt)1095 static double osCalculateArcRadius(pointObj *pnt)
1096 {
1097 double rc;
1098 double r1, r2, r3;
1099
1100 r1 = sqrt( pow(pnt[0].x-pnt[1].x,2) + pow(pnt[0].y-pnt[1].y,2) );
1101 r2 = sqrt( pow(pnt[1].x-pnt[2].x,2) + pow(pnt[1].y-pnt[2].y,2) );
1102 r3 = sqrt( pow(pnt[2].x-pnt[0].x,2) + pow(pnt[2].y-pnt[0].y,2) );
1103 rc = ( r1+r2+r3 )/2;
1104
1105 return ( ( r1*r2*r3 )/( 4*sqrt( rc * (rc-r1) * (rc-r2) * (rc-r3) ) ) );
1106 }
1107
osCalculateArc(pointObj * pnt,int data3d,int data4d,double area,double radius,double npoints,int side,lineObj arcline,shapeObj * shape)1108 static void osCalculateArc(pointObj *pnt, int data3d, int data4d, double area, double radius, double npoints, int side, lineObj arcline, shapeObj *shape)
1109 {
1110 double length, ctrl, angle;
1111 double divbas, plusbas, cosbas, sinbas = 0;
1112 #ifdef USE_POINT_Z_M
1113 double zrange = 0;
1114 #endif /* USE_POINT_Z_M */
1115 int i = 0;
1116
1117 if ( npoints > 0 ) {
1118 length = sqrt(((pnt[1].x-pnt[0].x)*(pnt[1].x-pnt[0].x))+((pnt[1].y-pnt[0].y)*(pnt[1].y-pnt[0].y)));
1119 ctrl = length/(2*radius);
1120
1121 #ifdef USE_POINT_Z_M
1122 if (data3d||data4d) {
1123 zrange = labs(pnt[0].z-pnt[1].z)/npoints;
1124 if ((pnt[0].z > pnt[1].z) && side == 1)
1125 zrange *= -1;
1126 else if ((pnt[0].z < pnt[1].z) && side == 1)
1127 zrange = zrange;
1128 else if ((pnt[0].z > pnt[1].z) && side != 1)
1129 zrange *= -1;
1130 else if ((pnt[0].z < pnt[1].z) && side != 1)
1131 zrange = zrange;
1132 }
1133 #endif /* USE_POINT_Z_M */
1134
1135 if( ctrl <= 1 ) {
1136 divbas = 2 * asin(ctrl);
1137 plusbas = divbas/(npoints);
1138 cosbas = (pnt[0].x-pnt[3].x)/radius;
1139 sinbas = (pnt[0].y-pnt[3].y)/radius;
1140 angle = plusbas;
1141
1142 arcline.point = (pointObj *)malloc(sizeof(pointObj)*(npoints+1));
1143 arcline.point[0].x = pnt[0].x;
1144 arcline.point[0].y = pnt[0].y;
1145 #ifdef USE_POINT_Z_M
1146 if (data3d||data4d)
1147 arcline.point[0].z = pnt[0].z;
1148 #endif /* USE_POINT_Z_M */
1149
1150 for (i = 1; i <= npoints; i++) {
1151 if( side == 1) {
1152 arcline.point[i].x = pnt[3].x + radius * ((cosbas*cos(angle))-(sinbas*sin(angle)));
1153 arcline.point[i].y = pnt[3].y + radius * ((sinbas*cos(angle))+(cosbas*sin(angle)));
1154 #ifdef USE_POINT_Z_M
1155 if (data3d||data4d)
1156 arcline.point[i].z = pnt[0].z + (zrange*i);
1157 #endif /* USE_POINT_Z_M */
1158 } else {
1159 if ( side == -1) {
1160 arcline.point[i].x = pnt[3].x + radius * ((cosbas*cos(angle))+(sinbas*sin(angle)));
1161 arcline.point[i].y = pnt[3].y + radius * ((sinbas*cos(angle))-(cosbas*sin(angle)));
1162 #ifdef USE_POINT_Z_M
1163 if (data3d||data4d)
1164 arcline.point[i].z = pnt[0].z + (zrange*i);
1165 #endif /* USE_POINT_Z_M */
1166 } else {
1167 arcline.point[i].x = pnt[0].x;
1168 arcline.point[i].y = pnt[0].y;
1169 #ifdef USE_POINT_Z_M
1170 if (data3d||data4d)
1171 arcline.point[i].z = pnt[0].z;
1172 #endif /* USE_POINT_Z_M */
1173 }
1174 }
1175 angle += plusbas;
1176 }
1177
1178 arcline.numpoints = npoints+1;
1179 msAddLine( shape, &arcline );
1180 free (arcline.point);
1181 }
1182 } else {
1183 arcline.point = (pointObj *)malloc(sizeof(pointObj)*(2));
1184 arcline.point[0].x = pnt[0].x;
1185 arcline.point[0].y = pnt[0].y;
1186 arcline.point[1].x = pnt[1].x;
1187 arcline.point[1].y = pnt[1].y;
1188
1189 #ifdef USE_POINT_Z_M
1190 if(data3d||data4d) {
1191 arcline.point[0].z = pnt[0].z;
1192 arcline.point[1].z = pnt[1].z;
1193 }
1194 #endif /* USE_POINT_Z_M */
1195
1196 arcline.numpoints = 2;
1197
1198 msAddLine( shape, &arcline );
1199 free (arcline.point);
1200 }
1201 }
1202
1203 /* Part of this function was based on Terralib function TeGenerateArc
1204 * found in TeGeometryAlgorith.cpp (www.terralib.org).
1205 * Part of this function was based on Dr. Ialo (Univali/Cttmar) functions. */
osGenerateArc(shapeObj * shape,lineObj arcline,lineObj points,int i,int n,int data3d,int data4d)1206 static void osGenerateArc(shapeObj *shape, lineObj arcline, lineObj points, int i, int n, int data3d, int data4d)
1207 {
1208 double mult, plus1, plus2, plus3, bpoint;
1209 double cx, cy;
1210 double radius, side, area, npoints;
1211 double dist1 = 0;
1212 double dist2 = 0;
1213 pointObj point5[4];
1214
1215 mult = ( points.point[i+1].x - points.point[i].x )
1216 * ( points.point[i+2].y - points.point[i].y )
1217 - ( points.point[i+1].y - points.point[i].y )
1218 * ( points.point[i+2].x - points.point[i].x );
1219
1220 if (mult) {
1221 /*point5 = (pointObj *)malloc(sizeof(pointObj)*(4));*/
1222
1223 plus1 = points.point[i].x * points.point[i].x + points.point[i].y * points.point[i].y;
1224 plus2 = points.point[i+1].x * points.point[i+1].x + points.point[i+1].y * points.point[i+1].y;
1225 plus3 = points.point[i+2].x * points.point[i+2].x + points.point[i+2].y * points.point[i+2].y;
1226
1227 bpoint = plus1 * ( points.point[i+1].y - points.point[i+2].y )
1228 + plus2 * ( points.point[i+2].y - points.point[i].y )
1229 + plus3 * ( points.point[i].y - points.point[i+1].y );
1230
1231 cx = bpoint / (2.0 * mult);
1232
1233 bpoint = plus1 * ( points.point[i+2].x - points.point[i+1].x )
1234 + plus2 * ( points.point[i].x - points.point[i+2].x )
1235 + plus3 * ( points.point[i+1].x - points.point[i].x );
1236
1237 cy = bpoint / (2.0 * mult);
1238
1239 dist1 = (points.point[i+1].x - points.point[i].x) * (cy - points.point[i].y);
1240 dist2 = (points.point[i+1].y - points.point[i].y) * (cx - points.point[i].x);
1241 side = 0;
1242
1243 if((dist1-dist2) > 0)
1244 side = 1;
1245 else {
1246 if((dist1-dist2) < 0)
1247 side = -1;
1248 }
1249
1250 point5[0] = points.point[i];
1251 point5[1] = points.point[i+1];
1252 point5[2] = points.point[i+2];
1253 point5[3].x = cx;
1254 point5[3].y = cy;
1255
1256 radius = osCalculateArcRadius(point5);
1257
1258 area = ((points.point[i].x + points.point[i+1].x) * (points.point[i+1].y - points.point[i].y))
1259 + ((points.point[i+1].x + points.point[i+2].x) * (points.point[i+2].y - points.point[i+1].y));
1260
1261 npoints = labs(area/radius);
1262
1263 point5[0] = points.point[i];
1264 point5[1] = points.point[i+1];
1265 osCalculateArc(point5, data3d, data4d, area, radius, (npoints>1000)?1000:npoints, side, arcline, shape);
1266
1267 point5[0] = points.point[i+1];
1268 point5[1] = points.point[i+2];
1269 osCalculateArc(point5, data3d, data4d, area, radius, (npoints>1000)?1000:npoints, side, arcline, shape);
1270
1271 } else {
1272 arcline.point = (pointObj *)malloc(sizeof(pointObj)*(2));
1273 arcline.point[0].x = points.point[i].x;
1274 arcline.point[0].y = points.point[i].y;
1275 arcline.point[1].x = points.point[i+2].x;
1276 arcline.point[1].y = points.point[i+2].y;
1277
1278 #ifdef USE_POINT_Z_M
1279 if (data3d||data4d) {
1280 arcline.point[0].z = points.point[i].z;
1281 arcline.point[1].z = points.point[i+2].z;
1282 }
1283 #endif /* USE_POINT_Z_M */
1284
1285 arcline.numpoints = 2;
1286
1287 msAddLine( shape, &arcline );
1288 free (arcline.point);
1289 }
1290 }
1291
osShapeBounds(shapeObj * shp)1292 static void osShapeBounds ( shapeObj *shp )
1293 {
1294 int i, f;
1295
1296 if ( (shp->numlines > 0) && (shp->line[0].numpoints > 0) ) {
1297 shp->bounds.minx = shp->line[0].point[0].x;
1298 shp->bounds.maxx = shp->line[0].point[0].x;
1299 shp->bounds.miny = shp->line[0].point[0].y;
1300 shp->bounds.maxy = shp->line[0].point[0].y;
1301 }
1302
1303 for ( i = 0 ; i < shp->numlines; i++) {
1304 for( f = 0; f < shp->line[i].numpoints; f++) {
1305 if (shp->line[i].point[f].x < shp->bounds.minx)
1306 shp->bounds.minx = shp->line[i].point[f].x;
1307 if (shp->line[i].point[f].x > shp->bounds.maxx)
1308 shp->bounds.maxx = shp->line[i].point[f].x;
1309 if (shp->line[i].point[f].y < shp->bounds.miny)
1310 shp->bounds.miny = shp->line[i].point[f].y;
1311 if (shp->line[i].point[f].y > shp->bounds.maxy)
1312 shp->bounds.maxy = shp->line[i].point[f].y;
1313 }
1314 }
1315 }
1316
osCloneShape(shapeObj * shape,shapeObj * newshape,int data3d,int data4d)1317 static void osCloneShape(shapeObj *shape, shapeObj *newshape, int data3d, int data4d)
1318 {
1319 int max_points = 0;
1320 int i,f,g;
1321 lineObj shapeline = {0, NULL};
1322
1323 for (i = 0; i < shape->numlines; i++)
1324 max_points += shape->line[i].numpoints;
1325
1326 if (max_points > 0)
1327 shapeline.point = (pointObj *)malloc( sizeof(pointObj)*max_points );
1328
1329 g = 0;
1330 for ( i = 0 ; i < shape->numlines; i++) {
1331 for( f = 0; f < shape->line[i].numpoints && g <= max_points; f++, g++) {
1332 shapeline.point[g].x = shape->line[i].point[f].x;
1333 shapeline.point[g].y = shape->line[i].point[f].y;
1334 #ifdef USE_POINT_Z_M
1335 if (data3d||data4d)
1336 shapeline.point[g].z = shape->line[i].point[f].z;
1337 #endif /* USE_POINT_Z_M */
1338 }
1339 }
1340
1341 if (g) {
1342 shapeline.numpoints = g;
1343 newshape->type = shape->type; /* jimk: 2009/09/23 Fixes compound linestrings being converted to polygons */
1344 msAddLine( newshape, &shapeline );
1345 }
1346 }
1347
osPointCluster(msOracleSpatialHandler * hand,shapeObj * shape,SDOGeometryObj * obj,int start,int end,lineObj points,int interpretation,int data3d,int data4d)1348 static void osPointCluster(msOracleSpatialHandler *hand, shapeObj *shape, SDOGeometryObj *obj, int start, int end, lineObj points, int interpretation, int data3d, int data4d)
1349 {
1350 int n;
1351
1352 n = (end - start)/2;
1353 /* n = interpretation; */
1354
1355 /* if (n == interpretation) { */
1356 points.point = (pointObj *)malloc( sizeof(pointObj)*n );
1357
1358 if (data3d)
1359 n = msOCIGet3DOrdinates( hand, obj, start, end, points.point );
1360 else if (data4d)
1361 n = msOCIGet4DOrdinates( hand, obj, start, end, points.point );
1362 else
1363 n = msOCIGet2DOrdinates( hand, obj, start, end, points.point );
1364
1365 if (n == interpretation && n>0) {
1366 shape->type = MS_SHAPE_POINT;
1367 points.numpoints = n;
1368 msAddLine( shape, &points );
1369 }
1370 free( points.point );
1371 /* } */
1372 }
1373
osPoint(msOracleSpatialHandler * hand,shapeObj * shape,SDOGeometryObj * obj,int start,int end,lineObj points,pointObj * pnt,int data3d,int data4d)1374 static void osPoint(msOracleSpatialHandler *hand, shapeObj *shape, SDOGeometryObj *obj, int start, int end, lineObj points, pointObj *pnt, int data3d, int data4d)
1375 {
1376 int n;
1377
1378 if (data3d)
1379 n = msOCIGet3DOrdinates( hand, obj, start, end, pnt );
1380 else if (data4d)
1381 n = msOCIGet4DOrdinates( hand, obj, start, end, pnt );
1382 else
1383 n = msOCIGet2DOrdinates( hand, obj, start, end, pnt ); /* n must be < 5 */
1384
1385 if (n == 1) {
1386 shape->type = MS_SHAPE_POINT;
1387 points.numpoints = 1;
1388 points.point = pnt;
1389 msAddLine( shape, &points );
1390 }
1391 }
1392
osClosedPolygon(msOracleSpatialHandler * hand,shapeObj * shape,SDOGeometryObj * obj,int start,int end,lineObj points,int elem_type,int data3d,int data4d)1393 static void osClosedPolygon(msOracleSpatialHandler *hand, shapeObj *shape, SDOGeometryObj *obj, int start, int end, lineObj points, int elem_type, int data3d, int data4d)
1394 {
1395 int n;
1396
1397 n = (end - start)/2;
1398 points.point = (pointObj *)malloc( sizeof(pointObj)*n );
1399
1400 if (data3d)
1401 n = msOCIGet3DOrdinates( hand, obj, start, end, points.point );
1402 else if (data4d)
1403 n = msOCIGet4DOrdinates( hand, obj, start, end, points.point );
1404 else
1405 n = msOCIGet2DOrdinates( hand, obj, start, end, points.point );
1406
1407 if (n > 0) {
1408 shape->type = (elem_type==21) ? MS_SHAPE_LINE : MS_SHAPE_POLYGON;
1409 points.numpoints = n;
1410 msAddLine( shape, &points );
1411 }
1412 free( points.point );
1413 }
1414
osRectangle(msOracleSpatialHandler * hand,shapeObj * shape,SDOGeometryObj * obj,int start,int end,lineObj points,pointObj * pnt,int data3d,int data4d)1415 static void osRectangle(msOracleSpatialHandler *hand, shapeObj *shape, SDOGeometryObj *obj, int start, int end, lineObj points, pointObj *pnt, int data3d, int data4d)
1416 {
1417 int n;
1418
1419 if (data3d)
1420 n = msOCIGet3DOrdinates( hand, obj, start, end, pnt ); /* n must be < 5 */
1421 else if (data4d)
1422 n = msOCIGet4DOrdinates( hand, obj, start, end, pnt ); /* n must be < 5 */
1423 else
1424 n = msOCIGet2DOrdinates( hand, obj, start, end, pnt ); /* n must be < 5 */
1425
1426 if (n == 2) {
1427 shape->type = MS_SHAPE_POLYGON;
1428 points.numpoints = 5;
1429 points.point = pnt;
1430
1431 /* point5 [0] & [1] contains the lower-left and upper-right points of the rectangle */
1432 pnt[2] = pnt[1];
1433 pnt[1].x = pnt[0].x;
1434 pnt[3].x = pnt[2].x;
1435 pnt[3].y = pnt[0].y;
1436 pnt[4] = pnt[0];
1437 #ifdef USE_POINT_Z_M
1438 if (data3d||data4d) {
1439 pnt[1].z = pnt[0].z;
1440 pnt[3].z = pnt[2].z;
1441 }
1442 #endif /* USE_POINT_Z_M */
1443
1444 msAddLine( shape, &points );
1445 }
1446 }
1447
osCircle(msOracleSpatialHandler * hand,shapeObj * shape,SDOGeometryObj * obj,int start,int end,lineObj points,pointObj * pnt,int data3d,int data4d)1448 static void osCircle(msOracleSpatialHandler *hand, shapeObj *shape, SDOGeometryObj *obj, int start, int end, lineObj points, pointObj *pnt, int data3d, int data4d)
1449 {
1450 int n;
1451
1452 if (data3d)
1453 n = msOCIGet3DOrdinates( hand, obj, start, end, pnt ); /* n must be < 5 */
1454 else if (data4d)
1455 n = msOCIGet4DOrdinates( hand, obj, start, end, pnt ); /* n must be < 5 */
1456 else
1457 n = msOCIGet2DOrdinates( hand, obj, start, end, pnt ); /* n must be < 5 */
1458
1459 if (n == 3) {
1460 if (msOCIConvertCircle( pnt )) {
1461 shape->type = MS_SHAPE_POINT;
1462 points.numpoints = 2;
1463 points.point = pnt;
1464 msAddLine( shape, &points );
1465 } else {
1466 strlcpy( (char *)hand->last_oci_error, "Points in circle object are colinear", sizeof(hand->last_oci_error));
1467 hand->last_oci_status = MS_FAILURE;
1468 }
1469 }
1470 }
1471
osArcPolygon(msOracleSpatialHandler * hand,shapeObj * shape,SDOGeometryObj * obj,int start,int end,lineObj arcpoints,int elem_type,int data3d,int data4d)1472 static void osArcPolygon(msOracleSpatialHandler *hand, shapeObj *shape, SDOGeometryObj *obj, int start, int end, lineObj arcpoints, int elem_type, int data3d, int data4d)
1473 {
1474 int n, i;
1475 lineObj points = {0, NULL};
1476
1477 n = (end - start)/2;
1478 points.point = (pointObj *)malloc( sizeof(pointObj)*n );
1479
1480 if (data3d)
1481 n = msOCIGet3DOrdinates( hand, obj, start, end, points.point );
1482 else if (data4d)
1483 n = msOCIGet4DOrdinates( hand, obj, start, end, points.point );
1484 else
1485 n = msOCIGet2DOrdinates( hand, obj, start, end, points.point );
1486
1487 if (n > 2) {
1488 shape->type = (elem_type==32) ? MS_SHAPE_POLYGON : MS_SHAPE_LINE;
1489 points.numpoints = n;
1490
1491 for (i = 0; i < n-2; i = i+2)
1492 osGenerateArc(shape, arcpoints, points, i, n, data3d, data4d);
1493 }
1494 free (points.point);
1495 }
1496
osCheck2DGtype(int pIntGtype)1497 static int osCheck2DGtype(int pIntGtype)
1498 {
1499 if (pIntGtype > 2000 && pIntGtype < 2008) {
1500 if (pIntGtype != 2004)
1501 return MS_TRUE;
1502 }
1503
1504 return MS_FALSE;
1505 }
1506
osCheck3DGtype(int pIntGtype)1507 static int osCheck3DGtype(int pIntGtype)
1508 {
1509 if (pIntGtype > 3000 && pIntGtype < 3308) {
1510 if (pIntGtype > 3007)
1511 pIntGtype-= 300;
1512
1513 if (pIntGtype <= 3007 && pIntGtype != 3004)
1514 return MS_TRUE;
1515 }
1516 /*
1517 * Future version, untested
1518 * return (pIntGtype & 2208 && (pIntGtype & 3000 || pIntGtype & 3296) && pIntGtype & 3);
1519 */
1520 return MS_FALSE;
1521 }
1522
osCheck4DGtype(int pIntGtype)1523 static int osCheck4DGtype(int pIntGtype)
1524 {
1525
1526 if (pIntGtype > 4000 && pIntGtype < 4408) {
1527 if (pIntGtype > 4007)
1528 pIntGtype-= 400;
1529
1530 if (pIntGtype <= 4007 && pIntGtype != 4004)
1531 return MS_TRUE;
1532
1533
1534 }
1535
1536 return MS_FALSE;
1537 }
1538
1539
1540
osGetOrdinates(msOracleSpatialDataHandler * dthand,msOracleSpatialHandler * hand,shapeObj * shape,SDOGeometryObj * obj,SDOGeometryInd * ind)1541 static int osGetOrdinates(msOracleSpatialDataHandler *dthand, msOracleSpatialHandler *hand, shapeObj *shape, SDOGeometryObj *obj, SDOGeometryInd *ind)
1542 {
1543 int gtype, elem_type, compound_type;
1544 float compound_lenght, compound_count;
1545 ub4 etype;
1546 ub4 interpretation;
1547 int nelems, nords, data3d, data4d;
1548 int elem, ord_start, ord_end;
1549 boolean exists;
1550 OCINumber *oci_number;
1551 double x, y;
1552 #ifdef USE_POINT_Z_M
1553 double z;
1554 #endif /* USE_POINT_Z_M */
1555 int success;
1556 lineObj points = {0, NULL};
1557 pointObj point5[5]; /* for quick access */
1558 shapeObj newshape; /* for compound polygons */
1559
1560 /*stat the variables for compound polygons*/
1561 compound_lenght = 0;
1562 compound_type = 0;
1563 compound_count = -1;
1564 data3d = 0;
1565 data4d = 0;
1566
1567 if (ind->_atomic != OCI_IND_NULL) { /* not a null object */
1568 nelems = nords = 0;
1569 success = TRY( hand, OCICollSize( hand->envhp, hand->errhp, (OCIColl *)obj->elem_info, &nelems ) )
1570 && TRY( hand, OCICollSize( hand->envhp, hand->errhp, (OCIColl *)obj->ordinates, &nords ) )
1571 && TRY( hand, OCINumberToInt( hand->errhp, &(obj->gtype), (uword)sizeof(int), OCI_NUMBER_SIGNED, (dvoid *)>ype ) );
1572 /*&& (nords%2==0 && nelems%3==0);*/ /* check %2==0 for 2D geometries; and %3==0 for element info triplets */
1573
1574 if (success && osCheck2DGtype(gtype)) {
1575 success = (nords%2==0 && nelems%3==0)?1:0; /* check %2==0 for 2D geometries; and %3==0 for element info triplets */
1576 } else if (success && osCheck3DGtype(gtype)) {
1577 success = (nords%3==0 && nelems%3==0)?1:0; /* check %2==0 for 2D geometries; and %3==0 for element info triplets */
1578 data3d = 1;
1579
1580 } else if (success && osCheck4DGtype(gtype)) {
1581 success = (nords%4==0 && nelems%3==0)?1:0; /* check %2==0 for 2D geometries; and %3==0 for element info triplets */
1582 data4d = 1;
1583 }
1584
1585
1586 if (success) {
1587 /* reading SDO_POINT from SDO_GEOMETRY for a 2D/3D point geometry */
1588 if ((gtype==2001 || gtype==3001 || gtype==4001 ) && ind->point._atomic == OCI_IND_NOTNULL && ind->point.x == OCI_IND_NOTNULL && ind->point.y == OCI_IND_NOTNULL) {
1589
1590
1591 success = TRY( hand, OCINumberToReal( hand->errhp, &(obj->point.x), (uword)sizeof(double), (dvoid *)&x ) )
1592 && TRY( hand, OCINumberToReal( hand->errhp, &(obj->point.y), (uword)sizeof(double), (dvoid *)&y ) );
1593
1594 if (ERROR( "osGetOrdinates()", hand, dthand ))
1595 return MS_FAILURE;
1596
1597 shape->type = MS_SHAPE_POINT;
1598
1599 points.numpoints = 1;
1600 points.point = point5;
1601 point5[0].x = x;
1602 point5[0].y = y;
1603 #ifdef USE_POINT_Z_M
1604 if (data3d || data4d) {
1605 if (ind->point.z == OCI_IND_NOTNULL) {
1606 success = TRY( hand, OCINumberToReal( hand->errhp, &(obj->point.z), (uword)sizeof(double), (dvoid *)&z ));
1607 if (ERROR( "osGetOrdinates()", hand, dthand ))
1608 return MS_FAILURE;
1609 else
1610 point5[0].z = z;
1611 } else
1612 point5[0].z = z;
1613 }
1614 #endif /* USE_POINT_Z_M */
1615 msAddLine( shape, &points );
1616 return MS_SUCCESS;
1617 }
1618 /* if SDO_POINT not fetched, proceed reading elements (element info/ordinates) */
1619 success = TRY( hand, OCICollGetElem( hand->envhp, hand->errhp, (OCIColl *)obj->elem_info,(sb4)0, (boolean *)&exists, (dvoid *)&oci_number, (dvoid **)0 ) )
1620 && TRY( hand, OCINumberToInt( hand->errhp, oci_number, (uword)sizeof(ub4), OCI_NUMBER_SIGNED, (dvoid *)&ord_end ) );
1621
1622 elem = 0;
1623 ord_end--; /* shifts offset from 1..n to 0..n-1 */
1624
1625 do {
1626 ord_start = ord_end;
1627 if (elem+3 >= nelems) { /* processing last element */
1628 ord_end = nords;
1629 success = 1;
1630 } else { /* get start ordinate position for next element which is ord_end for this element */
1631 success = TRY( hand, OCICollGetElem( hand->envhp, hand->errhp, (OCIColl *)obj->elem_info, (sb4)elem+3, (boolean *)&exists, (dvoid *)&oci_number, (dvoid **)0 ) )
1632 && TRY( hand, OCINumberToInt( hand->errhp, oci_number, (uword)sizeof(ub4), OCI_NUMBER_SIGNED, (dvoid *)&ord_end ) );
1633
1634 ord_end--; /* shifts offset from 1..n to 0..n-1 */
1635 }
1636 success = (success
1637 && TRY( hand, OCICollGetElem( hand->envhp, hand->errhp, (OCIColl *)obj->elem_info, (sb4)elem+1, (boolean *)&exists, (dvoid *)&oci_number, (dvoid **)0) )
1638 && TRY( hand, OCINumberToInt( hand->errhp, oci_number, (uword)sizeof(ub4), OCI_NUMBER_UNSIGNED, (dvoid *)&etype ) )
1639 && TRY( hand, OCICollGetElem( hand->envhp, hand->errhp, (OCIColl *)obj->elem_info, (sb4)elem+2, (boolean *)&exists, (dvoid *)&oci_number, (dvoid **)0 ) )
1640 && TRY( hand, OCINumberToInt( hand->errhp, oci_number, (uword)sizeof(ub4), OCI_NUMBER_UNSIGNED, (dvoid *)&interpretation ) ));
1641
1642 if (ERROR( "osGetOrdinates()", hand, dthand ))
1643 return MS_FAILURE;
1644
1645 if ( etype == 1005 || etype == 2005 || etype == 4 ) {
1646 compound_type = 1;
1647 compound_lenght = interpretation;
1648 compound_count = 0;
1649 msInitShape(&newshape);
1650 }
1651
1652 elem_type = (etype == 1 && interpretation > 1) ? 10 : ((etype%10)*10 + interpretation);
1653
1654
1655 /* msDebug("osGetOrdinates shape->index = %ld\telem_type = %d\n",shape->index, elem_type); */
1656
1657 switch (elem_type) {
1658 case 10: /* point cluster with 'interpretation'-points */
1659 osPointCluster (hand, shape, obj, ord_start, ord_end, points, interpretation, data3d, data4d);
1660 break;
1661 case 11: /* point type */
1662 osPoint(hand, shape, obj, ord_start, ord_end, points, point5, data3d, data4d);
1663 break;
1664 case 21: /* line string whose vertices are connected by straight line segments */
1665 if (compound_type)
1666 osClosedPolygon(hand, &newshape, obj, ord_start, (compound_count<compound_lenght)?ord_end+2:ord_end, points, elem_type, data3d, data4d);
1667 else
1668 osClosedPolygon(hand, shape, obj, ord_start, ord_end, points, elem_type, data3d, data4d);
1669 break;
1670 case 22: /* compound type */
1671 if (compound_type)
1672 osArcPolygon(hand, &newshape, obj, ord_start, (compound_count<compound_lenght)?ord_end+2:ord_end , points, elem_type, data3d, data4d);
1673 else
1674 osArcPolygon(hand, shape, obj, ord_start, ord_end, points, elem_type, data3d, data4d);
1675 break;
1676 case 31: /* simple polygon with n points, last point equals the first one */
1677 osClosedPolygon(hand, shape, obj, ord_start, ord_end, points, elem_type, data3d, data4d);
1678 break;
1679 case 32: /* Polygon with arcs */
1680 osArcPolygon(hand, shape, obj, ord_start, ord_end, points, elem_type, data3d, data4d);
1681 break;
1682 case 33: /* rectangle defined by 2 points */
1683 osRectangle(hand, shape, obj, ord_start, ord_end, points, point5, data3d, data4d);
1684 break;
1685 case 34: /* circle defined by 3 points */
1686 osCircle(hand, shape, obj, ord_start, ord_end, points, point5, data3d, data4d);
1687 break;
1688 }
1689
1690 if (compound_count >= compound_lenght) {
1691 osCloneShape(&newshape, shape, data3d, data4d);
1692 msFreeShape(&newshape);
1693 }
1694
1695 if (ERROR( "osGetOrdinates()", hand, dthand ))
1696 return MS_FAILURE;
1697
1698 /* prepare for next cycle */
1699 ord_start = ord_end;
1700 elem += 3;
1701
1702 if (compound_type)
1703 compound_count++;
1704
1705 } while (elem < nelems); /* end of element loop */
1706 } /* end of gtype big-if */
1707 } /* end of not-null-object if */
1708
1709 if (compound_type){
1710 if (gtype == 2003 || gtype == 2007)
1711 shape->type = MS_SHAPE_POLYGON;
1712 msFreeShape(&newshape);
1713 }
1714
1715 return MS_SUCCESS;
1716 }
1717
msOCICloseConnection(void * hand)1718 static void msOCICloseConnection( void *hand )
1719 {
1720 msOCICloseHandlers( (msOracleSpatialHandler *)hand );
1721 }
1722
1723 /* opens a layer by connecting to db with username/password@database stored in layer->connection */
msOracleSpatialLayerOpen(layerObj * layer)1724 int msOracleSpatialLayerOpen( layerObj *layer )
1725 {
1726 char *username = NULL, *password = NULL, *dblink = NULL;
1727
1728 msOracleSpatialLayerInfo *layerinfo = NULL;
1729 msOracleSpatialDataHandler *dthand = NULL;
1730 msOracleSpatialStatement *sthand = NULL, *sthand2 = NULL;
1731 msOracleSpatialHandler *hand = NULL;
1732
1733 if (layer->debug >=2)
1734 msDebug("msOracleSpatialLayerOpen called with: %s (Layer pointer %p)\n",layer->data, layer);
1735
1736 if (layer->layerinfo != NULL) /* Skip if layer is already open */
1737 return MS_SUCCESS;
1738
1739 if (layer->data == NULL) {
1740 msDebug( "Error parsing OracleSpatial DATA variable. Must be:"
1741 "'geometry_column FROM table_name [USING UNIQUE <column> SRID srid# FUNCTION]' or "
1742 "'geometry_column FROM (SELECT stmt) [USING UNIQUE <column> SRID srid# FUNCTION]'."
1743 "If want to set the FUNCTION statement you can use: FILTER, RELATE, GEOMRELATE or NONE.\n");
1744 msSetError( MS_ORACLESPATIALERR,
1745 "Error parsing OracleSpatial DATA variable. More info in server logs", "msOracleSpatialLayerOpen()");
1746
1747 return MS_FAILURE;
1748 }
1749
1750 layerinfo = (msOracleSpatialLayerInfo *)malloc(sizeof(msOracleSpatialLayerInfo));
1751 dthand = (msOracleSpatialDataHandler *)malloc(sizeof(msOracleSpatialDataHandler));
1752 sthand = (msOracleSpatialStatement *)malloc(sizeof(msOracleSpatialStatement));
1753 sthand2 = (msOracleSpatialStatement *)malloc(sizeof(msOracleSpatialStatement));
1754
1755 if ((dthand == NULL) || (layerinfo == NULL)) {
1756 msSetError(MS_MEMERR, NULL, "msOracleSpatialLayerOpen()");
1757 return MS_FAILURE;
1758 }
1759
1760 memset( dthand, 0, sizeof(msOracleSpatialDataHandler) );
1761 memset( sthand, 0, sizeof(msOracleSpatialStatement) );
1762 memset( sthand2, 0, sizeof(msOracleSpatialStatement) );
1763 memset( layerinfo, 0, sizeof(msOracleSpatialLayerInfo) );
1764 layerinfo->paging = MS_TRUE;
1765
1766 msSplitLogin( layer->connection, layer->map, &username, &password, &dblink );
1767
1768 hand = (msOracleSpatialHandler *) msConnPoolRequest( layer );
1769
1770 if( hand == NULL ) {
1771
1772 hand = msOCISetHandlers( username, password, dblink );
1773
1774 if (hand == NULL) {
1775 msOCICloseDataHandlers( dthand );
1776 msOCIFinishStatement( sthand );
1777 msOCIFinishStatement( sthand2 );
1778 msOCIClearLayerInfo( layerinfo );
1779
1780 if (username) free(username);
1781 if (password) free(password);
1782 if (dblink) free(dblink);
1783
1784 return MS_FAILURE;
1785 }
1786
1787 if ( layer->debug >=2)
1788 msDebug("msOracleSpatialLayerOpen. Shared connection not available. Creating one.\n");
1789
1790 msConnPoolRegister( layer, hand, msOCICloseConnection );
1791 } else {
1792 hand->ref_count++;
1793 hand->last_oci_status = MS_SUCCESS;
1794 hand->last_oci_error[0] = (text)'\0';
1795 }
1796
1797 if (!(msOCISetDataHandlers(hand, dthand) & msOCIOpenStatement(hand, sthand) & msOCIOpenStatement(hand, sthand2))) {
1798 msSetError( MS_ORACLESPATIALERR,
1799 "Cannot create OCI LayerInfo. "
1800 "Connection failure.",
1801 "msOracleSpatialLayerOpen()");
1802
1803 if (layer->debug>=2)
1804 msDebug("msOracleSpatialLayerOpen. Cannot create OCI LayerInfo. Connection failure.\n");
1805
1806 msOCICloseDataHandlers ( dthand );
1807 msOCICloseHandlers( hand );
1808 msOCIClearLayerInfo( layerinfo );
1809 }
1810 layerinfo->orahandlers = hand;
1811 layerinfo->oradatahandlers = dthand;
1812 layerinfo->orastmt = sthand;
1813 layerinfo->orastmt2 = sthand2;
1814 layer->layerinfo = layerinfo;
1815
1816 if (username) free(username);
1817 if (password) free(password);
1818 if (dblink) free(dblink);
1819
1820 return layer->layerinfo != NULL ? MS_SUCCESS : MS_FAILURE;
1821 }
1822
1823 /* return MS_TRUE if layer is open, MS_FALSE otherwise.*/
msOracleSpatialLayerIsOpen(layerObj * layer)1824 int msOracleSpatialLayerIsOpen(layerObj *layer)
1825 {
1826 if (layer->layerinfo != NULL)
1827 return MS_TRUE;
1828
1829 return MS_FALSE;
1830 }
1831
1832 /* closes the layer, disconnecting from db if connected. layer->layerinfo is freed */
msOracleSpatialLayerClose(layerObj * layer)1833 int msOracleSpatialLayerClose( layerObj *layer )
1834 {
1835 msOracleSpatialLayerInfo *layerinfo = (msOracleSpatialLayerInfo *)layer->layerinfo;
1836 /*int lIntSuccessFree = 0;*/
1837
1838 if (layer->debug>=2)
1839 msDebug("msOracleSpatialLayerClose was called. Layer: %p, Layer name: %s\n", layer, layer->name);
1840
1841 if (layerinfo != NULL) {
1842
1843 /*
1844 * Some errors with the OCIObjectFree with query function
1845 * If uncomment draw mode will work but no query modes
1846 * Need to investigate the error cause
1847 */
1848 /*lIntSuccessFree = TRY (layerinfo->orahandlers, OCIObjectFree(layerinfo->orahandlers->envhp, layerinfo->orahandlers->errhp, (dvoid *)layerinfo->obj, (ub2)OCI_OBJECTFREE_FORCE));
1849 *if (!lIntSuccessFree)
1850 * msDebug("Error: %s\n", layerinfo->orahandlers->last_oci_error);
1851 */
1852 /* Release Statement Handles */
1853 if (layerinfo->orastmt != NULL) {
1854 msOCIFinishStatement(layerinfo->orastmt);
1855 layerinfo->orastmt = NULL;
1856 }
1857 if (layerinfo->orastmt2 != NULL) {
1858 msOCIFinishStatement(layerinfo->orastmt2);
1859 layerinfo->orastmt2 = NULL;
1860 }
1861
1862 /* Release Datahandlers */
1863 if (layer->debug>=4)
1864 msDebug("msOracleSpatialLayerClose. Cleaning layerinfo handlers.\n");
1865 msOCICloseDataHandlers( layerinfo->oradatahandlers );
1866 layerinfo->oradatahandlers = NULL;
1867
1868 /* Free the OCI cache only if there is no more layer that could use it */
1869 layerinfo->orahandlers->ref_count--;
1870 if (layerinfo->orahandlers->ref_count == 0)
1871 OCICacheFree (layerinfo->orahandlers->envhp, layerinfo->orahandlers->errhp, layerinfo->orahandlers->svchp);
1872
1873 /* Release Mapserver Pool */
1874 if (layer->debug>=4)
1875 msDebug("msOracleSpatialLayerClose. Release the Oracle Pool.\n");
1876 msConnPoolRelease( layer, layerinfo->orahandlers );
1877
1878 /* Release Layerinfo */
1879 layerinfo->orahandlers = NULL;
1880
1881 msOCIClearLayerInfo( layerinfo );
1882 layer->layerinfo = NULL;
1883 }
1884
1885 return MS_SUCCESS;
1886 }
1887
1888 /* create SQL statement for retrieving shapes */
1889 /* Sets up cursor for use in *NextShape and *GetShape */
msOracleSpatialLayerWhichShapes(layerObj * layer,rectObj rect,int isQuery)1890 int msOracleSpatialLayerWhichShapes( layerObj *layer, rectObj rect, int isQuery)
1891 {
1892 int success, i;
1893 int function = 0;
1894 int version = 0;
1895 char query_str[6000];
1896 char query_str2[256];
1897 char *tmp_str=NULL, *tmp1_str=NULL;
1898 char *table_name;
1899 char *geom_column_name = NULL, *unique = NULL, *srid = NULL, *indexfield=NULL;
1900 OCIDefine *adtp = NULL;
1901 OCIDefine **items = NULL;
1902 OCINumber oci_number;
1903 OCIBind *bnd1p = NULL, *bnd2p = NULL;
1904
1905 int existunique = MS_FALSE;
1906 int rownumisuniquekey = MS_FALSE;
1907 int numitemsinselect = 0;
1908
1909 /* get layerinfo */
1910 msOracleSpatialLayerInfo *layerinfo = (msOracleSpatialLayerInfo *)layer->layerinfo;
1911 msOracleSpatialDataHandler *dthand = NULL;
1912 msOracleSpatialHandler *hand = NULL;
1913 msOracleSpatialStatement *sthand = NULL;
1914
1915 if (layer->debug>=3)
1916 msDebug("msOracleSpatialLayerWhichShapes was called.\n");
1917
1918 if (layerinfo == NULL) {
1919 msSetError( MS_ORACLESPATIALERR,
1920 "msOracleSpatialLayerWhichShapes called on unopened layer",
1921 "msOracleSpatialLayerWhichShapes()" );
1922
1923 return MS_FAILURE;
1924 } else {
1925 dthand = (msOracleSpatialDataHandler *)layerinfo->oradatahandlers;
1926 hand = (msOracleSpatialHandler *)layerinfo->orahandlers;
1927 sthand = (msOracleSpatialStatement *)layerinfo->orastmt2;
1928 }
1929
1930 /*init uniqueindex field*/
1931 sthand->uniqueidindex=0;
1932
1933 table_name = (char *) malloc(sizeof(char) * TABLE_NAME_SIZE);
1934 /* parse geom_column_name and table_name */
1935 if (!msSplitData( layer->data, &geom_column_name, &table_name, &unique, &srid, &indexfield, &function, &version)) {
1936 msDebug( "Error parsing OracleSpatial DATA variable. Must be:"
1937 "'geometry_column FROM table_name [USING UNIQUE <column> SRID srid# FUNCTION]' or "
1938 "'geometry_column FROM (SELECT stmt) [USING UNIQUE <column> SRID srid# FUNCTION]'."
1939 "If want to set the FUNCTION statement you can use: FILTER, RELATE, GEOMRELATE or NONE."
1940 "Your data statement: (%s)"
1941 "in msOracleSpatialLayerWhichShapes()\n", layer->data );
1942 msSetError( MS_ORACLESPATIALERR,
1943 "Error parsing OracleSpatial DATA variable. More info in server logs",
1944 "msOracleSpatialLayerWhichShapes()" );
1945
1946 if (geom_column_name) free(geom_column_name);
1947 if (srid) free(srid);
1948 if (unique) free(unique);
1949 if (indexfield) free(indexfield);
1950 free(table_name);
1951 return MS_FAILURE;
1952 }
1953
1954 /*rownum will be the first in the select if no UNIQUE key is defined or
1955 will be added at the end of the select*/
1956 rownumisuniquekey = MS_TRUE;
1957 /*Define the unique*/
1958 if (unique[0] == '\0')
1959 strcpy( unique, "rownum" );
1960 else
1961 rownumisuniquekey = MS_FALSE;
1962
1963 /* Check if the unique field is already in the items list */
1964 existunique = MS_FALSE;
1965 if (unique) {
1966 for( i=0; i < layer->numitems; ++i ) {
1967 if (strcasecmp(unique, layer->items[i])==0) {
1968 sthand->uniqueidindex = i;
1969 existunique = MS_TRUE;
1970 break;
1971 }
1972 }
1973 }
1974
1975 /* If no SRID is provided, set it to -1 (NULL) for binding */
1976 if (strcmp(srid,"NULL") == 0)
1977 strcpy(srid,"-1");
1978
1979 snprintf( query_str, sizeof(query_str), "SELECT ");
1980 numitemsinselect = layer->numitems;
1981 /* allocate enough space for items */
1982 if (layer->numitems >= 0) {
1983 /*we will always add a rownumber in the selection*/
1984 numitemsinselect++;
1985
1986 /*if unique key in the data is specfied and is not part of the current item lists,
1987 we should add it to the select*/
1988 if(existunique == MS_FALSE && rownumisuniquekey == MS_FALSE)
1989 numitemsinselect++;
1990
1991 /*the usinque index is there was no uniqueid given or the uniqueid given was not part of the items lists*/
1992 if (existunique == MS_FALSE)
1993 sthand->uniqueidindex = layer->numitems;
1994
1995 sthand->items = (item_text_array *)malloc( sizeof(item_text_array) * (numitemsinselect) );
1996 if (sthand->items == NULL) {
1997 msSetError( MS_ORACLESPATIALERR,"Cannot allocate layerinfo->items buffer","msOracleSpatialLayerWhichShapes()" );
1998 if (geom_column_name) free(geom_column_name);
1999 if (srid) free(srid);
2000 if (unique) free(unique);
2001 if(indexfield) free(indexfield);
2002 free(table_name);
2003 return MS_FAILURE;
2004 }
2005
2006 items = (OCIDefine **)malloc(sizeof(OCIDefine *)*(numitemsinselect));
2007 if (items == NULL) {
2008 msSetError( MS_ORACLESPATIALERR,"Cannot allocate items buffer","msOracleSpatialLayerWhichShapes()" );
2009 if (geom_column_name) free(geom_column_name);
2010 if (srid) free(srid);
2011 if (unique) free(unique);
2012 if(indexfield) free(indexfield);
2013 free(table_name);
2014 return MS_FAILURE;
2015 }
2016 memset(items ,0,sizeof(OCIDefine *)*(numitemsinselect));
2017 }
2018
2019 /* define SQL query */
2020 for( i=0; i < layer->numitems; ++i ) {
2021
2022 snprintf( query_str + strlen(query_str), sizeof(query_str)-strlen(query_str), "\"%s\", ", layer->items[i] );
2023 }
2024
2025 /*we add the uniqueid if it was not part of the current item list*/
2026 if(existunique == MS_FALSE && rownumisuniquekey == MS_FALSE)
2027 snprintf( query_str + strlen(query_str), sizeof(query_str)-strlen(query_str), "%s,", unique);
2028
2029 /*we always want to add rownum is the selection to allow paging to work*/
2030 snprintf( query_str + strlen(query_str), sizeof(query_str)-strlen(query_str), "%s, ", "rownum");
2031
2032
2033 snprintf( query_str + strlen(query_str), sizeof(query_str)-strlen(query_str), "%s FROM %s", geom_column_name, table_name );
2034
2035 osFilteritem(layer, function, query_str, sizeof(query_str), 1);
2036
2037 if (layerinfo->paging && layer->maxfeatures > 0 && layer->startindex < 0) {
2038 if (function == FUNCTION_NONE && layer->filter.native_string == NULL)
2039 snprintf( query_str + strlen(query_str), sizeof(query_str)-strlen(query_str), "%s"," WHERE ");
2040 else if (function == FUNCTION_NONE && layer->filter.native_string != NULL)
2041 snprintf( query_str + strlen(query_str), sizeof(query_str)-strlen(query_str), "%s"," AND ");
2042 snprintf( query_str + strlen(query_str), sizeof(query_str)-strlen(query_str), " ROWNUM<=%d ", layer->maxfeatures);
2043 if (function != FUNCTION_NONE)
2044 snprintf (query_str + strlen(query_str), sizeof(query_str)-strlen(query_str), " AND ");
2045 }
2046
2047 if ((((atol(srid) >= 8192) && (atol(srid) <= 8330)) || (atol(srid) == 2) || (atol(srid) == 5242888) || (atol(srid) == 2000001)) && (version == VERSION_9i))
2048 osGeodeticData(function, version, query_str, sizeof(query_str), geom_column_name, indexfield, srid, rect);
2049 else
2050 osNoGeodeticData(function, version, query_str, sizeof(query_str), geom_column_name, indexfield, srid, rect);
2051
2052 if( layer->sortBy.nProperties > 0 ) {
2053 msDebug("Layer sorting is requested\n");
2054 tmp1_str = msLayerBuildSQLOrderBy(layer);
2055 snprintf( query_str + strlen(query_str), sizeof(query_str)-strlen(query_str), " ORDER BY %s ", tmp1_str );
2056 msFree(tmp1_str);
2057 }
2058
2059 /*assuming startindex starts at 1*/
2060 if (layerinfo->paging && layer->startindex > 0) {
2061 tmp1_str = msStrdup("SELECT * from (SELECT atmp.*, ROWNUM rnum from (");
2062 tmp_str = msStringConcatenate(tmp_str, tmp1_str);
2063 msFree(tmp1_str);
2064 tmp_str = msStringConcatenate(tmp_str, query_str);
2065 /*oder by rowid does not seem to work with function using the spatial filter, at least
2066 on layers loaded using ogr in a 11g database*/
2067 if (function == FUNCTION_NONE || function == FUNCTION_RELATE || function == FUNCTION_GEOMRELATE)
2068 tmp1_str = msStrdup( "order by rowid");
2069 /* Populate strOrderBy, if necessary */
2070 else
2071 tmp1_str = msStrdup("");
2072
2073 if (layer->maxfeatures > 0)
2074 snprintf(query_str2, sizeof(query_str2), " %s) atmp where ROWNUM<=%d) where rnum >=%d", tmp1_str,
2075 layer->maxfeatures+layer->startindex-1, layer->startindex);
2076 else
2077 snprintf( query_str2, sizeof(query_str2), " %s) atmp) where rnum >=%d", tmp1_str, layer->startindex);
2078 msFree(tmp1_str);
2079
2080 tmp_str = msStringConcatenate(tmp_str, query_str2);
2081 snprintf(query_str, sizeof(query_str), "%s", tmp_str);
2082 msFree(tmp_str);
2083 }
2084
2085
2086 if (layer->debug)
2087 msDebug("msOracleSpatialLayerWhichShapes. Using this Sql to retrieve the data: %s\n", query_str);
2088
2089 if (layer->debug)
2090 msDebug("msOracleSpatialLayerWhichShapes. Bind values: srid:%s minx:%f miny:%f maxx:%f maxy:%f \n", srid, rect.minx, rect.miny, rect.maxx, rect.maxy);
2091
2092 /* prepare */
2093 success = TRY( hand, OCIStmtPrepare( sthand->stmthp, hand->errhp, (text *)query_str, (ub4)strlen(query_str), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT) );
2094
2095 if (layer->debug>=4)
2096 msDebug("msOracleSpatialLayerWhichShapes getting ordinate definition.\n");
2097
2098 /* get the object definition of the ordinate array */
2099 ordinates_tdo = get_tdo(SDO_ORDINATE_ARRAY, hand, dthand );
2100
2101 if (layer->debug>=4)
2102 msDebug("msOracleSpatialLayerWhichShapes converting to OCIColl.\n");
2103
2104 /* initialized the collection array */
2105 success = TRY( hand, OCIObjectNew(hand->envhp, hand->errhp, hand->svchp, OCI_TYPECODE_VARRAY, ordinates_tdo, (dvoid *)NULL, OCI_DURATION_SESSION, FALSE, (dvoid **)&ordinates) );
2106
2107 /* convert it to a OCI number and then append minx...maxy to the collection */
2108 success = TRY ( hand, OCINumberFromReal(hand->errhp, (dvoid *)&(rect.minx), (uword)sizeof(double),(dvoid *)&oci_number))
2109 &&TRY ( hand, OCICollAppend(hand->envhp, hand->errhp,(dvoid *) &oci_number,(dvoid *)0, (OCIColl *)ordinates))
2110 &&TRY ( hand, OCINumberFromReal(hand->errhp, (dvoid *)&(rect.miny), (uword)sizeof(double),(dvoid *)&oci_number))
2111 &&TRY ( hand, OCICollAppend(hand->envhp, hand->errhp,(dvoid *) &oci_number,(dvoid *)0, (OCIColl *)ordinates))
2112 &&TRY ( hand, OCINumberFromReal(hand->errhp, (dvoid *)&(rect.maxx), (uword)sizeof(double),(dvoid *)&oci_number))
2113 &&TRY ( hand, OCICollAppend(hand->envhp, hand->errhp,(dvoid *) &oci_number,(dvoid *)0, (OCIColl *)ordinates))
2114 &&TRY ( hand, OCINumberFromReal(hand->errhp, (dvoid *)&(rect.maxy), (uword)sizeof(double),(dvoid *)&oci_number))
2115 &&TRY ( hand, OCICollAppend(hand->envhp, hand->errhp,(dvoid *) &oci_number,(dvoid *)0, (OCIColl *)ordinates));
2116
2117
2118 if (layer->debug>=3)
2119 msDebug("msOracleSpatialLayerWhichShapes bind by name and object.\n");
2120
2121 /* do the actual binding */
2122
2123 if (success && function != FUNCTION_NONE) {
2124 const char* bind_key;
2125 char* bind_value;
2126 char* bind_tag;
2127 success = TRY( hand,
2128 /* bind in srid */
2129 OCIBindByName( sthand->stmthp, &bnd2p, hand->errhp, (text *) ":srid", strlen(":srid"),(ub1 *) srid, strlen(srid)+1, SQLT_STR,
2130 (dvoid *) 0, (ub2 *) 0, (ub2) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT) )
2131 && TRY(hand,
2132 /* bind in rect by name */
2133 OCIBindByName( sthand->stmthp, &bnd1p, hand->errhp, (text *)":ordinates", -1, (dvoid *)0, (sb4)0, SQLT_NTY, (dvoid *)0, (ub2 *)0,(ub2 *)0, (ub4)0, (ub4 *)0, (ub4)OCI_DEFAULT))
2134 && TRY(hand,
2135 /* bind in rect object */
2136 OCIBindObject(bnd1p, hand->errhp, ordinates_tdo, (dvoid **)&ordinates, (ub4 *)0, (dvoid **)0, (ub4 *)0));
2137
2138 /* bind the variables from the bindvals hash */
2139 bind_key = (char*)msFirstKeyFromHashTable(&layer->bindvals);
2140 while(bind_key != NULL) {
2141 bind_value = msLookupHashTable(&layer->bindvals, bind_key);
2142 bind_tag = (char*)malloc(sizeof(char) * strlen(bind_key) + 2);
2143 sprintf(bind_tag, ":%s", bind_key);
2144
2145 success = success && TRY(hand, OCIBindByName( sthand->stmthp, &bnd2p, hand->errhp, (text *)bind_tag, strlen(bind_tag),(ub1 *) bind_value, strlen(bind_value)+1, SQLT_STR,
2146 (dvoid *) 0, (ub2 *) 0, (ub2) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT));
2147 bind_key = msNextKeyFromHashTable(&layer->bindvals, bind_key);
2148 }
2149 }
2150
2151
2152 if (layer->debug>=3)
2153 msDebug("msOracleSpatialLayerWhichShapes name and object now bound.\n");
2154
2155
2156 if (success && layer->numitems >= 0) {
2157 for( i=0; i < numitemsinselect && success; ++i ){
2158 if (i< numitemsinselect -1) {
2159 //msDebug("Defining by POS, for %s\n", layer->items[i]);
2160 //msDebug("datatype retrieved is %i\n", layer->iteminfo);
2161 }
2162 success = TRY( hand, OCIDefineByPos( sthand->stmthp, &items[i], hand->errhp, (ub4)i+1, (dvoid *)sthand->items[i], (sb4)TEXT_SIZE, SQLT_STR, (dvoid *)0, (ub2 *)0, (ub2 *)0, (ub4)OCI_DEFAULT ) );
2163 }
2164 }
2165
2166
2167 if (success) {
2168 int cursor_type = OCI_DEFAULT;
2169 if(isQuery) cursor_type =OCI_STMT_SCROLLABLE_READONLY;
2170
2171 success = TRY( hand,
2172 /* define spatial position adtp ADT object */
2173 OCIDefineByPos( sthand->stmthp, &adtp, hand->errhp, (ub4)numitemsinselect+1, (dvoid *)0, (sb4)0, SQLT_NTY, (dvoid *)0, (ub2 *)0, (ub2 *)0, (ub4)OCI_DEFAULT) )
2174 && TRY( hand,
2175 /* define object tdo from adtp */
2176 OCIDefineObject( adtp, hand->errhp, dthand->tdo, (dvoid **)sthand->obj, (ub4 *)0, (dvoid **)sthand->ind, (ub4 *)0 ) )
2177 && TRY(hand,
2178 /* execute */
2179 OCIStmtExecute( hand->svchp, sthand->stmthp, hand->errhp, (ub4)ARRAY_SIZE, (ub4)0, (OCISnapshot *)NULL, (OCISnapshot *)NULL, (ub4)cursor_type ) )
2180 && TRY( hand,
2181 /* get rows fetched */
2182 OCIAttrGet( (dvoid *)sthand->stmthp, (ub4)OCI_HTYPE_STMT, (dvoid *)&sthand->rows_fetched, (ub4 *)0, (ub4)OCI_ATTR_ROWS_FETCHED, hand->errhp ) )
2183 && TRY( hand,
2184 /* get rows count */
2185 OCIAttrGet( (dvoid *)sthand->stmthp, (ub4)OCI_HTYPE_STMT, (dvoid *)&sthand->rows_count, (ub4 *)0, (ub4)OCI_ATTR_ROW_COUNT, hand->errhp ) );
2186 }
2187
2188 if (!success) {
2189 msDebug( "Error: %s . "
2190 "Query statement: %s . "
2191 "Check your data statement."
2192 "msOracleSpatialLayerWhichShapes()\n", hand->last_oci_error, query_str );
2193 msSetError( MS_ORACLESPATIALERR,
2194 "Check your data statement and server logs",
2195 "msOracleSpatialLayerWhichShapes()");
2196
2197 /* clean items */
2198 free(items);
2199 if (geom_column_name) free(geom_column_name);
2200 if (srid) free(srid);
2201 if (unique) free(unique);
2202 if (indexfield) free(indexfield);
2203 free(table_name);
2204
2205 return MS_FAILURE;
2206 }
2207
2208 /* should begin processing first row */
2209 sthand->row_num = sthand->row = 0;
2210
2211 /* clean items */
2212 free(items);
2213 if (geom_column_name) free(geom_column_name);
2214 if (srid) free(srid);
2215 if (unique) free(unique);
2216 if (indexfield) free(indexfield);
2217 free(table_name);
2218
2219 return MS_SUCCESS;
2220 }
2221
2222 /* fetch next shape from previous SELECT stmt (see *WhichShape()) */
msOracleSpatialLayerNextShape(layerObj * layer,shapeObj * shape)2223 int msOracleSpatialLayerNextShape( layerObj *layer, shapeObj *shape )
2224 {
2225 SDOGeometryObj *obj;
2226 SDOGeometryInd *ind;
2227 int success, /*lIntSuccessFree,*/ i;
2228
2229 /* get layerinfo */
2230 msOracleSpatialLayerInfo *layerinfo = (msOracleSpatialLayerInfo *)layer->layerinfo;
2231 msOracleSpatialDataHandler *dthand = NULL;
2232 msOracleSpatialHandler *hand = NULL;
2233 msOracleSpatialStatement *sthand = NULL;
2234
2235
2236 if (layerinfo == NULL) {
2237 msSetError( MS_ORACLESPATIALERR, "msOracleSpatialLayerWhichShapes called on unopened layer", "msOracleSpatialLayerNextShape()" );
2238 return MS_FAILURE;
2239 } else {
2240 dthand = (msOracleSpatialDataHandler *)layerinfo->oradatahandlers;
2241 hand = (msOracleSpatialHandler *)layerinfo->orahandlers;
2242 sthand = (msOracleSpatialStatement *)layerinfo->orastmt2;
2243 }
2244
2245 /* no rows fetched */
2246 if (sthand->rows_fetched == 0)
2247 return MS_DONE;
2248
2249 if(layer->debug >=5 )
2250 msDebug("msOracleSpatialLayerNextShape on layer %p, row_num: %d\n", layer, sthand->row_num);
2251
2252 do {
2253 /* is buffer empty? */
2254 if (sthand->row >= sthand->rows_fetched) {
2255 /* fetch more */
2256 success = TRY( hand, OCIStmtFetch2( sthand->stmthp, hand->errhp, (ub4)ARRAY_SIZE, (ub2)OCI_FETCH_NEXT, (sb4)0, (ub4)OCI_DEFAULT ) )
2257 && TRY( hand, OCIAttrGet( (dvoid *)sthand->stmthp, (ub4)OCI_HTYPE_STMT, (dvoid *)&sthand->rows_fetched, (ub4 *)0, (ub4)OCI_ATTR_ROWS_FETCHED, hand->errhp ) )
2258 && TRY( hand, OCIAttrGet( (dvoid *)sthand->stmthp, (ub4)OCI_HTYPE_STMT, (dvoid *)&sthand->rows_count, (ub4 *)0, (ub4)OCI_ATTR_ROW_COUNT, hand->errhp ) );
2259
2260
2261 if (!success || sthand->rows_fetched == 0 || sthand->row_num >= sthand->rows_count) {
2262 hand->last_oci_status=MS_SUCCESS;
2263 return MS_DONE;
2264 }
2265 if(layer->debug >= 4 )
2266 msDebug("msOracleSpatialLayerNextShape on layer %p, Fetched %d more rows (%d total)\n", layer, sthand->rows_fetched, sthand->rows_count);
2267
2268 sthand->row = 0; /* reset buffer row index */
2269 }
2270
2271 /* set obj & ind for current row */
2272 obj = sthand->obj[ sthand->row ];
2273 ind = sthand->ind[ sthand->row ];
2274
2275 /* get the items for the shape */
2276 shape->index = atol( (char *)(sthand->items[sthand->uniqueidindex][ sthand->row ])); /* Primary Key */
2277 shape->resultindex = sthand->row_num;
2278 shape->numvalues = layer->numitems;
2279
2280 shape->values = (char **)malloc( sizeof(char*) * shape->numvalues );
2281 if (shape->values == NULL) {
2282 msSetError( MS_ORACLESPATIALERR, "No memory avaliable to allocate the values", "msOracleSpatialLayerNextShape()" );
2283 return MS_FAILURE;
2284 }
2285
2286 for( i=0; i < shape->numvalues; ++i ) {
2287 shape->values[i] = (char *)malloc(strlen((char *)sthand->items[i][ sthand->row ])+1);
2288 if (shape->values[i] == NULL) {
2289 msSetError( MS_ORACLESPATIALERR, "No memory avaliable to allocate the items", "msOracleSpatialLayerNextShape()" );
2290 return MS_FAILURE;
2291 } else {
2292 strcpy(shape->values[i], (char *)sthand->items[i][ sthand->row ]);
2293 shape->values[i][strlen((char *)sthand->items[i][ sthand->row ])] = '\0';
2294 }
2295 }
2296
2297 /* fetch a layer->type object */
2298 success = osGetOrdinates(dthand, hand, shape, obj, ind);
2299
2300 /* increment for next row */
2301 sthand->row_num++;
2302 sthand->row++;
2303
2304 if (success != MS_SUCCESS) {
2305 return MS_FAILURE;
2306 }
2307
2308 osShapeBounds(shape);
2309 } while(shape->type == MS_SHAPE_NULL);
2310
2311 return MS_SUCCESS;
2312 }
2313
msOracleSpatialLayerGetShape(layerObj * layer,shapeObj * shape,resultObj * record)2314 int msOracleSpatialLayerGetShape( layerObj *layer, shapeObj *shape, resultObj *record)
2315 {
2316 int success, i;
2317 SDOGeometryObj *obj;
2318 SDOGeometryInd *ind;
2319 msOracleSpatialDataHandler *dthand = NULL;
2320 msOracleSpatialHandler *hand = NULL;
2321 msOracleSpatialLayerInfo *layerinfo;
2322 msOracleSpatialStatement *sthand = NULL;
2323
2324 long shapeindex = record->shapeindex;
2325 int resultindex = record->resultindex;
2326
2327 if(layer == NULL) {
2328 msSetError( MS_ORACLESPATIALERR, "msOracleSpatialLayerGetShape called on unopened layer","msOracleSpatialLayerGetShape()" );
2329 return MS_FAILURE;
2330 }
2331
2332 layerinfo = (msOracleSpatialLayerInfo *)layer->layerinfo;
2333
2334 if (layerinfo == NULL) {
2335 msSetError( MS_ORACLESPATIALERR, "msOracleSpatialLayerGetShape called on unopened layer (layerinfo)","msOracleSpatialLayerGetShape()" );
2336 return MS_FAILURE;
2337 }
2338
2339 /* If resultindex is set, fetch the shape from the resultcache, otherwise fetch it from the DB */
2340 if (resultindex >= 0) {
2341 long buffer_first_row_num, buffer_last_row_num;
2342
2343 /* get layerinfo */
2344 dthand = (msOracleSpatialDataHandler *)layerinfo->oradatahandlers;
2345 hand = (msOracleSpatialHandler *)layerinfo->orahandlers;
2346 sthand = (msOracleSpatialStatement *)layerinfo->orastmt2;
2347
2348 if (layer->resultcache == NULL) {
2349 msSetError( MS_ORACLESPATIALERR, "msOracleSpatialLayerGetShape called before msOracleSpatialLayerWhichShapes()","msOracleSpatialLayerGetShape()" );
2350 return MS_FAILURE;
2351 }
2352
2353 if (resultindex >= sthand->rows_count) {
2354 if (layer->debug >= 5)
2355 msDebug("msOracleSpatialLayerGetShape problem with cursor. Trying to fetch record = %d of %d, falling back to GetShape\n", resultindex, sthand->rows_count);
2356
2357 msSetError( MS_ORACLESPATIALERR, "msOracleSpatialLayerGetShape record out of range","msOracleSpatialLayerGetShape()" );
2358 return MS_FAILURE;
2359 }
2360
2361 if (layer->debug >= 5)
2362 msDebug("msOracleSpatialLayerGetShape was called. Using the record = %d of %d. (shape: %ld should equal pkey: %ld)\n",
2363 resultindex, layer->resultcache->numresults, layer->resultcache->results[resultindex].shapeindex, shapeindex);
2364
2365 /* NOTE: with the way the resultcache works, we should see items in increasing order, but some may have been filtered out. */
2366 /* Best case: item in buffer */
2367 /* Next best case: item is in next fetch block */
2368 /* Worst case: item is random access */
2369 buffer_first_row_num = sthand->row_num - sthand->row; /* cursor id of first item in buffer */
2370 buffer_last_row_num = buffer_first_row_num + sthand->rows_fetched - 1; /* cursor id of last item in buffer */
2371 if(resultindex >= buffer_first_row_num && resultindex <= buffer_last_row_num) { /* Item is in buffer. Calculate position in buffer */
2372 sthand->row += resultindex - sthand->row_num; /* move sthand row an row_num by offset from last call */
2373 sthand->row_num += resultindex - sthand->row_num;
2374 } else { /* Item is not in buffer. Fetch item from Oracle */
2375 if (layer->debug >= 4)
2376 msDebug("msOracleSpatialLayerGetShape: Fetching result from DB start: %ld end:%ld record: %d\n", buffer_first_row_num, buffer_last_row_num, resultindex);
2377
2378 success = TRY( hand, OCIStmtFetch2( sthand->stmthp, hand->errhp, (ub4)ARRAY_SIZE, (ub2)OCI_FETCH_ABSOLUTE, (sb4)resultindex+1, (ub4)OCI_DEFAULT ) )
2379 && TRY( hand, OCIAttrGet( (dvoid *)sthand->stmthp, (ub4)OCI_HTYPE_STMT, (dvoid *)&sthand->rows_fetched, (ub4 *)0, (ub4)OCI_ATTR_ROWS_FETCHED, hand->errhp ) );
2380
2381 sthand->row_num = resultindex;
2382 sthand->row = 0; /* reset row index */
2383
2384 if(ERROR("msOracleSpatialLayerGetShape", hand, dthand))
2385 return MS_FAILURE;
2386
2387 if (!success || sthand->rows_fetched == 0) {
2388 msSetError( MS_ORACLESPATIALERR, "msOracleSpatialLayerGetShape could not fetch specified record.", "msOracleSpatialLayerGetShape()" );
2389 return MS_FAILURE;
2390 }
2391 }
2392
2393 /* set obj & ind for current row */
2394 obj = sthand->obj[ sthand->row ];
2395 ind = sthand->ind[ sthand->row ];
2396
2397 /* get the items for the shape */
2398 shape->index = shapeindex; /* By definition this is what we asked for */
2399 shape->numvalues = layer->numitems;
2400
2401 shape->values = (char **)malloc( sizeof(char*) * shape->numvalues );
2402 if (shape->values == NULL) {
2403 msSetError( MS_ORACLESPATIALERR, "No memory avaliable to allocate the values", "msOracleSpatialLayerNextShape()" );
2404 return MS_FAILURE;
2405 }
2406
2407 for( i=0; i < shape->numvalues; ++i ) {
2408 shape->values[i] = (char *)malloc(strlen((char *)sthand->items[i][ sthand->row ])+1);
2409 if (shape->values[i] == NULL) {
2410 msSetError( MS_ORACLESPATIALERR, "No memory avaliable to allocate the items", "msOracleSpatialLayerNextShape()" );
2411 return MS_FAILURE;
2412 } else {
2413 strcpy(shape->values[i], (char *)sthand->items[i][ sthand->row ]);
2414 shape->values[i][strlen((char *)sthand->items[i][ sthand->row ])] = '\0';
2415 }
2416 }
2417
2418 /* fetch a layer->type object */
2419 success = osGetOrdinates(dthand, hand, shape, obj, ind);
2420
2421 if (success != MS_SUCCESS) {
2422 msSetError( MS_ORACLESPATIALERR, "Call to osGetOrdinates failed.", "msOracleSpatialLayerGetShape()" );
2423 return MS_FAILURE;
2424 }
2425
2426 osShapeBounds(shape);
2427 if(shape->type == MS_SHAPE_NULL) {
2428 msSetError( MS_ORACLESPATIALERR, "Shape type is null... this probably means a record number was requested that could not have beeen in a result set (as returned by NextShape).", "msOracleSpatialLayerGetShape()" );
2429 return MS_FAILURE;
2430 }
2431
2432 return (MS_SUCCESS);
2433 } else { /* no resultindex, fetch the shape from the DB */
2434 char *table_name;
2435 char query_str[6000], *geom_column_name = NULL, *unique = NULL, *srid = NULL, *indexfield = NULL;
2436 int function = 0;
2437 int version = 0;
2438 sb2 *nullind = NULL;
2439 /*OCIDefine *adtp = NULL, *items[QUERY_SIZE] = { NULL };*/
2440 OCIDefine *adtp = NULL;
2441 OCIDefine **items = NULL;
2442
2443 if (layer->debug>=4)
2444 msDebug("msOracleSpatialLayerGetShape was called. Using the record = %ld.\n", shapeindex);
2445
2446 dthand = (msOracleSpatialDataHandler *)layerinfo->oradatahandlers;
2447 hand = (msOracleSpatialHandler *)layerinfo->orahandlers;
2448 sthand = (msOracleSpatialStatement *) layerinfo->orastmt;
2449
2450 /* allocate enough space for items */
2451 if (layer->numitems > 0) {
2452 if (sthand->items_query == NULL)
2453 sthand->items_query = (item_text_array_query *)malloc( sizeof(item_text_array_query) * (layer->numitems) );
2454
2455 if (sthand->items_query == NULL) {
2456 msSetError( MS_ORACLESPATIALERR, "Cannot allocate layerinfo->items_query buffer", "msOracleSpatialLayerGetShape()" );
2457 return MS_FAILURE;
2458 }
2459
2460 nullind = (sb2 *)malloc( sizeof(sb2) * (layer->numitems) );
2461 if (nullind == NULL) {
2462 msSetError( MS_ORACLESPATIALERR, "Cannot allocate nullind buffer", "msOracleSpatialLayerGetShape()" );
2463 return MS_FAILURE;
2464 }
2465 memset(nullind ,0, sizeof(sb2) * (layer->numitems) );
2466
2467 items = (OCIDefine **)malloc(sizeof(OCIDefine *)*layer->numitems);
2468 if (items == NULL) {
2469 msSetError( MS_ORACLESPATIALERR,"Cannot allocate items buffer","msOracleSpatialLayerWhichShapes()" );
2470
2471 /* clean nullind */
2472 free(nullind);
2473
2474 return MS_FAILURE;
2475 }
2476 memset(items ,0,sizeof(OCIDefine *)*layer->numitems);
2477 }
2478
2479 table_name = (char *) malloc(sizeof(char) * TABLE_NAME_SIZE);
2480 if (!msSplitData( layer->data, &geom_column_name, &table_name, &unique, &srid, &indexfield, &function, &version )) {
2481 msDebug( "Error parsing OracleSpatial DATA variable. Must be: "
2482 "'geometry_column FROM table_name [USING UNIQUE <column> SRID srid# FUNCTION]' or "
2483 "'geometry_column FROM (SELECT stmt) [USING UNIQUE <column> SRID srid# FUNCTION]'. "
2484 "If want to set the FUNCTION statement you can use: FILTER, RELATE, GEOMRELATE or NONE. "
2485 "Your data statement: (%s) msOracleSpatialLayerGetShape()\n", layer->data );
2486 msSetError( MS_ORACLESPATIALERR,
2487 "Error parsing OracleSpatial DATA variable. Check server logs. ",
2488 "msOracleSpatialLayerGetShape()");
2489
2490 /* clean nullind */
2491 free(nullind);
2492
2493 /* clean items */
2494 free(items);
2495
2496 if (geom_column_name) free(geom_column_name);
2497 if (srid) free(srid);
2498 if (unique) free(unique);
2499 if (indexfield) free(indexfield);
2500 free(table_name);
2501
2502 return MS_FAILURE;
2503 }
2504
2505 /*Define the first query to retrive itens*/
2506 if (unique[0] == '\0') {
2507 msSetError( MS_ORACLESPATIALERR,
2508 "Error parsing OracleSpatial DATA variable for query. To execute "
2509 "query functions you need to define one "
2510 "unique column [USING UNIQUE <#column>]",
2511 "msOracleSpatialLayerGetShape()" );
2512
2513 /* clean nullind */
2514 free(nullind);
2515
2516 /* clean items */
2517 free(items);
2518
2519 if (geom_column_name) free(geom_column_name);
2520 if (srid) free(srid);
2521 if (unique) free(unique);
2522 if (indexfield) free(indexfield);
2523 free(table_name);
2524
2525 return MS_FAILURE;
2526 } else
2527 snprintf( query_str, sizeof(query_str), "SELECT");
2528
2529 /*Define the query*/
2530 for( i = 0; i < layer->numitems; ++i )
2531 snprintf( query_str + strlen(query_str), sizeof(query_str)-strlen(query_str), " %s,", layer->items[i] );
2532
2533 snprintf( query_str + strlen(query_str), sizeof(query_str)-strlen(query_str), " %s FROM %s WHERE %s = %ld", geom_column_name, table_name, unique, shapeindex);
2534
2535 /*if (layer->filter.native_string != NULL)
2536 sprintf( query_str + strlen(query_str), " AND %s", (layer->filter.string));*/
2537 osFilteritem(layer, FUNCTION_NONE, query_str, sizeof(query_str), 2);
2538
2539
2540 if (layer->debug)
2541 msDebug("msOracleSpatialLayerGetShape. Sql: %s\n", query_str);
2542
2543 /*Prepare the handlers to the query*/
2544 success = TRY( hand,OCIStmtPrepare( sthand->stmthp, hand->errhp, (text *)query_str, (ub4)strlen(query_str), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT) );
2545
2546 if (success && layer->numitems > 0) {
2547 for( i = 0; i < layer->numitems && success; i++ )
2548 success = TRY( hand, OCIDefineByPos( sthand->stmthp, &items[i], hand->errhp, (ub4)i+1, (dvoid *)sthand->items_query[i], (sb4)TEXT_SIZE, SQLT_STR, (sb2 *)&nullind[i], (ub2 *)0, (ub2 *)0, (ub4)OCI_DEFAULT ) );
2549 }
2550
2551 if(!success) {
2552 msSetError( MS_ORACLESPATIALERR,
2553 "Error: %s . "
2554 "Query statement: %s . "
2555 "Check your data statement.",
2556 "msOracleSpatialLayerGetShape()\n", hand->last_oci_error, query_str );
2557
2558 /* clean nullind */
2559 free(nullind);
2560
2561 /* clean items */
2562 free(items);
2563
2564 if (geom_column_name) free(geom_column_name);
2565 if (srid) free(srid);
2566 if (unique) free(unique);
2567 if (indexfield) free(indexfield);
2568 free(table_name);
2569
2570 return MS_FAILURE;
2571 }
2572
2573 if (success) {
2574 success = TRY( hand, OCIDefineByPos( sthand->stmthp, &adtp, hand->errhp, (ub4)layer->numitems+1, (dvoid *)0, (sb4)0, SQLT_NTY, (dvoid *)0, (ub2 *)0, (ub2 *)0, (ub4)OCI_DEFAULT) )
2575 && TRY( hand, OCIDefineObject( adtp, hand->errhp, dthand->tdo, (dvoid **)sthand->obj, (ub4 *)0, (dvoid **)sthand->ind, (ub4 *)0 ) )
2576 && TRY (hand, OCIStmtExecute( hand->svchp, sthand->stmthp, hand->errhp, (ub4)QUERY_SIZE, (ub4)0, (OCISnapshot *)NULL, (OCISnapshot *)NULL, (ub4)OCI_DEFAULT ))
2577 && TRY (hand, OCIAttrGet( (dvoid *)sthand->stmthp, (ub4)OCI_HTYPE_STMT, (dvoid *)&sthand->rows_fetched, (ub4 *)0, (ub4)OCI_ATTR_ROW_COUNT, hand->errhp ));
2578
2579 }
2580
2581 if(!success) {
2582 msDebug( "Error: %s . "
2583 "Query statement: %s ."
2584 "Check your data statement."
2585 "in msOracleSpatialLayerGetShape()\n", hand->last_oci_error, query_str );
2586 msSetError( MS_ORACLESPATIALERR,
2587 "Error in Query statement. Check your server logs","msOracleSpatialLayerGetShape()");
2588
2589 /* clean nullind */
2590 free(nullind);
2591
2592 /* clean items */
2593 free(items);
2594
2595 if (geom_column_name) free(geom_column_name);
2596 if (srid) free(srid);
2597 if (unique) free(unique);
2598 if (indexfield) free(indexfield);
2599 free(table_name);
2600
2601 return MS_FAILURE;
2602 }
2603
2604 shape->type = MS_SHAPE_NULL;
2605
2606 /* no rows fetched */
2607 if (sthand->rows_fetched == 0) {
2608 /* clean nullind */
2609 free(nullind);
2610
2611 /* clean items */
2612 free(items);
2613
2614 if (geom_column_name) free(geom_column_name);
2615 if (srid) free(srid);
2616 if (unique) free(unique);
2617 if (indexfield) free(indexfield);
2618 free(table_name);
2619
2620 return (MS_DONE);
2621 }
2622
2623 obj = sthand->obj[ sthand->row ];
2624 ind = sthand->ind[ sthand->row ];
2625
2626 /* get the items for the shape */
2627 shape->numvalues = layer->numitems;
2628 shape->values = (char **) malloc(sizeof(char *) * layer->numitems);
2629 if (shape->values == NULL) {
2630 msSetError( MS_ORACLESPATIALERR, "No memory avaliable to allocate the values.", "msOracleSpatialLayerGetShape()" );
2631
2632 /* clean nullind */
2633 free(nullind);
2634
2635 /* clean items */
2636 free(items);
2637
2638 if (geom_column_name) free(geom_column_name);
2639 if (srid) free(srid);
2640 if (unique) free(unique);
2641 if (indexfield) free(indexfield);
2642 free(table_name);
2643
2644 return MS_FAILURE;
2645 }
2646
2647 shape->index = shapeindex;
2648
2649 for( i = 0; i < layer->numitems; ++i ) {
2650 shape->values[i] = (char *)malloc(strlen((char *)sthand->items_query[sthand->row][i])+1);
2651
2652 if (shape->values[i] == NULL) {
2653 msSetError( MS_ORACLESPATIALERR, "No memory avaliable to allocate the items buffer.", "msOracleSpatialLayerGetShape()" );
2654
2655 /* clean nullind */
2656 free(nullind);
2657
2658 /* clean items */
2659 free(items);
2660
2661 if (geom_column_name) free(geom_column_name);
2662 if (srid) free(srid);
2663 if (unique) free(unique);
2664 if (indexfield) free(indexfield);
2665 free(table_name);
2666
2667 return MS_FAILURE;
2668 } else {
2669 if (nullind[i] != OCI_IND_NULL) {
2670 strcpy(shape->values[i], (char *)sthand->items_query[sthand->row][i]);
2671 shape->values[i][strlen((char *)sthand->items_query[sthand->row][i])] = '\0';
2672 } else {
2673 shape->values[i][0] = '\0';
2674 }
2675 }
2676 }
2677
2678 /* increment for next row */
2679 sthand->row_num++;
2680 sthand->row++;
2681
2682 /* fetch a layer->type object */
2683 success = osGetOrdinates(dthand, hand, shape, obj, ind);
2684 if (success != MS_SUCCESS) {
2685 msSetError( MS_ORACLESPATIALERR, "Cannot execute query", "msOracleSpatialLayerGetShape()" );
2686
2687 /* clean nullind */
2688 free(nullind);
2689
2690 /* clean items */
2691 free(items);
2692
2693 if (geom_column_name) free(geom_column_name);
2694 if (srid) free(srid);
2695 if (unique) free(unique);
2696 if (indexfield) free(indexfield);
2697 free(table_name);
2698
2699 return MS_FAILURE;
2700 }
2701 osShapeBounds(shape);
2702 sthand->row = sthand->row_num = 0;
2703
2704 /* clean nullind */
2705 free(nullind);
2706
2707 /* clean items */
2708 free(items);
2709
2710 if (geom_column_name) free(geom_column_name);
2711 if (srid) free(srid);
2712 if (unique) free(unique);
2713 if (indexfield) free(indexfield);
2714 free(table_name);
2715
2716 return (MS_SUCCESS);
2717 }
2718 }
2719
msOracleSpatialLayerInitItemInfo(layerObj * layer)2720 int msOracleSpatialLayerInitItemInfo( layerObj *layer )
2721 {
2722 int i;
2723 int *itemindexes ;
2724
2725 if (layer->debug>=3)
2726 msDebug("msOracleSpatialLayerInitItemInfo was called.\n");
2727
2728 if (layer->numitems == 0)
2729 return MS_SUCCESS;
2730
2731 if (layer->iteminfo)
2732 free( layer->iteminfo );
2733
2734 if ((layer->iteminfo = (long *)malloc(sizeof(int)*layer->numitems))== NULL) {
2735 msSetError(MS_MEMERR, NULL, "msOracleSpatialLayerInitItemInfo()");
2736 return MS_FAILURE;
2737 }
2738
2739 itemindexes = (int*)layer->iteminfo;
2740
2741
2742
2743 for(i=0; i < layer->numitems; i++){
2744 itemindexes[i] = i; /*last one is always the geometry one - the rest are non-geom*/
2745 }
2746
2747 return MS_SUCCESS;
2748 }
2749
2750 /* AutoProjection Support for RFC 37 #3333
2751 * TODO: Needs testing
2752 */
msOracleSpatialLayerGetAutoProjection(layerObj * layer,projectionObj * projection)2753 int msOracleSpatialLayerGetAutoProjection( layerObj *layer, projectionObj *projection )
2754 {
2755 char *table_name;
2756 char *query_str, *geom_column_name = NULL, *unique = NULL, *srid = NULL, *indexfield=NULL;
2757 int success;
2758 int function = 0;
2759 int version = 0;
2760 char wktext[4000];
2761
2762 OCIDefine *def1p = NULL;
2763 OCIBind *bnd1p = NULL, *bnd2p = NULL;
2764
2765 msOracleSpatialLayerInfo *layerinfo = (msOracleSpatialLayerInfo *)layer->layerinfo;
2766 msOracleSpatialDataHandler *dthand = NULL;
2767 msOracleSpatialHandler *hand = NULL;
2768 msOracleSpatialStatement *sthand = NULL;
2769
2770 if (layer->debug>=3)
2771 msDebug("msOracleSpatialLayerGetAutoProjection was called.\n");
2772
2773 if (layerinfo == NULL) {
2774 msSetError( MS_ORACLESPATIALERR, "msOracleSpatialLayerGetAutoProjection called on unopened layer","msOracleSpatialLayerGetAutoProjection()");
2775 return MS_FAILURE;
2776 } else {
2777 dthand = (msOracleSpatialDataHandler *)layerinfo->oradatahandlers;
2778 hand = (msOracleSpatialHandler *)layerinfo->orahandlers;
2779 sthand = (msOracleSpatialStatement *) layerinfo->orastmt;
2780 }
2781
2782 table_name = (char *) malloc(sizeof(char) * TABLE_NAME_SIZE);
2783 if (!msSplitData( layer->data, &geom_column_name, &table_name, &unique, &srid, &indexfield, &function, &version )) {
2784 msDebug( "Error parsing OracleSpatial DATA variable. Must be: "
2785 "'geometry_column FROM table_name [USING UNIQUE <column> SRID srid# FUNCTION]' or "
2786 "'geometry_column FROM (SELECT stmt) [USING UNIQUE <column> SRID srid# FUNCTION]'. "
2787 "If want to set the FUNCTION statement you can use: FILTER, RELATE, GEOMRELATE or NONE. "
2788 "Your data statement: (%s) "
2789 "in msOracleSpatialLayerGetAutoProjection()\n", layer->data );
2790
2791 msSetError( MS_ORACLESPATIALERR,
2792 "Error parsing OracleSpatial DATA variable",
2793 "msOracleSpatialLayerGetAutoProjection()");
2794
2795 if (geom_column_name) free(geom_column_name);
2796 if (srid) free(srid);
2797 if (unique) free(unique);
2798 if (indexfield) free(indexfield);
2799 free(table_name);
2800
2801 return MS_FAILURE;
2802 }
2803
2804 query_str = "SELECT wktext FROM mdsys.all_sdo_geom_metadata m, mdsys.cs_srs c WHERE c.srid = m.srid and m.owner||'.'||m.table_name = :table_name and m.column_name = :geo_col_name "
2805 "UNION SELECT wktext from mdsys.user_sdo_geom_metadata m, mdsys.cs_srs c WHERE c.srid = m.srid and m.table_name = :table_name and m.column_name = :geo_col_name";
2806
2807 if (layer->debug>=2)
2808 msDebug("msOracleSpatialLayerGetAutoProjection. Using this Sql to retrieve the projection: %s.\n", query_str);
2809
2810 /*Prepare the handlers to the query*/
2811 success = TRY( hand, OCIStmtPrepare( sthand->stmthp, hand->errhp, (text *)query_str, (ub4)strlen(query_str), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT ) )
2812 && TRY( hand, OCIBindByName( sthand->stmthp, &bnd2p, hand->errhp, (text *) ":table_name", strlen(":table_name"), (ub1*) table_name, strlen(table_name)+1, SQLT_STR, (dvoid *) 0, (ub2 *) 0, (ub2) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT ) )
2813 && TRY( hand, OCIBindByName( sthand->stmthp, &bnd1p, hand->errhp, (text *) ":geo_col_name", strlen(":geo_col_name"), (ub1*) geom_column_name, strlen(geom_column_name)+1, SQLT_STR, (dvoid *) 0, (ub2 *) 0, (ub2) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT ) )
2814 && TRY( hand, OCIDefineByPos( sthand->stmthp, &def1p, hand->errhp, (ub4)1, (dvoid *)wktext, (sb4)4000, SQLT_STR, (dvoid *)0, (ub2 *)0, (ub2 *)0, (ub4)OCI_DEFAULT ) )
2815 && TRY( hand, OCIStmtExecute( hand->svchp, sthand->stmthp, hand->errhp, (ub4)0, (ub4)0, (OCISnapshot *)NULL, (OCISnapshot *)NULL, (ub4)OCI_DEFAULT ) )
2816 && TRY( hand, OCIAttrGet( (dvoid *)sthand->stmthp, (ub4)OCI_HTYPE_STMT, (dvoid *)&sthand->rows_fetched, (ub4 *)0, (ub4)OCI_ATTR_ROWS_FETCHED, hand->errhp ) );
2817
2818 if(!success) {
2819 msDebug( "Error: %s . "
2820 "Query statement: %s . "
2821 "Check your data statement."
2822 "in msOracleSpatialLayerGetAutoProjection()\n", hand->last_oci_error, query_str );
2823 msSetError( MS_ORACLESPATIALERR,
2824 "Error "
2825 "Check your data statement and server logs",
2826 "msOracleSpatialLayerGetAutoProjection()" );
2827
2828 if (geom_column_name) free(geom_column_name);
2829 if (srid) free(srid);
2830 if (unique) free(unique);
2831 if (indexfield) free(indexfield);
2832 free(table_name);
2833 return MS_FAILURE;
2834 }
2835 do {
2836 success = TRY( hand, OCIStmtFetch( sthand->stmthp, hand->errhp, (ub4)1, (ub2)OCI_FETCH_NEXT, (ub4)OCI_DEFAULT ) )
2837 && TRY( hand, OCIAttrGet( (dvoid *)sthand->stmthp, (ub4)OCI_HTYPE_STMT, (dvoid *)&sthand->rows_fetched, (ub4 *)0, (ub4)OCI_ATTR_ROWS_FETCHED, hand->errhp ) );
2838 if (success && sthand->rows_fetched > 0) {
2839
2840 if( layer->debug )
2841 msDebug("Found WKT projection for table %s: %s\n", table_name, wktext);
2842
2843 if(wktext != NULL && projection != NULL)
2844 if(msOGCWKT2ProjectionObj(wktext, projection, layer->debug) == MS_FAILURE)
2845 return(MS_FAILURE);
2846 }
2847 } while (sthand->rows_fetched > 0);
2848
2849 if (geom_column_name) free(geom_column_name);
2850 if (srid) free(srid);
2851 if (unique) free(unique);
2852 if (indexfield) free(indexfield);
2853 free(table_name);
2854 return MS_SUCCESS;
2855 }
2856
2857 /**********************************************************************
2858 * msOracleSpatialGetFieldDefn()
2859 *
2860 * Pass the field definitions through to the layer metadata in the
2861 * "gml_[item]_{type,width,precision}" set of metadata items for
2862 * defining fields.
2863 **********************************************************************/
2864 static void
msOracleSpatialGetFieldDefn(layerObj * layer,msOracleSpatialHandler * hand,const char * item,OCIParam * pard)2865 msOracleSpatialGetFieldDefn( layerObj *layer,
2866 msOracleSpatialHandler *hand,
2867 const char *item,
2868 OCIParam *pard )
2869
2870 {
2871 const char *gml_type = "Character";
2872 char md_item_name[256];
2873 char gml_width[32], gml_precision[32];
2874 int success;
2875 ub2 rzttype, nOCILen;
2876
2877 gml_width[0] = '\0';
2878 gml_precision[0] = '\0';
2879
2880 /* -------------------------------------------------------------------- */
2881 /* Get basic parameter details. */
2882 /* -------------------------------------------------------------------- */
2883 success =
2884 TRY( hand, OCIAttrGet ((dvoid *) pard,(ub4) OCI_DTYPE_PARAM,
2885 (dvoid*)&rzttype,(ub4 *)0,
2886 (ub4) OCI_ATTR_DATA_TYPE, hand->errhp ))
2887 && TRY( hand, OCIAttrGet ((dvoid *) pard,(ub4) OCI_DTYPE_PARAM,
2888 (dvoid*)&nOCILen ,(ub4 *)0,
2889 (ub4) OCI_ATTR_DATA_SIZE, hand->errhp ));
2890
2891 if( !success )
2892 return;
2893
2894 switch( rzttype ) {
2895 case SQLT_CHR:
2896 case SQLT_AFC:
2897 gml_type = "Character";
2898 if( nOCILen <= 4000 )
2899 sprintf( gml_width, "%d", nOCILen );
2900 break;
2901
2902 case SQLT_NUM: {
2903 /* NOTE: OCI docs say this should be ub1 type, but we have
2904 determined that oracle is actually returning a short so we
2905 use that type and try to compensate for possible problems by
2906 initializing, and dividing by 256 if it is large. */
2907 unsigned short byPrecision = 0;
2908 sb1 nScale = 0;
2909
2910 if( !TRY( hand, OCIAttrGet ((dvoid *) pard,(ub4) OCI_DTYPE_PARAM,
2911 (dvoid*)&byPrecision ,(ub4 *)0,
2912 (ub4) OCI_ATTR_PRECISION,
2913 hand->errhp ))
2914 || !TRY( hand, OCIAttrGet ((dvoid *) pard,(ub4) OCI_DTYPE_PARAM,
2915 (dvoid*)&nScale,(ub4 *)0,
2916 (ub4) OCI_ATTR_SCALE,
2917 hand->errhp )) )
2918 return;
2919 if( byPrecision > 255 )
2920 byPrecision = byPrecision / 256;
2921
2922 if( nScale > 0 ) {
2923 gml_type = "Real";
2924 sprintf( gml_width, "%d", byPrecision );
2925 sprintf( gml_precision, "%d", nScale );
2926 } else if( nScale < 0 )
2927 gml_type = "Real";
2928 else {
2929 gml_type = "Integer";
2930 if( byPrecision < 38 )
2931 sprintf( gml_width, "%d", byPrecision );
2932 }
2933 }
2934 break;
2935
2936 case SQLT_DAT:
2937 case SQLT_DATE:
2938 gml_type = "Date";
2939 break;
2940 case SQLT_TIMESTAMP:
2941 case SQLT_TIMESTAMP_TZ:
2942 case SQLT_TIMESTAMP_LTZ:
2943 gml_type = "DateTime";
2944 break;
2945 case SQLT_TIME:
2946 case SQLT_TIME_TZ:
2947 gml_type = "Time";
2948 break;
2949
2950 default:
2951 gml_type = "Character";
2952 }
2953
2954 snprintf( md_item_name, sizeof(md_item_name), "gml_%s_type", item );
2955 if( msOWSLookupMetadata(&(layer->metadata), "G", "type") == 0 )
2956 msInsertHashTable(&(layer->metadata), md_item_name, gml_type );
2957
2958 snprintf( md_item_name, sizeof(md_item_name), "gml_%s_width", item );
2959 if( strlen(gml_width) > 0
2960 && msOWSLookupMetadata(&(layer->metadata), "G", "width") == 0 )
2961 msInsertHashTable(&(layer->metadata), md_item_name, gml_width );
2962
2963 snprintf( md_item_name, sizeof(md_item_name), "gml_%s_precision",item );
2964 if( strlen(gml_precision) > 0
2965 && msOWSLookupMetadata(&(layer->metadata), "G", "precision")==0 )
2966 msInsertHashTable(&(layer->metadata), md_item_name, gml_precision );
2967 }
2968
msOracleSpatialLayerGetItems(layerObj * layer)2969 int msOracleSpatialLayerGetItems( layerObj *layer )
2970 {
2971 char *rzt = "";
2972 ub2 rzttype = 0;
2973 char *flk = "";
2974 int function = 0;
2975 int version = 0;
2976 int existgeom;
2977 int count_item, flk_len, success, i;
2978 char *table_name;
2979 char query_str[6000], *geom_column_name = NULL, *unique = NULL, *srid = NULL, *indexfield=NULL;
2980 OCIParam *pard = (OCIParam *) 0;
2981
2982 msOracleSpatialLayerInfo *layerinfo = (msOracleSpatialLayerInfo *) layer->layerinfo;
2983 msOracleSpatialDataHandler *dthand = NULL;
2984 msOracleSpatialHandler *hand = NULL;
2985 msOracleSpatialStatement *sthand = NULL;
2986 int get_field_details = 0;
2987 const char *value;
2988
2989 if (layer->debug>=3)
2990 msDebug("msOracleSpatialLayerGetItems was called.\n");
2991
2992 if (layerinfo == NULL) {
2993 msSetError( MS_ORACLESPATIALERR, "msOracleSpatialLayerGetItems called on unopened layer", "msOracleSpatialLayerGetItems()" );
2994 return MS_FAILURE;
2995 } else {
2996 dthand = (msOracleSpatialDataHandler *)layerinfo->oradatahandlers;
2997 hand = (msOracleSpatialHandler *)layerinfo->orahandlers;
2998 sthand = (msOracleSpatialStatement *) layerinfo->orastmt;
2999 }
3000
3001 /* Will we want to capture the field details? */
3002 if((value = msOWSLookupMetadata(&(layer->metadata), "G", "types")) != NULL
3003 && strcasecmp(value,"auto") == 0 )
3004 get_field_details = 1;
3005
3006 table_name = (char *) malloc(sizeof(char) * TABLE_NAME_SIZE);
3007 if (!msSplitData(layer->data, &geom_column_name, &table_name, &unique, &srid, &indexfield, &function, &version)) {
3008 msDebug( "Error parsing OracleSpatial DATA variable. Must be: "
3009 "'geometry_column FROM table_name [USING UNIQUE <column> SRID srid# FUNCTION]' or "
3010 "'geometry_column FROM (SELECT stmt) [USING UNIQUE <column> SRID srid# FUNCTION]'. "
3011 "If want to set the FUNCTION statement you can use: FILTER, RELATE, GEOMRELATE or NONE. "
3012 "Your data statement: (%s)"
3013 "in msOracleSpatialLayerGetItems()\n", layer->data );
3014 msSetError( MS_ORACLESPATIALERR,
3015 "Error parsing OracleSpatial DATA variable. Check server logs. ",
3016 "msOracleSpatialLayerGetItems()");
3017
3018 if (geom_column_name) free(geom_column_name);
3019 if (srid) free(srid);
3020 if (unique) free(unique);
3021 if (indexfield) free(indexfield);
3022 free(table_name);
3023 return MS_FAILURE;
3024 }
3025
3026 snprintf( query_str, sizeof(query_str), "SELECT * FROM %s", table_name );
3027
3028 success = TRY( hand, OCIStmtPrepare( sthand->stmthp, hand->errhp, (text *)query_str, (ub4)strlen(query_str), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DESCRIBE_ONLY) )
3029 && TRY( hand, OCIStmtExecute( hand->svchp, sthand->stmthp, hand->errhp, (ub4)QUERY_SIZE, (ub4)0, (OCISnapshot *)NULL, (OCISnapshot *)NULL, (ub4)OCI_DESCRIBE_ONLY ) )
3030 && TRY( hand, OCIAttrGet( (dvoid *)sthand->stmthp, (ub4)OCI_HTYPE_STMT, (dvoid *)&layer->numitems, (ub4 *)0, OCI_ATTR_PARAM_COUNT, hand->errhp) );
3031
3032
3033 if (!success) {
3034 msSetError( MS_QUERYERR, "Cannot retrieve column list", "msOracleSpatialLayerGetItems()" );
3035 if (geom_column_name) free(geom_column_name);
3036 if (srid) free(srid);
3037 if (unique) free(unique);
3038 if (indexfield) free(indexfield);
3039 free(table_name);
3040 return MS_FAILURE;
3041 }
3042
3043 sthand->row_num = sthand->row = 0;
3044 layer->numitems = layer->numitems-1;
3045
3046 layer->items = malloc (sizeof(char *) * (layer->numitems));
3047 if (layer->items == NULL) {
3048 msSetError( MS_ORACLESPATIALERR,"Cannot allocate items", "msOracleSpatialLayerGetItems()" );
3049 if (geom_column_name) free(geom_column_name);
3050 if (srid) free(srid);
3051 if (unique) free(unique);
3052 if (indexfield) free(indexfield);
3053 free(table_name);
3054 return MS_FAILURE;
3055 }
3056
3057 if (layer->numitems > 0) {
3058 if (sthand->items_query == NULL)
3059 sthand->items_query = (item_text_array_query *)malloc( sizeof(item_text_array_query) * (layer->numitems) );
3060
3061 if (sthand->items_query == NULL) {
3062 msSetError( MS_ORACLESPATIALERR,"Cannot allocate items buffer", "msOracleSpatialLayerGetItems()" );
3063 if (geom_column_name) free(geom_column_name);
3064 if (srid) free(srid);
3065 if (unique) free(unique);
3066 if (indexfield) free(indexfield);
3067 free(table_name);
3068 return MS_FAILURE;
3069 }
3070 }
3071
3072 count_item = 0;
3073 existgeom = 0;
3074
3075 /*Upcase conversion for the geom_column_name*/
3076 for (i=0; geom_column_name[i] != '\0'; i++)
3077 geom_column_name[i] = toupper(geom_column_name[i]);
3078
3079 /*Retrive columns name from the user table*/
3080 for (i = 0; i <= layer->numitems; i++) {
3081
3082 success = TRY( hand, OCIParamGet ((dvoid*) sthand->stmthp, (ub4)OCI_HTYPE_STMT,hand->errhp,(dvoid*)&pard, (ub4)i+1))
3083 && TRY( hand, OCIAttrGet ((dvoid *) pard,(ub4) OCI_DTYPE_PARAM,(dvoid*)&rzttype,(ub4 *)0, (ub4) OCI_ATTR_DATA_TYPE, hand->errhp ))
3084 && TRY( hand, OCIParamGet ((dvoid*) sthand->stmthp, (ub4)OCI_HTYPE_STMT,hand->errhp,(dvoid*)&pard, (ub4)i+1))
3085 && TRY( hand, OCIAttrGet ((dvoid *) pard,(ub4) OCI_DTYPE_PARAM,(dvoid*)&rzt,(ub4 *)&flk_len, (ub4) OCI_ATTR_NAME, hand->errhp ));
3086
3087 /* if (layer->debug)
3088 msDebug("msOracleSpatialLayerGetItems checking type. Column = %s Type = %d\n", rzt, rzttype); */
3089 flk = (char *)malloc(sizeof(char*) * flk_len+1);
3090 if (flk == NULL) {
3091 msSetError( MS_ORACLESPATIALERR, "No memory avaliable to allocate the items", "msOracleSpatialLayerGetItems()" );
3092 if (geom_column_name) free(geom_column_name);
3093 if (srid) free(srid);
3094 if (unique) free(unique);
3095 free(table_name);
3096 return MS_FAILURE;
3097 } else {
3098 //layer->iteminfo->dtype[i]= 1;
3099 strlcpy(flk, rzt, flk_len+1);
3100 }
3101
3102 /*Comapre the column name (flk) with geom_column_name and ignore with true*/
3103 if (strcmp(flk, geom_column_name) != 0) {
3104 if (rzttype!=OCI_TYPECODE_BLOB) {
3105 layer->items[count_item] = (char *)malloc(sizeof(char) * flk_len+1);
3106 if (layer->items[count_item] == NULL) {
3107 msSetError( MS_ORACLESPATIALERR, "No memory avaliable to allocate the items buffer", "msOracleSpatialLayerGetItems()" );
3108 if (geom_column_name) free(geom_column_name);
3109 if (srid) free(srid);
3110 if (unique) free(unique);
3111 free(table_name);
3112 return MS_FAILURE;
3113 }
3114
3115 strcpy(layer->items[count_item], flk);
3116 count_item++;
3117
3118 if( get_field_details )
3119 msOracleSpatialGetFieldDefn( layer, hand,
3120 layer->items[count_item-1],
3121 pard );
3122 }
3123 } else
3124 existgeom = 1;
3125
3126 strcpy( rzt, "" );
3127 free(flk); /* Better?!*/
3128 flk_len = 0;
3129 }
3130
3131 layer->numitems = count_item;
3132
3133 if (!(existgeom)) {
3134 msSetError (MS_ORACLESPATIALERR, "No geometry column, check stmt", "msOracleSpatialLayerGetItems()" );
3135 if (geom_column_name) free(geom_column_name);
3136 if (srid) free(srid);
3137 if (unique) free(unique);
3138 if (indexfield) free(indexfield);
3139 free(table_name);
3140 return MS_FAILURE;
3141 }
3142
3143 if (geom_column_name) free(geom_column_name);
3144 if (srid) free(srid);
3145 if (unique) free(unique);
3146 if (indexfield) free(indexfield);
3147 free(table_name);
3148 return msOracleSpatialLayerInitItemInfo( layer );
3149 }
3150
msOracleSpatialLayerGetExtent(layerObj * layer,rectObj * extent)3151 int msOracleSpatialLayerGetExtent(layerObj *layer, rectObj *extent)
3152 {
3153 char *table_name;
3154 char query_str[6000], *geom_column_name = NULL, *unique = NULL, *srid = NULL, *indexfield=NULL;
3155 int success, i;
3156 int function = 0;
3157 int version = 0;
3158 SDOGeometryObj *obj = NULL;
3159 SDOGeometryInd *ind = NULL;
3160 shapeObj shape;
3161 rectObj bounds;
3162 /*OCIDefine *adtp = NULL, *items[QUERY_SIZE] = { NULL };*/
3163 OCIDefine *adtp = NULL;
3164 OCIDefine **items = NULL;
3165
3166 msOracleSpatialLayerInfo *layerinfo = (msOracleSpatialLayerInfo *)layer->layerinfo;
3167 msOracleSpatialDataHandler *dthand = NULL;
3168 msOracleSpatialHandler *hand = NULL;
3169 msOracleSpatialStatement *sthand = NULL;
3170
3171 if (layer->debug>=3)
3172 msDebug("msOracleSpatialLayerGetExtent was called.\n");
3173
3174 if (layerinfo == NULL) {
3175 msSetError( MS_ORACLESPATIALERR, "msOracleSpatialLayerGetExtent called on unopened layer","msOracleSpatialLayerGetExtent()");
3176 return MS_FAILURE;
3177 } else {
3178 dthand = (msOracleSpatialDataHandler *)layerinfo->oradatahandlers;
3179 hand = (msOracleSpatialHandler *)layerinfo->orahandlers;
3180 sthand = (msOracleSpatialStatement *) layerinfo->orastmt;
3181 }
3182
3183 /* allocate enough space for items */
3184 if (layer->numitems > 0) {
3185 sthand->items_query = (item_text_array_query *)malloc( sizeof(item_text_array_query) * (layer->numitems) );
3186 if (sthand->items_query == NULL) {
3187 msSetError( MS_ORACLESPATIALERR, "Cannot allocate layerinfo->items buffer", "msOracleSpatialLayerGetExtent()" );
3188 return MS_FAILURE;
3189 }
3190 items = (OCIDefine **)malloc(sizeof(OCIDefine *)*layer->numitems);
3191 if (items == NULL) {
3192 msSetError( MS_ORACLESPATIALERR,"Cannot allocate items buffer","msOracleSpatialLayerWhichShapes()" );
3193 return MS_FAILURE;
3194 }
3195 memset(items ,0,sizeof(OCIDefine *)*layer->numitems);
3196 }
3197
3198 table_name = (char *) malloc(sizeof(char) * TABLE_NAME_SIZE);
3199 if (!msSplitData( layer->data, &geom_column_name, &table_name, &unique, &srid, &indexfield, &function, &version )) {
3200 msDebug( "Error parsing OracleSpatial DATA variable. Must be: "
3201 "'geometry_column FROM table_name [USING UNIQUE <column> SRID srid# FUNCTION]' or "
3202 "'geometry_column FROM (SELECT stmt) [USING UNIQUE <column> SRID srid# FUNCTION]'. "
3203 "If want to set the FUNCTION statement you can use: FILTER, RELATE, GEOMRELATE or NONE. "
3204 "Your data statement: (%s) "
3205 "in msOracleSpatialLayerGetExtent()\n", layer->data );
3206 msSetError( MS_ORACLESPATIALERR,
3207 "Error parsing OracleSpatial DATA variable. Check server logs. ",
3208 "msOracleSpatialLayerGetExtent()");
3209 /* clean items */
3210 free(items);
3211
3212 if (geom_column_name) free(geom_column_name);
3213 if (srid) free(srid);
3214 if (unique) free(unique);
3215 if (indexfield) free(indexfield);
3216 free(table_name);
3217
3218 return MS_FAILURE;
3219 }
3220
3221 //if (version == VERSION_10g)
3222 osAggrGetExtent(layer, query_str, sizeof(query_str), geom_column_name, table_name);
3223 /*else {
3224 if (((atol(srid) < 8192) || (atol(srid) > 8330)) && (atol(srid) != 2) && (atol(srid) != 5242888) && (atol(srid) != 2000001)) {
3225 if (version == VERSION_9i)
3226 osAggrGetExtent(layer, query_str, sizeof(query_str), geom_column_name, table_name);
3227 else
3228 osConvexHullGetExtent(layer, query_str, sizeof(query_str), geom_column_name, table_name);
3229 } else
3230 osConvexHullGetExtent(layer, query_str, sizeof(query_str), geom_column_name, table_name);
3231 } */
3232
3233 if (layer->debug>=3)
3234 msDebug("msOracleSpatialLayerGetExtent. Using this Sql to retrieve the extent: %s.\n", query_str);
3235
3236 /*Prepare the handlers to the query*/
3237 success = TRY( hand,OCIStmtPrepare( sthand->stmthp, hand->errhp, (text *)query_str, (ub4)strlen(query_str), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT) );
3238
3239 if (success && layer->numitems > 0) {
3240 for( i = 0; i < layer->numitems && success; ++i )
3241 success = TRY( hand, OCIDefineByPos( sthand->stmthp, &items[i], hand->errhp, (ub4)i+1, (dvoid *)sthand->items_query[i], (sb4)TEXT_SIZE, SQLT_STR, (dvoid *)0, (ub2 *)0, (ub2 *)0, (ub4)OCI_DEFAULT ) );
3242 }
3243
3244 if(!success) {
3245 msDebug( "Error: %s . "
3246 "Query statement: %s . "
3247 "Check your data statement."
3248 "in msOracleSpatialLayerGetExtent()\n", hand->last_oci_error, query_str );
3249
3250 msSetError( MS_ORACLESPATIALERR,
3251 "Check your data statement and server logs",
3252 "msOracleSpatialLayerGetExtent()" );
3253
3254 /* clean items */
3255 free(items);
3256
3257 if (geom_column_name) free(geom_column_name);
3258 if (srid) free(srid);
3259 if (unique) free(unique);
3260 if (indexfield) free(indexfield);
3261 free(table_name);
3262
3263 return MS_FAILURE;
3264 }
3265
3266 if (success) {
3267 success = TRY( hand, OCIDefineByPos( sthand->stmthp, &adtp, hand->errhp, (ub4)layer->numitems+1, (dvoid *)0, (sb4)0, SQLT_NTY, (dvoid *)0, (ub2 *)0, (ub2 *)0, (ub4)OCI_DEFAULT) )
3268 && TRY( hand, OCIDefineObject( adtp, hand->errhp, dthand->tdo, (dvoid **)sthand->obj, (ub4 *)0, (dvoid **)sthand->ind, (ub4 *)0 ) )
3269 && TRY (hand, OCIStmtExecute( hand->svchp, sthand->stmthp, hand->errhp, (ub4)QUERY_SIZE, (ub4)0, (OCISnapshot *)NULL, (OCISnapshot *)NULL, (ub4)OCI_DEFAULT ))
3270 && TRY (hand, OCIAttrGet( (dvoid *)sthand->stmthp, (ub4)OCI_HTYPE_STMT, (dvoid *)&sthand->rows_fetched, (ub4 *)0, (ub4)OCI_ATTR_ROW_COUNT, hand->errhp ));
3271
3272 }
3273
3274 if(!success) {
3275 msDebug( "Error: %s . "
3276 "Query statement: %s ."
3277 "Check your data statement."
3278 "in msOracleSpatialLayerGetExtent()\n", hand->last_oci_error, query_str );
3279 msSetError( MS_ORACLESPATIALERR,
3280 "Check your data statement and server logs",
3281 "msOracleSpatialLayerGetExtent()" );
3282
3283 /* clean items */
3284 free(items);
3285
3286 if (geom_column_name) free(geom_column_name);
3287 if (srid) free(srid);
3288 if (unique) free(unique);
3289 if (indexfield) free(indexfield);
3290 free(table_name);
3291
3292 return MS_FAILURE;
3293 }
3294
3295 /* should begin processing first row */
3296 sthand->row_num = sthand->row = 0;
3297 msInitShape( &shape );
3298 do {
3299 /* is buffer empty? */
3300 if (sthand->row_num >= sthand->rows_fetched) {
3301 /* fetch more */
3302 success = TRY( hand, OCIStmtFetch( sthand->stmthp, hand->errhp, (ub4)ARRAY_SIZE, (ub2)OCI_FETCH_NEXT, (ub4)OCI_DEFAULT ) )
3303 && TRY( hand, OCIAttrGet( (dvoid *)sthand->stmthp, (ub4)OCI_HTYPE_STMT, (dvoid *)&sthand->rows_fetched, (ub4 *)0, (ub4)OCI_ATTR_ROW_COUNT, hand->errhp ) );
3304
3305 if (!success || sthand->rows_fetched == 0 || sthand->row_num >= sthand->rows_fetched) {
3306 hand->last_oci_status=MS_SUCCESS;
3307 break;
3308 }
3309
3310 sthand->row = 0; /* reset row index */
3311 }
3312
3313 /* no rows fetched */
3314 if (sthand->rows_fetched == 0)
3315 break;
3316
3317 obj = sthand->obj[ sthand->row ];
3318 ind = sthand->ind[ sthand->row ];
3319
3320 /* get the items for the shape */
3321 shape.numvalues = layer->numitems;
3322 shape.values = (char **) malloc(sizeof(char *) * layer->numitems);
3323 if (shape.values == NULL) {
3324 msSetError( MS_ORACLESPATIALERR, "No memory avaliable to allocate the values.", "msOracleSpatialLayerGetExtent()" );
3325 if (geom_column_name) free(geom_column_name);
3326 if (srid) free(srid);
3327 if (unique) free(unique);
3328 if (indexfield) free(indexfield);
3329 free(table_name);
3330 return MS_FAILURE;
3331 }
3332
3333 shape.index = sthand->row_num;
3334
3335 for( i = 0; i < layer->numitems; ++i ) {
3336 shape.values[i] = (char *)malloc(strlen((char *)sthand->items_query[sthand->row][i])+1);
3337
3338 if (shape.values[i] == NULL) {
3339 msSetError( MS_ORACLESPATIALERR, "No memory avaliable to allocate the items buffer.", "msOracleSpatialLayerGetExtent()" );
3340
3341 /* clean items */
3342 free(items);
3343
3344 if (geom_column_name) free(geom_column_name);
3345 if (srid) free(srid);
3346 if (unique) free(unique);
3347 if (indexfield) free(indexfield);
3348 free(table_name);
3349
3350 return MS_FAILURE;
3351 } else {
3352 strcpy(shape.values[i], (char *)sthand->items_query[sthand->row][i]);
3353 shape.values[i][strlen((char *)sthand->items_query[sthand->row][i])] = '\0';
3354 }
3355 }
3356
3357 /* increment for next row */
3358 sthand->row_num++;
3359 sthand->row++;
3360
3361 /* fetch a layer->type object */
3362 success = osGetOrdinates(dthand, hand, &shape, obj, ind);
3363 if (success != MS_SUCCESS) {
3364 msSetError( MS_ORACLESPATIALERR, "Cannot execute query", "msOracleSpatialLayerGetExtent()" );
3365
3366 /* clean items */
3367 free(items);
3368
3369 if (geom_column_name) free(geom_column_name);
3370 if (srid) free(srid);
3371 if (unique) free(unique);
3372 if (indexfield) free(indexfield);
3373 free(table_name);
3374
3375 return MS_FAILURE;
3376 }
3377
3378 } while(sthand->row <= sthand->rows_fetched);
3379
3380 sthand->row = sthand->row_num = 0;
3381
3382 osShapeBounds(&shape);
3383 bounds = shape.bounds;
3384
3385 extent->minx = bounds.minx;
3386 extent->miny = bounds.miny;
3387 extent->maxx = bounds.maxx;
3388 extent->maxy = bounds.maxy;
3389
3390 msFreeShape(&shape);
3391
3392 /* clean items */
3393 free(items);
3394
3395 if (geom_column_name) free(geom_column_name);
3396 if (srid) free(srid);
3397 if (unique) free(unique);
3398 if (indexfield) free(indexfield);
3399 free(table_name);
3400
3401 return(MS_SUCCESS);
3402 }
3403
msOracleSpatialLayerFreeItemInfo(layerObj * layer)3404 void msOracleSpatialLayerFreeItemInfo( layerObj *layer )
3405 {
3406 if (layer->debug>=3)
3407 msDebug("msOracleSpatialLayerFreeItemInfo was called.\n");
3408
3409 if (layer->iteminfo)
3410 free(layer->iteminfo);
3411
3412 layer->iteminfo = NULL;
3413 /* nothing to do */
3414 }
3415
msOracleSpatialLayerGetAutoStyle(mapObj * map,layerObj * layer,classObj * c,shapeObj * shape)3416 int msOracleSpatialLayerGetAutoStyle( mapObj *map, layerObj *layer, classObj *c, shapeObj *shape )
3417 {
3418 msSetError( MS_ORACLESPATIALERR, "Function not implemented yet", "msLayerGetAutoStyle()" );
3419 return MS_FAILURE;
3420 }
3421
3422 /************************************************************************/
3423 /* msOracleSpatialEscapePropertyName */
3424 /* */
3425 /* Return the property name in a properly escaped and quoted form. */
3426 /************************************************************************/
msOracleSpatialEscapePropertyName(layerObj * layer,const char * pszString)3427 char *msOracleSpatialEscapePropertyName(layerObj *layer, const char* pszString)
3428 {
3429 char* pszEscapedStr=NULL;
3430 int i, j = 0;
3431
3432 if (layer && pszString && strlen(pszString) > 0) {
3433 int nLength = strlen(pszString);
3434
3435 pszEscapedStr = (char*) msSmallMalloc( 1 + 2 * nLength + 1 + 1);
3436 //pszEscapedStr[j++] = '';
3437
3438 for (i=0; i<nLength; i++) {
3439 char c = pszString[i];
3440 if (c == '"') {
3441 pszEscapedStr[j++] = '"';
3442 pszEscapedStr[j++] ='"';
3443 } else if (c == '\\') {
3444 pszEscapedStr[j++] = '\\';
3445 pszEscapedStr[j++] = '\\';
3446 } else
3447 pszEscapedStr[j++] = c;
3448 }
3449 //pszEscapedStr[j++] = '';
3450 pszEscapedStr[j++] = 0;
3451
3452 }
3453 return pszEscapedStr;
3454 }
3455
msOracleSpatialGetPaging(layerObj * layer)3456 int msOracleSpatialGetPaging(layerObj *layer)
3457 {
3458 msOracleSpatialLayerInfo *layerinfo = NULL;
3459
3460 //if (layer->debug)
3461 // msDebug("msOracleSpatialLayerGetPaging was called.\n");
3462
3463 if(!msOracleSpatialLayerIsOpen(layer))
3464 return MS_TRUE;
3465
3466 assert( layer->layerinfo != NULL);
3467 layerinfo = (msOracleSpatialLayerInfo *)layer->layerinfo;
3468
3469 return layerinfo->paging;
3470 }
3471
msOracleSpatialEnablePaging(layerObj * layer,int value)3472 void msOracleSpatialEnablePaging(layerObj *layer, int value)
3473 {
3474 msOracleSpatialLayerInfo *layerinfo = NULL;
3475
3476 if (layer->debug>=3)
3477 msDebug("msOracleSpatialLayerEnablePaging was called.\n");
3478
3479 if(!msOracleSpatialLayerIsOpen(layer))
3480 msOracleSpatialLayerOpen(layer);
3481
3482 assert( layer->layerinfo != NULL);
3483 layerinfo = (msOracleSpatialLayerInfo *)layer->layerinfo;
3484
3485 layerinfo->paging = value;
3486
3487 return;
3488 }
3489
msOracleSpatialLayerTranslateFilter(layerObj * layer,expressionObj * filter,char * filteritem)3490 int msOracleSpatialLayerTranslateFilter(layerObj *layer, expressionObj *filter, char *filteritem)
3491 {
3492 char *native_string = NULL;
3493
3494 int nodeCount = 0;
3495
3496 int function = 0, version = 0, dwithin = 0, regexp_like = 0, case_ins = 0, ieq = 0;
3497 char *table_name;
3498 char *geom_column_name = NULL, *unique = NULL, *srid = NULL, *indexfield=NULL;
3499 char *snippet = NULL;
3500 char *strtmpl = NULL;
3501 double dfDistance = -1;
3502
3503 table_name = (char *) malloc(sizeof(char) * TABLE_NAME_SIZE);
3504 if (!msSplitData( layer->data, &geom_column_name, &table_name, &unique, &srid, &indexfield, &function, &version )) {
3505 msDebug( "Error parsing OracleSpatial DATA variable. Must be: "
3506 "'geometry_column FROM table_name [USING UNIQUE <column> SRID srid# FUNCTION]' or "
3507 "'geometry_column FROM (SELECT stmt) [USING UNIQUE <column> SRID srid# FUNCTION]'. "
3508 "If want to set the FUNCTION statement you can use: FILTER, RELATE, GEOMRELATE or NONE. "
3509 "Your data statement: (%s)"
3510 "in msOracleSpatialLayerGetExtent()\n", layer->data );
3511 msSetError( MS_ORACLESPATIALERR,
3512 "Error parsing OracleSpatial DATA variable. Check server logs. ",
3513 "msOracleSpatialLayerGetExtent()");
3514 /* clean items */
3515
3516 if (geom_column_name) free(geom_column_name);
3517 if (srid) free(srid);
3518 if (unique) free(unique);
3519 if (indexfield) free(indexfield);
3520 free(table_name);
3521
3522 return MS_FAILURE;
3523 }
3524
3525 //msDebug("filter.string was set: %s\n",filter->string);
3526 if(!filter->string) return MS_SUCCESS;
3527
3528 /* for backwards compatibility we continue to allow SQL snippets as a string */
3529
3530 if(filter->type == MS_STRING && filter->string && filteritem) { /* item/value pair */
3531 if(filter->flags & MS_EXP_INSENSITIVE) {
3532 native_string = msStringConcatenate(native_string, "upper(");
3533 native_string = msStringConcatenate(native_string, filteritem);
3534 native_string = msStringConcatenate(native_string, ") = upper(");
3535 } else {
3536 native_string = msStringConcatenate(native_string, filteritem);
3537 native_string = msStringConcatenate(native_string, " = ");
3538 }
3539
3540 strtmpl = "'%s'"; /* don't have a type for the righthand literal so assume it's a string and we quote */
3541 snippet = (char *) msSmallMalloc(strlen(strtmpl) + strlen(filter->string));
3542 sprintf(snippet, strtmpl, filter->string); // TODO: escape filter->string (msPostGISEscapeSQLParam)
3543 native_string = msStringConcatenate(native_string, snippet);
3544 free(snippet);
3545
3546 if(filter->flags & MS_EXP_INSENSITIVE) native_string = msStringConcatenate(native_string, ")");
3547
3548 if (layer->debug>=2) msDebug("msOracleSpatialLayerTranslateFilter: **item/value combo: %s\n", native_string);
3549 } else if(filter->type == MS_REGEX && filter->string && filteritem) { /* item/regex pair */
3550 native_string = msStringConcatenate(native_string, "REGEXP_LIKE (");
3551 native_string = msStrdup(filteritem);
3552 native_string = msStringConcatenate(native_string, ", ");
3553 strtmpl = "'%s'";
3554 snippet = (char *) msSmallMalloc(strlen(strtmpl) + strlen(filter->string));
3555 sprintf(snippet, strtmpl, filter->string); // TODO: escape filter->string (msPostGISEscapeSQLParam)
3556 native_string = msStringConcatenate(native_string, snippet);
3557
3558 if(filter->flags & MS_EXP_INSENSITIVE) {
3559 native_string = msStringConcatenate(native_string, ",i ");
3560 }
3561 native_string = msStringConcatenate(native_string, " )");
3562 free(snippet);
3563 } else if(filter->type == MS_EXPRESSION) {
3564
3565 tokenListNodeObjPtr node = NULL;
3566 //tokenListNodeObjPtr nextNode = NULL;
3567
3568 if (layer->debug>2)
3569 msDebug("msOracleSpatialLayerTranslateFilter. String: %s \n", filter->string);
3570 if (layer->debug>2 && !filter->tokens)
3571 msDebug("msOracleSpatialLayerTranslateFilter. No tokens to process\n");
3572
3573 if(!filter->tokens) return MS_SUCCESS; /* nothing to work from */
3574
3575 if (layer->debug>2)
3576 msDebug("msOracleSpatialLayerTranslateFilter. There are tokens to process \n");
3577
3578 /* try to convert tokens */
3579 node = filter->tokens;
3580 while (node != NULL) {
3581 //msDebug("token count :%i, token is %i\n", nodeCount, node->token);
3582 switch(node->token) {
3583 case '(':
3584 // if (buffer == MS_FALSE)
3585 native_string = msStringConcatenate(native_string, "( ");
3586 break;
3587 case ')':
3588 if (regexp_like == MS_TRUE) {
3589 if (case_ins == MS_TRUE) {
3590 native_string = msStringConcatenate(native_string, ",'i' ");
3591 case_ins = MS_FALSE;
3592 }
3593 regexp_like = MS_FALSE;
3594 native_string = msStringConcatenate(native_string, " )");
3595 msDebug("closing RE comparison\n");
3596 }
3597 native_string = msStringConcatenate(native_string, " )");
3598 break;
3599 case MS_TOKEN_LITERAL_NUMBER:
3600 strtmpl = "%lf";
3601 snippet = (char *) msSmallMalloc(strlen(strtmpl) + 16);
3602 sprintf(snippet, strtmpl, node->tokenval.dblval); // TODO: escape strval
3603 if (dwithin == MS_TRUE) {
3604 dfDistance = node->tokenval.dblval;
3605 if (layer->units == MS_DD){
3606 dfDistance *= msInchesPerUnit(MS_DD,0)/msInchesPerUnit(MS_METERS,0);
3607 //msDebug("Converted Distance value is %lf\n", dfDistance);
3608 }
3609 sprintf(snippet, strtmpl, dfDistance);
3610 native_string = msStringConcatenate(native_string, "'distance=");
3611 native_string = msStringConcatenate(native_string, snippet);
3612 native_string = msStringConcatenate(native_string, "'");
3613 } else {
3614 native_string = msStringConcatenate(native_string, snippet);
3615 }
3616 free(snippet);
3617
3618 break;
3619 case MS_TOKEN_LITERAL_STRING:
3620 strtmpl = "%s";
3621 snippet = (char *) msSmallMalloc(strlen(strtmpl) + strlen(node->tokenval.strval));
3622 sprintf(snippet, strtmpl, node->tokenval.strval); // TODO: escape strval
3623 snippet = msReplaceSubstring(snippet,"'","''");
3624 native_string = msStringConcatenate(native_string, "'");
3625 if (ieq == MS_TRUE) {
3626 native_string = msStringConcatenate(native_string, "^");
3627 }
3628 native_string = msStringConcatenate(native_string, snippet);
3629 if (ieq == MS_TRUE) {
3630 native_string = msStringConcatenate(native_string, "$");
3631 ieq = MS_FALSE;
3632 }
3633 native_string = msStringConcatenate(native_string, "'");
3634 msFree(snippet);
3635 break;
3636 case MS_TOKEN_LITERAL_BOOLEAN:
3637 if(node->tokenval.dblval == MS_TRUE)
3638 native_string = msStringConcatenate(native_string, "'TRUE'");
3639 else
3640 native_string = msStringConcatenate(native_string, "'FALSE'");
3641 break;
3642 case MS_TOKEN_LITERAL_TIME:
3643 {
3644 int resolution = msTimeGetResolution(node->tokensrc);
3645 snippet = (char *) msSmallMalloc(128);
3646 switch(resolution) {
3647 case TIME_RESOLUTION_YEAR:
3648 strtmpl = "to_date('%d-01','YYYY-MM')";
3649 sprintf(snippet, strtmpl, (node->tokenval.tmval.tm_year+1900));
3650 break;
3651 case TIME_RESOLUTION_MONTH:
3652 strtmpl = "to_date('%d-%02d','YYYY-MM')";
3653 sprintf(snippet, strtmpl, (node->tokenval.tmval.tm_year+1900), (node->tokenval.tmval.tm_mon+1));
3654 break;
3655 case TIME_RESOLUTION_DAY:
3656 strtmpl = "to_date('%d-%02d-%02d','YYYY-MM-DD') ";
3657 sprintf(snippet, strtmpl, (node->tokenval.tmval.tm_year+1900), (node->tokenval.tmval.tm_mon+1), node->tokenval.tmval.tm_mday);
3658 break;
3659 case TIME_RESOLUTION_HOUR:
3660 strtmpl = "to_timestamp('%d-%02d-%02d %02d','YYYY-MM-DD hh24')";
3661 sprintf(snippet, strtmpl, (node->tokenval.tmval.tm_year+1900), (node->tokenval.tmval.tm_mon+1), node->tokenval.tmval.tm_mday, node->tokenval.tmval.tm_hour);
3662 break;
3663 case TIME_RESOLUTION_MINUTE:
3664 strtmpl = "to_timestamp('%d-%02d-%02d %02d:%02d','YYYY-MM-DD hh24:mi')";
3665 sprintf(snippet, strtmpl, (node->tokenval.tmval.tm_year+1900), (node->tokenval.tmval.tm_mon+1), node->tokenval.tmval.tm_mday, node->tokenval.tmval.tm_hour, node->tokenval.tmval.tm_min);
3666 break;
3667 case TIME_RESOLUTION_SECOND:
3668 strtmpl = "to_timestamp('%d-%02d-%02d %02d:%02d:%02d','YYYY-MM-DD hh24:mi:ss')";
3669 sprintf(snippet, strtmpl, (node->tokenval.tmval.tm_year+1900), (node->tokenval.tmval.tm_mon+1), node->tokenval.tmval.tm_mday, node->tokenval.tmval.tm_hour, node->tokenval.tmval.tm_min, node->tokenval.tmval.tm_sec);
3670 break;
3671 }
3672 native_string = msStringConcatenate(native_string, snippet);
3673 msFree(snippet);
3674 break;
3675 }
3676 case MS_TOKEN_LITERAL_SHAPE:
3677 native_string = msStringConcatenate(native_string, " SDO_GEOMETRY('");
3678 native_string = msStringConcatenate(native_string, msShapeToWKT(node->tokenval.shpval));
3679 native_string = msStringConcatenate(native_string, "'");
3680 if(srid && strcmp(srid, "") != 0) {
3681 native_string = msStringConcatenate(native_string, ", ");
3682 native_string = msStringConcatenate(native_string, srid);
3683 }
3684 native_string = msStringConcatenate(native_string, ") ");
3685 //msDebug("------> srid node value: %s", node->tokenval.shpval);
3686 break;
3687 case MS_TOKEN_BINDING_DOUBLE:
3688 native_string = msStringConcatenate(native_string, node->tokenval.bindval.item);
3689 break;
3690 case MS_TOKEN_BINDING_INTEGER:
3691 native_string = msStringConcatenate(native_string, node->tokenval.bindval.item);
3692 break;
3693 case MS_TOKEN_BINDING_STRING:
3694 if (node->next->token == MS_TOKEN_COMPARISON_RE || node->next->token == MS_TOKEN_COMPARISON_IRE
3695 || node->next->token == MS_TOKEN_COMPARISON_IEQ ) {
3696 native_string = msStringConcatenate(native_string, "REGEXP_LIKE( ");
3697 }
3698 strtmpl = "%s";
3699 snippet = (char *) msSmallMalloc(strlen(strtmpl) + strlen(node->tokenval.strval));
3700 sprintf(snippet, strtmpl, node->tokenval.strval); // TODO: escape strval (msPostGISEscapeSQLParam)
3701 native_string = msStringConcatenate(native_string, snippet);
3702 free(snippet);
3703 break;
3704 case MS_TOKEN_BINDING_TIME:
3705 native_string = msStringConcatenate(native_string, node->tokenval.bindval.item);
3706 break;
3707 case MS_TOKEN_BINDING_SHAPE:
3708 native_string = msStringConcatenate(native_string, geom_column_name);
3709 break;
3710 case MS_TOKEN_BINDING_MAP_CELLSIZE:
3711 strtmpl = "%lf";
3712 snippet = (char *) msSmallMalloc(strlen(strtmpl) + 16);
3713 sprintf(snippet, strtmpl, layer->map->cellsize);
3714 native_string = msStringConcatenate(native_string, snippet);
3715 free(snippet);
3716 break;
3717 case MS_TOKEN_LOGICAL_AND:
3718 native_string = msStringConcatenate(native_string, " AND ");
3719 break;
3720 case MS_TOKEN_LOGICAL_OR:
3721 native_string = msStringConcatenate(native_string, " OR ");
3722 break;
3723 case MS_TOKEN_LOGICAL_NOT:
3724 native_string = msStringConcatenate(native_string, " NOT ");
3725 break;
3726 case MS_TOKEN_COMPARISON_EQ:
3727 native_string = msStringConcatenate(native_string, " = ");
3728 break;
3729 case MS_TOKEN_COMPARISON_NE:
3730 native_string = msStringConcatenate(native_string, " != ");
3731 break;
3732 case MS_TOKEN_COMPARISON_GT:
3733 native_string = msStringConcatenate(native_string, " > ");
3734 break;
3735 case MS_TOKEN_COMPARISON_GE:
3736 native_string = msStringConcatenate(native_string, " >= ");
3737 break;
3738 case MS_TOKEN_COMPARISON_LT:
3739 native_string = msStringConcatenate(native_string, " < ");
3740 break;
3741 case MS_TOKEN_COMPARISON_LE:
3742 native_string = msStringConcatenate(native_string, " <= ");
3743 break;
3744 case MS_TOKEN_COMPARISON_IEQ:
3745 // this is for case insensitve equals check
3746 msDebug("got a IEQ comparison\n");
3747 regexp_like = MS_TRUE;
3748 case_ins = MS_TRUE;
3749 ieq = MS_TRUE;
3750 native_string = msStringConcatenate(native_string, ", ");
3751 break;
3752 case MS_TOKEN_COMPARISON_RE:
3753 // the regex formats that MS uses as Oracle users are different so just return and eval the regex's in MS
3754 //return MS_SUCCESS;
3755 msDebug("got a RE comparison\n");
3756 regexp_like = MS_TRUE;
3757 native_string = msStringConcatenate(native_string, ", ");
3758 break;
3759 case MS_TOKEN_COMPARISON_IRE:
3760 // the regex formats that MS uses as Oracle users are different so just return and eval the regex's in MS
3761 regexp_like = MS_TRUE;
3762 case_ins = MS_TRUE;
3763 native_string = msStringConcatenate(native_string, ", ");
3764 break;
3765 case MS_TOKEN_COMPARISON_IN:
3766 native_string = msStringConcatenate(native_string, " IN ");
3767 break;
3768 case MS_TOKEN_COMPARISON_LIKE:
3769 native_string = msStringConcatenate(native_string, " LIKE ");
3770 break;
3771 case MS_TOKEN_COMPARISON_INTERSECTS:
3772 native_string = msStringConcatenate(native_string, " ST_INTERSECTS ");
3773 break;
3774 case MS_TOKEN_COMPARISON_DISJOINT:
3775 native_string = msStringConcatenate(native_string, " NOT ST_INTERSECTS ");
3776 break;
3777 case MS_TOKEN_COMPARISON_TOUCHES:
3778 native_string = msStringConcatenate(native_string, " ST_TOUCH ");
3779 break;
3780 case MS_TOKEN_COMPARISON_OVERLAPS:
3781 native_string = msStringConcatenate(native_string, " ST_OVERLAPS ");
3782 break;
3783 case MS_TOKEN_COMPARISON_CROSSES:
3784 native_string = msStringConcatenate(native_string, " SDO_OVERLAPBDYDISJOINT ");
3785 break;
3786 case MS_TOKEN_COMPARISON_WITHIN:
3787 native_string = msStringConcatenate(native_string, " ST_INSIDE ");
3788 break;
3789 case MS_TOKEN_COMPARISON_CONTAINS:
3790 native_string = msStringConcatenate(native_string, " SDO_CONTAINS ");
3791 break;
3792 case MS_TOKEN_COMPARISON_EQUALS:
3793 native_string = msStringConcatenate(native_string, " SDO_EQUAL ");
3794 break;
3795 case MS_TOKEN_COMPARISON_BEYOND:
3796 //support for the wfs case
3797 dwithin = MS_TRUE;
3798 native_string = msStringConcatenate(native_string, "NOT SDO_WITHIN_DISTANCE ");
3799 break;
3800 case MS_TOKEN_COMPARISON_DWITHIN:
3801 dwithin = MS_TRUE;
3802 native_string = msStringConcatenate(native_string, "SDO_WITHIN_DISTANCE ");
3803 break;
3804 case MS_TOKEN_FUNCTION_LENGTH:
3805 break;
3806 case MS_TOKEN_FUNCTION_TOSTRING:
3807 break;
3808 case MS_TOKEN_FUNCTION_COMMIFY:
3809 break;
3810 case MS_TOKEN_FUNCTION_AREA:
3811 native_string = msStringConcatenate(native_string, "SDO_GEOM.SDO_AREA ");
3812 break;
3813 case MS_TOKEN_FUNCTION_ROUND:
3814 native_string = msStringConcatenate(native_string, "ROUND ");
3815 break;
3816 case MS_TOKEN_FUNCTION_FROMTEXT:
3817 native_string = msStringConcatenate(native_string, "SDO_GEOMETRY ");
3818 break;
3819 case MS_TOKEN_FUNCTION_BUFFER:
3820 // native_string = msStringConcatenate(native_string, " SDO_BUFFER ");
3821 //buffer = MS_TRUE;
3822 break;
3823 case MS_TOKEN_FUNCTION_DIFFERENCE:
3824 native_string = msStringConcatenate(native_string, "ST_DIFFERENCE ");
3825 break;
3826 case MS_TOKEN_FUNCTION_SIMPLIFY:
3827 native_string = msStringConcatenate(native_string, "SDO_UTIL.SIMPLIFY ");
3828 break;
3829 case MS_TOKEN_FUNCTION_SIMPLIFYPT:
3830 break;
3831 case MS_TOKEN_FUNCTION_GENERALIZE:
3832 native_string = msStringConcatenate(native_string, "SDO_UTIL.SIMPLIFY ");
3833 break;
3834 case ',':
3835 native_string = msStringConcatenate(native_string, ",");
3836 break;
3837 case '~':
3838 break;
3839 default:
3840 fprintf(stderr, "Translation to native SQL failed.\n");
3841 msFree(native_string);
3842 if (layer->debug) {
3843 msDebug("Token not caught, exiting: Token is %i\n", node->token);
3844 }
3845
3846 return MS_SUCCESS; /* not an error */
3847 }
3848 nodeCount++;
3849 node = node->next;
3850
3851 //fprintf(stderr, "native filter: %s\n", native_string);
3852 }
3853
3854 filter->native_string = msStrdup(native_string);
3855 if (layer->debug>=4)
3856 msDebug("total filter tokens are %i\n,", nodeCount);
3857 msFree(native_string);
3858 }
3859 return MS_SUCCESS;
3860 }
3861
3862
3863 #else
3864 /* OracleSpatial "not-supported" procedures */
3865
msOracleSpatialLayerOpen(layerObj * layer)3866 int msOracleSpatialLayerOpen(layerObj *layer)
3867 {
3868 msSetError( MS_ORACLESPATIALERR, "OracleSpatial is not supported", "msOracleSpatialLayerOpen()" );
3869 return MS_FAILURE;
3870 }
3871
msOracleSpatialLayerIsOpen(layerObj * layer)3872 int msOracleSpatialLayerIsOpen(layerObj *layer)
3873 {
3874 msSetError( MS_ORACLESPATIALERR, "OracleSpatial is not supported", "msOracleSpatialLayerIsOpen()" );
3875 return MS_FALSE;
3876 }
3877
msOracleSpatialLayerClose(layerObj * layer)3878 int msOracleSpatialLayerClose(layerObj *layer)
3879 {
3880 msSetError( MS_ORACLESPATIALERR, "OracleSpatial is not supported", "msOracleSpatialLayerClose()" );
3881 return MS_FAILURE;
3882 }
3883
msOracleSpatialLayerWhichShapes(layerObj * layer,rectObj rect,int isQuery)3884 int msOracleSpatialLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery)
3885 {
3886 msSetError( MS_ORACLESPATIALERR, "OracleSpatial is not supported", "msOracleSpatialLayerWhichShapes()" );
3887 return MS_FAILURE;
3888 }
3889
msOracleSpatialLayerNextShape(layerObj * layer,shapeObj * shape)3890 int msOracleSpatialLayerNextShape(layerObj *layer, shapeObj *shape)
3891 {
3892 msSetError( MS_ORACLESPATIALERR, "OracleSpatial is not supported", "msOracleSpatialLayerNextShape()" );
3893 return MS_FAILURE;
3894 }
3895
msOracleSpatialLayerGetItems(layerObj * layer)3896 int msOracleSpatialLayerGetItems(layerObj *layer)
3897 {
3898 msSetError( MS_ORACLESPATIALERR, "OracleSpatial is not supported", "msOracleSpatialLayerGetItems()" );
3899 return MS_FAILURE;
3900 }
3901
msOracleSpatialLayerGetShape(layerObj * layer,shapeObj * shape,resultObj * record)3902 int msOracleSpatialLayerGetShape( layerObj *layer, shapeObj *shape, resultObj *record )
3903 {
3904 msSetError( MS_ORACLESPATIALERR, "OracleSpatial is not supported", "msOracleSpatialLayerGetShape()" );
3905 return MS_FAILURE;
3906 }
3907
msOracleSpatialLayerGetExtent(layerObj * layer,rectObj * extent)3908 int msOracleSpatialLayerGetExtent(layerObj *layer, rectObj *extent)
3909 {
3910 msSetError( MS_ORACLESPATIALERR, "OracleSpatial is not supported", "msOracleSpatialLayerGetExtent()" );
3911 return MS_FAILURE;
3912 }
3913
msOracleSpatialLayerInitItemInfo(layerObj * layer)3914 int msOracleSpatialLayerInitItemInfo(layerObj *layer)
3915 {
3916 msSetError( MS_ORACLESPATIALERR, "OracleSpatial is not supported", "msOracleSpatialLayerInitItemInfo()" );
3917 return MS_FAILURE;
3918 }
3919
msOracleSpatialLayerFreeItemInfo(layerObj * layer)3920 void msOracleSpatialLayerFreeItemInfo(layerObj *layer)
3921 {
3922 msSetError( MS_ORACLESPATIALERR, "OracleSpatial is not supported", "msOracleSpatialLayerFreeItemInfo()" );
3923 }
3924
msOracleSpatialLayerGetAutoStyle(mapObj * map,layerObj * layer,classObj * c,shapeObj * shape)3925 int msOracleSpatialLayerGetAutoStyle( mapObj *map, layerObj *layer, classObj *c, shapeObj *shape )
3926 {
3927 msSetError( MS_ORACLESPATIALERR, "OracleSpatial is not supported", "msLayerGetAutoStyle()" );
3928 return MS_FAILURE;
3929 }
3930
msOracleSpatialEnablePaging(layerObj * layer,int value)3931 void msOracleSpatialEnablePaging(layerObj *layer, int value)
3932 {
3933 msSetError( MS_ORACLESPATIALERR, "OracleSpatial is not supported", "msLayerEnablePaging()" );
3934 return;
3935 }
3936
msOracleSpatialGetPaging(layerObj * layer)3937 int msOracleSpatialGetPaging(layerObj *layer)
3938 {
3939 msSetError( MS_ORACLESPATIALERR, "OracleSpatial is not supported", "msLayerGetPaging()" );
3940 return MS_FAILURE;
3941 }
3942
msOracleSpatialLayerTranslateFilter(layerObj * layer,expressionObj * filter,char * filteritem)3943 int msOracleSpatialLayerTranslateFilter(layerObj *layer, expressionObj *filter, char *filteritem)
3944 {
3945 msSetError( MS_ORACLESPATIALERR, "OracleSpatial is not supported", "msLayerTranslateFilter()" );
3946 return MS_FAILURE;
3947 }
3948
msOracleSpatialEscapePropertyName(layerObj * layer,const char * pszString)3949 char *msOracleSpatialEscapePropertyName(layerObj *layer, const char* pszString)
3950 {
3951 msSetError( MS_ORACLESPATIALERR, "OracleSpatial is not supported", "msLayerEscapePropertyName()" );
3952 return msStrdup(pszString);
3953 }
3954 #endif
3955
3956 #if defined USE_ORACLE_PLUGIN
3957 MS_DLL_EXPORT int
PluginInitializeVirtualTable(layerVTableObj * vtable,layerObj * layer)3958 PluginInitializeVirtualTable(layerVTableObj* vtable, layerObj *layer)
3959 {
3960 assert(layer != NULL);
3961 assert(vtable != NULL);
3962
3963 vtable->LayerTranslateFilter = msOracleSpatialLayerTranslateFilter;
3964
3965
3966 vtable->LayerInitItemInfo = msOracleSpatialLayerInitItemInfo;
3967 vtable->LayerFreeItemInfo = msOracleSpatialLayerFreeItemInfo;
3968 vtable->LayerOpen = msOracleSpatialLayerOpen;
3969 vtable->LayerIsOpen = msOracleSpatialLayerIsOpen;
3970 vtable->LayerWhichShapes = msOracleSpatialLayerWhichShapes;
3971 vtable->LayerNextShape = msOracleSpatialLayerNextShape;
3972 vtable->LayerGetShape = msOracleSpatialLayerGetShape;
3973 vtable->LayerClose = msOracleSpatialLayerClose;
3974 vtable->LayerGetItems = msOracleSpatialLayerGetItems;
3975 vtable->LayerGetExtent = msOracleSpatialLayerGetExtent;
3976 /* layer->vtable->LayerGetAutoStyle, use default */
3977 /* layer->vtable->LayerApplyFilterToLayer, use default */
3978 vtable->LayerCloseConnection = msOracleSpatialLayerClose;
3979 vtable->LayerApplyFilterToLayer = msLayerApplyCondSQLFilterToLayer;
3980 vtable->LayerSetTimeFilter = msLayerMakeBackticsTimeFilter;
3981 //vtable->LayerSetTimeFilter = msOracleSpatialLayerSetTimeFilter;
3982 //vtable->LayerEscapePropertyName = msOracleSpatialEscapePropertyName;
3983 /* layer->vtable->LayerGetNumFeatures, use default */
3984 /* layer->vtable->LayerGetAutoProjection = msOracleSpatialLayerGetAutoProjection; Disabled until tested */
3985 vtable->LayerEnablePaging = msOracleSpatialEnablePaging;
3986 vtable->LayerGetPaging = msOracleSpatialGetPaging;
3987
3988 return MS_SUCCESS;
3989 }
3990
3991 #else /*if ORACLE_PLUGIN is defined, then this file is not used by libmapserver
3992 and therefre there is no need to include this function */
msOracleSpatialLayerInitializeVirtualTable(layerObj * layer)3993 int msOracleSpatialLayerInitializeVirtualTable(layerObj *layer)
3994 {
3995 assert(layer != NULL);
3996 assert(layer->vtable != NULL);
3997
3998 layer->vtable->LayerTranslateFilter = msOracleSpatialLayerTranslateFilter;
3999
4000
4001 layer->vtable->LayerInitItemInfo = msOracleSpatialLayerInitItemInfo;
4002 layer->vtable->LayerFreeItemInfo = msOracleSpatialLayerFreeItemInfo;
4003 layer->vtable->LayerOpen = msOracleSpatialLayerOpen;
4004 layer->vtable->LayerIsOpen = msOracleSpatialLayerIsOpen;
4005 layer->vtable->LayerWhichShapes = msOracleSpatialLayerWhichShapes;
4006 layer->vtable->LayerNextShape = msOracleSpatialLayerNextShape;
4007 layer->vtable->LayerGetShape = msOracleSpatialLayerGetShape;
4008 /* layer->vtable->LayerGetShapeCount, use default */
4009 layer->vtable->LayerClose = msOracleSpatialLayerClose;
4010 layer->vtable->LayerGetItems = msOracleSpatialLayerGetItems;
4011 layer->vtable->LayerGetExtent = msOracleSpatialLayerGetExtent;
4012 /* layer->vtable->LayerGetAutoStyle, use default */
4013 layer->vtable->LayerCloseConnection = msOracleSpatialLayerClose;
4014 layer->vtable->LayerApplyFilterToLayer = msLayerApplyCondSQLFilterToLayer;
4015 layer->vtable->LayerSetTimeFilter = msLayerMakeBackticsTimeFilter;
4016 //layer->vtable->LayerSetTimeFilter = msOracleSpatialLayerSetTimeFilter;
4017 //layer->vtable->LayerEscapePropertyName = msOracleSpatialEscapePropertyName;
4018 /* layer->vtable->LayerCreateItems, use default */
4019 /* layer->vtable->LayerGetNumFeatures, use default */
4020 /* layer->vtable->LayerGetAutoProjection = msOracleSpatialLayerGetAutoProjection; Disabled until tested */
4021 layer->vtable->LayerEnablePaging = msOracleSpatialEnablePaging;
4022 layer->vtable->LayerGetPaging = msOracleSpatialGetPaging;
4023
4024 return MS_SUCCESS;
4025 }
4026 #endif
4027