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

svn at svn.open-ils.org svn at svn.open-ils.org
Sun Mar 7 14:33:20 EST 2010


Author: scottmk
Date: 2010-03-07 14:33:15 -0500 (Sun, 07 Mar 2010)
New Revision: 15726

Modified:
   trunk/Open-ILS/src/c-apps/oils_cstore.c
Log:
Added comments; tinkered with white space here and there.

Rearranged the code a bit for clarity, without changing functionality.

In doFieldMapperSearch():

- Renamed meta to class_meta, in order to distiguish it from method metadata.
- Rename obj to row_obj, which is more descriptive, and moved its declaration
  closer to its first use.
- Moved the declaration of dedup and links closer to their first uses.

In oilsMakeFieldmapperFromResult():

- Moved the declarations of several variables closer to their first uses.
- Eliminated a couple of unnecessary calls to memset().

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


Modified: trunk/Open-ILS/src/c-apps/oils_cstore.c
===================================================================
--- trunk/Open-ILS/src/c-apps/oils_cstore.c	2010-03-06 17:28:47 UTC (rev 15725)
+++ trunk/Open-ILS/src/c-apps/oils_cstore.c	2010-03-07 19:33:15 UTC (rev 15726)
@@ -104,7 +104,7 @@
 static jsonObject* doRetrieve ( osrfMethodContext*, int* );
 static jsonObject* doUpdate ( osrfMethodContext*, int* );
 static jsonObject* doDelete ( osrfMethodContext*, int* );
-static jsonObject* doFieldmapperSearch ( osrfMethodContext* ctx, osrfHash* meta,
+static jsonObject* doFieldmapperSearch ( osrfMethodContext* ctx, osrfHash* class_meta,
 		jsonObject* where_hash, jsonObject* query_hash, int* err );
 static jsonObject* oilsMakeFieldmapperFromResult( dbi_result, osrfHash* );
 static jsonObject* oilsMakeJSONFromResult( dbi_result );
@@ -1829,8 +1829,8 @@
 	// Set the last_xact_id
 	int index = oilsIDL_ntop( target->classname, "last_xact_id" );
 	if (index > -1) {
-		osrfLogDebug( OSRF_LOG_MARK, "Setting last_xact_id to %s on %s at position %d",
-			trans_id, target->classname, index );
+		osrfLogDebug(OSRF_LOG_MARK, "Setting last_xact_id to %s on %s at position %d",
+			trans_id, target->classname, index);
 		jsonObjectSetIndex(target, index, jsonNewObject(trans_id));
 	}
 
@@ -5079,21 +5079,19 @@
 	return err;
 }
 
