// Process a layer and add labels. simplet_status_t simplet_layer_process(simplet_layer_t *layer, simplet_map_t *map, simplet_lithograph_t *litho, cairo_t *ctx){ simplet_listiter_t *iter; OGRDataSourceH source; if(!(source = OGROpenShared(layer->source, 0, NULL))) return set_error(layer, SIMPLET_OGR_ERR, "error opening layer source"); // Retain the datasource because we want to cache open connections to a // data source like postgres. if(OGR_DS_GetRefCount(source) == 1) OGR_DS_Reference(source); if(!(iter = simplet_get_list_iter(layer->filters))){ OGRReleaseDataSource(source); return set_error(layer, SIMPLET_OOM, "out of memory getting list iterator"); } // Loop through the layer's filters and process them. simplet_filter_t *filter; simplet_status_t status = SIMPLET_OK; while((filter = simplet_list_next(iter))) { status = simplet_filter_process(filter, map, source, litho, ctx); if(status != SIMPLET_OK){ simplet_list_iter_free(iter); OGRReleaseDataSource(source); return status; } simplet_lithograph_apply(litho, filter->styles); } OGRReleaseDataSource(source); return SIMPLET_OK; }
static void OGR2SQLITE_ogr_datasource_load_layers(sqlite3_context* pContext, int argc, sqlite3_value** argv) { sqlite3* hDB = (sqlite3*) sqlite3_user_data(pContext); if( (argc < 1 || argc > 3) || sqlite3_value_type (argv[0]) != SQLITE_TEXT ) { sqlite3_result_int (pContext, 0); return; } const char* pszDataSource = (const char*) sqlite3_value_text(argv[0]); int bUpdate = FALSE; if( argc >= 2 ) { if( sqlite3_value_type(argv[1]) != SQLITE_INTEGER ) { sqlite3_result_int (pContext, 0); return; } bUpdate = sqlite3_value_int(argv[1]); } const char* pszPrefix = NULL; if( argc >= 3 ) { if( sqlite3_value_type(argv[2]) != SQLITE_TEXT ) { sqlite3_result_int (pContext, 0); return; } pszPrefix = (const char*) sqlite3_value_text(argv[2]); } OGRDataSource* poDS = (OGRDataSource*)OGROpenShared(pszDataSource, bUpdate, NULL); if( poDS == NULL ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot open %s", pszDataSource); sqlite3_result_int (pContext, 0); return; } CPLString osEscapedDataSource = OGRSQLiteEscape(pszDataSource); for(int i=0; i<poDS->GetLayerCount(); i++) { const char* pszLayerName = poDS->GetLayer(i)->GetName(); CPLString osEscapedLayerName = OGRSQLiteEscape(pszLayerName); CPLString osTableName; if( pszPrefix != NULL ) { osTableName = pszPrefix; osTableName += "_"; osTableName += OGRSQLiteEscapeName(pszLayerName); } else { osTableName = OGRSQLiteEscapeName(pszLayerName); } char* pszErrMsg = NULL; if( sqlite3_exec(hDB, CPLSPrintf( "CREATE VIRTUAL TABLE \"%s\" USING VirtualOGR('%s', %d, '%s')", osTableName.c_str(), osEscapedDataSource.c_str(), bUpdate, osEscapedLayerName.c_str()), NULL, NULL, &pszErrMsg) != SQLITE_OK ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot create table \"%s\" : %s", osTableName.c_str(), pszErrMsg); sqlite3_free(pszErrMsg); } } poDS->Release(); sqlite3_result_int (pContext, 1); }
OGRLayer * OGRDataSource::ExecuteSQL( const char *pszStatement, OGRGeometry *poSpatialFilter, const char *pszDialect ) { const char *pszError; swq_select *psSelectInfo = NULL; (void) pszDialect; /* -------------------------------------------------------------------- */ /* Handle CREATE INDEX statements specially. */ /* -------------------------------------------------------------------- */ if( EQUALN(pszStatement,"CREATE INDEX",12) ) { ProcessSQLCreateIndex( pszStatement ); return NULL; } /* -------------------------------------------------------------------- */ /* Handle DROP INDEX statements specially. */ /* -------------------------------------------------------------------- */ if( EQUALN(pszStatement,"DROP INDEX",10) ) { ProcessSQLDropIndex( pszStatement ); return NULL; } /* -------------------------------------------------------------------- */ /* Preparse the SQL statement. */ /* -------------------------------------------------------------------- */ pszError = swq_select_preparse( pszStatement, &psSelectInfo ); if( pszError != NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "SQL: %s", pszError ); return NULL; } /* -------------------------------------------------------------------- */ /* Validate that all the source tables are recognised, count */ /* fields. */ /* -------------------------------------------------------------------- */ int nFieldCount = 0, iTable; for( iTable = 0; iTable < psSelectInfo->table_count; iTable++ ) { swq_table_def *psTableDef = psSelectInfo->table_defs + iTable; OGRLayer *poSrcLayer; OGRDataSource *poTableDS = this; if( psTableDef->data_source != NULL ) { poTableDS = (OGRDataSource *) OGROpenShared( psTableDef->data_source, FALSE, NULL ); if( poTableDS == NULL ) { if( strlen(CPLGetLastErrorMsg()) == 0 ) CPLError( CE_Failure, CPLE_AppDefined, "Unable to open secondary datasource\n" "`%s' required by JOIN.", psTableDef->data_source ); swq_select_free( psSelectInfo ); return NULL; } // This drops explicit reference, but leave it open for use by // code in ogr_gensql.cpp poTableDS->Dereference(); } poSrcLayer = poTableDS->GetLayerByName( psTableDef->table_name ); if( poSrcLayer == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "SELECT from table %s failed, no such table/featureclass.", psTableDef->table_name ); swq_select_free( psSelectInfo ); return NULL; } nFieldCount += poSrcLayer->GetLayerDefn()->GetFieldCount(); } /* -------------------------------------------------------------------- */ /* Build the field list for all indicated tables. */ /* -------------------------------------------------------------------- */ swq_field_list sFieldList; int nFIDIndex = 0; memset( &sFieldList, 0, sizeof(sFieldList) ); sFieldList.table_count = psSelectInfo->table_count; sFieldList.table_defs = psSelectInfo->table_defs; sFieldList.count = 0; sFieldList.names = (char **) CPLMalloc( sizeof(char *) * (nFieldCount+1) ); sFieldList.types = (swq_field_type *) CPLMalloc( sizeof(swq_field_type) * (nFieldCount+1) ); sFieldList.table_ids = (int *) CPLMalloc( sizeof(int) * (nFieldCount+1) ); sFieldList.ids = (int *) CPLMalloc( sizeof(int) * (nFieldCount+1) ); for( iTable = 0; iTable < psSelectInfo->table_count; iTable++ ) { swq_table_def *psTableDef = psSelectInfo->table_defs + iTable; OGRDataSource *poTableDS = this; OGRLayer *poSrcLayer; int iField; if( psTableDef->data_source != NULL ) { poTableDS = (OGRDataSource *) OGROpenShared( psTableDef->data_source, FALSE, NULL ); CPLAssert( poTableDS != NULL ); poTableDS->Dereference(); } poSrcLayer = poTableDS->GetLayerByName( psTableDef->table_name ); for( iField = 0; iField < poSrcLayer->GetLayerDefn()->GetFieldCount(); iField++ ) { OGRFieldDefn *poFDefn=poSrcLayer->GetLayerDefn()->GetFieldDefn(iField); int iOutField = sFieldList.count++; sFieldList.names[iOutField] = (char *) poFDefn->GetNameRef(); if( poFDefn->GetType() == OFTInteger ) sFieldList.types[iOutField] = SWQ_INTEGER; else if( poFDefn->GetType() == OFTReal ) sFieldList.types[iOutField] = SWQ_FLOAT; else if( poFDefn->GetType() == OFTString ) sFieldList.types[iOutField] = SWQ_STRING; else sFieldList.types[iOutField] = SWQ_OTHER; sFieldList.table_ids[iOutField] = iTable; sFieldList.ids[iOutField] = iField; } if( iTable == 0 ) nFIDIndex = poSrcLayer->GetLayerDefn()->GetFieldCount(); } /* -------------------------------------------------------------------- */ /* Expand '*' in 'SELECT *' now before we add the pseudo field */ /* 'FID'. */ /* -------------------------------------------------------------------- */ pszError = swq_select_expand_wildcard( psSelectInfo, &sFieldList ); if( pszError != NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "SQL: %s", pszError ); return NULL; } sFieldList.names[sFieldList.count] = "FID"; sFieldList.types[sFieldList.count] = SWQ_INTEGER; sFieldList.table_ids[sFieldList.count] = 0; sFieldList.ids[sFieldList.count] = nFIDIndex; sFieldList.count++; /* -------------------------------------------------------------------- */ /* Finish the parse operation. */ /* -------------------------------------------------------------------- */ pszError = swq_select_parse( psSelectInfo, &sFieldList, 0 ); CPLFree( sFieldList.names ); CPLFree( sFieldList.types ); CPLFree( sFieldList.table_ids ); CPLFree( sFieldList.ids ); if( pszError != NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "SQL: %s", pszError ); return NULL; } /* -------------------------------------------------------------------- */ /* Everything seems OK, try to instantiate a results layer. */ /* -------------------------------------------------------------------- */ OGRGenSQLResultsLayer *poResults; poResults = new OGRGenSQLResultsLayer( this, psSelectInfo, poSpatialFilter ); // Eventually, we should keep track of layers to cleanup. return poResults; }
OGRLayer * OGRDataSource::ExecuteSQL( const char *pszStatement, OGRGeometry *poSpatialFilter, const char *pszDialect ) { const char *pszError; swq_select *psSelectInfo = NULL; (void) pszDialect; swq_field_list sFieldList; int nFIDIndex = 0; OGRGenSQLResultsLayer *poResults = NULL; memset( &sFieldList, 0, sizeof(sFieldList) ); /* -------------------------------------------------------------------- */ /* Handle CREATE INDEX statements specially. */ /* -------------------------------------------------------------------- */ if( EQUALN(pszStatement,"CREATE INDEX",12) ) { ProcessSQLCreateIndex( pszStatement ); return NULL; } /* -------------------------------------------------------------------- */ /* Handle DROP INDEX statements specially. */ /* -------------------------------------------------------------------- */ if( EQUALN(pszStatement,"DROP INDEX",10) ) { ProcessSQLDropIndex( pszStatement ); return NULL; } /* -------------------------------------------------------------------- */ /* Preparse the SQL statement. */ /* -------------------------------------------------------------------- */ pszError = swq_select_preparse( pszStatement, &psSelectInfo ); if( pszError != NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "SQL: %s", pszError ); return NULL; } /* -------------------------------------------------------------------- */ /* Validate that all the source tables are recognised, count */ /* fields. */ /* -------------------------------------------------------------------- */ int nFieldCount = 0, iTable, iField; int iEDS; int nExtraDSCount = 0; OGRDataSource** papoExtraDS = NULL; OGRSFDriverRegistrar *poReg=OGRSFDriverRegistrar::GetRegistrar(); for( iTable = 0; iTable < psSelectInfo->table_count; iTable++ ) { swq_table_def *psTableDef = psSelectInfo->table_defs + iTable; OGRLayer *poSrcLayer; OGRDataSource *poTableDS = this; if( psTableDef->data_source != NULL ) { poTableDS = (OGRDataSource *) OGROpenShared( psTableDef->data_source, FALSE, NULL ); if( poTableDS == NULL ) { if( strlen(CPLGetLastErrorMsg()) == 0 ) CPLError( CE_Failure, CPLE_AppDefined, "Unable to open secondary datasource\n" "`%s' required by JOIN.", psTableDef->data_source ); swq_select_free( psSelectInfo ); goto end; } /* Keep in an array to release at the end of this function */ papoExtraDS = (OGRDataSource** )CPLRealloc(papoExtraDS, sizeof(OGRDataSource*) * (nExtraDSCount + 1)); papoExtraDS[nExtraDSCount++] = poTableDS; } poSrcLayer = poTableDS->GetLayerByName( psTableDef->table_name ); if( poSrcLayer == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "SELECT from table %s failed, no such table/featureclass.", psTableDef->table_name ); swq_select_free( psSelectInfo ); goto end; } nFieldCount += poSrcLayer->GetLayerDefn()->GetFieldCount(); } /* -------------------------------------------------------------------- */ /* Build the field list for all indicated tables. */ /* -------------------------------------------------------------------- */ sFieldList.table_count = psSelectInfo->table_count; sFieldList.table_defs = psSelectInfo->table_defs; sFieldList.count = 0; sFieldList.names = (char **) CPLMalloc( sizeof(char *) * (nFieldCount+SPECIAL_FIELD_COUNT) ); sFieldList.types = (swq_field_type *) CPLMalloc( sizeof(swq_field_type) * (nFieldCount+SPECIAL_FIELD_COUNT) ); sFieldList.table_ids = (int *) CPLMalloc( sizeof(int) * (nFieldCount+SPECIAL_FIELD_COUNT) ); sFieldList.ids = (int *) CPLMalloc( sizeof(int) * (nFieldCount+SPECIAL_FIELD_COUNT) ); for( iTable = 0; iTable < psSelectInfo->table_count; iTable++ ) { swq_table_def *psTableDef = psSelectInfo->table_defs + iTable; OGRDataSource *poTableDS = this; OGRLayer *poSrcLayer; if( psTableDef->data_source != NULL ) { poTableDS = (OGRDataSource *) OGROpenShared( psTableDef->data_source, FALSE, NULL ); CPLAssert( poTableDS != NULL ); poTableDS->Dereference(); } poSrcLayer = poTableDS->GetLayerByName( psTableDef->table_name ); for( iField = 0; iField < poSrcLayer->GetLayerDefn()->GetFieldCount(); iField++ ) { OGRFieldDefn *poFDefn=poSrcLayer->GetLayerDefn()->GetFieldDefn(iField); int iOutField = sFieldList.count++; sFieldList.names[iOutField] = (char *) poFDefn->GetNameRef(); if( poFDefn->GetType() == OFTInteger ) sFieldList.types[iOutField] = SWQ_INTEGER; else if( poFDefn->GetType() == OFTReal ) sFieldList.types[iOutField] = SWQ_FLOAT; else if( poFDefn->GetType() == OFTString ) sFieldList.types[iOutField] = SWQ_STRING; else sFieldList.types[iOutField] = SWQ_OTHER; sFieldList.table_ids[iOutField] = iTable; sFieldList.ids[iOutField] = iField; } if( iTable == 0 ) nFIDIndex = poSrcLayer->GetLayerDefn()->GetFieldCount(); } /* -------------------------------------------------------------------- */ /* Expand '*' in 'SELECT *' now before we add the pseudo fields */ /* -------------------------------------------------------------------- */ pszError = swq_select_expand_wildcard( psSelectInfo, &sFieldList ); if( pszError != NULL ) { swq_select_free( psSelectInfo ); CPLError( CE_Failure, CPLE_AppDefined, "SQL: %s", pszError ); goto end; } for (iField = 0; iField < SPECIAL_FIELD_COUNT; iField++) { sFieldList.names[sFieldList.count] = (char*) SpecialFieldNames[iField]; sFieldList.types[sFieldList.count] = SpecialFieldTypes[iField]; sFieldList.table_ids[sFieldList.count] = 0; sFieldList.ids[sFieldList.count] = nFIDIndex + iField; sFieldList.count++; } /* -------------------------------------------------------------------- */ /* Finish the parse operation. */ /* -------------------------------------------------------------------- */ pszError = swq_select_parse( psSelectInfo, &sFieldList, 0 ); if( pszError != NULL ) { swq_select_free( psSelectInfo ); CPLError( CE_Failure, CPLE_AppDefined, "SQL: %s", pszError ); goto end; } /* -------------------------------------------------------------------- */ /* Everything seems OK, try to instantiate a results layer. */ /* -------------------------------------------------------------------- */ poResults = new OGRGenSQLResultsLayer( this, psSelectInfo, poSpatialFilter ); // Eventually, we should keep track of layers to cleanup. end: CPLFree( sFieldList.names ); CPLFree( sFieldList.types ); CPLFree( sFieldList.table_ids ); CPLFree( sFieldList.ids ); /* Release the datasets we have opened with OGROpenShared() */ /* It is safe to do that as the 'new OGRGenSQLResultsLayer' itself */ /* has taken a reference on them, which it will release in its */ /* destructor */ for(iEDS = 0; iEDS < nExtraDSCount; iEDS++) poReg->ReleaseDataSource( papoExtraDS[iEDS] ); CPLFree(papoExtraDS); return poResults; }