Example #1
0
OGROCISession * OGRGetOCISession( const char *pszUserid, 
                                  const char *pszPassword,
                                  const char *pszDatabase )

{
    OGROCISession *poSession;

    poSession = new OGROCISession();
    if( poSession->EstablishSession( pszUserid, pszPassword, pszDatabase ) )
        return poSession;
    else
    {
        delete poSession;
        return NULL;
    }
}
int OGROCIWritableLayer::FindFieldIndex( const char *pszFieldName, int bExactMatch )
{
  int iField = GetLayerDefn()->GetFieldIndex( pszFieldName );

  if( !bExactMatch && iField < 0 )
  {
      // try laundered version
      OGROCISession *poSession = poDS->GetSession();
      char *pszSafeName = CPLStrdup( pszFieldName );

      poSession->CleanName( pszSafeName );

      iField = GetLayerDefn()->GetFieldIndex( pszSafeName );

      CPLFree( pszSafeName );
  }

  return iField;
}
OGRErr OGROCIWritableLayer::CreateField( OGRFieldDefn *poFieldIn, int bApproxOK )

{
    OGROCISession      *poSession = poDS->GetSession();
    char                szFieldType[256];
    char                szFieldName[30];     // specify at most 30 characters, see ORA-00972
    OGRFieldDefn        oField( poFieldIn );

/* -------------------------------------------------------------------- */
/*      Do we want to "launder" the column names into Oracle            */
/*      friendly format?                                                */
/* -------------------------------------------------------------------- */
    if( bLaunderColumnNames )
    {
        char    *pszSafeName = CPLStrdup( oField.GetNameRef() );

        poSession->CleanName( pszSafeName );
        oField.SetName( pszSafeName );
        CPLFree( pszSafeName );
    }
    
/* -------------------------------------------------------------------- */
/*      Work out the Oracle type.                                       */
/* -------------------------------------------------------------------- */
    if( oField.GetType() == OFTInteger )
    {
        if( bPreservePrecision && oField.GetWidth() != 0 )
            sprintf( szFieldType, "NUMBER(%d)", oField.GetWidth() );
        else
            strcpy( szFieldType, "INTEGER" );
    }
    else if( oField.GetType() == OFTInteger64 )
    {
        if( bPreservePrecision && oField.GetWidth() != 0 )
            sprintf( szFieldType, "NUMBER(%d)", oField.GetWidth() );
        else
            strcpy( szFieldType, "NUMBER(20)" );
    }
    else if( oField.GetType() == OFTReal )
    {
        if( bPreservePrecision && oField.GetWidth() != 0 )
            sprintf( szFieldType, "NUMBER(%d,%d)", 
                     oField.GetWidth(), oField.GetPrecision() );
        else
            strcpy( szFieldType, "FLOAT(126)" );
    }
    else if( oField.GetType() == OFTString )
    {
        if( oField.GetWidth() == 0 || !bPreservePrecision )
            strcpy( szFieldType, "VARCHAR2(2047)" );
        else
            sprintf( szFieldType, "VARCHAR2(%d)", oField.GetWidth() );
    }
    else if ( oField.GetType() == OFTDate )
    {
        sprintf( szFieldType, "DATE" );
    }
    else if ( oField.GetType() == OFTDateTime )
    {
        sprintf( szFieldType, "TIMESTAMP" );
    }
    else if( bApproxOK )
    {
        oField.SetDefault(NULL);
        CPLError( CE_Warning, CPLE_NotSupported,
                  "Can't create field %s with type %s on Oracle layers.  Creating as VARCHAR.",
                  oField.GetNameRef(),
                  OGRFieldDefn::GetFieldTypeName(oField.GetType()) );
        strcpy( szFieldType, "VARCHAR2(2047)" );
    }
    else
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Can't create field %s with type %s on Oracle layers.",
                  oField.GetNameRef(),
                  OGRFieldDefn::GetFieldTypeName(oField.GetType()) );

        return OGRERR_FAILURE;
    }

