Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}