예제 #1
0
OGRLayer * OGRShapeDataSource::ExecuteSQL( const char *pszStatement,
                                           OGRGeometry *poSpatialFilter,
                                           const char *pszDialect )

{
/* ==================================================================== */
/*      Handle command to drop a spatial index.                         */
/* ==================================================================== */
    if( EQUALN(pszStatement, "REPACK ", 7) )
    {
        OGRShapeLayer *poLayer = (OGRShapeLayer *) 
            GetLayerByName( pszStatement + 7 );

        if( poLayer != NULL )
        {
            if( poLayer->Repack() != OGRERR_NONE )
            {
                CPLError( CE_Failure, CPLE_AppDefined,
                          "REPACK of layer '%s' failed.",
                          pszStatement + 7 );
            }
        }
        else
        {
            CPLError( CE_Failure, CPLE_AppDefined, 
                      "No such layer as '%s' in REPACK.", 
                      pszStatement + 7 );
        }
        return NULL;
    }

/* ==================================================================== */
/*      Handle command to shrink columns to their minimum size.         */
/* ==================================================================== */
    if( EQUALN(pszStatement, "RESIZE ", 7) )
    {
        OGRShapeLayer *poLayer = (OGRShapeLayer *)
            GetLayerByName( pszStatement + 7 );

        if( poLayer != NULL )
            poLayer->ResizeDBF();
        else
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "No such layer as '%s' in RESIZE.",
                      pszStatement + 7 );
        }
        return NULL;
    }

/* ==================================================================== */
/*      Handle command to recompute extent                             */
/* ==================================================================== */
    if( EQUALN(pszStatement, "RECOMPUTE EXTENT ON ", 20) )
    {
        OGRShapeLayer *poLayer = (OGRShapeLayer *) 
            GetLayerByName( pszStatement + 20 );

        if( poLayer != NULL )
            poLayer->RecomputeExtent();
        else
        {
            CPLError( CE_Failure, CPLE_AppDefined, 
                      "No such layer as '%s' in RECOMPUTE EXTENT.", 
                      pszStatement + 20 );
        }
        return NULL;
    }
    
/* ==================================================================== */
/*      Handle command to drop a spatial index.                         */
/* ==================================================================== */
    if( EQUALN(pszStatement, "DROP SPATIAL INDEX ON ", 22) )
    {
        OGRShapeLayer *poLayer = (OGRShapeLayer *) 
            GetLayerByName( pszStatement + 22 );

        if( poLayer != NULL )
            poLayer->DropSpatialIndex();
        else
        {
            CPLError( CE_Failure, CPLE_AppDefined, 
                      "No such layer as '%s' in DROP SPATIAL INDEX.", 
                      pszStatement + 22 );
        }
        return NULL;
    }
    
/* ==================================================================== */
/*      Handle all comands except spatial index creation generically.   */
/* ==================================================================== */
    if( !EQUALN(pszStatement,"CREATE SPATIAL INDEX ON ",24) )
    {
        char **papszTokens = CSLTokenizeString( pszStatement );
        if( CSLCount(papszTokens) >=4
            && (EQUAL(papszTokens[0],"CREATE") || EQUAL(papszTokens[0],"DROP"))
            && EQUAL(papszTokens[1],"INDEX")
            && EQUAL(papszTokens[2],"ON") )
        {
            OGRShapeLayer *poLayer = (OGRShapeLayer *) GetLayerByName(papszTokens[3]);
            if (poLayer != NULL)
                poLayer->InitializeIndexSupport( poLayer->GetFullName() );
        }
        CSLDestroy( papszTokens );

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

/* -------------------------------------------------------------------- */
/*      Parse into keywords.                                            */
/* -------------------------------------------------------------------- */
    char **papszTokens = CSLTokenizeString( pszStatement );
    
    if( CSLCount(papszTokens) < 5
        || !EQUAL(papszTokens[0],"CREATE")
        || !EQUAL(papszTokens[1],"SPATIAL")
        || !EQUAL(papszTokens[2],"INDEX") 
        || !EQUAL(papszTokens[3],"ON") 
        || CSLCount(papszTokens) > 7 
        || (CSLCount(papszTokens) == 7 && !EQUAL(papszTokens[5],"DEPTH")) )
    {
        CSLDestroy( papszTokens );
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Syntax error in CREATE SPATIAL INDEX command.\n"
                  "Was '%s'\n"
                  "Should be of form 'CREATE SPATIAL INDEX ON <table> [DEPTH <n>]'",
                  pszStatement );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Get depth if provided.                                          */
/* -------------------------------------------------------------------- */
    int nDepth = 0;
    if( CSLCount(papszTokens) == 7 )
        nDepth = atoi(papszTokens[6]);

/* -------------------------------------------------------------------- */
/*      What layer are we operating on.                                 */
/* -------------------------------------------------------------------- */
    OGRShapeLayer *poLayer = (OGRShapeLayer *) GetLayerByName(papszTokens[4]);

    if( poLayer == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Layer %s not recognised.", 
                  papszTokens[4] );
        CSLDestroy( papszTokens );
        return NULL;
    }

    CSLDestroy( papszTokens );

    poLayer->CreateSpatialIndex( nDepth );
    return NULL;
}
OGRLayer * OGRShapeDataSource::ExecuteSQL( const char *pszStatement,
        OGRGeometry *poSpatialFilter,
        const char *pszDialect )

