CPLErr OGRSQLiteViewLayer::EstablishFeatureDefn() { int rc; sqlite3 *hDB = poDS->GetDB(); sqlite3_stmt *hColStmt = NULL; const char *pszSQL; OGRSQLiteLayer* poUnderlyingLayer = (OGRSQLiteLayer*) poDS->GetLayerByName(osUnderlyingTableName); if (poUnderlyingLayer == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot find underlying layer %s for view %s", osUnderlyingTableName.c_str(), pszViewName); return CE_Failure; } if ( !poUnderlyingLayer->IsTableLayer() ) { CPLError(CE_Failure, CPLE_AppDefined, "Underlying layer %s for view %s is not a regular table", osUnderlyingTableName.c_str(), pszViewName); return CE_Failure; } const char* pszRealUnderlyingGeometryColumn = poUnderlyingLayer->GetGeometryColumn(); if ( pszRealUnderlyingGeometryColumn == NULL || !EQUAL(pszRealUnderlyingGeometryColumn, osUnderlyingGeometryColumn.c_str()) ) { CPLError(CE_Failure, CPLE_AppDefined, "Underlying layer %s for view %s has not expected geometry column name (%s instead of %s)", osUnderlyingTableName.c_str(), pszViewName, pszRealUnderlyingGeometryColumn ? pszRealUnderlyingGeometryColumn : "(null)", osUnderlyingGeometryColumn.c_str()); return CE_Failure; } poSRS = poUnderlyingLayer->GetSpatialRef(); if (poSRS) poSRS->Reference(); this->bHasSpatialIndex = poUnderlyingLayer->HasSpatialIndex(); /* -------------------------------------------------------------------- */ /* Get the column definitions for this table. */ /* -------------------------------------------------------------------- */ hColStmt = NULL; pszSQL = CPLSPrintf( "SELECT %s, * FROM '%s' LIMIT 1", pszFIDColumn, pszEscapedTableName ); rc = sqlite3_prepare( hDB, pszSQL, strlen(pszSQL), &hColStmt, NULL ); if( rc != SQLITE_OK ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to query table %s for column definitions : %s.", pszViewName, sqlite3_errmsg(hDB) ); return CE_Failure; } rc = sqlite3_step( hColStmt ); if ( rc != SQLITE_DONE && rc != SQLITE_ROW ) { CPLError( CE_Failure, CPLE_AppDefined, "In Initialize(): sqlite3_step(%s):\n %s", pszSQL, sqlite3_errmsg(hDB) ); sqlite3_finalize( hColStmt ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Collect the rest of the fields. */ /* -------------------------------------------------------------------- */ BuildFeatureDefn( pszViewName, hColStmt ); sqlite3_finalize( hColStmt ); /* -------------------------------------------------------------------- */ /* Set the geometry type if we know it. */ /* -------------------------------------------------------------------- */ poFeatureDefn->SetGeomType( poUnderlyingLayer->GetGeomType() ); return CE_None; }
OGRSQLiteLayer* OGRSQLiteSelectLayer::GetBaseLayer(size_t& i) { char** papszTokens = CSLTokenizeString(osSQLBase.c_str()); int bCanInsertSpatialFilter = TRUE; int nCountSelect = 0, nCountFrom = 0, nCountWhere = 0; for(int iToken = 0; papszTokens[iToken] != NULL; iToken++) { if (EQUAL(papszTokens[iToken], "SELECT")) nCountSelect ++; else if (EQUAL(papszTokens[iToken], "FROM")) nCountFrom ++; else if (EQUAL(papszTokens[iToken], "WHERE")) nCountWhere ++; else if (EQUAL(papszTokens[iToken], "UNION") || EQUAL(papszTokens[iToken], "JOIN") || EQUAL(papszTokens[iToken], "INTERSECT") || EQUAL(papszTokens[iToken], "EXCEPT")) { bCanInsertSpatialFilter = FALSE; } } CSLDestroy(papszTokens); if (!(bCanInsertSpatialFilter && nCountSelect == 1 && nCountFrom == 1 && nCountWhere <= 1)) { CPLDebug("SQLITE", "SQL expression too complex to analyse"); return NULL; } size_t nFromPos = osSQLBase.ifind(" from "); if (nFromPos == std::string::npos) { return NULL; } int bInSingleQuotes = (osSQLBase[nFromPos + 6] == '\''); CPLString osBaseLayerName; for( i = nFromPos + 6 + (bInSingleQuotes ? 1 : 0); i < osSQLBase.size(); i++ ) { if (osSQLBase[i] == '\'' && i + 1 < osSQLBase.size() && osSQLBase[i + 1] == '\'' ) { osBaseLayerName += osSQLBase[i]; i++; } else if (osSQLBase[i] == '\'' && bInSingleQuotes) { i++; break; } else if (osSQLBase[i] == ' ' && !bInSingleQuotes) break; else osBaseLayerName += osSQLBase[i]; } OGRSQLiteLayer* poUnderlyingLayer = NULL; if( strchr(osBaseLayerName, '(') == NULL && osGeomColumn.size() != 0 ) { CPLString osNewUnderlyingTableName; osNewUnderlyingTableName.Printf("%s(%s)", osBaseLayerName.c_str(), osGeomColumn.c_str()); poUnderlyingLayer = (OGRSQLiteLayer*) poDS->GetLayerByName(osNewUnderlyingTableName); } if( poUnderlyingLayer == NULL ) poUnderlyingLayer = (OGRSQLiteLayer*) poDS->GetLayerByName(osBaseLayerName); if( poUnderlyingLayer != NULL && poSRS != NULL && poUnderlyingLayer->GetSpatialRef() != NULL && poSRS != poUnderlyingLayer->GetSpatialRef() && !poSRS->IsSame(poUnderlyingLayer->GetSpatialRef()) ) { CPLDebug("SQLITE", "Result layer and base layer don't have the same SRS."); return NULL; } return poUnderlyingLayer; }