Example #1
0
int OGRAVCLayer::AppendTableDefinition( AVCTableDef *psTableDef )

{
    for( int iField = 0; iField < psTableDef->numFields; iField++ )
    {
        AVCFieldInfo *psFInfo = psTableDef->pasFieldDef + iField;
        char szFieldName[128];

        /* Strip off white space */
        strcpy( szFieldName, psFInfo->szName );
        if( strstr(szFieldName," ") != NULL )
            *(strstr(szFieldName," ")) = '\0';

        OGRFieldDefn oFDefn( szFieldName, OFTInteger );

        if( psFInfo->nIndex < 0 )
            continue;

        // Skip FNODE#, TNODE#, LPOLY# and RPOLY# from AAT table.
        if( eSectionType == AVCFileARC && iField < 4 )
            continue;

        oFDefn.SetWidth( psFInfo->nFmtWidth );

        if( psFInfo->nType1 * 10 == AVC_FT_DATE
            || psFInfo->nType1 * 10 == AVC_FT_CHAR )
            oFDefn.SetType( OFTString );

        else if( psFInfo->nType1 * 10 == AVC_FT_FIXINT
                 || psFInfo->nType1 * 10 == AVC_FT_BININT )
            oFDefn.SetType( OFTInteger );

        else if( psFInfo->nType1 * 10 == AVC_FT_FIXNUM
                 || psFInfo->nType1 * 10 == AVC_FT_BINFLOAT )
        {
            oFDefn.SetType( OFTReal );
            if( psFInfo->nFmtPrec > 0 )
                oFDefn.SetPrecision( psFInfo->nFmtPrec );
        }

        poFeatureDefn->AddFieldDefn( &oFDefn );
    }
    return TRUE;
}
Example #2
0
OGRLayer * OGRCouchDBDataSource::ExecuteSQLStats( const char *pszSQLCommand )
{
    swq_select sSelectInfo;
    if( sSelectInfo.preparse( pszSQLCommand ) != CE_None )
    {
        return NULL;
    }

    if (sSelectInfo.table_count != 1)
    {
        return NULL;
    }

    swq_table_def *psTableDef = &sSelectInfo.table_defs[0];
    if( psTableDef->data_source != NULL )
    {
        return NULL;
    }

    OGRCouchDBLayer* _poSrcLayer =
        (OGRCouchDBLayer* )GetLayerByName( psTableDef->table_name );
    if (_poSrcLayer == NULL)
    {
        return NULL;
    }
    if (_poSrcLayer->GetLayerType() != COUCHDB_TABLE_LAYER)
        return NULL;

    OGRCouchDBTableLayer* poSrcLayer = (OGRCouchDBTableLayer* ) _poSrcLayer;

    int nFieldCount = poSrcLayer->GetLayerDefn()->GetFieldCount();

    swq_field_list sFieldList;
    memset( &sFieldList, 0, sizeof(sFieldList) );
    sFieldList.table_count = sSelectInfo.table_count;
    sFieldList.table_defs = sSelectInfo.table_defs;

    sFieldList.count = 0;
    sFieldList.names = static_cast<char **>(
        CPLMalloc( sizeof(char *) * nFieldCount ));
    sFieldList.types = static_cast<swq_field_type *>(
        CPLMalloc( sizeof(swq_field_type) * nFieldCount ));
    sFieldList.table_ids = static_cast<int *>(
        CPLMalloc( sizeof(int) * nFieldCount ));
    sFieldList.ids = static_cast<int *>(
        CPLMalloc( sizeof(int) * nFieldCount ));

    PointerAutoFree oHolderNames(sFieldList.names);
    PointerAutoFree oHolderTypes(sFieldList.types);
    PointerAutoFree oHolderTableIds(sFieldList.table_ids);
    PointerAutoFree oHolderIds(sFieldList.ids);

    for( int 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] = 0;
        sFieldList.ids[iOutField] = iField;
    }

    CPLString osLastFieldName;
    for( int iField = 0; iField < sSelectInfo.result_columns; iField++ )
    {
        swq_col_def *psColDef = sSelectInfo.column_defs + iField;
        if (psColDef->field_name == NULL)
            return NULL;

        if (strcmp(psColDef->field_name, "*") != 0)
        {
            if (osLastFieldName.empty())
                osLastFieldName = psColDef->field_name;
            else if (strcmp(osLastFieldName, psColDef->field_name) != 0)
                return NULL;

            if (poSrcLayer->GetLayerDefn()->GetFieldIndex(psColDef->field_name) == -1)
                return NULL;
        }

        if (!(psColDef->col_func == SWQCF_AVG ||
              psColDef->col_func == SWQCF_MIN ||
              psColDef->col_func == SWQCF_MAX ||
              psColDef->col_func == SWQCF_COUNT ||
              psColDef->col_func == SWQCF_SUM))
            return NULL;

        if (psColDef->distinct_flag) /* TODO: could perhaps be relaxed */
            return NULL;
    }

    if (osLastFieldName.empty())
        return NULL;

    /* Normalize field name */
    int nIndex = poSrcLayer->GetLayerDefn()->GetFieldIndex(osLastFieldName);
    osLastFieldName = poSrcLayer->GetLayerDefn()->GetFieldDefn(nIndex)->GetNameRef();

