Ejemplo n.º 1
0
OGRErr OGRSQLiteSelectLayerCommonBehaviour::SetAttributeFilter( const char *pszQuery )

{
    char*& m_pszAttrQuertyString = poLayer->GetAttrQueryString();
    if( m_pszAttrQuertyString == NULL && pszQuery == NULL )
        return OGRERR_NONE;

    CPLFree(m_pszAttrQuertyString);
    m_pszAttrQuertyString = (pszQuery) ? CPLStrdup(pszQuery) : NULL;

    bAllowResetReadingEvenIfIndexAtZero = TRUE;

    OGRFeatureQuery oQuery;

    CPLPushErrorHandler(CPLQuietErrorHandler);
    int bHasSpecialFields = (pszQuery != NULL && pszQuery[0] != '\0' &&
        oQuery.Compile( poLayer->GetLayerDefn(), pszQuery ) == OGRERR_NONE &&
        HasSpecialFields((swq_expr_node*)oQuery.GetSWQExpr(), poLayer->GetLayerDefn()->GetFieldCount()) );
    CPLPopErrorHandler();

    if( bHasSpecialFields || !BuildSQL() )
    {
        return poLayer->BaseSetAttributeFilter(pszQuery);
    }

    ResetReading();

    return OGRERR_NONE;
}
Ejemplo n.º 2
0
OGRLayer * OGRCouchDBDataSource::ExecuteSQL( const char *pszSQLCommand,
                                          OGRGeometry *poSpatialFilter,
                                          const char *pszDialect )

{
/* -------------------------------------------------------------------- */
/*      Use generic implementation for recognized dialects              */
/* -------------------------------------------------------------------- */
    if( IsGenericSQLDialect(pszDialect) )
        return OGRDataSource::ExecuteSQL( pszSQLCommand,
                                          poSpatialFilter,
                                          pszDialect );

/* -------------------------------------------------------------------- */
/*      Special case DELLAYER: command.                                 */
/* -------------------------------------------------------------------- */
    if( STARTS_WITH_CI(pszSQLCommand, "DELLAYER:") )
    {
        const char *pszLayerName = pszSQLCommand + 9;

        while( *pszLayerName == ' ' )
            pszLayerName++;

        DeleteLayer( pszLayerName );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Special case 'COMPACT ON ' command.                             */
/* -------------------------------------------------------------------- */
    if( STARTS_WITH_CI(pszSQLCommand, "COMPACT ON ") )
    {
        const char *pszLayerName = pszSQLCommand + 11;

        while( *pszLayerName == ' ' )
            pszLayerName++;

        CPLString osURI("/");
        osURI += pszLayerName;
        osURI += "/_compact";

        json_object* poAnswerObj = POST(osURI, NULL);
        IsError(poAnswerObj, "Database compaction failed");
        json_object_put(poAnswerObj);

        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Special case 'VIEW CLEANUP ON ' command.                        */
/* -------------------------------------------------------------------- */
    if( STARTS_WITH_CI(pszSQLCommand, "VIEW CLEANUP ON ") )
    {
        const char *pszLayerName = pszSQLCommand + 16;

        while( *pszLayerName == ' ' )
            pszLayerName++;

        CPLString osURI("/");
        osURI += pszLayerName;
        osURI += "/_view_cleanup";

        json_object* poAnswerObj = POST(osURI, NULL);
        IsError(poAnswerObj, "View cleanup failed");
        json_object_put(poAnswerObj);

        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Deal with "DELETE FROM layer_name WHERE expression" statement   */
/* -------------------------------------------------------------------- */
    if( STARTS_WITH_CI(pszSQLCommand, "DELETE FROM ") )
    {
        const char* pszIter = pszSQLCommand + 12;
        while(*pszIter && *pszIter != ' ')
            pszIter ++;
        if (*pszIter == 0)
        {
            CPLError(CE_Failure, CPLE_AppDefined, "Invalid statement");
            return NULL;
        }

        CPLString osName = pszSQLCommand + 12;
        osName.resize(pszIter - (pszSQLCommand + 12));
        OGRCouchDBLayer* poLayer = (OGRCouchDBLayer*)GetLayerByName(osName);
        if (poLayer == NULL)
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "Unknown layer : %s", osName.c_str());
            return NULL;
        }
        if (poLayer->GetLayerType() != COUCHDB_TABLE_LAYER)
            return NULL;
        OGRCouchDBTableLayer* poTableLayer = (OGRCouchDBTableLayer*)poLayer;

        while( *pszIter == ' ' )
            pszIter ++;
        if (!STARTS_WITH_CI(pszIter, "WHERE "))
        {
            CPLError(CE_Failure, CPLE_AppDefined, "WHERE clause missing");
            return NULL;
        }
        pszIter += 5;

        const char* pszQuery = pszIter;

        /* Check with the generic SQL engine that this is a valid WHERE clause */
        OGRFeatureQuery oQuery;
        OGRErr eErr = oQuery.Compile( poLayer->GetLayerDefn(), pszQuery );
        if( eErr != OGRERR_NONE )
        {
            return NULL;
        }

        swq_expr_node * pNode = (swq_expr_node *) oQuery.GetSWQExpr();
        if (pNode->eNodeType == SNT_OPERATION &&
            pNode->nOperation == SWQ_EQ &&
            pNode->nSubExprCount == 2 &&
            pNode->papoSubExpr[0]->eNodeType == SNT_COLUMN &&
            pNode->papoSubExpr[1]->eNodeType == SNT_CONSTANT &&
            pNode->papoSubExpr[0]->field_index == COUCHDB_ID_FIELD &&
            pNode->papoSubExpr[1]->field_type == SWQ_STRING)
        {
            poTableLayer->DeleteFeature(pNode->papoSubExpr[1]->string_value);
        }
        else
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "Invalid WHERE clause. Expecting '_id' = 'a_value'");
            return NULL;
        }

        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Try an optimized implementation when doing only stats           */
/* -------------------------------------------------------------------- */
    if (poSpatialFilter == NULL && STARTS_WITH_CI(pszSQLCommand, "SELECT"))
    {
        OGRLayer* poRet = ExecuteSQLStats(pszSQLCommand);
        if (poRet)
            return poRet;
    }

    return OGRDataSource::ExecuteSQL( pszSQLCommand,
                                        poSpatialFilter,
                                        pszDialect );
}