From: scottmk Date: Thu, 19 Feb 2009 02:12:46 +0000 (+0000) Subject: In searchJOIN: substantially rewrote the code for the condition where X-Git-Tag: sprint4-merge-nov22~10771 X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=767efd9c88d24223154870dbc528e889c2bfbb30;p=working%2FEvergreen.git In searchJOIN: substantially rewrote the code for the condition where the JSON query specifies neither of the join columns. 1. Corrected an apparent bug whereby we could join in only one direction, even when a join in the opposite direction was valid and equivalent. 2. Rewrote the search loops for better performance. 3. When testing for the success of the searches for join columns, success should mean that we have identified both columns. Identifying just one isn't enough. git-svn-id: svn://svn.open-ils.org/ILS/trunk@12227 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- diff --git a/Open-ILS/src/c-apps/oils_cstore.c b/Open-ILS/src/c-apps/oils_cstore.c index cc1780870c..59559fa28b 100644 --- a/Open-ILS/src/c-apps/oils_cstore.c +++ b/Open-ILS/src/c-apps/oils_cstore.c @@ -2080,35 +2080,46 @@ static char* searchJOIN ( const jsonObject* join_hash, osrfHash* leftmeta ) { } else if (!field && !fkey) { osrfHash* _links = oilsIDLFindPath("/%s/links", leftclass); - int i = 0; - const char* tmp_fkey; - osrfStringArray* keys = osrfHashKeys( _links ); - while ( (tmp_fkey = osrfStringArrayGetString(keys, i++)) ) { - if ( !strcmp( (char*)oilsIDLFindPath("/%s/links/%s/class", leftclass, tmp_fkey), class) ) { - field = strdup( (char*)oilsIDLFindPath("/%s/links/%s/key", leftclass, tmp_fkey) ); - fkey = strdup(tmp_fkey); + // For each link defined for the left class: + // see if the link references the joined class + osrfHashIterator* itr = osrfNewHashIterator( _links ); + osrfHash* curr_link = NULL; + while( (curr_link = osrfHashIteratorNext( itr ) ) ) { + const char* other_class = osrfHashGet( curr_link, "class" ); + if( other_class && !strcmp( other_class, class ) ) { + + // Found a link between the classes + fkey = strdup( osrfHashIteratorKey( itr ) ); + const char* other_key = osrfHashGet( curr_link, "key" ); + field = other_key ? strdup( other_key ) : NULL; break; } } - osrfStringArrayFree(keys); - - if (!field && !fkey) { + osrfHashIteratorFree( itr ); + + if (!field || !fkey) { + // Do another such search, with the classes reversed _links = oilsIDLFindPath("/%s/links", class); - i = 0; - const char* tmp_fld; - keys = osrfHashKeys( _links ); - while ( (tmp_fld = osrfStringArrayGetString(keys, i++)) ) { - if ( !strcmp( (char*)oilsIDLFindPath("/%s/links/%s/class", class, tmp_fld), class) ) { - fkey = strdup( (char*)oilsIDLFindPath("/%s/links/%s/key", class, tmp_fld) ); - field = strdup( tmp_fld ); + // For each link defined for the joined class: + // see if the link references the left class + osrfHashIterator* itr = osrfNewHashIterator( _links ); + osrfHash* curr_link = NULL; + while( (curr_link = osrfHashIteratorNext( itr ) ) ) { + const char* other_class = osrfHashGet( curr_link, "class" ); + if( other_class && !strcmp( other_class, leftclass ) ) { + + // Found a link between the classes + fkey = strdup( osrfHashIteratorKey( itr ) ); + const char* other_key = osrfHashGet( curr_link, "key" ); + field = other_key ? strdup( other_key ) : NULL; break; } } - osrfStringArrayFree(keys); + osrfHashIteratorFree( itr ); } - if (!field && !fkey) { + if (!field || !fkey) { osrfLogError( OSRF_LOG_MARK, "%s: JOIN failed. No link defined between %s and %s",