From 767efd9c88d24223154870dbc528e889c2bfbb30 Mon Sep 17 00:00:00 2001 From: scottmk Date: Thu, 19 Feb 2009 02:12:46 +0000 Subject: [PATCH] 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 --- Open-ILS/src/c-apps/oils_cstore.c | 49 ++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 19 deletions(-) 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", -- 2.11.0