int OGRMSSQLSpatialDataSource::Open( const char * pszNewName, int bUpdate, int bTestOpen ) { CPLAssert( nLayers == 0 ); if( !EQUALN(pszNewName,"MSSQL:",6) ) { if( !bTestOpen ) CPLError( CE_Failure, CPLE_AppDefined, "%s does not conform to MSSSQLSpatial naming convention," " MSSQL:*\n", pszNewName ); return FALSE; } /* Determine if the connection string contains specific values */ char* pszTableSpec = NULL; char* pszGeometryFormat = NULL; char* pszConnectionName = CPLStrdup(pszNewName + 6); int nCurrent, nNext, nTerm; nCurrent = nNext = nTerm = strlen(pszConnectionName); while (nCurrent > 0) { --nCurrent; if (pszConnectionName[nCurrent] == ';') { nNext = nCurrent; continue; } if (ParseValue(&pszCatalog, pszConnectionName, "database=", nCurrent, nNext, nTerm, FALSE)) continue; if (ParseValue(&pszTableSpec, pszConnectionName, "tables=", nCurrent, nNext, nTerm, TRUE)) continue; if (ParseValue(&pszGeometryFormat, pszConnectionName, "geometryformat=", nCurrent, nNext, nTerm, TRUE)) { if (EQUALN(pszGeometryFormat, "wkb",3)) nGeometryFormat = MSSQLGEOMETRY_WKB; else if (EQUALN(pszGeometryFormat,"wkt",3)) nGeometryFormat = MSSQLGEOMETRY_WKT; else if (EQUALN(pszGeometryFormat,"native",3)) nGeometryFormat = MSSQLGEOMETRY_NATIVE; else { CPLError( CE_Failure, CPLE_AppDefined, "Invalid geometry type specified: %s," " MSSQL:*\n", pszGeometryFormat ); CPLFree(pszTableSpec); CPLFree(pszGeometryFormat); CPLFree(pszConnectionName); return FALSE; } CPLFree(pszGeometryFormat); pszGeometryFormat = NULL; continue; } } /* Determine if the connection string contains the catalog portion */ if( pszCatalog == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "'%s' does not contain the 'database' portion\n", pszNewName ); CPLFree(pszTableSpec); CPLFree(pszGeometryFormat); CPLFree(pszConnectionName); return FALSE; } pszName = CPLStrdup(pszNewName); char **papszTableNames=NULL; char **papszSchemaNames=NULL; char **papszGeomColumnNames=NULL; char **papszCoordDimensions=NULL; char **papszSRIds=NULL; /* Determine if the connection string contains the TABLES portion */ if( pszTableSpec != NULL ) { char **papszTableList; int i; papszTableList = CSLTokenizeString2( pszTableSpec, ",", 0 ); for( i = 0; i < CSLCount(papszTableList); i++ ) { char **papszQualifiedParts; // Get schema and table name papszQualifiedParts = CSLTokenizeString2( papszTableList[i], ".", 0 ); /* Find the geometry column name if specified */ if( CSLCount( papszQualifiedParts ) >= 1 ) { char* pszGeomColumnName = NULL; char* pos = strchr(papszQualifiedParts[CSLCount( papszQualifiedParts ) - 1], '('); if (pos != NULL) { *pos = '\0'; pszGeomColumnName = pos+1; int len = strlen(pszGeomColumnName); if (len > 0) pszGeomColumnName[len - 1] = '\0'; } papszGeomColumnNames = CSLAddString( papszGeomColumnNames, pszGeomColumnName ? pszGeomColumnName : ""); } if( CSLCount( papszQualifiedParts ) == 2 ) { papszSchemaNames = CSLAddString( papszSchemaNames, papszQualifiedParts[0] ); papszTableNames = CSLAddString( papszTableNames, papszQualifiedParts[1] ); } else if( CSLCount( papszQualifiedParts ) == 1 ) { papszSchemaNames = CSLAddString( papszSchemaNames, "dbo"); papszTableNames = CSLAddString( papszTableNames, papszQualifiedParts[0] ); } CSLDestroy(papszQualifiedParts); } CSLDestroy(papszTableList); } CPLFree(pszTableSpec); /* Initialize the SQL Server connection. */ CPLDebug( "OGR_MSSQLSpatial", "EstablishSession(Connection:\"%s\")", pszConnectionName); if( !oSession.EstablishSession( CPLSPrintf("DRIVER=SQL Server;%s", pszConnectionName), "", "" ) ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to initialize connection to the server for %s,\n" "%s", pszNewName, oSession.GetLastError() ); CSLDestroy( papszTableNames ); CSLDestroy( papszSchemaNames ); CSLDestroy( papszGeomColumnNames ); CSLDestroy( papszCoordDimensions ); CSLDestroy( papszSRIds ); CPLFree(pszGeometryFormat); CPLFree(pszConnectionName); return FALSE; } char** papszTypes = NULL; /* Determine the available tables if not specified. */ if (papszTableNames == NULL) { CPLODBCStatement oStmt( &oSession ); oStmt.Append( "SELECT f_table_schema, f_table_name, f_geometry_column, coord_dimension, srid, geometry_type FROM dbo.geometry_columns"); if( oStmt.ExecuteSQL() ) { while( oStmt.Fetch() ) { papszSchemaNames = CSLAddString( papszSchemaNames, oStmt.GetColData(0) ); papszTableNames = CSLAddString( papszTableNames, oStmt.GetColData(1) ); papszGeomColumnNames = CSLAddString( papszGeomColumnNames, oStmt.GetColData(2) ); papszCoordDimensions = CSLAddString( papszCoordDimensions, oStmt.GetColData(3) ); papszSRIds = CSLAddString( papszSRIds, oStmt.GetColData(4) ); papszTypes = CSLAddString( papszTypes, oStmt.GetColData(5) ); } } } int nSRId, nCoordDimension; OGRwkbGeometryType eType; for( int iTable = 0; papszTableNames != NULL && papszTableNames[iTable] != NULL; iTable++ ) { if (papszSRIds != NULL) nSRId = atoi(papszSRIds[iTable]); else nSRId = -1; if (papszCoordDimensions != NULL) nCoordDimension = atoi(papszCoordDimensions[iTable]); else nCoordDimension = 2; if (papszTypes != NULL) eType = OGRFromOGCGeomType(papszTypes[iTable]); else eType = wkbUnknown; if( strlen(papszGeomColumnNames[iTable]) > 0 ) OpenTable( papszSchemaNames[iTable], papszTableNames[iTable], papszGeomColumnNames[iTable], nCoordDimension, nSRId, eType, bUpdate ); else OpenTable( papszSchemaNames[iTable], papszTableNames[iTable], NULL, nCoordDimension, nSRId, eType, bUpdate ); } CSLDestroy( papszTableNames ); CSLDestroy( papszSchemaNames ); CSLDestroy( papszGeomColumnNames ); CSLDestroy( papszCoordDimensions ); CSLDestroy( papszSRIds ); CSLDestroy( papszTypes ); CPLFree(pszGeometryFormat); CPLFree(pszConnectionName); bDSUpdate = bUpdate; return TRUE; }
int OGRMSSQLSpatialDataSource::Open( const char * pszNewName, int bUpdate, int bTestOpen ) { CPLAssert( nLayers == 0 ); if( !EQUALN(pszNewName,"MSSQL:",6) ) { if( !bTestOpen ) CPLError( CE_Failure, CPLE_AppDefined, "%s does not conform to MSSSQLSpatial naming convention," " MSSQL:*\n", pszNewName ); return FALSE; } /* Determine if the connection string contains specific values */ char* pszTableSpec = NULL; char* pszGeometryFormat = NULL; char* pszConnectionName = CPLStrdup(pszNewName + 6); char* pszDriver = NULL; int nCurrent, nNext, nTerm; nCurrent = nNext = nTerm = strlen(pszConnectionName); while (nCurrent > 0) { --nCurrent; if (pszConnectionName[nCurrent] == ';') { nNext = nCurrent; continue; } if (ParseValue(&pszCatalog, pszConnectionName, "database=", nCurrent, nNext, nTerm, FALSE)) continue; if (ParseValue(&pszTableSpec, pszConnectionName, "tables=", nCurrent, nNext, nTerm, TRUE)) continue; if (ParseValue(&pszDriver, pszConnectionName, "driver=", nCurrent, nNext, nTerm, FALSE)) continue; if (ParseValue(&pszGeometryFormat, pszConnectionName, "geometryformat=", nCurrent, nNext, nTerm, TRUE)) { if (EQUALN(pszGeometryFormat,"wkbzm",5)) nGeometryFormat = MSSQLGEOMETRY_WKBZM; else if (EQUALN(pszGeometryFormat, "wkb",3)) nGeometryFormat = MSSQLGEOMETRY_WKB; else if (EQUALN(pszGeometryFormat,"wkt",3)) nGeometryFormat = MSSQLGEOMETRY_WKT; else if (EQUALN(pszGeometryFormat,"native",6)) nGeometryFormat = MSSQLGEOMETRY_NATIVE; else { CPLError( CE_Failure, CPLE_AppDefined, "Invalid geometry type specified: %s," " MSSQL:*\n", pszGeometryFormat ); CPLFree(pszTableSpec); CPLFree(pszGeometryFormat); CPLFree(pszConnectionName); CPLFree(pszDriver); return FALSE; } CPLFree(pszGeometryFormat); pszGeometryFormat = NULL; continue; } } /* Determine if the connection string contains the catalog portion */ if( pszCatalog == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "'%s' does not contain the 'database' portion\n", pszNewName ); CPLFree(pszTableSpec); CPLFree(pszGeometryFormat); CPLFree(pszConnectionName); CPLFree(pszDriver); return FALSE; } pszName = CPLStrdup(pszNewName); char **papszTableNames=NULL; char **papszSchemaNames=NULL; char **papszGeomColumnNames=NULL; char **papszCoordDimensions=NULL; char **papszSRIds=NULL; char **papszSRTexts=NULL; /* Determine if the connection string contains the TABLES portion */ if( pszTableSpec != NULL ) { char **papszTableList; int i; papszTableList = CSLTokenizeString2( pszTableSpec, ",", 0 ); for( i = 0; i < CSLCount(papszTableList); i++ ) { char **papszQualifiedParts; // Get schema and table name papszQualifiedParts = CSLTokenizeString2( papszTableList[i], ".", 0 ); /* Find the geometry column name if specified */ if( CSLCount( papszQualifiedParts ) >= 1 ) { char* pszGeomColumnName = NULL; char* pos = strchr(papszQualifiedParts[CSLCount( papszQualifiedParts ) - 1], '('); if (pos != NULL) { *pos = '\0'; pszGeomColumnName = pos+1; int len = strlen(pszGeomColumnName); if (len > 0) pszGeomColumnName[len - 1] = '\0'; } papszGeomColumnNames = CSLAddString( papszGeomColumnNames, pszGeomColumnName ? pszGeomColumnName : ""); } if( CSLCount( papszQualifiedParts ) == 2 ) { papszSchemaNames = CSLAddString( papszSchemaNames, papszQualifiedParts[0] ); papszTableNames = CSLAddString( papszTableNames, papszQualifiedParts[1] ); } else if( CSLCount( papszQualifiedParts ) == 1 ) { papszSchemaNames = CSLAddString( papszSchemaNames, "dbo"); papszTableNames = CSLAddString( papszTableNames, papszQualifiedParts[0] ); } CSLDestroy(papszQualifiedParts); } CSLDestroy(papszTableList); } CPLFree(pszTableSpec); /* Initialize the SQL Server connection. */ int nResult; if ( pszDriver != NULL ) { /* driver has been specified */ CPLDebug( "OGR_MSSQLSpatial", "EstablishSession(Connection:\"%s\")", pszConnectionName); nResult = oSession.EstablishSession( pszConnectionName, "", "" ); } else { /* no driver has been specified, defautls to SQL Server */ CPLDebug( "OGR_MSSQLSpatial", "EstablishSession(Connection:\"%s\")", pszConnectionName); nResult = oSession.EstablishSession( CPLSPrintf("DRIVER=SQL Server;%s", pszConnectionName), "", "" ); } CPLFree(pszDriver); if( !nResult ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to initialize connection to the server for %s,\n" "%s", pszNewName, oSession.GetLastError() ); CSLDestroy( papszTableNames ); CSLDestroy( papszSchemaNames ); CSLDestroy( papszGeomColumnNames ); CSLDestroy( papszCoordDimensions ); CSLDestroy( papszSRIds ); CSLDestroy( papszSRTexts ); CPLFree(pszGeometryFormat); CPLFree(pszConnectionName); return FALSE; } char** papszTypes = NULL; /* read metadata for the specified tables */ if (papszTableNames != NULL && bUseGeometryColumns) { for( int iTable = 0; papszTableNames != NULL && papszTableNames[iTable] != NULL; iTable++ ) { CPLODBCStatement oStmt( &oSession ); /* Use join to make sure the existence of the referred column/table */ oStmt.Appendf( "SELECT f_geometry_column, coord_dimension, g.srid, srtext, geometry_type FROM dbo.geometry_columns g JOIN INFORMATION_SCHEMA.COLUMNS ON f_table_schema = TABLE_SCHEMA and f_table_name = TABLE_NAME and f_geometry_column = COLUMN_NAME left outer join dbo.spatial_ref_sys s on g.srid = s.srid WHERE f_table_schema = '%s' AND f_table_name = '%s'", papszSchemaNames[iTable], papszTableNames[iTable]); if( oStmt.ExecuteSQL() ) { while( oStmt.Fetch() ) { if (papszGeomColumnNames == NULL) papszGeomColumnNames = CSLAddString( papszGeomColumnNames, oStmt.GetColData(0) ); else if (*papszGeomColumnNames[iTable] == 0) { CPLFree(papszGeomColumnNames[iTable]); papszGeomColumnNames[iTable] = CPLStrdup( oStmt.GetColData(0) ); } papszCoordDimensions = CSLAddString( papszCoordDimensions, oStmt.GetColData(1, "2") ); papszSRIds = CSLAddString( papszSRIds, oStmt.GetColData(2, "0") ); papszSRTexts = CSLAddString( papszSRTexts, oStmt.GetColData(3, "") ); papszTypes = CSLAddString( papszTypes, oStmt.GetColData(4, "GEOMETRY") ); } } else { /* probably the table is missing at all */ InitializeMetadataTables(); } } } /* if requesting all user database table then this takes priority */ if (papszTableNames == NULL && bListAllTables) { CPLODBCStatement oStmt( &oSession ); oStmt.Append( "select sys.schemas.name, sys.schemas.name + '.' + sys.objects.name, sys.columns.name from sys.columns join sys.types on sys.columns.system_type_id = sys.types.system_type_id and sys.columns.user_type_id = sys.types.user_type_id join sys.objects on sys.objects.object_id = sys.columns.object_id join sys.schemas on sys.objects.schema_id = sys.schemas.schema_id where (sys.types.name = 'geometry' or sys.types.name = 'geography') and (sys.objects.type = 'U' or sys.objects.type = 'V') union all select sys.schemas.name, sys.schemas.name + '.' + sys.objects.name, '' from sys.objects join sys.schemas on sys.objects.schema_id = sys.schemas.schema_id where not exists (select * from sys.columns sc1 join sys.types on sc1.system_type_id = sys.types.system_type_id where (sys.types.name = 'geometry' or sys.types.name = 'geography') and sys.objects.object_id = sc1.object_id) and (sys.objects.type = 'U' or sys.objects.type = 'V')" ); if( oStmt.ExecuteSQL() ) { while( oStmt.Fetch() ) { papszSchemaNames = CSLAddString( papszSchemaNames, oStmt.GetColData(0) ); papszTableNames = CSLAddString( papszTableNames, oStmt.GetColData(1) ); papszGeomColumnNames = CSLAddString( papszGeomColumnNames, oStmt.GetColData(2) ); } } } /* Determine the available tables if not specified. */ if (papszTableNames == NULL && bUseGeometryColumns) { CPLODBCStatement oStmt( &oSession ); /* Use join to make sure the existence of the referred column/table */ oStmt.Append( "SELECT f_table_schema, f_table_name, f_geometry_column, coord_dimension, g.srid, srtext, geometry_type FROM dbo.geometry_columns g JOIN INFORMATION_SCHEMA.COLUMNS ON f_table_schema = TABLE_SCHEMA and f_table_name = TABLE_NAME and f_geometry_column = COLUMN_NAME left outer join dbo.spatial_ref_sys s on g.srid = s.srid"); if( oStmt.ExecuteSQL() ) { while( oStmt.Fetch() ) { papszSchemaNames = CSLAddString( papszSchemaNames, oStmt.GetColData(0, "dbo") ); papszTableNames = CSLAddString( papszTableNames, oStmt.GetColData(1) ); papszGeomColumnNames = CSLAddString( papszGeomColumnNames, oStmt.GetColData(2) ); papszCoordDimensions = CSLAddString( papszCoordDimensions, oStmt.GetColData(3, "2") ); papszSRIds = CSLAddString( papszSRIds, oStmt.GetColData(4, "0") ); papszSRTexts = CSLAddString( papszSRTexts, oStmt.GetColData(5, "") ); papszTypes = CSLAddString( papszTypes, oStmt.GetColData(6, "GEOMETRY") ); } } else { /* probably the table is missing at all */ InitializeMetadataTables(); } } /* Query catalog for tables having geometry columns */ if (papszTableNames == NULL) { CPLODBCStatement oStmt( &oSession ); oStmt.Append( "SELECT sys.schemas.name, sys.schemas.name + '.' + sys.objects.name, sys.columns.name from sys.columns join sys.types on sys.columns.system_type_id = sys.types.system_type_id and sys.columns.user_type_id = sys.types.user_type_id join sys.objects on sys.objects.object_id = sys.columns.object_id join sys.schemas on sys.objects.schema_id = sys.schemas.schema_id where (sys.types.name = 'geometry' or sys.types.name = 'geography') and (sys.objects.type = 'U' or sys.objects.type = 'V')"); if( oStmt.ExecuteSQL() ) { while( oStmt.Fetch() ) { papszSchemaNames = CSLAddString( papszSchemaNames, oStmt.GetColData(0) ); papszTableNames = CSLAddString( papszTableNames, oStmt.GetColData(1) ); papszGeomColumnNames = CSLAddString( papszGeomColumnNames, oStmt.GetColData(2) ); } } } int nSRId, nCoordDimension; OGRwkbGeometryType eType; for( int iTable = 0; papszTableNames != NULL && papszTableNames[iTable] != NULL; iTable++ ) { if (papszSRIds != NULL) nSRId = atoi(papszSRIds[iTable]); else nSRId = -1; if (papszCoordDimensions != NULL) nCoordDimension = atoi(papszCoordDimensions[iTable]); else nCoordDimension = 2; if (papszTypes != NULL) eType = OGRFromOGCGeomType(papszTypes[iTable]); else eType = wkbUnknown; if( strlen(papszGeomColumnNames[iTable]) > 0 ) OpenTable( papszSchemaNames[iTable], papszTableNames[iTable], papszGeomColumnNames[iTable], nCoordDimension, nSRId, papszSRTexts? papszSRTexts[iTable] : NULL, eType, bUpdate ); else OpenTable( papszSchemaNames[iTable], papszTableNames[iTable], NULL, nCoordDimension, nSRId, papszSRTexts? papszSRTexts[iTable] : NULL, wkbNone, bUpdate ); } CSLDestroy( papszTableNames ); CSLDestroy( papszSchemaNames ); CSLDestroy( papszGeomColumnNames ); CSLDestroy( papszCoordDimensions ); CSLDestroy( papszSRIds ); CSLDestroy( papszSRTexts ); CSLDestroy( papszTypes ); CPLFree(pszGeometryFormat); CPLFree(pszConnectionName); bDSUpdate = bUpdate; return TRUE; }
void OGRCloudantTableLayer::LoadMetadata() { if( bHasLoadedMetadata ) return; bHasLoadedMetadata = true; if (pszSpatialDDoc == nullptr) GetSpatialView(); if( pszSpatialDDoc == nullptr ) return; CPLString osURI("/"); osURI += osEscapedName; osURI += "/"; osURI += pszSpatialDDoc; json_object* poAnswerObj = poDS->GET(osURI); if (poAnswerObj == nullptr) return; if ( !json_object_is_type(poAnswerObj, json_type_object) ) { CPLError(CE_Failure, CPLE_AppDefined, "LoadMetadata() failed"); json_object_put(poAnswerObj); return; } json_object* poRev = CPL_json_object_object_get(poAnswerObj, "_rev"); const char* pszRev = json_object_get_string(poRev); if (pszRev) osMetadataRev = pszRev; json_object* poError = CPL_json_object_object_get(poAnswerObj, "error"); const char* pszError = json_object_get_string(poError); if (pszError && strcmp(pszError, "not_found") == 0) { json_object_put(poAnswerObj); return; } if (poDS->IsError(poAnswerObj, "LoadMetadata() failed")) { json_object_put(poAnswerObj); return; } json_object* poJsonSRS = CPL_json_object_object_get(poAnswerObj, "srsid"); const char* pszSRS = json_object_get_string(poJsonSRS); if (pszSRS != nullptr) { poSRS = new OGRSpatialReference(); if (poSRS->importFromURN(pszSRS) != OGRERR_NONE) { delete poSRS; poSRS = nullptr; } } json_object* poGeomType = CPL_json_object_object_get(poAnswerObj, "geomtype"); const char* pszGeomType = json_object_get_string(poGeomType); if (pszGeomType) { if (EQUAL(pszGeomType, "NONE")) { eGeomType = wkbNone; bExtentValid = true; } else { eGeomType = OGRFromOGCGeomType(pszGeomType); json_object* poIs25D = CPL_json_object_object_get(poAnswerObj, "is_25D"); if (poIs25D && json_object_get_boolean(poIs25D)) eGeomType = wkbSetZ(eGeomType); json_object* poExtent = CPL_json_object_object_get(poAnswerObj, "extent"); if (poExtent && json_object_get_type(poExtent) == json_type_object) { json_object* poBbox = CPL_json_object_object_get(poExtent, "bbox"); if (poBbox && json_object_get_type(poBbox) == json_type_array && json_object_array_length(poBbox) == 4 && OGRCloudantIsNumericObject(json_object_array_get_idx(poBbox, 0)) && OGRCloudantIsNumericObject(json_object_array_get_idx(poBbox, 1)) && OGRCloudantIsNumericObject(json_object_array_get_idx(poBbox, 2)) && OGRCloudantIsNumericObject(json_object_array_get_idx(poBbox, 3))) { dfMinX = json_object_get_double(json_object_array_get_idx(poBbox, 0)); dfMinY = json_object_get_double(json_object_array_get_idx(poBbox, 1)); dfMaxX = json_object_get_double(json_object_array_get_idx(poBbox, 2)); dfMaxY = json_object_get_double(json_object_array_get_idx(poBbox, 3)); bExtentValid = true; bExtentSet = true; } } } } json_object* poGeoJSON = CPL_json_object_object_get(poAnswerObj, "geojson_documents"); if (poGeoJSON && json_object_is_type(poGeoJSON, json_type_boolean)) bGeoJSONDocument = CPL_TO_BOOL(json_object_get_boolean(poGeoJSON)); json_object* poFields = CPL_json_object_object_get(poAnswerObj, "fields"); if (poFields && json_object_is_type(poFields, json_type_array)) { poFeatureDefn = new OGRFeatureDefn( osName ); poFeatureDefn->Reference(); poFeatureDefn->SetGeomType(eGeomType); if( poFeatureDefn->GetGeomFieldCount() != 0 ) poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(poSRS); OGRFieldDefn oFieldId("_id", OFTString); poFeatureDefn->AddFieldDefn(&oFieldId); OGRFieldDefn oFieldRev("_rev", OFTString); poFeatureDefn->AddFieldDefn(&oFieldRev); int nFields = json_object_array_length(poFields); for(int i=0;i<nFields;i++) { json_object* poField = json_object_array_get_idx(poFields, i); if (poField && json_object_is_type(poField, json_type_object)) { json_object* poName = CPL_json_object_object_get(poField, "name"); const char* pszName = json_object_get_string(poName); if (pszName) { json_object* poType = CPL_json_object_object_get(poField, "type"); const char* pszType = json_object_get_string(poType); OGRFieldType eType = OFTString; if (pszType) { if (strcmp(pszType, "integer") == 0) eType = OFTInteger; else if (strcmp(pszType, "integerlist") == 0) eType = OFTIntegerList; else if (strcmp(pszType, "real") == 0) eType = OFTReal; else if (strcmp(pszType, "reallist") == 0) eType = OFTRealList; else if (strcmp(pszType, "string") == 0) eType = OFTString; else if (strcmp(pszType, "stringlist") == 0) eType = OFTStringList; } OGRFieldDefn oField(pszName, eType); poFeatureDefn->AddFieldDefn(&oField); } } } } std::sort(aosIdsToFetch.begin(), aosIdsToFetch.end()); json_object_put(poAnswerObj); return; }
int swq_select::PushField( swq_expr_node *poExpr, const char *pszAlias, int distinct_flag ) { if( query_mode == SWQM_DISTINCT_LIST && distinct_flag ) { CPLError(CE_Failure, CPLE_NotSupported, "SELECT DISTINCT and COUNT(DISTINCT...) not supported together"); return FALSE; } /* -------------------------------------------------------------------- */ /* Grow the array. */ /* -------------------------------------------------------------------- */ result_columns++; column_defs = (swq_col_def *) CPLRealloc( column_defs, sizeof(swq_col_def) * result_columns ); swq_col_def *col_def = column_defs + result_columns - 1; memset( col_def, 0, sizeof(swq_col_def) ); /* -------------------------------------------------------------------- */ /* Try to capture a field name. */ /* -------------------------------------------------------------------- */ if( poExpr->eNodeType == SNT_COLUMN ) { col_def->table_name = CPLStrdup(poExpr->table_name ? poExpr->table_name : ""); col_def->field_name = CPLStrdup(poExpr->string_value); } else if( poExpr->eNodeType == SNT_OPERATION && (poExpr->nOperation == SWQ_CAST || (poExpr->nOperation >= SWQ_AVG && poExpr->nOperation <= SWQ_SUM)) && poExpr->nSubExprCount >= 1 && poExpr->papoSubExpr[0]->eNodeType == SNT_COLUMN ) { col_def->table_name = CPLStrdup(poExpr->papoSubExpr[0]->table_name ? poExpr->papoSubExpr[0]->table_name : ""); col_def->field_name = CPLStrdup(poExpr->papoSubExpr[0]->string_value); } else { col_def->table_name = CPLStrdup(""); col_def->field_name = CPLStrdup(""); } /* -------------------------------------------------------------------- */ /* Initialize fields. */ /* -------------------------------------------------------------------- */ if( pszAlias != NULL ) col_def->field_alias = CPLStrdup( pszAlias ); else if( pszAlias == NULL && poExpr->eNodeType == SNT_OPERATION && poExpr->nSubExprCount >= 1 && ( poExpr->nOperation == SWQ_CONCAT || poExpr->nOperation == SWQ_SUBSTR ) && poExpr->papoSubExpr[0]->eNodeType == SNT_COLUMN ) { const swq_operation *op = swq_op_registrar::GetOperator( (swq_op) poExpr->nOperation ); col_def->field_alias = CPLStrdup( CPLSPrintf("%s_%s", op->pszName, poExpr->papoSubExpr[0]->string_value)); } col_def->table_index = -1; col_def->field_index = -1; col_def->field_type = SWQ_OTHER; col_def->field_precision = -1; col_def->target_type = SWQ_OTHER; col_def->target_subtype = OFSTNone; col_def->col_func = SWQCF_NONE; col_def->distinct_flag = distinct_flag; /* -------------------------------------------------------------------- */ /* Do we have a CAST operator in play? */ /* -------------------------------------------------------------------- */ if( poExpr->eNodeType == SNT_OPERATION && poExpr->nOperation == SWQ_CAST ) { const char *pszTypeName = poExpr->papoSubExpr[1]->string_value; int parse_precision = 0; if( EQUAL(pszTypeName,"character") ) { col_def->target_type = SWQ_STRING; col_def->field_length = 1; } else if( strcasecmp(pszTypeName,"boolean") == 0 ) { col_def->target_type = SWQ_BOOLEAN; } else if( strcasecmp(pszTypeName,"integer") == 0 ) { col_def->target_type = SWQ_INTEGER; } else if( strcasecmp(pszTypeName,"bigint") == 0 ) { col_def->target_type = SWQ_INTEGER64; } else if( strcasecmp(pszTypeName,"smallint") == 0 ) { col_def->target_type = SWQ_INTEGER; col_def->target_subtype = OFSTInt16; } else if( strcasecmp(pszTypeName,"float") == 0 ) { col_def->target_type = SWQ_FLOAT; } else if( strcasecmp(pszTypeName,"numeric") == 0 ) { col_def->target_type = SWQ_FLOAT; parse_precision = 1; } else if( strcasecmp(pszTypeName,"timestamp") == 0 ) { col_def->target_type = SWQ_TIMESTAMP; } else if( strcasecmp(pszTypeName,"date") == 0 ) { col_def->target_type = SWQ_DATE; } else if( strcasecmp(pszTypeName,"time") == 0 ) { col_def->target_type = SWQ_TIME; } else if( strcasecmp(pszTypeName,"geometry") == 0 ) { col_def->target_type = SWQ_GEOMETRY; } else { CPLError( CE_Failure, CPLE_AppDefined, "Unrecognized typename %s in CAST operator.", pszTypeName ); CPLFree(col_def->table_name); col_def->table_name = NULL; CPLFree(col_def->field_name); col_def->field_name = NULL; CPLFree(col_def->field_alias); col_def->field_alias = NULL; result_columns--; return FALSE; } if( col_def->target_type == SWQ_GEOMETRY ) { if( poExpr->nSubExprCount > 2 ) { if( poExpr->papoSubExpr[2]->field_type != SWQ_STRING ) { CPLError( CE_Failure, CPLE_AppDefined, "First argument of CAST operator should be an geometry type identifier." ); CPLFree(col_def->table_name); col_def->table_name = NULL; CPLFree(col_def->field_name); col_def->field_name = NULL; CPLFree(col_def->field_alias); col_def->field_alias = NULL; result_columns--; return FALSE; } col_def->eGeomType = OGRFromOGCGeomType(poExpr->papoSubExpr[2]->string_value); // SRID if( poExpr->nSubExprCount > 3 ) { col_def->nSRID = (int)poExpr->papoSubExpr[3]->int_value; } } } else { // field width. if( poExpr->nSubExprCount > 2 ) { if( poExpr->papoSubExpr[2]->field_type != SWQ_INTEGER ) { CPLError( CE_Failure, CPLE_AppDefined, "First argument of CAST operator should be of integer type." ); CPLFree(col_def->table_name); col_def->table_name = NULL; CPLFree(col_def->field_name); col_def->field_name = NULL; CPLFree(col_def->field_alias); col_def->field_alias = NULL; result_columns--; return FALSE; } col_def->field_length = (int)poExpr->papoSubExpr[2]->int_value; } // field width. if( poExpr->nSubExprCount > 3 && parse_precision ) { col_def->field_precision = (int)poExpr->papoSubExpr[3]->int_value; if( col_def->field_precision == 0 ) { if( col_def->field_length < 10 ) col_def->target_type = SWQ_INTEGER; else if( col_def->field_length < 19 ) col_def->target_type = SWQ_INTEGER64; } } } } /* -------------------------------------------------------------------- */ /* Do we have a special column function in play? */ /* -------------------------------------------------------------------- */ if( poExpr->eNodeType == SNT_OPERATION && poExpr->nOperation >= SWQ_AVG && poExpr->nOperation <= SWQ_SUM ) { if( poExpr->nSubExprCount != 1 ) { const swq_operation *poOp = swq_op_registrar::GetOperator( (swq_op)poExpr->nOperation ); CPLError( CE_Failure, CPLE_AppDefined, "Column Summary Function '%s' has wrong number of arguments.", poOp->pszName ); CPLFree(col_def->table_name); col_def->table_name = NULL; CPLFree(col_def->field_name); col_def->field_name = NULL; CPLFree(col_def->field_alias); col_def->field_alias = NULL; result_columns--; return FALSE; } else if( poExpr->papoSubExpr[0]->eNodeType != SNT_COLUMN ) { const swq_operation *poOp = swq_op_registrar::GetOperator( (swq_op)poExpr->nOperation ); CPLError( CE_Failure, CPLE_AppDefined, "Argument of column Summary Function '%s' should be a column.", poOp->pszName ); CPLFree(col_def->table_name); col_def->table_name = NULL; CPLFree(col_def->field_name); col_def->field_name = NULL; CPLFree(col_def->field_alias); col_def->field_alias = NULL; result_columns--; return FALSE; } else { col_def->col_func = (swq_col_func) poExpr->nOperation; swq_expr_node *poSubExpr = poExpr->papoSubExpr[0]; poExpr->papoSubExpr[0] = NULL; poExpr->nSubExprCount = 0; delete poExpr; poExpr = poSubExpr; } } col_def->expr = poExpr; return TRUE; }
OGRFeatureDefn * OGRCARTODBTableLayer::GetLayerDefnInternal(CPL_UNUSED json_object* poObjIn) { if( poFeatureDefn != NULL ) return poFeatureDefn; CPLString osCommand; if( poDS->IsAuthenticatedConnection() ) { // Get everything ! osCommand.Printf( "SELECT a.attname, t.typname, a.attlen, " "format_type(a.atttypid,a.atttypmod), " "a.attnum, " "a.attnotnull, " "i.indisprimary, " "pg_get_expr(def.adbin, c.oid) AS defaultexpr, " "postgis_typmod_dims(a.atttypmod) dim, " "postgis_typmod_srid(a.atttypmod) srid, " "postgis_typmod_type(a.atttypmod)::text geomtyp, " "srtext " "FROM pg_class c " "JOIN pg_attribute a ON a.attnum > 0 AND " "a.attrelid = c.oid AND c.relname = '%s' " "JOIN pg_type t ON a.atttypid = t.oid " "JOIN pg_namespace n ON c.relnamespace=n.oid AND n.nspname= '%s' " "LEFT JOIN pg_index i ON c.oid = i.indrelid AND " "i.indisprimary = 't' AND a.attnum = ANY(i.indkey) " "LEFT JOIN pg_attrdef def ON def.adrelid = c.oid AND " "def.adnum = a.attnum " "LEFT JOIN spatial_ref_sys srs ON srs.srid = postgis_typmod_srid(a.atttypmod) " "ORDER BY a.attnum", OGRCARTODBEscapeLiteral(osName).c_str(), OGRCARTODBEscapeLiteral(poDS->GetCurrentSchema()).c_str()); } else if( poDS->HasOGRMetadataFunction() != FALSE ) { osCommand.Printf( "SELECT * FROM ogr_table_metadata('%s', '%s')", OGRCARTODBEscapeLiteral(poDS->GetCurrentSchema()).c_str(), OGRCARTODBEscapeLiteral(osName).c_str() ); } if( osCommand.size() ) { if( !poDS->IsAuthenticatedConnection() && poDS->HasOGRMetadataFunction() < 0 ) CPLPushErrorHandler(CPLQuietErrorHandler); OGRLayer* poLyr = poDS->ExecuteSQLInternal(osCommand); if( !poDS->IsAuthenticatedConnection() && poDS->HasOGRMetadataFunction() < 0 ) { CPLPopErrorHandler(); if( poLyr == NULL ) { CPLDebug("CARTODB", "ogr_table_metadata(text, text) not available"); CPLErrorReset(); } else if( poLyr->GetLayerDefn()->GetFieldCount() != 12 ) { CPLDebug("CARTODB", "ogr_table_metadata(text, text) has unexpected column count"); poDS->ReleaseResultSet(poLyr); poLyr = NULL; } poDS->SetOGRMetadataFunction(poLyr != NULL); } if( poLyr ) { OGRFeature* poFeat; while( (poFeat = poLyr->GetNextFeature()) != NULL ) { if( poFeatureDefn == NULL ) { // We could do that outside of the while() loop, but // by doing that here, we are somewhat robust to // ogr_table_metadata() returning suddenly an empty result set // for example if CDB_UserTables() no longer works poFeatureDefn = new OGRFeatureDefn(osName); poFeatureDefn->Reference(); poFeatureDefn->SetGeomType(wkbNone); } const char* pszAttname = poFeat->GetFieldAsString("attname"); const char* pszType = poFeat->GetFieldAsString("typname"); int nWidth = poFeat->GetFieldAsInteger("attlen"); const char* pszFormatType = poFeat->GetFieldAsString("format_type"); int bNotNull = poFeat->GetFieldAsInteger("attnotnull"); int bIsPrimary = poFeat->GetFieldAsInteger("indisprimary"); int iDefaultExpr = poLyr->GetLayerDefn()->GetFieldIndex("defaultexpr"); const char* pszDefault = (iDefaultExpr >= 0 && poFeat->IsFieldSet(iDefaultExpr)) ? poFeat->GetFieldAsString(iDefaultExpr) : NULL; if( bIsPrimary && (EQUAL(pszType, "int2") || EQUAL(pszType, "int4") || EQUAL(pszType, "int8") || EQUAL(pszType, "serial") || EQUAL(pszType, "bigserial")) ) { osFIDColName = pszAttname; } else if( strcmp(pszAttname, "created_at") == 0 || strcmp(pszAttname, "updated_at") == 0 || strcmp(pszAttname, "the_geom_webmercator") == 0) { /* ignored */ } else { if( EQUAL(pszType,"geometry") ) { int nDim = poFeat->GetFieldAsInteger("dim"); int nSRID = poFeat->GetFieldAsInteger("srid"); const char* pszGeomType = poFeat->GetFieldAsString("geomtyp"); const char* pszSRText = (poFeat->IsFieldSet( poLyr->GetLayerDefn()->GetFieldIndex("srtext"))) ? poFeat->GetFieldAsString("srtext") : NULL; OGRwkbGeometryType eType = OGRFromOGCGeomType(pszGeomType); if( nDim == 3 ) eType = wkbSetZ(eType); OGRCartoDBGeomFieldDefn *poFieldDefn = new OGRCartoDBGeomFieldDefn(pszAttname, eType); if( bNotNull ) poFieldDefn->SetNullable(FALSE); OGRSpatialReference* poSRS = NULL; if( pszSRText != NULL ) { poSRS = new OGRSpatialReference(); char* pszTmp = (char* )pszSRText; if( poSRS->importFromWkt(&pszTmp) != OGRERR_NONE ) { delete poSRS; poSRS = NULL; } if( poSRS != NULL ) { poFieldDefn->SetSpatialRef(poSRS); poSRS->Release(); } } poFieldDefn->nSRID = nSRID; poFeatureDefn->AddGeomFieldDefn(poFieldDefn, FALSE); } else { OGRFieldDefn oField(pszAttname, OFTString); if( bNotNull ) oField.SetNullable(FALSE); OGRPGCommonLayerSetType(oField, pszType, pszFormatType, nWidth); if( pszDefault ) OGRPGCommonLayerNormalizeDefault(&oField, pszDefault); poFeatureDefn->AddFieldDefn( &oField ); } } delete poFeat; } poDS->ReleaseResultSet(poLyr); } } if( poFeatureDefn == NULL ) { osBaseSQL.Printf("SELECT * FROM %s", OGRCARTODBEscapeIdentifier(osName).c_str()); EstablishLayerDefn(osName, NULL); osBaseSQL = ""; } if( osFIDColName.size() > 0 ) { osBaseSQL = "SELECT "; osBaseSQL += OGRCARTODBEscapeIdentifier(osFIDColName); } for(int i=0; i<poFeatureDefn->GetGeomFieldCount(); i++) { if( osBaseSQL.size() == 0 ) osBaseSQL = "SELECT "; else osBaseSQL += ", "; osBaseSQL += OGRCARTODBEscapeIdentifier(poFeatureDefn->GetGeomFieldDefn(i)->GetNameRef()); } for(int i=0; i<poFeatureDefn->GetFieldCount(); i++) { if( osBaseSQL.size() == 0 ) osBaseSQL = "SELECT "; else osBaseSQL += ", "; osBaseSQL += OGRCARTODBEscapeIdentifier(poFeatureDefn->GetFieldDefn(i)->GetNameRef()); } if( osBaseSQL.size() == 0 ) osBaseSQL = "SELECT *"; osBaseSQL += " FROM "; osBaseSQL += OGRCARTODBEscapeIdentifier(osName); osSELECTWithoutWHERE = osBaseSQL; return poFeatureDefn; }
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; }
int GMLFeatureClass::InitializeFromXML( CPLXMLNode *psRoot ) { /* -------------------------------------------------------------------- */ /* Do some rudimentary checking that this is a well formed */ /* node. */ /* -------------------------------------------------------------------- */ if( psRoot == NULL || psRoot->eType != CXT_Element || !EQUAL(psRoot->pszValue,"GMLFeatureClass") ) { CPLError( CE_Failure, CPLE_AppDefined, "GMLFeatureClass::InitializeFromXML() called on %s node!", psRoot->pszValue ); return FALSE; } if( CPLGetXMLValue( psRoot, "Name", NULL ) == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "GMLFeatureClass has no <Name> element." ); return FALSE; } /* -------------------------------------------------------------------- */ /* Collect base info. */ /* -------------------------------------------------------------------- */ CPLFree( m_pszName ); m_pszName = CPLStrdup( CPLGetXMLValue( psRoot, "Name", NULL ) ); n_nNameLen = strlen(m_pszName); SetElementName( CPLGetXMLValue( psRoot, "ElementPath", m_pszName ) ); /* -------------------------------------------------------------------- */ /* Collect geometry properties. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psThis; int bHasValidGeometryName = FALSE; int bHasValidGeometryElementPath = FALSE; int bHasFoundGeomType = FALSE; int bHasFoundGeomElements = FALSE; const char* pszGName = ""; const char* pszGPath = ""; int nGeomType = wkbUnknown; for( psThis = psRoot->psChild; psThis != NULL; psThis = psThis->psNext ) { if( psThis->eType == CXT_Element && EQUAL(psThis->pszValue, "GeomPropertyDefn") ) { const char *pszName = CPLGetXMLValue( psThis, "Name", "" ); const char *pszElementPath = CPLGetXMLValue( psThis, "ElementPath", "" ); const char *pszType = CPLGetXMLValue( psThis, "Type", NULL ); int bNullable = CSLTestBoolean(CPLGetXMLValue( psThis, "Nullable", "true") ); nGeomType = wkbUnknown; if( pszType != NULL && !EQUAL(pszType, "0") ) { nGeomType = atoi(pszType); OGRwkbGeometryType nFlattenGeomType = wkbFlatten(nGeomType); if( nGeomType != 0 && !(nFlattenGeomType >= wkbPoint && nFlattenGeomType <= wkbMultiSurface) ) { nGeomType = wkbUnknown; CPLError(CE_Warning, CPLE_AppDefined, "Unrecognised geometry type : %s", pszType); } else if( nGeomType == 0 ) nGeomType = OGRFromOGCGeomType(pszType); } bHasFoundGeomElements = TRUE; AddGeometryProperty( new GMLGeometryPropertyDefn( pszName, pszElementPath, nGeomType, -1, bNullable ) ); bHasValidGeometryName = FALSE; bHasValidGeometryElementPath = FALSE; bHasFoundGeomType = FALSE; } else if( psThis->eType == CXT_Element && strcmp(psThis->pszValue, "GeometryName") == 0 ) { bHasFoundGeomElements = TRUE; if( bHasValidGeometryName ) { AddGeometryProperty( new GMLGeometryPropertyDefn( pszGName, pszGPath, nGeomType, -1, TRUE ) ); bHasValidGeometryName = FALSE; bHasValidGeometryElementPath = FALSE; bHasFoundGeomType = FALSE; pszGPath = ""; nGeomType = wkbUnknown; } pszGName = CPLGetXMLValue( psThis, NULL, "" ); bHasValidGeometryName = TRUE; } else if( psThis->eType == CXT_Element && strcmp(psThis->pszValue, "GeometryElementPath") == 0 ) { bHasFoundGeomElements = TRUE; if( bHasValidGeometryElementPath ) { AddGeometryProperty( new GMLGeometryPropertyDefn( pszGName, pszGPath, nGeomType, -1, TRUE ) ); bHasValidGeometryName = FALSE; bHasValidGeometryElementPath = FALSE; bHasFoundGeomType = FALSE; pszGName = ""; nGeomType = wkbUnknown; } pszGPath = CPLGetXMLValue( psThis, NULL, "" ); bHasValidGeometryElementPath = TRUE; } else if( psThis->eType == CXT_Element && strcmp(psThis->pszValue, "GeometryType") == 0 ) { bHasFoundGeomElements = TRUE; if( bHasFoundGeomType ) { AddGeometryProperty( new GMLGeometryPropertyDefn( pszGName, pszGPath, nGeomType, -1, TRUE ) ); bHasValidGeometryName = FALSE; bHasValidGeometryElementPath = FALSE; bHasFoundGeomType = FALSE; pszGName = ""; pszGPath = ""; nGeomType = wkbUnknown; } const char* pszGeometryType = CPLGetXMLValue( psThis, NULL, NULL ); nGeomType = wkbUnknown; if( pszGeometryType != NULL && !EQUAL(pszGeometryType, "0") ) { nGeomType = atoi(pszGeometryType); OGRwkbGeometryType nFlattenGeomType = wkbFlatten(nGeomType); if( nGeomType == 100 || EQUAL(pszGeometryType, "NONE") ) { bHasValidGeometryElementPath = FALSE; bHasFoundGeomType = FALSE; break; } else if( nGeomType != 0 && !(nFlattenGeomType >= wkbPoint && nFlattenGeomType <= wkbMultiSurface) ) { nGeomType = wkbUnknown; CPLError(CE_Warning, CPLE_AppDefined, "Unrecognised geometry type : %s", pszGeometryType); } else if( nGeomType == 0 ) nGeomType = OGRFromOGCGeomType(pszGeometryType); } bHasFoundGeomType = TRUE; } } /* If there was a dangling <GeometryElementPath> or <GeometryType> or */ /* that no explicit geometry information has been found, then add */ /* a geometry field */ if( bHasValidGeometryElementPath || bHasFoundGeomType || !bHasFoundGeomElements ) { AddGeometryProperty( new GMLGeometryPropertyDefn( pszGName, pszGPath, nGeomType, -1, TRUE ) ); } SetSRSName( CPLGetXMLValue( psRoot, "SRSName", NULL ) ); /* -------------------------------------------------------------------- */ /* Collect dataset specific info. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psDSI = CPLGetXMLNode( psRoot, "DatasetSpecificInfo" ); if( psDSI != NULL ) { const char *pszValue; pszValue = CPLGetXMLValue( psDSI, "FeatureCount", NULL ); if( pszValue != NULL ) SetFeatureCount( CPLAtoGIntBig(pszValue) ); // Eventually we should support XML subtrees. pszValue = CPLGetXMLValue( psDSI, "ExtraInfo", NULL ); if( pszValue != NULL ) SetExtraInfo( pszValue ); if( CPLGetXMLValue( psDSI, "ExtentXMin", NULL ) != NULL && CPLGetXMLValue( psDSI, "ExtentXMax", NULL ) != NULL && CPLGetXMLValue( psDSI, "ExtentYMin", NULL ) != NULL && CPLGetXMLValue( psDSI, "ExtentYMax", NULL ) != NULL ) { SetExtents( CPLAtof(CPLGetXMLValue( psDSI, "ExtentXMin", "0.0" )), CPLAtof(CPLGetXMLValue( psDSI, "ExtentXMax", "0.0" )), CPLAtof(CPLGetXMLValue( psDSI, "ExtentYMin", "0.0" )), CPLAtof(CPLGetXMLValue( psDSI, "ExtentYMax", "0.0" )) ); } } /* -------------------------------------------------------------------- */ /* Collect property definitions. */ /* -------------------------------------------------------------------- */ for( psThis = psRoot->psChild; psThis != NULL; psThis = psThis->psNext ) { if( psThis->eType == CXT_Element && EQUAL(psThis->pszValue, "PropertyDefn") ) { const char *pszName = CPLGetXMLValue( psThis, "Name", NULL ); const char *pszType = CPLGetXMLValue( psThis, "Type", "Untyped" ); const char *pszSubType = CPLGetXMLValue( psThis, "Subtype", "" ); const char *pszCondition = CPLGetXMLValue( psThis, "Condition", NULL ); int bNullable = CSLTestBoolean(CPLGetXMLValue( psThis, "Nullable", "true") ); GMLPropertyDefn *poPDefn; if( pszName == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "GMLFeatureClass %s has a PropertyDefn without a <Name>..", m_pszName ); return FALSE; } poPDefn = new GMLPropertyDefn( pszName, CPLGetXMLValue( psThis, "ElementPath", NULL ) ); poPDefn->SetNullable(bNullable); if( EQUAL(pszType,"Untyped") ) poPDefn->SetType( GMLPT_Untyped ); else if( EQUAL(pszType,"String") ) { if( EQUAL(pszSubType, "Boolean") ) { poPDefn->SetType( GMLPT_Boolean ); poPDefn->SetWidth( 1 ); } else { poPDefn->SetType( GMLPT_String ); poPDefn->SetWidth( atoi( CPLGetXMLValue( psThis, "Width", "0" ) ) ); } } else if( EQUAL(pszType,"Integer") ) { if( EQUAL(pszSubType, "Short") ) { poPDefn->SetType( GMLPT_Short ); } else if( EQUAL(pszSubType, "Integer64") ) { poPDefn->SetType( GMLPT_Integer64 ); } else { poPDefn->SetType( GMLPT_Integer ); } poPDefn->SetWidth( atoi( CPLGetXMLValue( psThis, "Width", "0" ) ) ); } else if( EQUAL(pszType,"Real") ) { if( EQUAL(pszSubType, "Float") ) { poPDefn->SetType( GMLPT_Float ); } else { poPDefn->SetType( GMLPT_Real ); } poPDefn->SetWidth( atoi( CPLGetXMLValue( psThis, "Width", "0" ) ) ); poPDefn->SetPrecision( atoi( CPLGetXMLValue( psThis, "Precision", "0" ) ) ); } else if( EQUAL(pszType,"StringList") ) { if( EQUAL(pszSubType, "Boolean") ) poPDefn->SetType( GMLPT_BooleanList ); else poPDefn->SetType( GMLPT_StringList ); } else if( EQUAL(pszType,"IntegerList") ) { if( EQUAL(pszSubType, "Integer64") ) poPDefn->SetType( GMLPT_Integer64List ); else poPDefn->SetType( GMLPT_IntegerList ); } else if( EQUAL(pszType,"RealList") ) poPDefn->SetType( GMLPT_RealList ); else if( EQUAL(pszType,"Complex") ) poPDefn->SetType( GMLPT_Complex ); else if( EQUAL(pszType,"FeatureProperty") ) poPDefn->SetType( GMLPT_FeatureProperty ); else if( EQUAL(pszType,"FeaturePropertyList") ) poPDefn->SetType( GMLPT_FeaturePropertyList ); else { CPLError( CE_Failure, CPLE_AppDefined, "Unrecognised property type %s.", pszType ); delete poPDefn; return FALSE; } if( pszCondition != NULL ) poPDefn->SetCondition(pszCondition); AddProperty( poPDefn ); } } return TRUE; }