ogrpgtablelayer.cpp
来自「支持各种栅格图像和矢量图像读取的库」· C++ 代码 · 共 1,798 行 · 第 1/4 页
CPP
1,798 行
if( j != 0 ) strcat( pszNeedToFree+nOff, "," ); nOff += strlen(pszNeedToFree+nOff); sprintf( pszNeedToFree+nOff, "%d", panItems[j] ); } strcat( pszNeedToFree+nOff, "}" ); pszStrValue = pszNeedToFree; } // We need special formatting for real list values. if( poFeatureDefn->GetFieldDefn(i)->GetType() == OFTRealList ) { int nCount, nOff = 0, j; const double *padfItems =poFeature->GetFieldAsDoubleList(i,&nCount); pszNeedToFree = (char *) CPLMalloc(nCount * 40 + 10); strcpy( pszNeedToFree, "{" ); for( j = 0; j < nCount; j++ ) { if( j != 0 ) strcat( pszNeedToFree+nOff, "," ); nOff += strlen(pszNeedToFree+nOff); sprintf( pszNeedToFree+nOff, "%.16g", padfItems[j] ); } strcat( pszNeedToFree+nOff, "}" ); pszStrValue = pszNeedToFree; } // Check if date is NULL: 0000-00-00 if( poFeatureDefn->GetFieldDefn(i)->GetType() == OFTDate ) { if( EQUALN( pszStrValue, "0000", 4 ) ) { pszStrValue = "NULL"; bIsDateNull = TRUE; } } if( poFeatureDefn->GetFieldDefn(i)->GetType() != OFTInteger && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTReal && !bIsDateNull ) { int iChar; /* We need to quote and escape string fields. */ osCommand += "'"; for( iChar = 0; pszStrValue[iChar] != '\0'; iChar++ ) { if( poFeatureDefn->GetFieldDefn(i)->GetType() != OFTIntegerList && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTRealList && poFeatureDefn->GetFieldDefn(i)->GetWidth() > 0 && iChar == poFeatureDefn->GetFieldDefn(i)->GetWidth() ) { CPLDebug( "PG", "Truncated %s field value, it was too long.", poFeatureDefn->GetFieldDefn(i)->GetNameRef() ); break; } if( pszStrValue[iChar] == '\\' || pszStrValue[iChar] == '\'' ) { osCommand += '\\'; osCommand += pszStrValue[iChar]; } else { osCommand += pszStrValue[iChar]; } } osCommand += "'"; } else { osCommand += pszStrValue; } if( pszNeedToFree ) CPLFree( pszNeedToFree ); } osCommand += ")";/* -------------------------------------------------------------------- *//* Execute the insert. *//* -------------------------------------------------------------------- */ hResult = PQexec(hPGConn, osCommand); if( PQresultStatus(hResult) != PGRES_COMMAND_OK ) { CPLDebug( "OGR_PG", "PQexec(%s)\n", osCommand.c_str() ); CPLError( CE_Failure, CPLE_AppDefined, "INSERT command for new feature failed.\n%s\nCommand: %s", PQerrorMessage(hPGConn), osCommand.c_str() ); OGRPGClearResult( hResult ); poDS->SoftRollback(); return OGRERR_FAILURE; }#ifdef notdef /* Should we use this oid to get back the FID and assign back to the feature? I think we are supposed to. */ Oid nNewOID = PQoidValue( hResult ); printf( "nNewOID = %d\n", (int) nNewOID );#endif OGRPGClearResult( hResult ); return poDS->SoftCommit();}/************************************************************************//* CreateFeatureViaCopy() *//************************************************************************/OGRErr OGRPGTableLayer::CreateFeatureViaCopy( OGRFeature *poFeature ){ int nCommandBufSize = 4000; /* First process geometry */ OGRGeometry *poGeometry = (OGRGeometry *) poFeature->GetGeometryRef(); char *pszGeom = NULL; if ( NULL != poGeometry ) { poGeometry->closeRings(); poGeometry->setCoordinateDimension( nCoordDimension ); pszGeom = GeometryToHex( poGeometry, nSRSId ); nCommandBufSize = nCommandBufSize + strlen(pszGeom); } char *pszCommand = (char *) CPLMalloc(nCommandBufSize); if ( poGeometry ) { sprintf( pszCommand, "%s", pszGeom); CPLFree( pszGeom ); } else { sprintf( pszCommand, "\\N"); } strcat( pszCommand, "\t" ); /* Next process the field id column */ if( bHasFid && poFeatureDefn->GetFieldIndex( pszFIDColumn ) != -1 ) { /* Set the FID */ if( poFeature->GetFID() != OGRNullFID ) { sprintf( pszCommand + strlen(pszCommand), "%ld ", poFeature->GetFID()); } else { strcat( pszCommand, "\\N" ); } strcat( pszCommand, "\t" ); } /* Now process the remaining fields */ int nOffset = strlen(pszCommand); int nFieldCount = poFeatureDefn->GetFieldCount(); for( int i = 0; i < nFieldCount; i++ ) { const char *pszStrValue = poFeature->GetFieldAsString(i); char *pszNeedToFree = NULL; if( !poFeature->IsFieldSet( i ) ) { strcat( pszCommand, "\\N" ); if( i < nFieldCount - 1 ) strcat( pszCommand, "\t" ); continue; } // We need special formatting for integer list values. if( poFeatureDefn->GetFieldDefn(i)->GetType() == OFTIntegerList ) { int nCount, nOff = 0, j; const int *panItems = poFeature->GetFieldAsIntegerList(i,&nCount); pszNeedToFree = (char *) CPLMalloc(nCount * 13 + 10); strcpy( pszNeedToFree, "{" ); for( j = 0; j < nCount; j++ ) { if( j != 0 ) strcat( pszNeedToFree+nOff, "," ); nOff += strlen(pszNeedToFree+nOff); sprintf( pszNeedToFree+nOff, "%d", panItems[j] ); } strcat( pszNeedToFree+nOff, "}" ); pszStrValue = pszNeedToFree; } // We need special formatting for real list values. if( poFeatureDefn->GetFieldDefn(i)->GetType() == OFTRealList ) { int nCount, nOff = 0, j; const double *padfItems =poFeature->GetFieldAsDoubleList(i,&nCount); pszNeedToFree = (char *) CPLMalloc(nCount * 40 + 10); strcpy( pszNeedToFree, "{" ); for( j = 0; j < nCount; j++ ) { if( j != 0 ) strcat( pszNeedToFree+nOff, "," ); nOff += strlen(pszNeedToFree+nOff); sprintf( pszNeedToFree+nOff, "%.16g", padfItems[j] ); } strcat( pszNeedToFree+nOff, "}" ); pszStrValue = pszNeedToFree; } // Grow the command buffer? if( (int) (strlen(pszStrValue) + strlen(pszCommand+nOffset) + nOffset) > nCommandBufSize-50 ) { nCommandBufSize = strlen(pszCommand) + strlen(pszStrValue) + 10000; pszCommand = (char *) CPLRealloc(pszCommand, nCommandBufSize ); } if( poFeatureDefn->GetFieldDefn(i)->GetType() != OFTInteger && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTReal ) { int iChar; nOffset += strlen(pszCommand+nOffset); for( iChar = 0; pszStrValue[iChar] != '\0'; iChar++ ) { if( poFeatureDefn->GetFieldDefn(i)->GetType() != OFTIntegerList && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTRealList && poFeatureDefn->GetFieldDefn(i)->GetWidth() > 0 && iChar == poFeatureDefn->GetFieldDefn(i)->GetWidth() ) { CPLDebug( "PG", "Truncated %s field value, it was too long.", poFeatureDefn->GetFieldDefn(i)->GetNameRef() ); break; } /* Escape embedded \, \t, \n, \r since they will cause COPY to misinterpret a line of text and thus abort */ if( pszStrValue[iChar] == '\\' || pszStrValue[iChar] == '\t' || pszStrValue[iChar] == '\r' || pszStrValue[iChar] == '\n' ) { pszCommand[nOffset++] = '\\'; } pszCommand[nOffset++] = pszStrValue[iChar]; } pszCommand[nOffset] = '\0';// strcat( pszCommand+nOffset, "'" ); } else { strcat( pszCommand+nOffset, pszStrValue ); } if( pszNeedToFree ) CPLFree( pszNeedToFree ); if( i < nFieldCount - 1 ) strcat( pszCommand, "\t" ); } /* Add end of line marker */ strcat( pszCommand, "\n" ); /* ------------------------------------------------------------ */ /* Execute the copy. */ /* ------------------------------------------------------------ */ PGconn *hPGConn = poDS->GetPGConn(); OGRErr result = OGRERR_NONE; /* This is for postgresql 7.4 and higher */#if !defined(PG_PRE74) int copyResult = PQputCopyData(hPGConn, pszCommand, strlen(pszCommand)); switch (copyResult) { case 0: CPLDebug( "OGR_PG", "PQexec(%s)\n", pszCommand ); CPLError( CE_Failure, CPLE_AppDefined, "Writing COPY data blocked."); result = OGRERR_FAILURE; break; case -1: CPLDebug( "OGR_PG", "PQexec(%s)\n", pszCommand ); CPLError( CE_Failure, CPLE_AppDefined, "%s", PQerrorMessage(hPGConn) ); result = OGRERR_FAILURE; break; }#else /* else defined(PG_PRE74) */ int copyResult = PQputline(hPGConn, pszCommand); if (copyResult == EOF) { CPLDebug( "OGR_PG", "PQexec(%s)\n", pszCommand ); CPLError( CE_Failure, CPLE_AppDefined, "Writing COPY data blocked."); result = OGRERR_FAILURE; } #endif /* end of defined(PG_PRE74) */ /* Free the buffer we allocated before returning */ CPLFree( pszCommand ); return result;}/************************************************************************//* TestCapability() *//************************************************************************/int OGRPGTableLayer::TestCapability( const char * pszCap ){ if ( bUpdateAccess ) { if( EQUAL(pszCap,OLCSequentialWrite) || EQUAL(pszCap,OLCCreateField) ) return TRUE; else if( EQUAL(pszCap,OLCRandomRead) || EQUAL(pszCap,OLCRandomWrite) ) return bHasFid; } return OGRPGLayer::TestCapability( pszCap );}/************************************************************************//* CreateField() *//************************************************************************/OGRErr OGRPGTableLayer::CreateField( OGRFieldDefn *poFieldIn, int bApproxOK ){ PGconn *hPGConn = poDS->GetPGConn(); PGresult *hResult = NULL; CPLString osCommand; char szFieldType[256]; OGRFieldDefn oField( poFieldIn );/* -------------------------------------------------------------------- *//* Do we want to "launder" the column names into Postgres *//* friendly format? *//* -------------------------------------------------------------------- */ if( bLaunderColumnNames ) { char *pszSafeName = poDS->LaunderName( oField.GetNameRef() ); oField.SetName( pszSafeName ); CPLFree( pszSafeName ); if( EQUAL(oField.GetNameRef(),"oid") ) { CPLError( CE_Warning, CPLE_AppDefined, "Renaming field 'oid' to 'oid_' to avoid conflict with internal oid field." ); oField.SetName( "oid_" ); } }/* -------------------------------------------------------------------- *//* Work out the PostgreSQL type. *//* -------------------------------------------------------------------- */ if( oField.GetType() == OFTInteger ) { if( oField.GetWidth() > 0 && bPreservePrecision ) sprintf( szFieldType, "NUMERIC(%d,0)", oField.GetWidth() ); else strcpy( szFieldType, "INTEGER" ); } else if( oField.GetType() == OFTReal ) { if( oField.GetWidth() > 0 && oField.GetPrecision() > 0 && bPreservePrecision ) sprintf( szFieldType, "NUMERIC(%d,%d)", oField.GetWidth(), oField.GetPrecision() ); else strcpy( szFieldType, "FLOAT8" ); } else if( oField.GetType() == OFTString ) { if( oField.GetWidth() == 0 || !bPreservePrecision ) strcpy( szFieldType, "VARCHAR" ); else sprintf( szFieldType, "CHAR(%d)", oField.GetWidth() ); } else if( oField.GetType() == OFTIntegerList ) { strcpy( szFieldType, "INTEGER[]" ); } else if( oField.GetType() == OFTRealList ) { strcpy( szFieldType, "FLOAT8[]" ); } else if( oField.GetType() == OFTDate ) { strcpy( szFieldType, "date" ); } else if( oField.GetType() == OFTTime ) { strcpy( szFieldType, "time" ); } else if( oField.GetType() == OFTDateTime ) { strcpy( szFieldType, "timestamp with time zone" ); } else if( bApproxOK ) { CPLError( CE_Warning, CPLE_NotSupported, "Can't create field %s with type %s on PostgreSQL layers. Creating as VARCHAR.", oField.GetNameRef(), OGRFieldDefn::GetFieldTypeName(oField.GetType()) ); strcpy( szFieldType, "VARCHAR" ); } else { CPLError( CE_Failure, CPLE_NotSupported, "Can't create field %s with type %s on PostgreSQL layers.", oField.GetNameRef(), OGRFieldDefn::GetFieldTypeName(oField.GetType()) ); return OGRERR_FAILURE; }/* -------------------------------------------------------------------- *//* Create the new field. *//* -------------------------------------------------------------------- */ poDS->FlushSoftTransaction();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?