/* -------------------------------------------------------------------- */
/*      Create the new field.                                           */
/* -------------------------------------------------------------------- */
    OGROCIStringBuf     oCommand;
    OGROCIStatement     oAddField( poSession );

    oCommand.MakeRoomFor( 70 + strlen(poFeatureDefn->GetName())
                          + strlen(oField.GetNameRef())
                          + strlen(szFieldType)
                          + (oField.GetDefault() ? strlen(oField.GetDefault()) : 0) );

    snprintf( szFieldName, sizeof( szFieldName ), "%s", oField.GetNameRef());
    szFieldName[sizeof( szFieldName )-1] = '\0';
    if ( strlen(oField.GetNameRef()) > sizeof ( szFieldName ) )
    {
        szFieldName[sizeof( szFieldName ) - 1] = '_';
        CPLError( CE_Warning, CPLE_AppDefined, 
                  "Column %s is too long (at most 30 characters). Using %s.", 
                  oField.GetNameRef(), szFieldName );
        oField.SetName(szFieldName);
    }
    sprintf( oCommand.GetString(), "ALTER TABLE %s ADD \"%s\" %s", 
             poFeatureDefn->GetName(), szFieldName, szFieldType);
    if( oField.GetDefault() != NULL && !oField.IsDefaultDriverSpecific() )
    {
        sprintf( oCommand.GetString() + strlen(oCommand.GetString()),
                 " DEFAULT %s", oField.GetDefault() );
    }
    if( !oField.IsNullable() )
        strcat( oCommand.GetString(), " NOT NULL");
    
    if( oAddField.Execute( oCommand.GetString() ) != CE_None )
        return OGRERR_FAILURE;

    poFeatureDefn->AddFieldDefn( &oField );

    return OGRERR_NONE;
}
Example #4
0
int main()

