[open-ils-commits] r16515 - trunk/Open-ILS/src/c-apps (scottmk)

svn at svn.open-ils.org svn at svn.open-ils.org
Thu May 27 08:38:49 EDT 2010


Author: scottmk
Date: 2010-05-27 08:38:48 -0400 (Thu, 27 May 2010)
New Revision: 16515

Modified:
   trunk/Open-ILS/src/c-apps/oils_sql.c
Log:
Bug fix in verifyObjectPCRUD().

When traversing a chain of rows according to the "jump" attribute:
if you encounter a null foreign key, just stop looking, without
issuing an exception.

M    Open-ILS/src/c-apps/oils_sql.c


Modified: trunk/Open-ILS/src/c-apps/oils_sql.c
===================================================================
--- trunk/Open-ILS/src/c-apps/oils_sql.c	2010-05-26 21:29:54 UTC (rev 16514)
+++ trunk/Open-ILS/src/c-apps/oils_sql.c	2010-05-27 12:38:48 UTC (rev 16515)
@@ -1448,7 +1448,7 @@
 				osrfHash* fcontext = NULL;
 				osrfHashIterator* class_itr = osrfNewHashIterator( foreign_context );
 				while( (fcontext = osrfHashIteratorNext( class_itr )) ) {
-					// For each linked class...
+					// For each class to which a foreign key points:
 					const char* class_name = osrfHashIteratorKey( class_itr );
 					osrfHash* fcontext = osrfHashGet( foreign_context, class_name );
 
@@ -1460,7 +1460,7 @@
 					);
 
 					// Get the name of the key field in the foreign table
-					char* foreign_pkey = osrfHashGet( fcontext, "field" );
+					const char* foreign_pkey = osrfHashGet( fcontext, "field" );
 
 					// Get the value of the foreign key pointing to the foreign table
 					char* foreign_pkey_value =
@@ -1485,48 +1485,68 @@
 
 					osrfStringArray* jump_list = osrfHashGet( fcontext, "jump" );
 
-					if( _fparam && jump_list ) {
-						// Follow another level of indirection to find one or more owners
+					const char* bad_class = NULL;  // For noting failed lookups
+					if( ! _fparam )
+						bad_class = class_name;    // Referenced row not found
+					else if( jump_list ) {
+						// Follow a chain of rows, linked by foreign keys, to find an owner
 						const char* flink = NULL;
 						int k = 0;
 						while ( (flink = osrfStringArrayGetString(jump_list, k++)) && _fparam ) {
-							// For each entry in the jump list.  Each entry is the name of a
-							// foreign key colum in the foreign table.
+							// For each entry in the jump list.  Each entry (i.e. flink) is
+							// the name of a foreign key column in the current row.
 
+							// From the IDL, get the linkage information for the next jump
 							osrfHash* foreign_link_hash =
 									oilsIDLFindPath( "/%s/links/%s", _fparam->classname, flink );
 
+							// Get the class metadata for the class
+							// to which the foreign key points
+							osrfHash* foreign_class_meta = osrfHashGet( oilsIDL(),
+									osrfHashGet( foreign_link_hash, "class" ));
+
+							// Get the name of the referenced key of that class
+							foreign_pkey = osrfHashGet( foreign_link_hash, "key" );
+
+							// Get the value of the foreign key pointing to that class
 							free( foreign_pkey_value );
 							foreign_pkey_value = oilsFMGetString( _fparam, flink );
-							foreign_pkey = osrfHashGet( foreign_link_hash, "key" );
+							if( !foreign_pkey_value )
+								break;    // Foreign key is null; quit looking
 
+							// Build a WHERE clause for the lookup
 							_tmp_params = single_hash( foreign_pkey, foreign_pkey_value );
 
-							_list = doFieldmapperSearch(
-								ctx,
-								osrfHashGet( oilsIDL(),
-										osrfHashGet( foreign_link_hash, "class" ) ),
-								_tmp_params,
-								NULL,
-								&err
-							);
+							// Do the lookup
+							_list = doFieldmapperSearch( ctx, foreign_class_meta,
+									_tmp_params, NULL, &err );
 
+							// Get the resulting row
 							jsonObjectFree( _fparam );
-							_fparam = NULL;
 							if( _list && JSON_ARRAY == _list->type && _list->size > 0 )
 								_fparam = jsonObjectExtractIndex( _list, 0 );
+							else {
+								// Referenced row not found
+								_fparam = NULL;
+								bad_class = osrfHashGet( foreign_link_hash, "class" );
+							}
+
 							jsonObjectFree( _tmp_params );
 							jsonObjectFree( _list );
 						}
 					}
 
-					if( !_fparam ) {
+					if( bad_class ) {
 
+						// We had a foreign key pointing to such-and-such a row, but then
+						// we couldn't fetch that row.  The data in the database are in an
+						// inconsistent state; the database itself may even be corrupted.
 						growing_buffer* msg = buffer_init( 128 );
 						buffer_fadd(
 							msg,
-							"%s: no object found with primary key %s of %s",
+							"%s: no object of class %s found with primary key %s of %s",
 							modulename,
+							bad_class,
 							foreign_pkey,
 							foreign_pkey_value ? foreign_pkey_value : "(null)"
 						);
@@ -1550,25 +1570,27 @@
 
 					free( foreign_pkey_value );
 
-					// Examine each context column of the foreign row,
-					// and add its value to the list of org units.
-					int j = 0;
-					const char* foreign_field = NULL;
-					osrfStringArray* ctx_array = osrfHashGet( fcontext, "context" );
-					while ( (foreign_field = osrfStringArrayGetString( ctx_array, j++ )) ) {
-						osrfStringArrayAdd( context_org_array,
-							oilsFMGetStringConst( _fparam, foreign_field ));
-						osrfLogDebug(
-							OSRF_LOG_MARK,
-							"adding foreign class %s field %s (value: %s) to the context org list",
-							class_name,
-							foreign_field,
-							osrfStringArrayGetString(
+					if( _fparam ) {
+						// Examine each context column of the foreign row,
+						// and add its value to the list of org units.
+						int j = 0;
+						const char* foreign_field = NULL;
+						osrfStringArray* ctx_array = osrfHashGet( fcontext, "context" );
+						while ( (foreign_field = osrfStringArrayGetString( ctx_array, j++ )) ) {
+							osrfStringArrayAdd( context_org_array,
+								oilsFMGetStringConst( _fparam, foreign_field ));
+							osrfLogDebug( OSRF_LOG_MARK,
+								"adding foreign class %s field %s (value: %s) "
+									"to the context org	 list",
+								class_name,
+								foreign_field,
+								osrfStringArrayGetString(
 									context_org_array, context_org_array->size - 1 )
-						);
+							);
+						}
+
+						jsonObjectFree( _fparam );
 					}
-
-					jsonObjectFree( _fparam );
 				}
 
 				osrfHashIteratorFree( class_itr );
@@ -1587,6 +1609,10 @@
 		OK = 1;
 	}
 
+	// For every combination of permission and context org unit: call a stored procedure
+	// to determine if the user has this permission in the context of this org unit.
+	// If the answer is yes at any point, then we're done, and the user has permission.
+	// In other words permissions are additive.
 	int i = 0;
 	while( (perm = osrfStringArrayGetString(permission, i++)) ) {
 		int j = 0;



More information about the open-ils-commits mailing list