Exemplo n.º 1
0
bool LocalCollectionQuery::
Query( const string &viewName, ExprTree *expr, bool two_way_matching )
{
	ViewRegistry::iterator	vri;
	ViewMembers::iterator	vmi;
	MatchClassAd			mad;
	View					*view;
	ClassAd					*ad=0; 
	const ClassAd			*parent;
	string					key;
	bool					match;
    bool                    given_classad=false;
    
	if (expr && expr->isClassad(&ad))
	{
		given_classad = true;
	}

    parent = NULL;

	// get the view to query
	if( !collection || ( vri = collection->viewRegistry.find( viewName ) ) == 
			collection->viewRegistry.end( ) ) {
		return( false );
	}
	view = vri->second;

	if( expr ) {
        if (given_classad) {
            mad.ReplaceLeftAd(ad);
        } else {
            // setup evluation environment if a constraint was supplied
            parent = expr->GetParentScope( );
            if( !( ad=mad.GetLeftAd() ) || !ad->Insert(ATTR_REQUIREMENTS,expr,false ) ) {
                expr->SetParentScope( parent );
                return( false );
            }
        }
	}
	keys.clear( );


	// iterate over the view members
	for( vmi=view->viewMembers.begin(); vmi!=view->viewMembers.end(); vmi++ ) {
		// ... and insert keys into local list in same order
		vmi->GetKey( key );

		if( expr ) {
			// if a constraint was supplied, make sure its satisfied
			ad = collection->GetClassAd( key );
			mad.ReplaceRightAd( ad );
			if( mad.EvaluateAttrBool( "RightMatchesLeft", match ) && match ) {
                bool add_key;
                if (!given_classad || !two_way_matching) {
                    add_key = true;
                } else if (mad.EvaluateAttrBool( "LeftMatchesRight", match ) && match) {
                    add_key = true;
                } else {
                    add_key = false;
                }
                if (add_key) {   
                    keys.push_back( key );
                }
			}
			mad.RemoveRightAd( );
		} else {
			keys.push_back( key );
		}
	}

	// initialize local iterator
	itr = keys.begin( );

	// clean up and return
	if( expr ) {
        if (given_classad) {
            mad.RemoveLeftAd();
        }
		expr->SetParentScope( parent );
		ad = mad.GetLeftAd();
		if (ad != NULL) {
			ad->Remove(ATTR_REQUIREMENTS);
		}
	}
	return( true );
}