{
    OGROCISession oSession;

    if( !oSession.EstablishSession( "warmerda", "LetoKing", 
                                    "gdal800.dreadfest.com" ) )
    {
        exit( 1 );
    }

    printf( "Session established.\n" );

    OGROCIStatement oStatement( &oSession );

    oStatement.Execute( "DROP TABLE fasttest" );
    oStatement.Execute( "CREATE TABLE fasttest (ifld INTEGER, cfld VARCHAR(4000), shape mdsys.sdo_geometry)" );
//    oStatement.Execute( "CREATE TABLE fasttest (ifld INTEGER, cfld VARCHAR(4000))" );

/* -------------------------------------------------------------------- */
/*      Prepare insert statement.                                       */
/* -------------------------------------------------------------------- */
    
    oStatement.Prepare( "INSERT INTO fasttest VALUES "
                        "(:field_1, :field_2, :field_3)" );
//    oStatement.Prepare( "INSERT INTO fasttest VALUES "
//                        "(:field_1, :field_2)" );
    
/* -------------------------------------------------------------------- */
/*      Do a conventional bind.                                         */
/* -------------------------------------------------------------------- */
    int anField1[100];
    char szField2[100*4];
    int anGType[100];
    int anSRID[100];
    OCIArray *aphElemInfos[100];
    OCIArray *aphOrdinates[100];
    SDO_GEOMETRY_TYPE  aoGeometries[100];
    SDO_GEOMETRY_ind   aoGeometryIndicators[100];
    SDO_GEOMETRY_TYPE *apoGeomMap[100];
    SDO_GEOMETRY_ind  *apoGeomIndMap[100];
    double adfX[100], adfY[100];

    memset( aphElemInfos, 0, sizeof(OCIArray*) * 100 );
    memset( aphOrdinates, 0, sizeof(OCIArray*) * 100 );
    memset( aoGeometries, 0, sizeof(SDO_GEOMETRY) * 100 );
    memset( aoGeometryIndicators, 0, sizeof(SDO_GEOMETRY_ind) * 100 );

    if( oStatement.BindScalar( ":field_1", anField1, 
                              sizeof(int), SQLT_INT ) != CE_None )
        exit( 1 );
    
    if( oStatement.BindScalar( ":field_2", szField2, 4, SQLT_STR ) != CE_None )
        exit( 1 );

    if( oStatement.BindObject( ":field_3", apoGeomMap, oSession.hGeometryTDO, 
                               (void**)apoGeomIndMap ) != CE_None )
        exit( 1 );

/* -------------------------------------------------------------------- */
/*      Create array of arrays for elem_info and ordinates.             */
/* -------------------------------------------------------------------- */
    int iBindRow;
    for( iBindRow = 0; iBindRow < 100; iBindRow++ )
    {
        if( oSession.Failed(
                OCIObjectNew( oSession.hEnv, oSession.hError, 
                              oSession.hSvcCtx, OCI_TYPECODE_VARRAY,
                              oSession.hElemInfoTDO, (dvoid *)NULL, 
                              OCI_DURATION_SESSION,
                              FALSE, (dvoid **) (aphElemInfos + iBindRow)),
                "OCIObjectNew()") )
            exit( 1 );

        if( oSession.Failed(
                OCIObjectNew( oSession.hEnv, oSession.hError, 
                              oSession.hSvcCtx, OCI_TYPECODE_VARRAY,
                              oSession.hOrdinatesTDO, (dvoid *)NULL, 
                              OCI_DURATION_SESSION,
                              FALSE, (dvoid **) (aphOrdinates + iBindRow)),
                "OCIObjectNew()") )
            exit( 1 );
    }

/* -------------------------------------------------------------------- */
/*      Populate VARRAYs                                                */
/* -------------------------------------------------------------------- */
    int iRow;

    for( iRow = 0; iRow < 100; iRow++ )
    {
        anField1[iRow] = iRow;                                         
        sprintf( szField2 + iRow*4, "%3d", iRow );
        anGType[iRow] = 3001;
        anSRID[iRow] = -1;
        adfX[iRow] = 100.0 + iRow;
        adfY[iRow] = 100.0 - iRow;

        //---------------------------------------------------------------
        int anElemInfo[3], nElemInfoCount;
        OCINumber oci_number; 
        int i;
        
        nElemInfoCount = 3;
        anElemInfo[0] = 1;
        anElemInfo[1] = 1;
        anElemInfo[2] = 1;

        // Prepare the VARRAY of ordinate values. 
        for (i = 0; i < nElemInfoCount; i++)
        {
            if( oSession.Failed( 
                OCINumberFromInt( oSession.hError, 
                                  (dvoid *) (anElemInfo + i),
                                  (uword)sizeof(int),
                                  OCI_NUMBER_SIGNED,
                                  &oci_number),
                "OCINumberFromInt") )
                exit( 1 );

            if( oSession.Failed( 
                OCICollAppend( oSession.hEnv, oSession.hError,
                               (dvoid *) &oci_number,
                               (dvoid *)0, aphElemInfos[iRow]),
                "OCICollAppend") )
                exit( 1 );
        }

        //---------------------------------------------------------------
        double adfOrdinates[6];
        int    nOrdCount;

        nOrdCount = 3;
        adfOrdinates[0] = iRow + 100;
        adfOrdinates[1] = iRow - 100;
        adfOrdinates[2] = 0.0;
        adfOrdinates[3] = iRow + 100;
        adfOrdinates[4] = iRow - 100;
        adfOrdinates[5] = 0.0;

        // Prepare the VARRAY of ordinate values. 
        for (i = 0; i < nOrdCount; i++)
        {
            if( oSession.Failed( 
                OCINumberFromReal( oSession.hError, 
                                  (dvoid *) (adfOrdinates + i),
                                  (uword)sizeof(double),
                                  &oci_number),
                "OCINumberFromReal") )
                exit( 1 );

            if( oSession.Failed( 
                OCICollAppend( oSession.hEnv, oSession.hError,
                               (dvoid *) &oci_number,
                               (dvoid *)0, aphOrdinates[iRow]),
                "OCICollAppend") )
                exit( 1 );
        }

        // -------------------------------------------------------------
        SDO_GEOMETRY_TYPE *poGeom = aoGeometries + iRow;
        SDO_GEOMETRY_ind  *poInd = aoGeometryIndicators + iRow;

        poInd->sdo_point._atomic = OCI_IND_NULL;

        if( oSession.Failed( 
                OCINumberFromInt( oSession.hError, 
                                  (dvoid *) (anGType + iRow),
                                  (uword)sizeof(int),
                                  OCI_NUMBER_SIGNED,
                                  &(poGeom->sdo_gtype)),
                "OCINumberFromInt" ) )
            exit( 1 );

        if( oSession.Failed( 
                OCINumberFromInt( oSession.hError, 
                                  (dvoid *) (anSRID + iRow),
                                  (uword)sizeof(int),
                                  OCI_NUMBER_SIGNED,
                                  &(poGeom->sdo_srid)),
                "OCINumberFromInt" ) )
            exit( 1 );

        poGeom->sdo_elem_info = aphElemInfos[iRow];
        poGeom->sdo_ordinates = aphOrdinates[iRow];

        apoGeomMap[iRow] = poGeom;
        apoGeomIndMap[iRow] = poInd;
    }

/* -------------------------------------------------------------------- */
/*      Execute the statement.                                          */
/* -------------------------------------------------------------------- */
    int iGroup;

    for( iGroup = 0; iGroup < 2; iGroup++ )
    {
        if( oSession.Failed( 
                OCIStmtExecute( oSession.hSvcCtx, oStatement.GetStatement(), 
                                oSession.hError, (ub4) 100, (ub4)0, 
                                (OCISnapshot *)NULL, (OCISnapshot *)NULL, 
                                (ub4) OCI_COMMIT_ON_SUCCESS ),
                "OCIStmtExecute" ) )
            exit( 1 );
    }

    printf( "Successful completion\n" );
    exit( 0 );
}
OGRFeatureDefn *
OGROCISelectLayer::ReadTableDefinition( OGROCIStatement *poCommand )