/* -------------------------------------------------------------------- */
/*      Finish the parse operation.                                     */
/* -------------------------------------------------------------------- */

    if( sSelectInfo.parse( &sFieldList, NULL ) != CE_None )
    {
        return NULL;
    }

    if (sSelectInfo.join_defs != NULL ||
        sSelectInfo.where_expr != NULL ||
        sSelectInfo.order_defs != NULL ||
        sSelectInfo.query_mode != SWQM_SUMMARY_RECORD)
    {
        return NULL;
    }

    for( int iField = 0; iField < sSelectInfo.result_columns; iField++ )
    {
        swq_col_def *psColDef = sSelectInfo.column_defs + iField;
        if (psColDef->field_index == -1)
        {
            if (psColDef->col_func == SWQCF_COUNT)
                continue;

            return NULL;
        }
        if (psColDef->field_type != SWQ_INTEGER &&
            psColDef->field_type != SWQ_FLOAT)
        {
            return NULL;
        }
    }

    const bool bFoundFilter = CPL_TO_BOOL(
        poSrcLayer->HasFilterOnFieldOrCreateIfNecessary(osLastFieldName));
    if( !bFoundFilter )
        return NULL;

    CPLString osURI = "/";
    osURI += poSrcLayer->GetName();
    osURI += "/_design/ogr_filter_";
    osURI += osLastFieldName;
    osURI += "/_view/filter?reduce=true";

    json_object* poAnswerObj = GET(osURI);
    json_object* poRows = NULL;
    if (!(poAnswerObj != NULL &&
          json_object_is_type(poAnswerObj, json_type_object) &&
          (poRows = CPL_json_object_object_get(poAnswerObj, "rows")) != NULL &&
          json_object_is_type(poRows, json_type_array)))
    {
        json_object_put(poAnswerObj);
        return NULL;
    }

    int nLength = json_object_array_length(poRows);
    if (nLength != 1)
    {
        json_object_put(poAnswerObj);
        return NULL;
    }

    json_object* poRow = json_object_array_get_idx(poRows, 0);
    if (!(poRow && json_object_is_type(poRow, json_type_object)))
    {
        json_object_put(poAnswerObj);
        return NULL;
    }

    json_object* poValue = CPL_json_object_object_get(poRow, "value");
    if (!(poValue != NULL && json_object_is_type(poValue, json_type_object)))
    {
        json_object_put(poAnswerObj);
        return NULL;
    }

    json_object* poSum = CPL_json_object_object_get(poValue, "sum");
    json_object* poCount = CPL_json_object_object_get(poValue, "count");
    json_object* poMin = CPL_json_object_object_get(poValue, "min");
    json_object* poMax = CPL_json_object_object_get(poValue, "max");
    if (poSum != NULL && (json_object_is_type(poSum, json_type_int) ||
                            json_object_is_type(poSum, json_type_double)) &&
        poCount != NULL && (json_object_is_type(poCount, json_type_int) ||
                            json_object_is_type(poCount, json_type_double)) &&
        poMin != NULL && (json_object_is_type(poMin, json_type_int) ||
                            json_object_is_type(poMin, json_type_double)) &&
        poMax != NULL && (json_object_is_type(poMax, json_type_int) ||
                            json_object_is_type(poMax, json_type_double)) )
    {
        double dfSum = json_object_get_double(poSum);
        int nCount = json_object_get_int(poCount);
        double dfMin = json_object_get_double(poMin);
        double dfMax = json_object_get_double(poMax);
        json_object_put(poAnswerObj);

        //CPLDebug("CouchDB", "sum=%f, count=%d, min=%f, max=%f",
        //         dfSum, nCount, dfMin, dfMax);

        OGRFeatureDefn* poFeatureDefn = new OGRFeatureDefn(poSrcLayer->GetName());
        poFeatureDefn->Reference();

        for( int iField = 0; iField < sSelectInfo.result_columns; iField++ )
        {
            swq_col_def *psColDef = sSelectInfo.column_defs + iField;
            OGRFieldDefn oFDefn( "", OFTInteger );

            if( psColDef->field_alias != NULL )
            {
                oFDefn.SetName(psColDef->field_alias);
            }
            else
            {
                const swq_operation *op = swq_op_registrar::GetOperator(
                    (swq_op) psColDef->col_func );
                oFDefn.SetName( CPLSPrintf( "%s_%s",
                                            op->pszName,
                                            psColDef->field_name ) );
            }

            if( psColDef->col_func == SWQCF_COUNT )
                oFDefn.SetType( OFTInteger );
            else if (psColDef->field_type == SWQ_INTEGER)
                oFDefn.SetType( OFTInteger );
            else if (psColDef->field_type == SWQ_FLOAT)
                oFDefn.SetType( OFTReal );

            poFeatureDefn->AddFieldDefn(&oFDefn);
        }

        OGRFeature* poFeature = new OGRFeature(poFeatureDefn);

        for( int iField = 0; iField < sSelectInfo.result_columns; iField++ )
        {
            swq_col_def *psColDef = sSelectInfo.column_defs + iField;
            switch(psColDef->col_func)
            {
                case SWQCF_AVG:
                    if (nCount)
                        poFeature->SetField(iField, dfSum / nCount);
                    break;
                case SWQCF_MIN:
                    poFeature->SetField(iField, dfMin);
                    break;
                case SWQCF_MAX:
                    poFeature->SetField(iField, dfMax);
                    break;
                case SWQCF_COUNT:
                    poFeature->SetField(iField, nCount);
                    break;
                case SWQCF_SUM:
                    poFeature->SetField(iField, dfSum);
                    break;
                default:
                    break;
            }
        }

        poFeature->SetFID(0);

        OGRCouchDBOneLineLayer* poAnswerLayer = new OGRCouchDBOneLineLayer();
        poAnswerLayer->poFeatureDefn = poFeatureDefn;
        poAnswerLayer->poFeature = poFeature;
        return poAnswerLayer;
    }
    json_object_put(poAnswerObj);

    return NULL;
}