现在的位置: 首页 > 综合 > 正文

Oracle空间数据库的读取与写入

2013年10月08日 ⁄ 综合 ⁄ 共 27698字 ⁄ 字号 评论关闭

这是一个控制台应用程序,包括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 *)&paramp, (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 *)&gtype));

  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));
}

抱歉!评论已关闭.