int OGRMySQLDataSource::OpenTable( const char *pszNewName, int bUpdate ) { /* -------------------------------------------------------------------- */ /* Create the layer object. */ /* -------------------------------------------------------------------- */ OGRMySQLTableLayer *poLayer; OGRErr eErr; poLayer = new OGRMySQLTableLayer( this, pszNewName, bUpdate ); eErr = poLayer->Initialize(pszNewName); if (eErr == OGRERR_FAILURE) return FALSE; /* -------------------------------------------------------------------- */ /* Add layer to data source layer list. */ /* -------------------------------------------------------------------- */ papoLayers = (OGRMySQLLayer **) CPLRealloc( papoLayers, sizeof(OGRMySQLLayer *) * (nLayers+1) ); papoLayers[nLayers++] = poLayer; return TRUE; }
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; }