CPLErr OGRMSSQLSpatialTableLayer::Initialize( const char *pszSchema, const char *pszLayerName, const char *pszGeomCol, int nCoordDimension, int nSRId, OGRwkbGeometryType eType ) { CPLFree( pszFIDColumn ); pszFIDColumn = NULL; /* -------------------------------------------------------------------- */ /* Parse out schema name if present in layer. We assume a */ /* schema is provided if there is a dot in the name, and that */ /* it is in the form <schema>.<tablename> */ /* -------------------------------------------------------------------- */ this->pszLayerName = CPLStrdup(pszLayerName); const char *pszDot = strstr(pszLayerName,"."); if( pszDot != NULL ) { pszTableName = CPLStrdup(pszDot + 1); pszSchemaName = CPLStrdup(pszLayerName); pszSchemaName[pszDot - pszLayerName] = '\0'; } else { pszTableName = CPLStrdup(pszLayerName); pszSchemaName = CPLStrdup(pszSchema); } /* -------------------------------------------------------------------- */ /* Have we been provided a geometry column? */ /* -------------------------------------------------------------------- */ CPLFree( pszGeomColumn ); if( pszGeomCol == NULL ) pszGeomColumn = NULL; else pszGeomColumn = CPLStrdup( pszGeomCol ); eGeomType = eType; /* -------------------------------------------------------------------- */ /* Try to find out the spatial reference */ /* -------------------------------------------------------------------- */ nSRSId = nSRId; if (nSRSId < 0) nSRSId = FetchSRSId(); GetSpatialRef(); return CE_None; }
CPLErr OGRMSSQLSpatialTableLayer::Initialize( const char *pszSchema, const char *pszLayerName, const char *pszGeomCol, int nCoordDimension, int nSRId, OGRwkbGeometryType eType ) { CPLODBCSession *poSession = poDS->GetSession(); CPLFree( pszFIDColumn ); pszFIDColumn = NULL; /* -------------------------------------------------------------------- */ /* Parse out schema name if present in layer. We assume a */ /* schema is provided if there is a dot in the name, and that */ /* it is in the form <schema>.<tablename> */ /* -------------------------------------------------------------------- */ const char *pszDot = strstr(pszLayerName,"."); if( pszDot != NULL ) { pszTableName = CPLStrdup(pszDot + 1); pszSchemaName = CPLStrdup(pszLayerName); pszSchemaName[pszDot - pszLayerName] = '\0'; } else { pszTableName = CPLStrdup(pszLayerName); pszSchemaName = CPLStrdup(pszSchema); } /* -------------------------------------------------------------------- */ /* Do we have a simple primary key? */ /* -------------------------------------------------------------------- */ CPLODBCStatement oGetKey( poSession ); if( oGetKey.GetPrimaryKeys( pszTableName, poDS->GetCatalog(), pszSchemaName ) && oGetKey.Fetch() ) { pszFIDColumn = CPLStrdup(oGetKey.GetColData( 3 )); if( oGetKey.Fetch() ) // more than one field in key! { CPLFree( pszFIDColumn ); pszFIDColumn = NULL; CPLDebug( "OGR_MSSQLSpatial", "Table %s has multiple primary key fields, " "ignoring them all.", pszTableName ); } } /* -------------------------------------------------------------------- */ /* Have we been provided a geometry column? */ /* -------------------------------------------------------------------- */ CPLFree( pszGeomColumn ); if( pszGeomCol == NULL ) pszGeomColumn = NULL; else pszGeomColumn = CPLStrdup( pszGeomCol ); /* -------------------------------------------------------------------- */ /* Get the column definitions for this table. */ /* -------------------------------------------------------------------- */ CPLODBCStatement oGetCol( poSession ); CPLErr eErr; if( !oGetCol.GetColumns( pszTableName, poDS->GetCatalog(), pszSchemaName ) ) return CE_Failure; eErr = BuildFeatureDefn( pszLayerName, &oGetCol ); if( eErr != CE_None ) return eErr; poFeatureDefn->SetGeomType(eType); if( poFeatureDefn->GetFieldCount() == 0 && pszFIDColumn == NULL && pszGeomColumn == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "No column definitions found for table '%s', layer not usable.", pszLayerName ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* If we got a geometry column, does it exist? Is it binary? */ /* -------------------------------------------------------------------- */ if( pszGeomColumn != NULL ) { int iColumn = oGetCol.GetColId( pszGeomColumn ); if( iColumn < 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Column %s requested for geometry, but it does not exist.", pszGeomColumn ); CPLFree( pszGeomColumn ); pszGeomColumn = NULL; } else { if ( nGeomColumnType < 0 ) { /* last attempt to identify the geometry column type */ if ( EQUAL(oGetCol.GetColTypeName( iColumn ), "geometry") ) nGeomColumnType = MSSQLCOLTYPE_GEOMETRY; else if ( EQUAL(oGetCol.GetColTypeName( iColumn ), "geography") ) nGeomColumnType = MSSQLCOLTYPE_GEOGRAPHY; else if ( EQUAL(oGetCol.GetColTypeName( iColumn ), "varchar") ) nGeomColumnType = MSSQLCOLTYPE_TEXT; else if ( EQUAL(oGetCol.GetColTypeName( iColumn ), "nvarchar") ) nGeomColumnType = MSSQLCOLTYPE_TEXT; else if ( EQUAL(oGetCol.GetColTypeName( iColumn ), "text") ) nGeomColumnType = MSSQLCOLTYPE_TEXT; else if ( EQUAL(oGetCol.GetColTypeName( iColumn ), "ntext") ) nGeomColumnType = MSSQLCOLTYPE_TEXT; else if ( EQUAL(oGetCol.GetColTypeName( iColumn ), "image") ) nGeomColumnType = MSSQLCOLTYPE_BINARY; else { CPLError( CE_Failure, CPLE_AppDefined, "Column type %s is not supported for geometry column.", oGetCol.GetColTypeName( iColumn ) ); CPLFree( pszGeomColumn ); pszGeomColumn = NULL; } } } } /* -------------------------------------------------------------------- */ /* Try to find out the spatial reference */ /* -------------------------------------------------------------------- */ nSRSId = nSRId; if (nSRSId < 0) nSRSId = FetchSRSId(); GetSpatialRef(); return CE_None; }
OGRLayer * OGRMSSQLSpatialDataSource::CreateLayer( const char * pszLayerName, OGRSpatialReference *poSRS, OGRwkbGeometryType eType, char ** papszOptions ) { char *pszTableName = NULL; char *pszSchemaName = NULL; const char *pszGeomType = NULL; const char *pszGeomColumn = NULL; int nCoordDimension = 3; /* determine the dimension */ if( eType == wkbFlatten(eType) ) nCoordDimension = 2; if( CSLFetchNameValue( papszOptions, "DIM") != NULL ) nCoordDimension = atoi(CSLFetchNameValue( papszOptions, "DIM")); /* MSSQL Schema handling: Extract schema name from input layer name or passed with -lco SCHEMA. Set layer name to "schema.table" or to "table" if schema is not specified */ const char* pszDotPos = strstr(pszLayerName,"."); if ( pszDotPos != NULL ) { int length = pszDotPos - pszLayerName; pszSchemaName = (char*)CPLMalloc(length+1); strncpy(pszSchemaName, pszLayerName, length); pszSchemaName[length] = '\0'; if( CSLFetchBoolean(papszOptions,"LAUNDER", TRUE) ) pszTableName = LaunderName( pszDotPos + 1 ); //skip "." else pszTableName = CPLStrdup( pszDotPos + 1 ); //skip "." } else { pszSchemaName = NULL; if( CSLFetchBoolean(papszOptions,"LAUNDER", TRUE) ) pszTableName = LaunderName( pszLayerName ); //skip "." else pszTableName = CPLStrdup( pszLayerName ); //skip "." } if( CSLFetchNameValue( papszOptions, "SCHEMA" ) != NULL ) { CPLFree(pszSchemaName); pszSchemaName = CPLStrdup(CSLFetchNameValue( papszOptions, "SCHEMA" )); } if (pszSchemaName == NULL) pszSchemaName = CPLStrdup("dbo"); /* -------------------------------------------------------------------- */ /* Do we already have this layer? If so, should we blow it */ /* away? */ /* -------------------------------------------------------------------- */ int iLayer; for( iLayer = 0; iLayer < nLayers; iLayer++ ) { if( EQUAL(pszLayerName,papoLayers[iLayer]->GetTableName()) ) { if( CSLFetchNameValue( papszOptions, "OVERWRITE" ) != NULL && !EQUAL(CSLFetchNameValue(papszOptions,"OVERWRITE"),"NO") ) { if (!pszSchemaName) pszSchemaName = CPLStrdup(papoLayers[iLayer]->GetSchemaName()); DeleteLayer( iLayer ); } else { CPLError( CE_Failure, CPLE_AppDefined, "Layer %s already exists, CreateLayer failed.\n" "Use the layer creation option OVERWRITE=YES to " "replace it.", pszLayerName ); CPLFree( pszSchemaName ); CPLFree( pszTableName ); return NULL; } } } /* -------------------------------------------------------------------- */ /* Handle the GEOM_TYPE option. */ /* -------------------------------------------------------------------- */ pszGeomType = CSLFetchNameValue( papszOptions, "GEOM_TYPE" ); if( !pszGeomType ) pszGeomType = "geometry"; if( !EQUAL(pszGeomType, "geometry") && !EQUAL(pszGeomType, "geography")) { CPLError( CE_Failure, CPLE_AppDefined, "FORMAT=%s not recognised or supported.", pszGeomType ); CPLFree( pszSchemaName ); CPLFree( pszTableName ); return NULL; } /* determine the geometry column name */ pszGeomColumn = CSLFetchNameValue( papszOptions, "GEOM_NAME"); if (!pszGeomColumn) pszGeomColumn = "ogr_geometry"; /* -------------------------------------------------------------------- */ /* Initialize the metadata tables */ /* -------------------------------------------------------------------- */ if (InitializeMetadataTables() != OGRERR_NONE) { CPLFree( pszSchemaName ); CPLFree( pszTableName ); return NULL; } /* -------------------------------------------------------------------- */ /* Try to get the SRS Id of this spatial reference system, */ /* adding to the srs table if needed. */ /* -------------------------------------------------------------------- */ int nSRSId = 0; if( CSLFetchNameValue( papszOptions, "SRID") != NULL ) nSRSId = atoi(CSLFetchNameValue( papszOptions, "SRID")); if( nSRSId == 0 && poSRS != NULL ) nSRSId = FetchSRSId( poSRS ); /* -------------------------------------------------------------------- */ /* Create a new table and create a new entry in the geometry, */ /* geometry_columns metadata table. */ /* -------------------------------------------------------------------- */ if( eType != wkbNone ) { const char *pszGeometryType = OGRToOGCGeomType(eType); CPLODBCStatement oStmt( &oSession ); oStmt.Appendf( "DELETE FROM geometry_columns WHERE f_table_schema = '%s' " "AND f_table_name = '%s'\n", pszSchemaName, pszTableName ); oStmt.Appendf("INSERT INTO [geometry_columns] ([f_table_catalog], [f_table_schema] ,[f_table_name], " "[f_geometry_column],[coord_dimension],[srid],[geometry_type]) VALUES ('%s', '%s', '%s', '%s', %d, %d, '%s')\n", pszCatalog, pszSchemaName, pszTableName, pszGeomColumn, nCoordDimension, nSRSId, pszGeometryType ); oStmt.Appendf("CREATE TABLE [%s].[%s] ([ogr_fid] [int] IDENTITY(1,1) NOT NULL, " "[%s] [%s] NULL, CONSTRAINT [PK_%s] PRIMARY KEY CLUSTERED ([ogr_fid] ASC))", pszSchemaName, pszTableName, pszGeomColumn, pszGeomType, pszTableName); oSession.BeginTransaction(); if( !oStmt.ExecuteSQL() ) { CPLError( CE_Failure, CPLE_AppDefined, "Error creating layer: %s", GetSession()->GetLastError() ); return NULL; } oSession.CommitTransaction(); } CPLFree( pszSchemaName ); CPLFree( pszTableName ); /* -------------------------------------------------------------------- */ /* Create the layer object. */ /* -------------------------------------------------------------------- */ OGRMSSQLSpatialTableLayer *poLayer; poLayer = new OGRMSSQLSpatialTableLayer( this ); poLayer->SetLaunderFlag( CSLFetchBoolean(papszOptions,"LAUNDER",TRUE) ); poLayer->SetPrecisionFlag( CSLFetchBoolean(papszOptions,"PRECISION",TRUE)); if (poLayer->Initialize("dbo", pszLayerName, pszGeomColumn, nCoordDimension, nSRSId, eType) == OGRERR_FAILURE) { return NULL; } /* -------------------------------------------------------------------- */ /* Add layer to data source layer list. */ /* -------------------------------------------------------------------- */ papoLayers = (OGRMSSQLSpatialTableLayer **) CPLRealloc( papoLayers, sizeof(OGRMSSQLSpatialTableLayer *) * (nLayers+1) ); papoLayers[nLayers++] = poLayer; return poLayer; }
OGRLayer * OGRMySQLDataSource::CreateLayer( const char * pszLayerNameIn, OGRSpatialReference *poSRS, OGRwkbGeometryType eType, char ** papszOptions ) { MYSQL_RES *hResult=NULL; CPLString osCommand; const char *pszGeometryType; const char *pszGeomColumnName; const char *pszExpectedFIDName; char *pszLayerName; int nDimension = 3; // MySQL only supports 2d currently /* -------------------------------------------------------------------- */ /* Make sure there isn't an active transaction already. */ /* -------------------------------------------------------------------- */ InterruptLongResult(); if( CSLFetchBoolean(papszOptions,"LAUNDER",TRUE) ) pszLayerName = LaunderName( pszLayerNameIn ); else pszLayerName = CPLStrdup( pszLayerNameIn ); if( wkbFlatten(eType) == eType ) nDimension = 2; CPLDebug("MYSQL","Creating layer %s.", pszLayerName); /* -------------------------------------------------------------------- */ /* Do we already have this layer? If so, should we blow it */ /* away? */ /* -------------------------------------------------------------------- */ int iLayer; for( iLayer = 0; iLayer < nLayers; iLayer++ ) { if( EQUAL(pszLayerName,papoLayers[iLayer]->GetLayerDefn()->GetName()) ) { if( CSLFetchNameValue( papszOptions, "OVERWRITE" ) != NULL && !EQUAL(CSLFetchNameValue(papszOptions,"OVERWRITE"),"NO") ) { DeleteLayer( iLayer ); } else { CPLError( CE_Failure, CPLE_AppDefined, "Layer %s already exists, CreateLayer failed.\n" "Use the layer creation option OVERWRITE=YES to " "replace it.", pszLayerName ); CPLFree( pszLayerName ); return NULL; } } } pszGeomColumnName = CSLFetchNameValue( papszOptions, "GEOMETRY_NAME" ); if (!pszGeomColumnName) pszGeomColumnName="SHAPE"; pszExpectedFIDName = CSLFetchNameValue( papszOptions, "MYSQL_FID" ); if (!pszExpectedFIDName) pszExpectedFIDName="OGR_FID"; CPLDebug("MYSQL","Geometry Column Name %s.", pszGeomColumnName); CPLDebug("MYSQL","FID Column Name %s.", pszExpectedFIDName); if( wkbFlatten(eType) == wkbNone ) { osCommand.Printf( "CREATE TABLE `%s` ( " " %s INT UNIQUE NOT NULL AUTO_INCREMENT )", pszLayerName, pszExpectedFIDName ); } else { osCommand.Printf( "CREATE TABLE `%s` ( " " %s INT UNIQUE NOT NULL AUTO_INCREMENT, " " %s GEOMETRY NOT NULL )", pszLayerName, pszExpectedFIDName, pszGeomColumnName ); } if( CSLFetchNameValue( papszOptions, "ENGINE" ) != NULL ) { osCommand += " ENGINE = "; osCommand += CSLFetchNameValue( papszOptions, "ENGINE" ); } if( !mysql_query(GetConn(), osCommand ) ) { if( mysql_field_count( GetConn() ) == 0 ) CPLDebug("MYSQL","Created table %s.", pszLayerName); else { ReportError( osCommand ); return NULL; } } else { ReportError( osCommand ); return NULL; } // make sure to attempt to free results of successful queries hResult = mysql_store_result( GetConn() ); if( hResult != NULL ) mysql_free_result( hResult ); hResult = NULL; // Calling this does no harm InitializeMetadataTables(); /* -------------------------------------------------------------------- */ /* Try to get the SRS Id of this spatial reference system, */ /* adding tot the srs table if needed. */ /* -------------------------------------------------------------------- */ int nSRSId = -1; if( poSRS != NULL ) nSRSId = FetchSRSId( poSRS ); /* -------------------------------------------------------------------- */ /* Sometimes there is an old crufty entry in the geometry_columns */ /* table if things were not properly cleaned up before. We make */ /* an effort to clean out such cruft. */ /* */ /* -------------------------------------------------------------------- */ osCommand.Printf( "DELETE FROM geometry_columns WHERE f_table_name = '%s'", pszLayerName ); if( mysql_query(GetConn(), osCommand ) ) { ReportError( osCommand ); return NULL; } // make sure to attempt to free results of successful queries hResult = mysql_store_result( GetConn() ); if( hResult != NULL ) mysql_free_result( hResult ); hResult = NULL; /* -------------------------------------------------------------------- */ /* Attempt to add this table to the geometry_columns table, if */ /* it is a spatial layer. */ /* -------------------------------------------------------------------- */ if( eType != wkbNone ) { int nCoordDimension; if( eType == wkbFlatten(eType) ) nCoordDimension = 2; else nCoordDimension = 3; pszGeometryType = OGRToOGCGeomType(eType); if( nSRSId == -1 ) osCommand.Printf( "INSERT INTO geometry_columns " " (F_TABLE_NAME, " " F_GEOMETRY_COLUMN, " " COORD_DIMENSION, " " TYPE) values " " ('%s', '%s', %d, '%s')", pszLayerName, pszGeomColumnName, nCoordDimension, pszGeometryType ); else osCommand.Printf( "INSERT INTO geometry_columns " " (F_TABLE_NAME, " " F_GEOMETRY_COLUMN, " " COORD_DIMENSION, " " SRID, " " TYPE) values " " ('%s', '%s', %d, %d, '%s')", pszLayerName, pszGeomColumnName, nCoordDimension, nSRSId, pszGeometryType ); if( mysql_query(GetConn(), osCommand ) ) { ReportError( osCommand ); return NULL; } // make sure to attempt to free results of successful queries hResult = mysql_store_result( GetConn() ); if( hResult != NULL ) mysql_free_result( hResult ); hResult = NULL; } /* -------------------------------------------------------------------- */ /* Create the spatial index. */ /* */ /* We're doing this before we add geometry and record to the table */ /* so this may not be exactly the best way to do it. */ /* -------------------------------------------------------------------- */ const char *pszSI = CSLFetchNameValue( papszOptions, "SPATIAL_INDEX" ); if( eType != wkbNone && (pszSI == NULL || CSLTestBoolean(pszSI)) ) { osCommand.Printf( "ALTER TABLE `%s` ADD SPATIAL INDEX(`%s`) ", pszLayerName, pszGeomColumnName); if( mysql_query(GetConn(), osCommand ) ) { ReportError( osCommand ); return NULL; } // make sure to attempt to free results of successful queries hResult = mysql_store_result( GetConn() ); if( hResult != NULL ) mysql_free_result( hResult ); hResult = NULL; } /* -------------------------------------------------------------------- */ /* Create the layer object. */ /* -------------------------------------------------------------------- */ OGRMySQLTableLayer *poLayer; OGRErr eErr; poLayer = new OGRMySQLTableLayer( this, pszLayerName, TRUE, nSRSId ); eErr = poLayer->Initialize(pszLayerName); if (eErr == OGRERR_FAILURE) return NULL; poLayer->SetLaunderFlag( CSLFetchBoolean(papszOptions,"LAUNDER",TRUE) ); poLayer->SetPrecisionFlag( CSLFetchBoolean(papszOptions,"PRECISION",TRUE)); /* -------------------------------------------------------------------- */ /* Add layer to data source layer list. */ /* -------------------------------------------------------------------- */ papoLayers = (OGRMySQLLayer **) CPLRealloc( papoLayers, sizeof(OGRMySQLLayer *) * (nLayers+1) ); papoLayers[nLayers++] = poLayer; CPLFree( pszLayerName ); return poLayer; }
OGRFeatureDefn *OGRIngresTableLayer::ReadTableDefinition( const char *pszTable ) { poDS->EstablishActiveLayer( NULL ); /* -------------------------------------------------------------------- */ /* Fire off commands to get back the schema of the table. */ /* -------------------------------------------------------------------- */ CPLString osCommand; OGRIngresStatement oStatement( poDS->GetConn() ); osCommand.Printf( "select column_name, column_datatype, column_length, " "column_scale, column_ingdatatype, " "column_internal_datatype " "from iicolumns where table_name = '%s'", pszTable ); if( !oStatement.ExecuteSQL( osCommand ) ) { return NULL; } /* -------------------------------------------------------------------- */ /* Parse the returned table information. */ /* -------------------------------------------------------------------- */ OGRFeatureDefn *poDefn = new OGRFeatureDefn( pszTable ); char **papszRow; poDefn->Reference(); poDefn->SetGeomType( wkbNone ); while( (papszRow = oStatement.GetRow()) != NULL ) { CPLString osFieldName = papszRow[0]; CPLString osIngresType = papszRow[1]; CPLString osInternalType = papszRow[5]; GInt32 nWidth, nScale; osIngresType.Trim(); osFieldName.Trim(); osInternalType.Trim(); memcpy( &nWidth, papszRow[2], 4 ); memcpy( &nScale, papszRow[3], 4 ); OGRFieldDefn oField(osFieldName, OFTString); if( osGeomColumn.size() == 0 && (EQUAL(osInternalType,"POINT") || EQUAL(osInternalType,"IPOINT") || EQUAL(osInternalType,"BOX") || EQUAL(osInternalType,"IBOX") || EQUAL(osInternalType,"LSEG") || EQUAL(osInternalType,"ILSEG") || EQUAL(osInternalType,"LINE") || EQUAL(osInternalType,"ILINE") || EQUAL(osInternalType,"LONG LINE") || EQUAL(osInternalType,"POLYGON") || EQUAL(osInternalType,"IPOLYGON") || EQUAL(osInternalType,"LONG POLYGON") || EQUAL(osInternalType,"CIRCLE") || EQUAL(osInternalType,"LINESTRING") || EQUAL(osInternalType,"MULTIPOINT") || EQUAL(osInternalType,"MULTIPOLYGON") || EQUAL(osInternalType,"MULTILINESTRING") || EQUAL(osInternalType,"GEOMETRYCOLLECTION") || EQUAL(osInternalType,"ICIRCLE")) ) { osGeomColumn = osFieldName; osIngresGeomType = osInternalType; if( strstr(osInternalType,"POINT") ) poDefn->SetGeomType( wkbPoint ); else if( strstr(osInternalType,"LINE") || strstr(osInternalType,"SEG") || strstr(osInternalType, "LINESTRING")) poDefn->SetGeomType( wkbLineString ); else if( strstr(osInternalType,"MULTIPOINT")) poDefn->SetGeomType(wkbMultiPoint); else if( strstr(osInternalType,"MULTIPOLYGON")) poDefn->SetGeomType(wkbMultiPolygon); else if( strstr(osInternalType,"MULTILINESTRING")) poDefn->SetGeomType(wkbMultiLineString); // Oddly this is the standin for a generic geometry type. else if( strstr(osInternalType,"GEOMETRYCOLLECTION")) poDefn->SetGeomType(wkbUnknown); else poDefn->SetGeomType( wkbPolygon ); continue; } else if( EQUALN(osIngresType,"byte",4) || EQUALN(osIngresType,"long byte",9) ) { oField.SetType( OFTBinary ); } else if( EQUALN(osIngresType,"varchar",7) || EQUAL(osIngresType,"text") || EQUALN(osIngresType,"long varchar",12) ) { oField.SetType( OFTString ); oField.SetWidth( nWidth ); } else if( EQUALN(osIngresType,"char",4) || EQUAL(osIngresType,"c") ) { oField.SetType( OFTString ); oField.SetWidth( nWidth ); } else if( EQUAL(osIngresType,"integer") ) { oField.SetType( OFTInteger ); } else if( EQUALN(osIngresType,"decimal", 7) ) { if( nScale != 0 ) { oField.SetType( OFTReal ); oField.SetPrecision( nScale ); oField.SetWidth( nWidth ); } else { oField.SetType( OFTInteger ); oField.SetWidth( nWidth ); } } else if( EQUALN(osIngresType,"float", 5) ) { oField.SetType( OFTReal ); } #ifdef notdef else if( EQUAL(osIngresType,"date") || EQUAL(osIngresType,"ansidate") || EQUAL(osIngresType,"ingresdate") ) { oField.SetType( OFTDate ); } #endif // Is this an integer primary key field? if( osFIDColumn.size() == 0 && oField.GetType() == OFTInteger && EQUAL(oField.GetNameRef(),"ogr_fid") ) { osFIDColumn = oField.GetNameRef(); continue; } poDefn->AddFieldDefn( &oField ); } if( osFIDColumn.size() ) CPLDebug( "Ingres", "table %s has FID column %s.", pszTable, osFIDColumn.c_str() ); else CPLDebug( "Ingres", "table %s has no FID column, FIDs will not be reliable!", pszTable ); //We must close the current statement before calling this or else //The query within FetchSRSId will fail oStatement.Close(); // Fetch the SRID for this table now // But only if it's the new Ingres Geospatial if(poDS->IsNewIngres() == TRUE) nSRSId = FetchSRSId(poDefn); return poDefn; }
OGRLayer * OGROCIDataSource::ICreateLayer( const char * pszLayerName, OGRSpatialReference *poSRS, OGRwkbGeometryType eType, char ** papszOptions ) { char szCommand[1024]; char *pszSafeLayerName = CPLStrdup(pszLayerName); poSession->CleanName( pszSafeLayerName ); CPLDebug( "OCI", "In Create Layer ..." ); bNoLogging = CPLFetchBool( papszOptions, "NO_LOGGING", false ); /* -------------------------------------------------------------------- */ /* Do we already have this layer? If so, should we blow it */ /* away? */ /* -------------------------------------------------------------------- */ int iLayer; if( CPLFetchBool( papszOptions, "TRUNCATE", false ) ) { CPLDebug( "OCI", "Calling TruncateLayer for %s", pszLayerName ); TruncateLayer( pszSafeLayerName ); } else { for( iLayer = 0; iLayer < nLayers; iLayer++ ) { if( EQUAL(pszSafeLayerName, papoLayers[iLayer]->GetLayerDefn()->GetName()) ) { if( CSLFetchNameValue( papszOptions, "OVERWRITE" ) != NULL && !EQUAL(CSLFetchNameValue(papszOptions,"OVERWRITE"),"NO") ) { DeleteLayer( pszSafeLayerName ); } else { CPLError( CE_Failure, CPLE_AppDefined, "Layer %s already exists, CreateLayer failed.\n" "Use the layer creation option OVERWRITE=YES to " "replace it.", pszSafeLayerName ); CPLFree( pszSafeLayerName ); return NULL; } } } } /* -------------------------------------------------------------------- */ /* Try to get the SRS Id of this spatial reference system, */ /* adding tot the srs table if needed. */ /* -------------------------------------------------------------------- */ char szSRSId[100]; if( CSLFetchNameValue( papszOptions, "SRID" ) != NULL ) strcpy( szSRSId, CSLFetchNameValue( papszOptions, "SRID" ) ); else if( poSRS != NULL ) snprintf( szSRSId, sizeof(szSRSId), "%d", FetchSRSId( poSRS ) ); else strcpy( szSRSId, "NULL" ); /* -------------------------------------------------------------------- */ /* Determine name of geometry column to use. */ /* -------------------------------------------------------------------- */ const char *pszGeometryName = CSLFetchNameValue( papszOptions, "GEOMETRY_NAME" ); if( pszGeometryName == NULL ) pszGeometryName = "ORA_GEOMETRY"; const bool bGeomNullable = CPLFetchBool(papszOptions, "GEOMETRY_NULLABLE", true); /* -------------------------------------------------------------------- */ /* Create a basic table with the FID. Also include the */ /* geometry if this is not a PostGIS enabled table. */ /* -------------------------------------------------------------------- */ const char *pszExpectedFIDName = CPLGetConfigOption( "OCI_FID", "OGR_FID" ); OGROCIStatement oStatement( poSession ); /* -------------------------------------------------------------------- */ /* If geometry type is wkbNone, do not create a geometry column. */ /* -------------------------------------------------------------------- */ if ( CSLFetchNameValue( papszOptions, "TRUNCATE" ) == NULL ) { if (eType == wkbNone) { snprintf( szCommand, sizeof(szCommand), "CREATE TABLE \"%s\" ( " "%s INTEGER PRIMARY KEY)", pszSafeLayerName, pszExpectedFIDName); } else { snprintf( szCommand, sizeof(szCommand), "CREATE TABLE \"%s\" ( " "%s INTEGER PRIMARY KEY, " "%s %s%s )", pszSafeLayerName, pszExpectedFIDName, pszGeometryName, SDO_GEOMETRY, (!bGeomNullable) ? " NOT NULL":""); } if (bNoLogging) { char szCommand2[1024]; strncpy( szCommand2, szCommand, sizeof(szCommand) ); snprintf( szCommand, sizeof(szCommand), "%s NOLOGGING " "VARRAY %s.SDO_ELEM_INFO STORE AS SECUREFILE LOB (NOCACHE NOLOGGING) " "VARRAY %s.SDO_ORDINATES STORE AS SECUREFILE LOB (NOCACHE NOLOGGING) ", szCommand2, pszGeometryName, pszGeometryName); } if( oStatement.Execute( szCommand ) != CE_None ) { CPLFree( pszSafeLayerName ); return NULL; } } /* -------------------------------------------------------------------- */ /* Create the layer object. */ /* -------------------------------------------------------------------- */ const char *pszLoaderFile = CSLFetchNameValue(papszOptions,"LOADER_FILE"); OGROCIWritableLayer *poLayer; if( pszLoaderFile == NULL ) poLayer = new OGROCITableLayer( this, pszSafeLayerName, eType, EQUAL(szSRSId,"NULL") ? -1 : atoi(szSRSId), TRUE, TRUE ); else poLayer = new OGROCILoaderLayer( this, pszSafeLayerName, pszGeometryName, EQUAL(szSRSId,"NULL") ? -1 : atoi(szSRSId), pszLoaderFile ); /* -------------------------------------------------------------------- */ /* Set various options on the layer. */ /* -------------------------------------------------------------------- */ poLayer->SetLaunderFlag( CPLFetchBool(papszOptions, "LAUNDER", false) ); poLayer->SetPrecisionFlag( CPLFetchBool(papszOptions, "PRECISION", true)); if( CSLFetchNameValue(papszOptions,"DIM") != NULL ) poLayer->SetDimension( atoi(CSLFetchNameValue(papszOptions,"DIM")) ); poLayer->SetOptions( papszOptions ); if( eType != wkbNone && !bGeomNullable ) poLayer->GetLayerDefn()->GetGeomFieldDefn(0)->SetNullable(FALSE); /* -------------------------------------------------------------------- */ /* Add layer to data source layer list. */ /* -------------------------------------------------------------------- */ papoLayers = (OGROCILayer **) CPLRealloc( papoLayers, sizeof(OGROCILayer *) * (nLayers+1) ); papoLayers[nLayers++] = poLayer; CPLFree( pszSafeLayerName ); return poLayer; }
OGRLayer *OGRCARTODBDataSource::ICreateLayer( const char *pszName, OGRSpatialReference *poSpatialRef, OGRwkbGeometryType eGType, char ** papszOptions ) { if (!bReadWrite) { CPLError(CE_Failure, CPLE_AppDefined, "Operation not available in read-only mode"); return NULL; } /* -------------------------------------------------------------------- */ /* Do we already have this layer? If so, should we blow it */ /* away? */ /* -------------------------------------------------------------------- */ int iLayer; for( iLayer = 0; iLayer < nLayers; iLayer++ ) { if( EQUAL(pszName,papoLayers[iLayer]->GetName()) ) { if( CSLFetchNameValue( papszOptions, "OVERWRITE" ) != NULL && !EQUAL(CSLFetchNameValue(papszOptions,"OVERWRITE"),"NO") ) { DeleteLayer( iLayer ); } else { CPLError( CE_Failure, CPLE_AppDefined, "Layer %s already exists, CreateLayer failed.\n" "Use the layer creation option OVERWRITE=YES to " "replace it.", pszName ); return NULL; } } } int nSRID = 0; if( poSpatialRef != NULL ) nSRID = FetchSRSId( poSpatialRef ); CPLString osGeomType; if( eGType != wkbNone ) { osGeomType = OGRToOGCGeomType(eGType); if( eGType & wkb25DBit ) osGeomType += "Z"; } CPLString osSQL; osSQL.Printf("CREATE TABLE %s ( %s SERIAL, ", OGRCARTODBEscapeIdentifier(pszName).c_str(), "cartodb_id"); if( osGeomType.size() > 0 ) { osSQL += CPLSPrintf("%s GEOMETRY(%s, %d), %s GEOMETRY(%s, %d),", "the_geom", osGeomType.c_str(), nSRID, "the_geom_webmercator", osGeomType.c_str(), 3857); } osSQL += CPLSPrintf("PRIMARY KEY (%s) )", "cartodb_id"); osSQL += ";"; osSQL += CPLSPrintf("DROP SEQUENCE IF EXISTS %s", OGRCARTODBEscapeIdentifier(CPLSPrintf("%s_%s_seq", pszName, "cartodb_id")).c_str()); osSQL += ";"; osSQL += CPLSPrintf("CREATE SEQUENCE %s START 1", OGRCARTODBEscapeIdentifier(CPLSPrintf("%s_%s_seq", pszName, "cartodb_id")).c_str()); osSQL += ";"; osSQL += CPLSPrintf("ALTER TABLE %s ALTER COLUMN %s SET DEFAULT nextval('%s')", pszName, "cartodb_id", OGRCARTODBEscapeLiteral(CPLSPrintf("%s_%s_seq", pszName, "cartodb_id")).c_str()); json_object* poObj = RunSQL(osSQL); if( poObj == NULL ) return NULL; json_object_put(poObj); OGRCARTODBTableLayer* poLayer = new OGRCARTODBTableLayer(this, pszName); papoLayers = (OGRLayer**) CPLRealloc( papoLayers, (nLayers + 1) * sizeof(OGRLayer*)); papoLayers[nLayers ++] = poLayer; return poLayer; }
OGRLayer * OGROCIDataSource::CreateLayer( const char * pszLayerName, OGRSpatialReference *poSRS, OGRwkbGeometryType eType, char ** papszOptions ) { char szCommand[1024]; char *pszSafeLayerName = CPLStrdup(pszLayerName); poSession->CleanName( pszSafeLayerName ); /* -------------------------------------------------------------------- */ /* Do we already have this layer? If so, should we blow it */ /* away? */ /* -------------------------------------------------------------------- */ int iLayer; for( iLayer = 0; iLayer < nLayers; iLayer++ ) { if( EQUAL(pszSafeLayerName, papoLayers[iLayer]->GetLayerDefn()->GetName()) ) { if( CSLFetchNameValue( papszOptions, "OVERWRITE" ) != NULL && !EQUAL(CSLFetchNameValue(papszOptions,"OVERWRITE"),"NO") ) { DeleteLayer( pszSafeLayerName ); } else { CPLError( CE_Failure, CPLE_AppDefined, "Layer %s already exists, CreateLayer failed.\n" "Use the layer creation option OVERWRITE=YES to " "replace it.", pszSafeLayerName ); CPLFree( pszSafeLayerName ); return NULL; } } } /* -------------------------------------------------------------------- */ /* Try to get the SRS Id of this spatial reference system, */ /* adding tot the srs table if needed. */ /* -------------------------------------------------------------------- */ char szSRSId[100]; if( CSLFetchNameValue( papszOptions, "SRID" ) != NULL ) strcpy( szSRSId, CSLFetchNameValue( papszOptions, "SRID" ) ); else if( poSRS != NULL ) sprintf( szSRSId, "%d", FetchSRSId( poSRS ) ); else strcpy( szSRSId, "NULL" ); /* -------------------------------------------------------------------- */ /* Determine name of geometry column to use. */ /* -------------------------------------------------------------------- */ const char *pszGeometryName = CSLFetchNameValue( papszOptions, "GEOMETRY_NAME" ); if( pszGeometryName == NULL ) pszGeometryName = "ORA_GEOMETRY"; /* -------------------------------------------------------------------- */ /* Create a basic table with the FID. Also include the */ /* geometry if this is not a PostGIS enabled table. */ /* -------------------------------------------------------------------- */ const char *pszExpectedFIDName = CPLGetConfigOption( "OCI_FID", "OGR_FID" ); OGROCIStatement oStatement( poSession ); /* -------------------------------------------------------------------- */ /* If geometry type is wkbNone, do not create a geoemtry column */ /* -------------------------------------------------------------------- */ if (eType == wkbNone) { sprintf( szCommand, "CREATE TABLE \"%s\" ( " "%s INTEGER)", pszSafeLayerName, pszExpectedFIDName); } else { sprintf( szCommand, "CREATE TABLE \"%s\" ( " "%s INTEGER, " "%s %s )", pszSafeLayerName, pszExpectedFIDName, pszGeometryName, SDO_GEOMETRY ); } if( oStatement.Execute( szCommand ) != CE_None ) { CPLFree( pszSafeLayerName ); return NULL; } /* -------------------------------------------------------------------- */ /* Create the layer object. */ /* -------------------------------------------------------------------- */ const char *pszLoaderFile = CSLFetchNameValue(papszOptions,"LOADER_FILE"); OGROCIWritableLayer *poLayer; if( pszLoaderFile == NULL ) poLayer = new OGROCITableLayer( this, pszSafeLayerName, EQUAL(szSRSId,"NULL") ? -1 : atoi(szSRSId), TRUE, TRUE ); else poLayer = new OGROCILoaderLayer( this, pszSafeLayerName, pszGeometryName, EQUAL(szSRSId,"NULL") ? -1 : atoi(szSRSId), pszLoaderFile ); /* -------------------------------------------------------------------- */ /* Set various options on the layer. */ /* -------------------------------------------------------------------- */ poLayer->SetLaunderFlag( CSLFetchBoolean(papszOptions,"LAUNDER",FALSE) ); poLayer->SetPrecisionFlag( CSLFetchBoolean(papszOptions,"PRECISION",TRUE)); if( CSLFetchNameValue(papszOptions,"DIM") != NULL ) poLayer->SetDimension( atoi(CSLFetchNameValue(papszOptions,"DIM")) ); poLayer->SetOptions( papszOptions ); /* -------------------------------------------------------------------- */ /* Add layer to data source layer list. */ /* -------------------------------------------------------------------- */ papoLayers = (OGROCILayer **) CPLRealloc( papoLayers, sizeof(OGROCILayer *) * (nLayers+1) ); papoLayers[nLayers++] = poLayer; CPLFree( pszSafeLayerName ); return poLayer; }
OGRLayer *OGRCARTODataSource::ICreateLayer( const char *pszNameIn, OGRSpatialReference *poSpatialRef, OGRwkbGeometryType eGType, char ** papszOptions ) { if (!bReadWrite) { CPLError(CE_Failure, CPLE_AppDefined, "Operation not available in read-only mode"); return NULL; } /* -------------------------------------------------------------------- */ /* Do we already have this layer? If so, should we blow it */ /* away? */ /* -------------------------------------------------------------------- */ int iLayer; for( iLayer = 0; iLayer < nLayers; iLayer++ ) { if( EQUAL(pszNameIn,papoLayers[iLayer]->GetName()) ) { if( CSLFetchNameValue( papszOptions, "OVERWRITE" ) != NULL && !EQUAL(CSLFetchNameValue(papszOptions,"OVERWRITE"),"NO") ) { DeleteLayer( iLayer ); } else { CPLError( CE_Failure, CPLE_AppDefined, "Layer %s already exists, CreateLayer failed.\n" "Use the layer creation option OVERWRITE=YES to " "replace it.", pszNameIn ); return NULL; } } } CPLString osName(pszNameIn); if( CPLFetchBool(const_cast<const char**>(papszOptions), "LAUNDER", true) ) { char* pszTmp = OGRPGCommonLaunderName(pszNameIn); osName = pszTmp; CPLFree(pszTmp); } OGRCARTOTableLayer* poLayer = new OGRCARTOTableLayer(this, osName); const bool bGeomNullable = CPLFetchBool(const_cast<const char**>(papszOptions), "GEOMETRY_NULLABLE", true); int nSRID = (poSpatialRef && eGType != wkbNone) ? FetchSRSId( poSpatialRef ) : 0; bool bCartoify = CPLFetchBool(const_cast<const char**>(papszOptions), "CARTODBFY", CPLFetchBool(const_cast<const char**>(papszOptions), "CARTODBIFY", true)); if( bCartoify ) { if( nSRID != 4326 ) { if( eGType != wkbNone ) { CPLError(CE_Warning, CPLE_AppDefined, "Cannot register table in dashboard with " "cdb_cartodbfytable() since its SRS is not EPSG:4326"); } bCartoify = false; } } poLayer->SetLaunderFlag( CPLFetchBool(const_cast<const char**>(papszOptions), "LAUNDER", true) ); poLayer->SetDeferredCreation(eGType, poSpatialRef, bGeomNullable, bCartoify); papoLayers = (OGRCARTOTableLayer**) CPLRealloc( papoLayers, (nLayers + 1) * sizeof(OGRCARTOTableLayer*)); papoLayers[nLayers ++] = poLayer; return poLayer; }
OGRFeatureDefn *OGRMySQLTableLayer::ReadTableDefinition( const char *pszTable ) { MYSQL_RES *hResult; char szCommand[1024]; /* -------------------------------------------------------------------- */ /* Fire off commands to get back the schema of the table. */ /* -------------------------------------------------------------------- */ sprintf( szCommand, "DESCRIBE `%s`", pszTable ); pszGeomColumnTable = CPLStrdup(pszTable); if( mysql_query( poDS->GetConn(), szCommand ) ) { poDS->ReportError( "DESCRIBE Failed" ); return FALSE; } hResult = mysql_store_result( poDS->GetConn() ); if( hResult == NULL ) { poDS->ReportError( "mysql_store_result() failed on DESCRIBE result." ); return FALSE; } /* -------------------------------------------------------------------- */ /* Parse the returned table information. */ /* -------------------------------------------------------------------- */ OGRFeatureDefn *poDefn = new OGRFeatureDefn( pszTable ); char **papszRow; poDefn->Reference(); while( (papszRow = mysql_fetch_row( hResult )) != NULL ) { const char *pszType; OGRFieldDefn oField( papszRow[0], OFTString); pszType = papszRow[1]; if( pszType == NULL ) continue; if( EQUAL(pszType,"varbinary") || (strlen(pszType)>3 && EQUAL(pszType+strlen(pszType)-4,"blob"))) { oField.SetType( OFTBinary ); } else if( EQUAL(pszType,"varchar") || EQUAL(pszType+strlen(pszType)-4,"enum") || EQUAL(pszType+strlen(pszType)-4,"set") ) { oField.SetType( OFTString ); } else if( EQUALN(pszType,"char",4) ) { oField.SetType( OFTString ); char ** papszTokens; papszTokens = CSLTokenizeString2(pszType,"(),",0); /* width is the second */ oField.SetWidth(atoi(papszTokens[1])); CSLDestroy( papszTokens ); oField.SetType( OFTString ); } if(strlen(pszType)>3 && EQUAL(pszType+strlen(pszType)-4,"text")) { oField.SetType( OFTString ); } else if( EQUALN(pszType,"varchar",6) ) { /* pszType is usually in the form "varchar(15)" so we'll split it up and get the width and precision */ oField.SetType( OFTString ); char ** papszTokens; papszTokens = CSLTokenizeString2(pszType,"(),",0); /* width is the second */ oField.SetWidth(atoi(papszTokens[1])); CSLDestroy( papszTokens ); oField.SetType( OFTString ); } else if( EQUALN(pszType,"int", 3) ) { oField.SetType( OFTInteger ); } else if( EQUALN(pszType,"tinyint", 7) ) { oField.SetType( OFTInteger ); } else if( EQUALN(pszType,"smallint", 8) ) { oField.SetType( OFTInteger ); } else if( EQUALN(pszType,"mediumint",9) ) { oField.SetType( OFTInteger ); } else if( EQUALN(pszType,"bigint",6) ) { oField.SetType( OFTInteger ); } else if( EQUALN(pszType,"decimal",7) ) { /* pszType is usually in the form "decimal(15,2)" so we'll split it up and get the width and precision */ oField.SetType( OFTReal ); char ** papszTokens; papszTokens = CSLTokenizeString2(pszType,"(),",0); /* width is the second and precision is the third */ oField.SetWidth(atoi(papszTokens[1])); oField.SetPrecision(atoi(papszTokens[2])); CSLDestroy( papszTokens ); } else if( EQUALN(pszType,"float", 5) ) { oField.SetType( OFTReal ); } else if( EQUAL(pszType,"double") ) { oField.SetType( OFTReal ); } else if( EQUALN(pszType,"double",6) ) { // double can also be double(15,2) // so we'll handle this case here after // we check for just a regular double // without a width and precision specified char ** papszTokens=NULL; papszTokens = CSLTokenizeString2(pszType,"(),",0); /* width is the second and precision is the third */ oField.SetWidth(atoi(papszTokens[1])); oField.SetPrecision(atoi(papszTokens[2])); CSLDestroy( papszTokens ); oField.SetType( OFTReal ); } else if( EQUAL(pszType,"decimal") ) { oField.SetType( OFTReal ); } else if( EQUAL(pszType, "date") ) { oField.SetType( OFTDate ); } else if( EQUAL(pszType, "time") ) { oField.SetType( OFTTime ); } else if( EQUAL(pszType, "datetime") || EQUAL(pszType, "timestamp") ) { oField.SetType( OFTDateTime ); } else if( EQUAL(pszType, "year") ) { oField.SetType( OFTString ); oField.SetWidth( 10 ); } else if( EQUAL(pszType, "geometry") ) { pszGeomColumn = CPLStrdup(papszRow[0]); continue; } // Is this an integer primary key field? if( !bHasFid && papszRow[3] != NULL && EQUAL(papszRow[3],"PRI") && oField.GetType() == OFTInteger ) { bHasFid = TRUE; pszFIDColumn = CPLStrdup(oField.GetNameRef()); continue; } poDefn->AddFieldDefn( &oField ); } // set to none for now... if we have a geometry column it will be set layer. poDefn->SetGeomType( wkbNone ); if( hResult != NULL ) { mysql_free_result( hResult ); hResultSet = NULL; } if( bHasFid ) CPLDebug( "MySQL", "table %s has FID column %s.", pszTable, pszFIDColumn ); else CPLDebug( "MySQL", "table %s has no FID column, FIDs will not be reliable!", pszTable ); if (pszGeomColumn) { char* pszType=NULL; // set to unknown first poDefn->SetGeomType( wkbUnknown ); sprintf(szCommand, "SELECT type, coord_dimension FROM geometry_columns WHERE f_table_name='%s'", pszTable ); hResult = NULL; if( !mysql_query( poDS->GetConn(), szCommand ) ) hResult = mysql_store_result( poDS->GetConn() ); papszRow = NULL; if( hResult != NULL ) papszRow = mysql_fetch_row( hResult ); if( papszRow != NULL && papszRow[0] != NULL ) { pszType = papszRow[0]; OGRwkbGeometryType nGeomType = wkbUnknown; // check only standard OGC geometry types if ( EQUAL(pszType, "POINT") ) nGeomType = wkbPoint; else if ( EQUAL(pszType,"LINESTRING")) nGeomType = wkbLineString; else if ( EQUAL(pszType,"POLYGON")) nGeomType = wkbPolygon; else if ( EQUAL(pszType,"MULTIPOINT")) nGeomType = wkbMultiPoint; else if ( EQUAL(pszType,"MULTILINESTRING")) nGeomType = wkbMultiLineString; else if ( EQUAL(pszType,"MULTIPOLYGON")) nGeomType = wkbMultiPolygon; else if ( EQUAL(pszType,"GEOMETRYCOLLECTION")) nGeomType = wkbGeometryCollection; if( papszRow[1] != NULL && atoi(papszRow[1]) == 3 ) nGeomType = (OGRwkbGeometryType) (nGeomType | wkb25DBit); poDefn->SetGeomType( nGeomType ); } if( hResult != NULL ) mysql_free_result( hResult ); //Free our query results for finding type. hResult = NULL; } // Fetch the SRID for this table now nSRSId = FetchSRSId(); return poDefn; }
OGRLayer * OGRIngresDataSource::CreateLayer( const char * pszLayerNameIn, OGRSpatialReference *poSRS, OGRwkbGeometryType eType, char ** papszOptions ) { const char *pszGeometryType = NULL; const char *pszGeomColumnName; const char *pszExpectedFIDName; char *pszLayerName; int nDimension = 3; // Ingres only supports 2d currently if( CSLFetchBoolean(papszOptions,"LAUNDER",TRUE) ) pszLayerName = LaunderName( pszLayerNameIn ); else pszLayerName = CPLStrdup( pszLayerNameIn ); if( wkbFlatten(eType) == eType ) nDimension = 2; CPLDebug("INGRES","Creating layer %s.", pszLayerName); /* -------------------------------------------------------------------- */ /* Do we already have this layer? If so, should we blow it */ /* away? */ /* -------------------------------------------------------------------- */ int iLayer; for( iLayer = 0; iLayer < nLayers; iLayer++ ) { if( EQUAL(pszLayerName,papoLayers[iLayer]->GetLayerDefn()->GetName()) ) { if( CSLFetchNameValue( papszOptions, "OVERWRITE" ) != NULL && !EQUAL(CSLFetchNameValue(papszOptions,"OVERWRITE"),"NO") ) { DeleteLayer( iLayer ); } else { CPLFree( pszLayerName ); CPLError( CE_Failure, CPLE_AppDefined, "Layer %s already exists, CreateLayer failed.\n" "Use the layer creation option OVERWRITE=YES to " "replace it.", pszLayerName ); return NULL; } } } /* -------------------------------------------------------------------- */ /* What do we want to use for geometry and FID columns? */ /* -------------------------------------------------------------------- */ pszGeomColumnName = CSLFetchNameValue( papszOptions, "GEOMETRY_NAME" ); if (!pszGeomColumnName) pszGeomColumnName="SHAPE"; pszExpectedFIDName = CSLFetchNameValue( papszOptions, "INGRES_FID" ); if (!pszExpectedFIDName) pszExpectedFIDName="OGR_FID"; CPLDebug("INGRES","Geometry Column Name %s.", pszGeomColumnName); CPLDebug("INGRES","FID Column Name %s.", pszExpectedFIDName); /* -------------------------------------------------------------------- */ /* What sort of geometry column do we want to create? */ /* -------------------------------------------------------------------- */ pszGeometryType = CSLFetchNameValue( papszOptions, "GEOMETRY_TYPE" ); if( pszGeometryType != NULL ) /* user selected type */; else if( wkbFlatten(eType) == wkbPoint ) pszGeometryType = "POINT"; else if( wkbFlatten(eType) == wkbLineString) { if( IsNewIngres() ) { pszGeometryType = "LINESTRING"; } else { pszGeometryType = "LONG LINE"; } } else if( wkbFlatten(eType) == wkbPolygon ) { if( IsNewIngres() ) { pszGeometryType = "POLYGON"; } else { pszGeometryType = "LONG POLYGON"; } } else if( wkbFlatten(eType) == wkbMultiPolygon ) { if( IsNewIngres() ) pszGeometryType = "MULTIPOLYGON"; } else if( wkbFlatten(eType) == wkbMultiLineString ) { if( IsNewIngres() ) pszGeometryType = "MULTILINESTRING"; } else if( wkbFlatten(eType) == wkbMultiPoint ) { if( IsNewIngres() ) pszGeometryType = "MULTIPOINT"; } else if( wkbFlatten(eType) == wkbGeometryCollection ) { if( IsNewIngres() ) pszGeometryType = "GEOMETRYCOLLECTION"; } else if( wkbFlatten(eType) == wkbUnknown ) { if( IsNewIngres() ) // this is also used as the generic geometry type. pszGeometryType = "GEOMETRYCOLLECTION"; } /* -------------------------------------------------------------------- */ /* Try to get the SRS Id of this spatial reference system, */ /* adding tot the srs table if needed. */ /* -------------------------------------------------------------------- */ int nSRSId = -1; if( poSRS != NULL && IsNewIngres() == TRUE ) nSRSId = FetchSRSId( poSRS ); /* -------------------------------------------------------------------- */ /* Form table creation command. */ /* -------------------------------------------------------------------- */ CPLString osCommand; if( pszGeometryType == NULL ) { osCommand.Printf( "CREATE TABLE %s ( " " %s INTEGER )", pszLayerName, pszExpectedFIDName ); } else { if(nSRSId != -1) { osCommand.Printf( "CREATE TABLE %s (" " %s INTEGER NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS seq_%s IDENTITY (START WITH 1 INCREMENT BY 1)," " %s %s SRID %d ) ", pszLayerName, pszExpectedFIDName, pszLayerName, pszGeomColumnName, pszGeometryType, nSRSId); } else { osCommand.Printf( "CREATE TABLE %s (" " %s INTEGER NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS seq_%s IDENTITY (START WITH 1 INCREMENT BY 1)," " %s %s )", pszLayerName, pszExpectedFIDName, pszLayerName, pszGeomColumnName, pszGeometryType); } } /* -------------------------------------------------------------------- */ /* Execute the create table command. */ /* -------------------------------------------------------------------- */ { OGRIngresStatement oStmt( hConn ); if( !oStmt.ExecuteSQL( osCommand ) ) return NULL; } /* -------------------------------------------------------------------- */ /* Create the layer object. */ /* -------------------------------------------------------------------- */ OGRIngresTableLayer *poLayer; OGRErr eErr; poLayer = new OGRIngresTableLayer( this, pszLayerName, TRUE, nSRSId ); eErr = poLayer->Initialize(pszLayerName); if (eErr == OGRERR_FAILURE) { delete poLayer; return NULL; } poLayer->SetLaunderFlag( CSLFetchBoolean(papszOptions,"LAUNDER",TRUE) ); poLayer->SetPrecisionFlag( CSLFetchBoolean(papszOptions,"PRECISION",TRUE)); /* -------------------------------------------------------------------- */ /* Add layer to data source layer list. */ /* -------------------------------------------------------------------- */ papoLayers = (OGRIngresLayer **) CPLRealloc( papoLayers, sizeof(OGRIngresLayer *) * (nLayers+1) ); papoLayers[nLayers++] = poLayer; CPLFree( pszLayerName ); return poLayer; }
OGRFeatureDefn *OGRMySQLResultLayer::ReadResultDefinition() { /* -------------------------------------------------------------------- */ /* Parse the returned table information. */ /* -------------------------------------------------------------------- */ OGRFeatureDefn *poDefn = new OGRFeatureDefn( "sql_statement" ); SetDescription( poDefn->GetName() ); poDefn->Reference(); mysql_field_seek( hResultSet, 0 ); for( int iRawField = 0; iRawField < (int) mysql_num_fields(hResultSet); iRawField++ ) { MYSQL_FIELD *psMSField = mysql_fetch_field( hResultSet ); OGRFieldDefn oField( psMSField->name, OFTString); switch( psMSField->type ) { case FIELD_TYPE_TINY: case FIELD_TYPE_SHORT: case FIELD_TYPE_LONG: case FIELD_TYPE_INT24: case FIELD_TYPE_LONGLONG: { oField.SetType( OFTInteger ); const int width = (int)psMSField->length; oField.SetWidth(width); poDefn->AddFieldDefn( &oField ); break; } case FIELD_TYPE_DECIMAL: #ifdef FIELD_TYPE_NEWDECIMAL case FIELD_TYPE_NEWDECIMAL: #endif { oField.SetType( OFTReal ); // a bunch of hackery to munge the widths that MySQL gives // us into corresponding widths and precisions for OGR const int precision = (int)psMSField->decimals; int width = (int)psMSField->length; if (!precision) width = width - 1; width = width - precision; oField.SetWidth(width); oField.SetPrecision(precision); poDefn->AddFieldDefn( &oField ); break; } case FIELD_TYPE_FLOAT: case FIELD_TYPE_DOUBLE: /* MYSQL_FIELD is always reporting ->length = 22 and ->decimals = 31 for double type regardless of the data it returned. In an example, the data it returned had only 5 or 6 decimal places which were exactly as entered into the database but reported the decimals as 31. */ /* Assuming that a length of 22 means no particular width and 31 decimals means no particular precision. */ { const int width = (int)psMSField->length; const int precision = (int)psMSField->decimals; oField.SetType( OFTReal ); if( width != 22 ) oField.SetWidth(width); if( precision != 31 ) oField.SetPrecision(precision); poDefn->AddFieldDefn( &oField ); break; } case FIELD_TYPE_DATE: { oField.SetType( OFTDate ); oField.SetWidth(0); poDefn->AddFieldDefn( &oField ); break; } case FIELD_TYPE_TIME: { oField.SetType( OFTTime ); oField.SetWidth(0); poDefn->AddFieldDefn( &oField ); break; } case FIELD_TYPE_TIMESTAMP: case FIELD_TYPE_DATETIME: { oField.SetType( OFTDateTime ); oField.SetWidth(0); poDefn->AddFieldDefn( &oField ); break; } case FIELD_TYPE_YEAR: case FIELD_TYPE_STRING: case FIELD_TYPE_VAR_STRING: { oField.SetType( OFTString ); oField.SetWidth((int)psMSField->length); poDefn->AddFieldDefn( &oField ); break; } case FIELD_TYPE_TINY_BLOB: case FIELD_TYPE_MEDIUM_BLOB: case FIELD_TYPE_LONG_BLOB: case FIELD_TYPE_BLOB: { if( psMSField->charsetnr == 63 ) oField.SetType( OFTBinary ); else oField.SetType( OFTString ); oField.SetWidth((int)psMSField->max_length); poDefn->AddFieldDefn( &oField ); break; } case FIELD_TYPE_GEOMETRY: { if (pszGeomColumn == nullptr) { pszGeomColumnTable = CPLStrdup( psMSField->table); pszGeomColumn = CPLStrdup( psMSField->name); } break; } default: // any other field we ignore. break; } // assume a FID name first, and if it isn't there // take a field that is not null, a primary key, // and is an integer-like field if( EQUAL(psMSField->name,"ogc_fid") ) { bHasFid = TRUE; pszFIDColumn = CPLStrdup(oField.GetNameRef()); continue; } else if (IS_NOT_NULL(psMSField->flags) && IS_PRI_KEY(psMSField->flags) && ( psMSField->type == FIELD_TYPE_TINY || psMSField->type == FIELD_TYPE_SHORT || psMSField->type == FIELD_TYPE_LONG || psMSField->type == FIELD_TYPE_INT24 || psMSField->type == FIELD_TYPE_LONGLONG ) ) { bHasFid = TRUE; pszFIDColumn = CPLStrdup(oField.GetNameRef()); continue; } } poDefn->SetGeomType( wkbNone ); if (pszGeomColumn) { char* pszType=nullptr; CPLString osCommand; char **papszRow; // set to unknown first poDefn->SetGeomType( wkbUnknown ); poDefn->GetGeomFieldDefn(0)->SetName( pszGeomColumn ); osCommand.Printf( "SELECT type FROM geometry_columns WHERE f_table_name='%s'", pszGeomColumnTable ); if( hResultSet != nullptr ) mysql_free_result( hResultSet ); hResultSet = nullptr; if( !mysql_query( poDS->GetConn(), osCommand ) ) hResultSet = mysql_store_result( poDS->GetConn() ); papszRow = nullptr; if( hResultSet != nullptr ) papszRow = mysql_fetch_row( hResultSet ); if( papszRow != nullptr && papszRow[0] != nullptr ) { pszType = papszRow[0]; OGRwkbGeometryType l_nGeomType = OGRFromOGCGeomType(pszType); poDefn->SetGeomType( l_nGeomType ); } nSRSId = FetchSRSId(); } return poDefn; }
OGRFeatureDefn *OGRMySQLTableLayer::ReadTableDefinition( const char *pszTable ) { MYSQL_RES *hResult; CPLString osCommand; /* -------------------------------------------------------------------- */ /* Fire off commands to get back the schema of the table. */ /* -------------------------------------------------------------------- */ osCommand.Printf("DESCRIBE `%s`", pszTable ); pszGeomColumnTable = CPLStrdup(pszTable); if( mysql_query( poDS->GetConn(), osCommand ) ) { poDS->ReportError( "DESCRIBE Failed" ); return NULL; } hResult = mysql_store_result( poDS->GetConn() ); if( hResult == NULL ) { poDS->ReportError( "mysql_store_result() failed on DESCRIBE result." ); return NULL; } /* -------------------------------------------------------------------- */ /* Parse the returned table information. */ /* -------------------------------------------------------------------- */ OGRFeatureDefn *poDefn = new OGRFeatureDefn( pszTable ); char **papszRow; OGRwkbGeometryType eForcedGeomType = wkbUnknown; int bGeomColumnNotNullable = FALSE; poDefn->Reference(); while( (papszRow = mysql_fetch_row( hResult )) != NULL ) { const char *pszType; OGRFieldDefn oField( papszRow[0], OFTString); int nLenType; pszType = papszRow[1]; if( pszType == NULL ) continue; nLenType = (int)strlen(pszType); if( EQUAL(pszType,"varbinary") || (nLenType>=4 && EQUAL(pszType+nLenType-4,"blob"))) { oField.SetType( OFTBinary ); } else if( EQUAL(pszType,"varchar") || (nLenType>=4 && EQUAL(pszType+nLenType-4,"enum")) || (nLenType>=3 && EQUAL(pszType+nLenType-3,"set")) ) { oField.SetType( OFTString ); } else if( STARTS_WITH_CI(pszType, "char") ) { oField.SetType( OFTString ); char ** papszTokens; papszTokens = CSLTokenizeString2(pszType,"(),",0); if (CSLCount(papszTokens) >= 2) { /* width is the second */ oField.SetWidth(atoi(papszTokens[1])); } CSLDestroy( papszTokens ); oField.SetType( OFTString ); } if(nLenType>=4 && EQUAL(pszType+nLenType-4,"text")) { oField.SetType( OFTString ); } else if( STARTS_WITH_CI(pszType,"varchar") ) { /* pszType is usually in the form "varchar(15)" so we'll split it up and get the width and precision */ oField.SetType( OFTString ); char ** papszTokens; papszTokens = CSLTokenizeString2(pszType,"(),",0); if (CSLCount(papszTokens) >= 2) { /* width is the second */ oField.SetWidth(atoi(papszTokens[1])); } CSLDestroy( papszTokens ); oField.SetType( OFTString ); } else if( STARTS_WITH_CI(pszType, "int") ) { oField.SetType( OFTInteger ); } else if( STARTS_WITH_CI(pszType, "tinyint") ) { oField.SetType( OFTInteger ); } else if( STARTS_WITH_CI(pszType, "smallint") ) { oField.SetType( OFTInteger ); } else if( STARTS_WITH_CI(pszType, "mediumint") ) { oField.SetType( OFTInteger ); } else if( STARTS_WITH_CI(pszType, "bigint") ) { oField.SetType( OFTInteger64 ); } else if( STARTS_WITH_CI(pszType, "decimal") ) { /* pszType is usually in the form "decimal(15,2)" so we'll split it up and get the width and precision */ oField.SetType( OFTReal ); char ** papszTokens; papszTokens = CSLTokenizeString2(pszType,"(),",0); if (CSLCount(papszTokens) >= 3) { /* width is the second and precision is the third */ oField.SetWidth(atoi(papszTokens[1])); oField.SetPrecision(atoi(papszTokens[2])); } CSLDestroy( papszTokens ); } else if( STARTS_WITH_CI(pszType, "float") ) { oField.SetType( OFTReal ); } else if( EQUAL(pszType,"double") ) { oField.SetType( OFTReal ); } else if( STARTS_WITH_CI(pszType, "double") ) { // double can also be double(15,2) // so we'll handle this case here after // we check for just a regular double // without a width and precision specified char ** papszTokens=NULL; papszTokens = CSLTokenizeString2(pszType,"(),",0); if (CSLCount(papszTokens) >= 3) { /* width is the second and precision is the third */ oField.SetWidth(atoi(papszTokens[1])); oField.SetPrecision(atoi(papszTokens[2])); } CSLDestroy( papszTokens ); oField.SetType( OFTReal ); } else if( EQUAL(pszType,"decimal") ) { oField.SetType( OFTReal ); } else if( EQUAL(pszType, "date") ) { oField.SetType( OFTDate ); } else if( EQUAL(pszType, "time") ) { oField.SetType( OFTTime ); } else if( EQUAL(pszType, "datetime") || EQUAL(pszType, "timestamp") ) { oField.SetType( OFTDateTime ); } else if( EQUAL(pszType, "year") ) { oField.SetType( OFTString ); oField.SetWidth( 10 ); } else if( EQUAL(pszType, "geometry") || OGRFromOGCGeomType(pszType) != wkbUnknown) { if (pszGeomColumn == NULL) { pszGeomColumn = CPLStrdup(papszRow[0]); eForcedGeomType = OGRFromOGCGeomType(pszType); bGeomColumnNotNullable = ( papszRow[2] != NULL && EQUAL(papszRow[2], "NO") ); } else { CPLDebug("MYSQL", "Ignoring %s as geometry column. Another one(%s) has already been found before", papszRow[0], pszGeomColumn); } continue; } // Is this an integer primary key field? if( !bHasFid && papszRow[3] != NULL && EQUAL(papszRow[3],"PRI") && (oField.GetType() == OFTInteger || oField.GetType() == OFTInteger64) ) { bHasFid = TRUE; pszFIDColumn = CPLStrdup(oField.GetNameRef()); if( oField.GetType() == OFTInteger64 ) SetMetadataItem(OLMD_FID64, "YES"); continue; } // Is not nullable ? if( papszRow[2] != NULL && EQUAL(papszRow[2], "NO") ) oField.SetNullable(FALSE); // Has default ? const char* pszDefault = papszRow[4]; if( pszDefault != NULL ) { if( !EQUAL(pszDefault, "NULL") && !STARTS_WITH_CI(pszDefault, "CURRENT_") && pszDefault[0] != '(' && pszDefault[0] != '\'' && CPLGetValueType(pszDefault) == CPL_VALUE_STRING ) { int nYear, nMonth, nDay, nHour, nMinute; float fSecond; if( oField.GetType() == OFTDateTime && sscanf(pszDefault, "%d-%d-%d %d:%d:%f", &nYear, &nMonth, &nDay, &nHour, &nMinute, &fSecond) == 6 ) { oField.SetDefault(CPLSPrintf("'%04d/%02d/%02d %02d:%02d:%02d'", nYear, nMonth, nDay, nHour, nMinute, (int)(fSecond+0.5))); } else { CPLString osDefault("'"); char* pszTmp = CPLEscapeString(pszDefault, -1, CPLES_SQL); osDefault += pszTmp; CPLFree(pszTmp); osDefault += "'"; oField.SetDefault(osDefault); } } else { oField.SetDefault(pszDefault); } } poDefn->AddFieldDefn( &oField ); } // set to none for now... if we have a geometry column it will be set layer. poDefn->SetGeomType( wkbNone ); if( hResult != NULL ) { mysql_free_result( hResult ); hResultSet = NULL; } if( bHasFid ) CPLDebug( "MySQL", "table %s has FID column %s.", pszTable, pszFIDColumn ); else CPLDebug( "MySQL", "table %s has no FID column, FIDs will not be reliable!", pszTable ); if (pszGeomColumn) { char* pszType=NULL; // set to unknown first poDefn->SetGeomType( wkbUnknown ); osCommand = "SELECT type, coord_dimension FROM geometry_columns WHERE f_table_name='"; osCommand += pszTable; osCommand += "'"; hResult = NULL; if( !mysql_query( poDS->GetConn(), osCommand ) ) hResult = mysql_store_result( poDS->GetConn() ); papszRow = NULL; if( hResult != NULL ) papszRow = mysql_fetch_row( hResult ); if( papszRow != NULL && papszRow[0] != NULL ) { pszType = papszRow[0]; OGRwkbGeometryType l_nGeomType = OGRFromOGCGeomType(pszType); if( papszRow[1] != NULL && atoi(papszRow[1]) == 3 ) l_nGeomType = wkbSetZ(l_nGeomType); poDefn->SetGeomType( l_nGeomType ); } else if (eForcedGeomType != wkbUnknown) poDefn->SetGeomType(eForcedGeomType); if( bGeomColumnNotNullable ) poDefn->GetGeomFieldDefn(0)->SetNullable(FALSE); if( hResult != NULL ) mysql_free_result( hResult ); //Free our query results for finding type. hResult = NULL; } // Fetch the SRID for this table now nSRSId = FetchSRSId(); return poDefn; }