{
    /* ==================================================================== */
    /*      Handle command to drop a spatial index.                         */
    /* ==================================================================== */
    if( EQUALN(pszStatement, "REPACK ", 7) )
    {
        OGRShapeLayer *poLayer = (OGRShapeLayer *)
                                 GetLayerByName( pszStatement + 7 );

        if( poLayer != NULL )
            poLayer->Repack();
        else
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "No such layer as '%s' in REPACK.",
                      pszStatement + 7 );
        }
        return NULL;
    }

    /* ==================================================================== */
    /*      Handle command to drop a spatial index.                         */
    /* ==================================================================== */
    if( EQUALN(pszStatement, "DROP SPATIAL INDEX ON ", 22) )
    {
        OGRShapeLayer *poLayer = (OGRShapeLayer *)
                                 GetLayerByName( pszStatement + 22 );

        if( poLayer != NULL )
            poLayer->DropSpatialIndex();
        else
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "No such layer as '%s' in DROP SPATIAL INDEX.",
                      pszStatement + 19 );
        }
        return NULL;
    }

    /* ==================================================================== */
    /*      Handle all comands except spatial index creation generically.   */
    /* ==================================================================== */
    if( !EQUALN(pszStatement,"CREATE SPATIAL INDEX ON ",24) )
        return OGRDataSource::ExecuteSQL( pszStatement, poSpatialFilter,
                                          pszDialect );

    /* -------------------------------------------------------------------- */
    /*      Parse into keywords.                                            */
    /* -------------------------------------------------------------------- */
    char **papszTokens = CSLTokenizeString( pszStatement );

    if( CSLCount(papszTokens) < 5
            || !EQUAL(papszTokens[0],"CREATE")
            || !EQUAL(papszTokens[1],"SPATIAL")
            || !EQUAL(papszTokens[2],"INDEX")
            || !EQUAL(papszTokens[3],"ON")
            || CSLCount(papszTokens) > 7
            || (CSLCount(papszTokens) == 7 && !EQUAL(papszTokens[5],"DEPTH")) )
    {
        CSLDestroy( papszTokens );
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Syntax error in CREATE SPATIAL INDEX command.\n"
                  "Was '%s'\n"
                  "Should be of form 'CREATE SPATIAL INDEX ON <table> [DEPTH <n>]'",
                  pszStatement );
        return NULL;
    }

    /* -------------------------------------------------------------------- */
    /*      Get depth if provided.                                          */
    /* -------------------------------------------------------------------- */
    int nDepth = 0;
    if( CSLCount(papszTokens) == 7 )
        nDepth = atoi(papszTokens[6]);

    /* -------------------------------------------------------------------- */
    /*      What layer are we operating on.                                 */
    /* -------------------------------------------------------------------- */
    OGRShapeLayer *poLayer = (OGRShapeLayer *) GetLayerByName(papszTokens[4]);
    CSLDestroy( papszTokens );

    if( poLayer == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Layer %s not recognised.",
                  papszTokens[4] );
        return NULL;
    }

    poLayer->CreateSpatialIndex( nDepth );
    return NULL;
}