这是一个控制台应用程序,包括3个文件。根据Oracle技术网上的一个C程序改写, 作用:用OCI来读取和写入Oracle空间数据。
//---------------------------------------------- // main.cpp : 定义控制台应用程序的入口点。 //---------------------------------------------- #include "WReadAndWriteGeometry.h"
int _tmain(int argc, _TCHAR* argv[]) { WReadAndWriteGeometry wjj("txk", "mlib", "147"); wjj.read_geometries("B562D8C5E4C81D0", "GEOLOC", "MI_PRINX", 1); return 0; }
//---------------------------------------------- // WReadAndWriteGeometry.h //---------------------------------------------- #if(!defined(WReadAndWriteGeometry_H)) #define WReadAndWriteGeometry_H
#pragma comment( lib, "oci.lib" ) #pragma comment( lib, "ociw32.lib" ) #pragma comment( lib, "oraocci9.lib" )
#ifndef OCI_ORACLE #include <oci.h> #include <oci1.h> #endif
/*--------------------------------------------------------------------------- PUBLIC TYPES AND CONSTANTS ---------------------------------------------------------------------------*/ #define ARRAY_SIZE 32 #define TYPE_OWNER "MDSYS" #define SDO_ORDINATE_ARRAY TYPE_OWNER".SDO_ORDINATE_ARRAY" #define SDO_ELEM_INFO_ARRAY TYPE_OWNER".SDO_ELEM_INFO_ARRAY" #define SDO_GEOMETRY TYPE_OWNER".SDO_GEOMETRY"
/*************************************************************************/ /* Type definitions */ /*************************************************************************/ struct sdo_point_type { OCINumber x; OCINumber y; OCINumber z; }; typedef struct sdo_point_type sdo_point_type;
typedef OCIArray sdo_elem_info_array; typedef OCIArray sdo_ordinate_array;
struct sdo_geometry { OCINumber sdo_gtype; OCINumber sdo_srid; sdo_point_type sdo_point; OCIArray *sdo_elem_info; OCIArray *sdo_ordinates; };
typedef struct sdo_geometry SDO_GEOMETRY_TYPE;
/*** ** Indicator structures for SDO_GEOMETRY_TYPE ***/
struct sdo_point_type_ind { OCIInd _atomic; OCIInd x; OCIInd y; OCIInd z; }; typedef struct sdo_point_type_ind sdo_point_type_ind;
struct SDO_GEOMETRY_ind { OCIInd _atomic; OCIInd sdo_gtype; OCIInd sdo_srid; struct sdo_point_type_ind sdo_point; OCIInd sdo_elem_info; OCIInd sdo_ordinates; }; typedef struct SDO_GEOMETRY_ind SDO_GEOMETRY_ind;
/*************************************************************************/ /* Class definitions */ /*************************************************************************/ class WReadAndWriteGeometry { public: WReadAndWriteGeometry(char *username, char *password,char *connectstring); ~WReadAndWriteGeometry(); void read_geometries (char *table, char *geom_column, char *id_column, int num_dimensions); void write_geometries ();
protected: void checkerr(OCIError *errhp, sword status); void connect(char *username, char *password, char *connectstring); void disconnect(void); OCIType *get_tdo(char *typeName); void process_data(int num_dimensions, char *id_column, int rows_to_process, int *rows_processed);
protected: int sc_ops_geom_null(void); void sc_ops_init_geometry (SDO_GEOMETRY_TYPE *, SDO_GEOMETRY_ind *, int); void sc_ops_get_gtype (void); void sc_ops_get_sdo_point (void); int sc_ops_next_elem (void); ub4 sc_ops_get_element_type (void); void sc_ops_get_type1 (void); void sc_ops_get_type2 (void); void sc_ops_get_type3 (void); void sc_ops_get_type4 (void); void sc_ops_get_type5 (void); ub4 get_interpretation (void); void get_ordinates (int starting_offset, int ending_offset); int get_next_ending_offset (int processing_type_4or5); int get_next_starting_offset (int read_varray);
private: OCIEnv *envhp; /* OCI general handles */ OCIError *errhp;
OCIServer *srvhp; OCISvcCtx *svchp; OCISession *usrhp; OCIStmt *stmthp; OCIDescribe *dschp;
//读GEOMETRY数据时,需要的变量 private: OCINumber global_gid[ARRAY_SIZE]; OCIType *geom_tdo; SDO_GEOMETRY_TYPE *global_geom_obj[ARRAY_SIZE];/* spatial object buffer */ SDO_GEOMETRY_ind *global_geom_ind[ARRAY_SIZE]; /* Object indicator */
//写GEOMETRY数据时,需要的变量 private: OCIType *elem_info_tdo; /* Varrays and the type descriptors */ OCIArray *elem_info; OCIType *ordinates_tdo; OCIArray *ordinates;
private: SDO_GEOMETRY_TYPE *m_geom_obj; SDO_GEOMETRY_ind *m_geom_ind; int global_num_dimensions; int global_elem_index; int global_ending_offset; int global_nelems; int global_nords; int global_first_elem;
}; #endif
//---------------------------------------------- // WReadAndWriteGeometry.cpp //---------------------------------------------- #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <vector> using namespace std;
#include "WReadAndWriteGeometry.h"
static double test_ordinates[] = { 0, 0, 1, 1 };
/******************************************************************************* ** ** Routine: WReadAndWriteGeometry ** ** Description: 构造函数 ** *******************************************************************************/ WReadAndWriteGeometry::WReadAndWriteGeometry(char *username, char *password,char *connectstring) { dschp = NULL; geom_tdo = NULL; elem_info_tdo = NULL; ordinates_tdo = NULL;
global_ending_offset = -1;
for(int i=0;i<ARRAY_SIZE;i++) { global_geom_obj[i] = NULL; global_geom_ind[i] = NULL; }
connect(username, password, connectstring); }
/******************************************************************************* ** ** Routine: ~WReadAndWriteGeometry ** ** Description: 析构函数 ** *******************************************************************************/ WReadAndWriteGeometry::~WReadAndWriteGeometry() { disconnect(); }
/******************************************************************************* ** ** Routine: checkerr ** ** Description: Error message routine ** *******************************************************************************/ void WReadAndWriteGeometry::checkerr(OCIError *errhp, sword status) { text errbuf[512]; sb4 errcode = 0;
switch (status) { case OCI_SUCCESS: break; case OCI_SUCCESS_WITH_INFO: fprintf(stderr, "OCI_SUCCESS_WITH_INFO\n"); break; case OCI_ERROR: OCIErrorGet((dvoid *)errhp, (ub4)1, (text *)NULL, &errcode, errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR); fprintf(stderr, "%.*s\n", 512, errbuf); break; case OCI_NEED_DATA: fprintf(stderr, "OCI_NEED_DATA\n"); break; case OCI_NO_DATA: fprintf(stderr, "OCI_NO_DATA\n"); break; case OCI_INVALID_HANDLE: fprintf(stderr, "OCI_INVALID_HANDLE\n"); break; case OCI_STILL_EXECUTING: fprintf(stderr, "OCI_STILL_EXECUTING\n"); break; case OCI_CONTINUE: fprintf(stderr, "OCI_CONTINUE\n"); break; default: break; }
if (status != OCI_SUCCESS && status != OCI_SUCCESS_WITH_INFO) disconnect(); }
/******************************************************************************* ** ** Routine: connect ** ** Description: Connects to oracle, and set error routine sqlerror. ** *******************************************************************************/ void WReadAndWriteGeometry::connect(char *username, char *password, char *connectstring) {
// int maxsz = 50 ; /* 50% increase ? */ // int optsz = 2048000 ; /* 2000 K bytes */ // int curmaxsz, curoptsz;
/* Allocate and initialize OCI environment handle, envhp */ OCIInitialize((ub4) OCI_OBJECT, (dvoid *)0, (dvoid * (*)(dvoid *,size_t)) 0, (dvoid * (*)(dvoid *, dvoid *, size_t)) 0, (void (*)(dvoid *, dvoid *)) 0 ); OCIEnvInit(&envhp, (ub4)OCI_DEFAULT, (size_t)0, (dvoid **)0);
/* ** Initialize error report handle, errhp ** Initialize sever context handle, srvhp */ OCIHandleAlloc((dvoid *)envhp, (dvoid **)&errhp, (ub4)OCI_HTYPE_ERROR, (size_t)0, (dvoid **)0); OCIHandleAlloc((dvoid *)envhp, (dvoid **)&srvhp, (ub4)OCI_HTYPE_SERVER, (size_t)0, (dvoid **)0); OCIServerAttach(srvhp, errhp, (text *)connectstring, (sb4)strlen(connectstring), (ub4)OCI_DEFAULT);
/* initialize svchp */ OCIHandleAlloc((dvoid *)envhp, (dvoid **)&svchp, (ub4)OCI_HTYPE_SVCCTX, (size_t)0, (dvoid **)0); OCIAttrSet((dvoid *)svchp, (ub4)OCI_HTYPE_SVCCTX, (dvoid *)srvhp, (ub4)0, (ub4)OCI_ATTR_SERVER, errhp);
/* initialize usrhp */ OCIHandleAlloc((dvoid *)envhp, (dvoid **)&usrhp, (ub4)OCI_HTYPE_SESSION, (size_t)0, (dvoid **)0); OCIAttrSet((dvoid *)usrhp, (ub4)OCI_HTYPE_SESSION, (dvoid *)username, (ub4)strlen(username), (ub4)OCI_ATTR_USERNAME, errhp); OCIAttrSet((dvoid *)usrhp, (ub4)OCI_HTYPE_SESSION, (dvoid *)password, (ub4)strlen(password), (ub4)OCI_ATTR_PASSWORD, errhp);
/* session begins */ checkerr(errhp, OCISessionBegin(svchp, errhp, usrhp, OCI_CRED_RDBMS, OCI_DEFAULT)); OCIAttrSet((dvoid *)svchp, (ub4)OCI_HTYPE_SVCCTX, (dvoid *)usrhp, (ub4)0, (ub4)OCI_ATTR_SESSION, errhp);
/* initialize stmthp */ checkerr(errhp, OCIHandleAlloc((dvoid *)envhp, (dvoid **)&stmthp, (ub4)OCI_HTYPE_STMT, (size_t)0, (dvoid **)0));
/* describe spatial object types */ checkerr(errhp, OCIHandleAlloc(envhp, (dvoid **)&dschp, (ub4)OCI_HTYPE_DESCRIBE, (size_t)0, (dvoid **)0));
geom_tdo = get_tdo(SDO_GEOMETRY);
printf ("\nConnected to Oracle.\n"); }
/******************************************************************************* ** ** Routine: disconnect ** ** Description: Disconnect from Oracle ** *******************************************************************************/ void WReadAndWriteGeometry::disconnect(void) { /* finalize type descriptor */ checkerr(errhp, OCIHandleFree((dvoid *)dschp, (ub4)OCI_HTYPE_DESCRIBE));
/* finalize stmthp */ OCIHandleFree((dvoid *)stmthp, (ub4)OCI_HTYPE_STMT);
/* session ends */ OCISessionEnd(svchp, errhp, usrhp, (ub4)OCI_DEFAULT); OCIServerDetach(srvhp, errhp, (ub4)OCI_DEFAULT);
/* finalize svchp, srvhp, and errhp */ OCIHandleFree((dvoid *)svchp, (ub4)OCI_HTYPE_SVCCTX); OCIHandleFree((dvoid *)srvhp, (ub4)OCI_HTYPE_SERVER); OCIHandleFree((dvoid *)errhp, (ub4)OCI_HTYPE_ERROR);
printf ("\nDisconnected from Oracle.\n"); exit(0); }
/****************************************************************************** ** ** Routine: get_tdo ** ** Description: Returns the ** ******************************************************************************/ OCIType *WReadAndWriteGeometry::get_tdo(char *typeName) { OCIParam *paramp = NULL; OCIRef *type_ref = NULL; OCIType *tdo = NULL;
checkerr(errhp, OCIDescribeAny(svchp, errhp, (text *)typeName, (ub4)strlen((char *)typeName), OCI_OTYPE_NAME, (ub1)1, (ub1)OCI_PTYPE_TYPE, dschp)); checkerr(errhp, OCIAttrGet((dvoid *)dschp, (ub4)OCI_HTYPE_DESCRIBE, (dvoid *)¶mp, (ub4 *)0, (ub4)OCI_ATTR_PARAM, errhp)); checkerr(errhp, OCIAttrGet((dvoid *)paramp, (ub4)OCI_DTYPE_PARAM, (dvoid *)&type_ref, (ub4 *)0, (ub4)OCI_ATTR_REF_TDO, errhp)); checkerr(errhp, OCIObjectPin(envhp, errhp, type_ref, (OCIComplexObject *)0, OCI_PIN_ANY, OCI_DURATION_SESSION, OCI_LOCK_NONE, (dvoid **)&tdo)); if (!tdo) { fprintf(stderr, "Null tdo returned for type %s.\n", typeName); disconnect(); }
return tdo; }
/******************************************************************************* ** ** Routine: process_data ** ** Description: Process the data for current host array fetch. ** *******************************************************************************/ void WReadAndWriteGeometry::process_data(int num_dimensions, char *id_column, int rows_to_process, int *rows_processed) { int row; double double_gid;
for (row = 0; row < rows_to_process; row++, (*rows_processed)++) { /* ** Get ID_COLUMN */ checkerr(errhp, OCINumberToReal(errhp, &(global_gid[row]), (uword)sizeof(double), (dvoid *)&double_gid));
printf("\n%s %.5lf\n", id_column, double_gid);
sc_ops_init_geometry (global_geom_obj[row], global_geom_ind[row], num_dimensions);
if (sc_ops_geom_null()) { printf ("OBJECT IS NULL\n"); fflush (stdout); } else { sc_ops_get_gtype (); sc_ops_get_sdo_point ();
/* Loop through and print all the elements for this geometry */ while (sc_ops_next_elem ()) { switch (sc_ops_get_element_type ()) { case 1: sc_ops_get_type1(); break; case 2: sc_ops_get_type2(); break; case 3: sc_ops_get_type3(); break; case 4: sc_ops_get_type4(); break; case 5: sc_ops_get_type5(); break; } }
/* free the spatial object instance */ checkerr(errhp, OCIObjectFree(envhp, errhp, (dvoid *)global_geom_obj[row], (ub2)OCI_OBJECTFREE_FORCE)); global_geom_obj[row] = NULL; } } /* end of for-loop: row */ }
/******************************************************************************* ** ** Routine: read_geometries ** ** Description: ** *******************************************************************************/ void WReadAndWriteGeometry::read_geometries (char *table, char *geom_column, char *id_column, int num_dimensions) { int nrows = 0, rows_fetched = 0, rows_processed = 0, rows_to_process = 0; char query[100]; sword status; boolean has_more_data = TRUE; OCIDefine *defn1p = NULL, *defn2p = NULL;
/* construct query */ sprintf(query, "SELECT %s, %s FROM %s", id_column, geom_column, table);
/* parse query */ checkerr(errhp, OCIStmtPrepare(stmthp, errhp, (text *)query, (ub4)strlen(query), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT));
/* define GID and spatial ADT object */ checkerr(errhp, OCIDefineByPos(stmthp, &defn1p, errhp, (ub4)1, (dvoid *)global_gid, (sb4)sizeof(OCINumber), SQLT_VNU, (dvoid *)0, (ub2 *)0, (ub2 *)0, (ub4)OCI_DEFAULT));
checkerr(errhp, OCIDefineByPos(stmthp, &defn2p, errhp, (ub4)2, (dvoid *)0, (sb4)0, SQLT_NTY, (dvoid *)0, (ub2 *)0, (ub2 *)0, (ub4)OCI_DEFAULT));
checkerr(errhp, OCIDefineObject(defn2p, errhp, geom_tdo, (dvoid **)global_geom_obj, (ub4 *)0, (dvoid **)global_geom_ind, (ub4 *)0));
/* execute */ status = OCIStmtExecute(svchp, stmthp, errhp, (ub4)ARRAY_SIZE, (ub4)0, (OCISnapshot *)NULL, (OCISnapshot *)NULL, (ub4)OCI_DEFAULT);
if (status == OCI_SUCCESS_WITH_INFO || status == OCI_NO_DATA) has_more_data = FALSE; else { has_more_data = TRUE; checkerr(errhp, status); }
/* process data */ checkerr(errhp, OCIAttrGet((dvoid *)stmthp, (ub4)OCI_HTYPE_STMT, (dvoid *)&rows_fetched, (ub4 *)0, (ub4)OCI_ATTR_ROW_COUNT, errhp)); rows_to_process = rows_fetched - rows_processed;
process_data(num_dimensions, id_column, rows_to_process, &rows_processed);
while (has_more_data) { status = OCIStmtFetch(stmthp, errhp, (ub4)ARRAY_SIZE, (ub2)OCI_FETCH_NEXT, (ub4)OCI_DEFAULT);
if (status != OCI_SUCCESS) has_more_data = FALSE;
/* process data */ checkerr(errhp, OCIAttrGet((dvoid *)stmthp, (ub4)OCI_HTYPE_STMT, (dvoid *)&rows_fetched, (ub4 *)0, (ub4)OCI_ATTR_ROW_COUNT, errhp)); rows_to_process = rows_fetched - rows_processed;
process_data(num_dimensions, id_column, rows_to_process, &rows_processed); }
if (status != OCI_SUCCESS_WITH_INFO && status != OCI_NO_DATA) checkerr(errhp, status); }
/******************************************************************************* ** ** Routine: sc_ops_geom_null ** ** Description: Retruns 1 if the geometry object is NULL. ** *******************************************************************************/ int WReadAndWriteGeometry::sc_ops_geom_null (void)
{ return (m_geom_ind->_atomic == OCI_IND_NULL); }
/******************************************************************************* ** ** Routine: sc_ops_init_geometry ** ** Description: Initializaton routine. ** This must be called for a geometry before you call any ** any other routines in sc_ops... ** *******************************************************************************/ void WReadAndWriteGeometry::sc_ops_init_geometry (SDO_GEOMETRY_TYPE *geom, SDO_GEOMETRY_ind *geom_ind, int num_dimensions)
{ m_geom_obj = geom; m_geom_ind = geom_ind; if (!sc_ops_geom_null()) { /* Get the size of the sdo_elem_info array */ checkerr(errhp, OCICollSize(envhp, errhp, ( OCIColl *)(m_geom_obj->sdo_elem_info), &global_nelems));
/* Get the size of the ordinates array */ checkerr(errhp, OCICollSize(envhp, errhp, (OCIColl *)(m_geom_obj->sdo_ordinates), &global_nords));
global_elem_index = 0; global_first_elem = 1; global_ending_offset = -1; global_num_dimensions = num_dimensions; } }
/******************************************************************************* ** ** Routine: sc_ops_get_gtype ** ** Description: Prints the gtype field. ** *******************************************************************************/ void WReadAndWriteGeometry::sc_ops_get_gtype (void)
{ int gtype;
checkerr(errhp, OCINumberToInt(errhp, &(m_geom_obj->sdo_gtype), (uword)sizeof(int), OCI_NUMBER_SIGNED, (dvoid *)>ype));
printf("-- gtype: %d \n", gtype); }
/******************************************************************************* ** ** Routine: sc_ops_get_sdo_point ** ** Description: Prints the SDO_POINT field. ** Routine checks for NULL sdo_point field and ** NULL x, y and z fields. ** *******************************************************************************/ void WReadAndWriteGeometry::sc_ops_get_sdo_point (void)
{ double x, y, z;
if (m_geom_ind->sdo_point._atomic == OCI_IND_NOTNULL) { if (m_geom_ind->sdo_point.x == OCI_IND_NOTNULL) { checkerr(errhp, OCINumberToReal(errhp, &(m_geom_obj->sdo_point.x), (uword)sizeof(double), (dvoid *)&x));
printf("-- sdo_point.X: %.9lf \n", x); }
if (m_geom_ind->sdo_point.y == OCI_IND_NOTNULL) { checkerr(errhp, OCINumberToReal(errhp, &(m_geom_obj->sdo_point.y), (uword)sizeof(double), (dvoid *)&y));
printf("-- sdo_point.Y: %.9lf \n", y); }
if (m_geom_ind->sdo_point.z == OCI_IND_NOTNULL) { checkerr(errhp, OCINumberToReal(errhp, &(m_geom_obj->sdo_point.z), (uword)sizeof(double), (dvoid *)&z));
printf("-- sdo_point.Z: %.9lf \n", z); } } else printf ("-- sdo_point IS NULL\n"); }
/******************************************************************************* ** ** Routine: sc_ops_next_elem ** ** Description: Go to the next element in this geometry. ** Returns 1 if there are more elements. ** Returns 0 if there are no more elements. ** *******************************************************************************/ int WReadAndWriteGeometry::sc_ops_next_elem (void)
{ int more_elems = 1;
if (global_first_elem) global_first_elem = 0; else global_elem_index = global_elem_index + 3;
return global_elem_index < global_nelems; }
/******************************************************************************* ** ** Routine: sc_ops_get_element_type ** ** Description: Prints the element_type for current element. ** *******************************************************************************/ ub4 WReadAndWriteGeometry::sc_ops_get_element_type ()
{ boolean exists; OCINumber *oci_number; ub4 element_type;
checkerr(errhp, OCICollGetElem(envhp, errhp, (OCIColl *)(m_geom_obj->sdo_elem_info), (sb4)(global_elem_index + 1), (boolean *)&exists, (dvoid **)&oci_number, (dvoid **)0)); checkerr(errhp, OCINumberToInt(errhp, oci_number, (uword)sizeof(ub4), OCI_NUMBER_UNSIGNED, (dvoid *)&element_type));
printf("-- element type: %u \n", element_type); fflush (stdout);
return element_type; }
/******************************************************************************* ** ** Routine: get_interpretation ** ** Description: Prints the interpretation field for current element. ** *******************************************************************************/ ub4 WReadAndWriteGeometry::get_interpretation (void)
{ boolean exists; OCINumber *oci_number; ub4 interpretation;
checkerr(errhp, OCICollGetElem(envhp, errhp, (OCIColl *)(m_geom_obj->sdo_elem_info), (sb4)(global_elem_index + 2), (boolean *)&exists, (dvoid **)&oci_number, (dvoid **)0));
checkerr(errhp, OCINumberToInt(errhp, oci_number, (uword)sizeof(ub4), OCI_NUMBER_UNSIGNED, (dvoid *)&interpretation));
printf("-- interpretation: %u \n", interpretation); fflush(stdout);
return interpretation; }
/******************************************************************************* ** ** Routine: get_ordinates ** ** Description: Prints ordinates out of the ordinates array. ** *******************************************************************************/ void WReadAndWriteGeometry::get_ordinates (int starting_offset, int ending_offset)
{ int col; boolean exists; OCINumber *oci_number; double double_val;
/* ** Get ordinates for the current element. */ for (col = starting_offset; col <= ending_offset; col++) { checkerr(errhp, OCICollGetElem(envhp, errhp, (OCIColl *)(m_geom_obj->sdo_ordinates), (sb4)col, (boolean *)&exists, (dvoid **)&oci_number, (dvoid **)0)); checkerr(errhp, OCINumberToReal(errhp, oci_number, (uword)sizeof(double), (dvoid *)&double_val)); if ((col % global_num_dimensions) == 0) printf("%.9lf", double_val); else printf(", %.9lf", double_val);
if ((col % global_num_dimensions) == (global_num_dimensions - 1)) printf("\n"); } /* end for */
printf("\n"); }
/******************************************************************************* ** ** Routine: get_next_ending_offset ** ** Description: Returns the ending offset of current element. ** *******************************************************************************/ int WReadAndWriteGeometry::get_next_ending_offset (int processing_type_4or5)
{ boolean exists; OCINumber *oci_number; int ending_offset;
/* last element? */ if (global_elem_index == global_nelems - 3) ending_offset = global_nords; else { checkerr(errhp, OCICollGetElem(envhp, errhp, (OCIColl *)(m_geom_obj->sdo_elem_info), (sb4)(global_elem_index + 3), (boolean *)&exists, (dvoid **)&oci_number, (dvoid **)0)); checkerr(errhp, OCINumberToInt(errhp, oci_number, (uword)sizeof(int), OCI_NUMBER_SIGNED, (dvoid *)&ending_offset));
if (processing_type_4or5) { /* Add 1 to next elements starting offset */ ending_offset++; } else { /* Subtract 1 from next elements starting offset */ ending_offset--; } }
/* shift offsets from 1..n to 0..n-1 */ ending_offset--;
printf("-- ending offset: %d \n", ending_offset+1);
return ending_offset; }
/******************************************************************************* ** ** Routine: get_next_starting_offset ** ** Description: Returns the starting offset of the current element. ** *******************************************************************************/ int WReadAndWriteGeometry::get_next_starting_offset (int read_varray)
{ boolean exists; OCINumber *oci_number; int starting_offset;
/* get the element info structure */ if (read_varray) { /* This is the first element, get the starting offset */ checkerr(errhp, OCICollGetElem(envhp, errhp, (OCIColl *)(m_geom_obj->sdo_elem_info), (sb4)(global_elem_index), (boolean *)&exists, (dvoid **)&oci_number, (dvoid **)0));
/* get starting and ending offsets in ordinate array */ checkerr(errhp, OCINumberToInt(errhp, oci_number, (uword)sizeof(ub4), OCI_NUMBER_SIGNED, (dvoid *)&starting_offset));
/* shift offsets from 1..n to 0..n-1 */ starting_offset--; } else starting_offset = global_ending_offset + 1; printf("-- starting offset: %d \n", starting_offset+1);
return starting_offset; }
/******************************************************************************* ** ** Routine: sc_ops_get_type1 ** ** Description: Print the ordinates for a type1 element. ** *******************************************************************************/ void WReadAndWriteGeometry::sc_ops_get_type1 (void)
{ int i, interp, start, end;
start = get_next_starting_offset (global_ending_offset == -1); end = get_next_ending_offset (0); interp = get_interpretation ();
for (i = 0; i < interp; i++) { get_ordinates (start, start + global_num_dimensions - 1); start = start + global_num_dimensions; } }
/******************************************************************************* ** ** Routine: sc_ops_get_type2 ** ** Description: Print the ordinates for a type2 element. ** *******************************************************************************/ void WReadAndWriteGeometry::sc_ops_get_type2 (void)
{ int interp = get_interpretation ();
get_ordinates (get_next_starting_offset(global_ending_offset == -1), get_next_ending_offset (0)); }
/******************************************************************************* ** ** Routine: sc_ops_get_type3 ** ** Description: Print the ordinates for a type3 element. ** *******************************************************************************/ void WReadAndWriteGeometry::sc_ops_get_type3 (void)
{ int interp = get_interpretation (), start = get_next_starting_offset(global_ending_offset == -1), end = get_next_ending_offset(0);
if (interp == 3) /* Rectangle, 2 po;ints */ get_ordinates (start, start + global_num_dimensions * 2 - 1);
else if (interp == 4) /* Circle, 3 points */ get_ordinates (start, start + global_num_dimensions * 3 - 1);
else if (interp == 1 || interp == 2) /* interpretation 1 or 2 */ get_ordinates (start, end); }
/******************************************************************************* ** ** Routine: sc_ops_get_type4 ** ** Description: Print the ordinates for a type4 element. ** *******************************************************************************/ void WReadAndWriteGeometry::sc_ops_get_type4 (void)
{ int interp = get_interpretation (), start, end, i;
for (i = 0; i < interp; i++) { global_elem_index = global_elem_index + 3; start = get_next_starting_offset(-1); if (i == interp - 1) end = get_next_ending_offset(0); else end = get_next_ending_offset(1);
get_ordinates (start, end); } }
/******************************************************************************* ** ** Routine: sc_ops_get_type5 ** ** Description: Print the ordinates for a type5 element. ** *******************************************************************************/ void WReadAndWriteGeometry::sc_ops_get_type5 (void)
{ int interp = get_interpretation (), start, end, i;
for (i = 0; i < interp; i++) { global_elem_index = global_elem_index + 3; start = get_next_starting_offset(-1); if (i == interp - 1) end = get_next_ending_offset(0); else end = get_next_ending_offset(1);
get_ordinates (start, end); } }
/******************************************************************************* ** ** Routine: write_geometries ** ** Description: ** *******************************************************************************/ void WReadAndWriteGeometry::write_geometries () { int i; int starting_offset = 1; int element_type = 2; int interpretation = 1; OCINumber oci_number; OCIBind *bnd1p = NULL, *bnd2p = NULL; char query[500];
for (i = 0; i < 1002; i++) { checkerr(errhp, OCINumberFromReal(errhp, (dvoid *)&(test_ordinates[i]), (uword)sizeof(double),&oci_number));
checkerr(errhp, OCICollAppend(envhp, errhp, (dvoid *) &oci_number, (dvoid *)0, (OCIColl *)ordinates)); }
checkerr(errhp, OCINumberFromInt(errhp, (dvoid *)&starting_offset, (uword)sizeof(ub4), OCI_NUMBER_UNSIGNED, &oci_number)); checkerr(errhp, OCICollAppend(envhp, errhp, (dvoid *)&oci_number, (dvoid *)0, (OCIColl *)elem_info));
checkerr(errhp, OCINumberFromInt(errhp, (dvoid *)&element_type, (uword)sizeof(ub4), OCI_NUMBER_UNSIGNED, &oci_number)); checkerr(errhp, OCICollAppend(envhp, errhp, (dvoid *)&oci_number, (dvoid *)0, (OCIColl *)elem_info));
checkerr(errhp, OCINumberFromInt(errhp, (dvoid *)&interpretation, (uword)sizeof(ub4), OCI_NUMBER_UNSIGNED, &oci_number)); checkerr(errhp, OCICollAppend(envhp, errhp, (dvoid *)&oci_number, (dvoid *)0, (OCIColl *)elem_info));
sprintf(query, "INSERT INTO %s (gid, %s) " "VALUES (1, %s(4, NULL, NULL, :elem_info, :ordinates))", "test_insert", "geometry", SDO_GEOMETRY);
checkerr(errhp, OCIStmtPrepare(stmthp, errhp, (text *)query, (ub4)strlen(query), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT));
/* bind info_obj varray object */ checkerr(errhp, OCIBindByName(stmthp, &bnd1p, errhp, (text *)":elem_info", (sb4)-1, (dvoid *)0, (sb4)0, SQLT_NTY, (dvoid *)0, (ub2 *)0, (ub2 *)0, (ub4)0, (ub4 *)0, (ub4)OCI_DEFAULT)); checkerr(errhp, OCIBindObject(bnd1p, errhp, elem_info_tdo, (dvoid **)&elem_info, (ub4 *)0, (dvoid **)0, (ub4 *)0)); /* bind coordinate varray object */ checkerr(errhp, OCIBindByName(stmthp, &bnd2p, errhp, (text *)":ordinates", (sb4)-1, (dvoid *)0, (sb4)0, SQLT_NTY, (dvoid *)0, (ub2 *)0, (ub2 *)0, (ub4)0, (ub4 *)0, (ub4)OCI_DEFAULT)); checkerr(errhp, OCIBindObject(bnd2p, errhp, ordinates_tdo, (dvoid **)&ordinates, (ub4 *)0, (dvoid **)0, (ub4 *)0));
checkerr(errhp, OCIStmtExecute(svchp, stmthp, errhp, (ub4)1, (ub4)0, (OCISnapshot *)NULL, (OCISnapshot *)NULL, (ub4)OCI_DEFAULT)); } 
|