这是一个控制台应用程序,包括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));
}
本文地址:http://com.8s8s.com/it/it27898.htm