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