-static jsonObject* doFieldmapperSearch ( osrfMethodContext* ctx, osrfHash* meta,
+static jsonObject* doFieldmapperSearch ( osrfMethodContext* ctx, osrfHash* class_meta,
 		jsonObject* where_hash, jsonObject* query_hash, int* err ) {
 
 	// XXX for now...
 	dbhandle = writehandle;
 
-	osrfHash* links = osrfHashGet(meta, "links");
-	osrfHash* fields = osrfHashGet(meta, "fields");
-	char* core_class = osrfHashGet(meta, "classname");
-	char* pkey = osrfHashGet(meta, "primarykey");
+	osrfHash* fields = osrfHashGet( class_meta, "fields" );
+	char* core_class = osrfHashGet( class_meta, "classname" );
+	char* pkey = osrfHashGet( class_meta, "primarykey" );
 
 	const jsonObject* _tmp;
-	jsonObject* obj;
 
-	char* sql = buildSELECT( where_hash, query_hash, meta, ctx );
+	char* sql = buildSELECT( where_hash, query_hash, class_meta, ctx );
 	if (!sql) {
 		osrfLogDebug(OSRF_LOG_MARK, "Problem building query, returning NULL");
 		*err = -1;
@@ -5105,7 +5103,7 @@
 	dbi_result result = dbi_conn_query(dbhandle, sql);
 	if( NULL == result ) {
 		osrfLogError(OSRF_LOG_MARK, "%s: Error retrieving %s with query [%s]",
-			MODULENAME, osrfHashGet(meta, "fieldmapper"), sql);
+			MODULENAME, osrfHashGet( class_meta, "fieldmapper" ), sql);
 		osrfAppSessionStatus(
 			ctx->session,
 			OSRF_STATUS_INTERNALSERVERERROR,
@@ -5122,51 +5120,62 @@
 	}
 
 	jsonObject* res_list = jsonNewObjectType(JSON_ARRAY);
-	osrfHash* dedup = osrfNewHash();
+	jsonObject* row_obj = NULL;
 
 	if (dbi_result_first_row(result)) {
-		/* JSONify the result */
+
+		// Convert each row to a JSON_ARRAY of column values, and enclose those objects
+		// in a JSON_ARRAY of rows.  If two or more rows have the same key value, then
+		// eliminate the duplicates.
 		osrfLogDebug(OSRF_LOG_MARK, "Query returned at least one row");
+		osrfHash* dedup = osrfNewHash();
 		do {
-			obj = oilsMakeFieldmapperFromResult( result, meta );
-			char* pkey_val = oilsFMGetString( obj, pkey );
+			row_obj = oilsMakeFieldmapperFromResult( result, class_meta );
+			char* pkey_val = oilsFMGetString( row_obj, pkey );
 			if ( osrfHashGet( dedup, pkey_val ) ) {
-				jsonObjectFree(obj);
-				free(pkey_val);
+				jsonObjectFree( row_obj );
+				free( pkey_val );
 			} else {
 				osrfHashSet( dedup, pkey_val, pkey_val );
-				jsonObjectPush(res_list, obj);
+				jsonObjectPush( res_list, row_obj );
 			}
 		} while (dbi_result_next_row(result));
+		osrfHashFree(dedup);
+
 	} else {
 		osrfLogDebug(OSRF_LOG_MARK, "%s returned no results for query %s",
 			MODULENAME, sql );
 	}
 
-	osrfHashFree(dedup);
 	/* clean up the query */
 	dbi_result_free(result);
 	free(sql);
 
+	// If we're asked to flesh, and there's anything to flesh, then flesh.
 	if (res_list->size && query_hash) {
 		_tmp = jsonObjectGetKeyConst( query_hash, "flesh" );
 		if (_tmp) {
-			int x = (int)jsonObjectGetNumber(_tmp);
-			if (x == -1 || x > max_flesh_depth) x = max_flesh_depth;
+			// Get the flesh depth
+			int x = (int) jsonObjectGetNumber(_tmp);
+			if (x == -1 || x > max_flesh_depth)
+				x = max_flesh_depth;
 
-			const jsonObject* temp_blob;
-			if ((temp_blob = jsonObjectGetKeyConst( query_hash, "flesh_fields" )) && x > 0) {
+			// We need a non-zero flesh depth, and a list of fields to flesh
+			const jsonObject* temp_blob = jsonObjectGetKeyConst( query_hash, "flesh_fields" );
+			if ( temp_blob && x > 0 ) {
 
 				jsonObject* flesh_blob = jsonObjectClone( temp_blob );
 				const jsonObject* flesh_fields = jsonObjectGetKeyConst( flesh_blob, core_class );
 
 				osrfStringArray* link_fields = NULL;
+				osrfHash* links = osrfHashGet( class_meta, "links" );
 
 				if (flesh_fields) {
 					if (flesh_fields->size == 1) {
 						const char* _t = jsonObjectGetString(
 							jsonObjectGetIndex( flesh_fields, 0 ) );
-						if (!strcmp(_t,"*")) link_fields = osrfHashKeys( links );
+						if (!strcmp(_t,"*"))
+							link_fields = osrfHashKeys( links );
 					}
 
 					if (!link_fields) {
@@ -5207,12 +5216,14 @@
 
 						if (!(strcmp( osrfHashGet(kid_link, "reltype"), "has_many" ))) {
 							// has_many
-							value_field = osrfHashGet( fields, osrfHashGet(meta, "primarykey") );
+							value_field = osrfHashGet(
+								fields, osrfHashGet( class_meta, "primarykey" ) );
 						}
 
 						if (!(strcmp( osrfHashGet(kid_link, "reltype"), "might_have" ))) {
 							// might_have
-							value_field = osrfHashGet( fields, osrfHashGet(meta, "primarykey") );
+							value_field = osrfHashGet(
+								fields, osrfHashGet( class_meta, "primarykey" ) );
 						}
 
 						osrfStringArray* link_map = osrfHashGet( kid_link, "map" );
@@ -5677,58 +5688,75 @@
 	free(id);
 
 	return obj;
-
 }
 
+/**
+	@brief Translate a row returned from the database into a jsonObject of type JSON_ARRAY.
+	@param result An iterator for a result set; we only look at the current row.
+	@param @meta Pointer to the class metadata for the core class.
+	@return Pointer to the resulting jsonObject if successful; otherwise NULL.
 
+	If a column is not defined in the IDL, or if it has no array_position defined for it in
+	the IDL, or if it is defined as virtual, ignore it.
+
+	Otherwise, translate the column value into a jsonObject of type JSON_NULL, JSON_NUMBER,
+	or JSON_STRING.  Then insert this jsonObject into the JSON_ARRAY according to its
+	array_position in the IDL.
+
+	A field defined in the IDL but not represented in the returned row will leave a hole
+	in the JSON_ARRAY.  In effect it will be treated as a null value.
+
+	In the resulting JSON_ARRAY, the field values appear in the sequence defined by the IDL,
+	regardless of their sequence in the SELECT statement.  The JSON_ARRAY is assigned the
+	classname corresponding to the @a meta argument.
+
+	The calling code is responsible for freeing the the resulting jsonObject by calling
+	jsonObjectFree().
+*/
 static jsonObject* oilsMakeFieldmapperFromResult( dbi_result result, osrfHash* meta) {
 	if(!(result && meta)) return jsonNULL;
 
-	jsonObject* object = jsonNewObject(NULL);
+	jsonObject* object = jsonNewObjectType( JSON_ARRAY );
 	jsonObjectSetClass(object, osrfHashGet(meta, "classname"));
+	osrfLogInternal(OSRF_LOG_MARK, "Setting object class to %s ", object->classname);
 
 	osrfHash* fields = osrfHashGet(meta, "fields");
 
-	osrfLogInternal(OSRF_LOG_MARK, "Setting object class to %s ", object->classname);
-
-	osrfHash* _f;
-	time_t _tmp_dt;
-	char dt_string[256];
-	struct tm gmdt;
-
-	int fmIndex;
 	int columnIndex = 1;
-	int attr;
-	unsigned short type;
 	const char* columnName;
 
-	/* cycle through the column list */
+	/* cycle through the columns in the row returned from the database */
 	while( (columnName = dbi_result_get_field_name(result, columnIndex)) ) {
 
 		osrfLogInternal(OSRF_LOG_MARK, "Looking for column named [%s]...", (char*)columnName);
 
-		fmIndex = -1; // reset the position
+		int fmIndex = -1;  // Will be set to the IDL's sequence number for this field
 
 		/* determine the field type and storage attributes */
-		type = dbi_result_get_field_type_idx(result, columnIndex);
-		attr = dbi_result_get_field_attribs_idx(result, columnIndex);
+		unsigned short type = dbi_result_get_field_type_idx(result, columnIndex);
+		int attr            = dbi_result_get_field_attribs_idx(result, columnIndex);
 
-		/* fetch the fieldmapper index */
-		if( (_f = osrfHashGet(fields, (char*)columnName)) ) {
+		// Fetch the IDL's sequence number for the field.  If the field isn't in the IDL,
+		// or if it has no sequence number there, or if it's virtual, skip it.
+		osrfHash* _f = osrfHashGet( fields, (char*) columnName );
+		if( _f ) {
 
 			if ( str_is_true( osrfHashGet(_f, "virtual") ) )
-				continue;
+				continue;   // skip this column: IDL says it's virtual
 
 			const char* pos = (char*)osrfHashGet(_f, "array_position");
-			if ( !pos )
-				continue;
+			if ( !pos )      // IDL has no sequence number for it.  This shouldn't happen,
+				continue;    // since we assign sequence numbers dynamically as we load the IDL.
 
 			fmIndex = atoi( pos );
 			osrfLogInternal(OSRF_LOG_MARK, "... Found column at position [%s]...", pos);
 		} else {
-			continue;
+			continue;     // This field is not defined in the IDL
 		}
 
+		// Stuff the column value into a slot in the JSON_ARRAY, indexed according to the
+		// sequence number from the IDL (which is likely to be different from the sequence
+		// of columns in the SELECT clause).
 		if (dbi_result_field_is_null_idx(result, columnIndex)) {
 			jsonObjectSetIndex( object, fmIndex, jsonNewObject(NULL) );
 		} else {
@@ -5753,7 +5781,6 @@
 
 				case DBI_TYPE_STRING :
 
-
 					jsonObjectSetIndex(
 						object,
 						fmIndex,
@@ -5762,14 +5789,15 @@
 
 					break;
 
-				case DBI_TYPE_DATETIME :
+				case DBI_TYPE_DATETIME : {
 
-					memset(dt_string, '\0', sizeof(dt_string));
-					memset(&gmdt, '\0', sizeof(gmdt));
+					char dt_string[256] = "";
+					struct tm gmdt;
 
-					_tmp_dt = dbi_result_get_datetime_idx(result, columnIndex);
+					// Fetch the date column as a time_t
+					time_t _tmp_dt = dbi_result_get_datetime_idx(result, columnIndex);
 
-
+					// Translate the time_t to a human-readable string
 					if (!(attr & DBI_DATETIME_DATE)) {
 						gmtime_r( &_tmp_dt, &gmdt );
 						strftime(dt_string, sizeof(dt_string), "%T", &gmdt);
@@ -5784,14 +5812,14 @@
 					jsonObjectSetIndex( object, fmIndex, jsonNewObject(dt_string) );
 
 					break;
-
+				}
 				case DBI_TYPE_BINARY :
 					osrfLogError( OSRF_LOG_MARK,
 						"Can't do binary at column %s : index %d", columnName, columnIndex);
-			}
+			} // End switch
 		}
 		++columnIndex;
-	}
+	} // End while
 
 	return object;
 }



More information about the open-ils-commits mailing list