{
    OGROCISession      *poSession = poDS->GetSession();

/* -------------------------------------------------------------------- */
/*      Parse the returned table information.                           */
/* -------------------------------------------------------------------- */
    for( int iParm = 0; TRUE; iParm++ )
    {                                                           
        OGRFieldDefn oField( "", OFTString );
        int          nStatus;
        OCIParam     *hParmDesc;
        ub2          nOCIType;
        ub4          nOCILen;

        nStatus = 
            OCIParamGet( poCommand->GetStatement(), OCI_HTYPE_STMT, 
                         poSession->hError, (dvoid**)&hParmDesc, 
                         (ub4) iParm+1 );

        if( nStatus == OCI_ERROR )
            break;

        if( poSession->GetParmInfo( hParmDesc, &oField, &nOCIType, &nOCILen )
            != CE_None )
            break;

        if( oField.GetType() == OFTBinary && nOCIType == 108 )
        {
            CPLFree( pszGeomName );
            pszGeomName = CPLStrdup( oField.GetNameRef() );
            iGeomColumn = iParm;
            break;
        }
    }

/* -------------------------------------------------------------------- */
/*      Use the schema off the statement.                               */
/* -------------------------------------------------------------------- */
    OGRFeatureDefn *poDefn;

    poDefn = poCommand->GetResultDefn();
    if( iGeomColumn >= 0 )
        poDefn->SetGeomType(wkbUnknown);
    poDefn->Reference();

/* -------------------------------------------------------------------- */
/*      Do we have an FID?                                              */
/* -------------------------------------------------------------------- */
    const char *pszExpectedFIDName = 
        CPLGetConfigOption( "OCI_FID", "OGR_FID" );
    if( poDefn->GetFieldIndex(pszExpectedFIDName) > -1 )
    {
        iFIDColumn = poDefn->GetFieldIndex(pszExpectedFIDName);
        pszFIDName = CPLStrdup(poDefn->GetFieldDefn(iFIDColumn)->GetNameRef());
    }

    if( EQUAL(pszExpectedFIDName, "OGR_FID") && pszFIDName )
    {
        for(int i=0;i<poDefn->GetFieldCount();i++)
        {
            // This is presumably a Integer since we always create Integer64 with a
            // defined precision
            if( poDefn->GetFieldDefn(i)->GetType() == OFTInteger64 &&
                poDefn->GetFieldDefn(i)->GetWidth() == 0 )
            {
                poDefn->GetFieldDefn(i)->SetType(OFTInteger);
            }
        }
    }

    return poDefn;
}