static void clear_query_stack( void );
static const jsonObject* verifyUserPCRUD( osrfMethodContext* );
-static int verifyObjectPCRUD( osrfMethodContext*, osrfHash*, const jsonObject*, const int );
+static int verifyObjectPCRUD( osrfMethodContext*, osrfHash*, const jsonObject*, int );
static const char* org_tree_root( osrfMethodContext* ctx );
static jsonObject* single_hash( const char* key, const char* value );
The @a obj parameter points to a JSON_HASH of column values, keyed on column name.
*/
-static int verifyObjectPCRUD ( osrfMethodContext* ctx, osrfHash *class, const jsonObject* obj, const int rs_size ) {
+static int verifyObjectPCRUD ( osrfMethodContext* ctx, osrfHash *class, const jsonObject* obj, int rs_size ) {
dbhandle = writehandle;
osrfHash* method_metadata = (osrfHash*) ctx->method->userData;
const char* method_type = osrfHashGet( method_metadata, "methodtype" );
+ if (!rs_size) {
+ int *rs_size_from_hash = osrfHashGetFmt( (osrfHash *) ctx->session->userData, "req_%d_rs_size", ctx->request );
+ if (rs_size_from_hash) {
+ rs_size = *rs_size_from_hash;
+ osrfLogDebug(OSRF_LOG_MARK, "used rs_size from request-scoped hash: %d", rs_size);
+ }
+ }
+
// Set fetch to 1 in all cases except for inserts, meaning that for local or foreign
// contexts we will do another lookup of the current row, even if we already have a
// previously fetched row image, because the row image in hand may not include the
if( fetch ) {
// Fetch the row so that we can look at the foreign key(s)
- osrfHashSet((osrfHash*) ctx->method->userData, "1", "inside_verify");
+ osrfHashSet((osrfHash*) ctx->session->userData, "1", "inside_verify");
jsonObject* _tmp_params = single_hash( pkey, pkey_value );
jsonObject* _list = doFieldmapperSearch( ctx, class, _tmp_params, NULL, &err );
jsonObjectFree( _tmp_params );
- osrfHashSet((osrfHash*) ctx->method->userData, "0", "inside_verify");
+ osrfHashSet((osrfHash*) ctx->session->userData, "0", "inside_verify");
param = jsonObjectExtractIndex( _list, 0 );
jsonObjectFree( _list );
// Look up the row to which the foreign key points
jsonObject* _tmp_params = single_hash( foreign_pkey, foreign_pkey_value );
- osrfHashSet((osrfHash*) ctx->method->userData, "1", "inside_verify");
+ osrfHashSet((osrfHash*) ctx->session->userData, "1", "inside_verify");
jsonObject* _list = doFieldmapperSearch(
ctx, osrfHashGet( oilsIDL(), class_name ), _tmp_params, NULL, &err );
- osrfHashSet((osrfHash*) ctx->method->userData, "0", "inside_verify");
+ osrfHashSet((osrfHash*) ctx->session->userData, "0", "inside_verify");
jsonObject* _fparam = NULL;
if( _list && JSON_ARRAY == _list->type && _list->size > 0 )
char* pkey = osrfHashGet( class_meta, "primarykey" );
- char *inside_verify = osrfHashGet( (osrfHash*) ctx->method->userData, "inside_verify" );
+ char *inside_verify = osrfHashGet( (osrfHash*) ctx->session->userData, "inside_verify" );
int need_to_verify = 1;
if (inside_verify)
need_to_verify = !atoi(inside_verify);
- const jsonObject* _tmp;
+ int want_flesh = 0; // we don't know yet
+ int flesh_depth = 0;
// XXX This can be redundant with another instance of the same test that happens
// within the functions that call doFieldmapperSearch(), but we have it here to
jsonObject* res_list = jsonNewObjectType( JSON_ARRAY );
jsonObject* row_obj = NULL;
+ // The following two steps are for verifyObjectPCRUD()'s benefit.
+ // 1. get the flesh depth
+ const jsonObject* _tmp = jsonObjectGetKeyConst( query_hash, "flesh" );
+ if( _tmp ) {
+ want_flesh = 1;
+ flesh_depth = (int) jsonObjectGetNumber( _tmp );
+ if( flesh_depth == -1 || flesh_depth > max_flesh_depth )
+ flesh_depth = max_flesh_depth;
+ }
+
+ // 2. figure out one consistent rs_size for verifyObjectPCRUD to use
+ // over the whole life of this request. This means if we've already set
+ // up a req_%d_rs_size, do nothing.
+ int *rs_size = osrfHashGetFmt( (osrfHash *) ctx->session->userData, "req_%d_rs_size", ctx->request );
+ if (!rs_size) { // pointer null, so value not set in hash
+ rs_size = (int *) safe_malloc( sizeof(int) );
+ unsigned long long result_count = dbi_result_get_numrows( result );
+ *rs_size = (int) result_count * (flesh_depth + 1); // yes, we could lose some bits, but come on
+ osrfLogDebug( OSRF_LOG_MARK, "about to set rs_size to %d", *rs_size );
+ osrfHashSet( (osrfHash *) ctx->session->userData, rs_size, "req_%d_rs_size", ctx->request );
+ int *rs_size_test = osrfHashGetFmt( (osrfHash *) ctx->session->userData, "req_%d_rs_size", ctx->request );
+ if (rs_size_test)
+ osrfLogDebug( OSRF_LOG_MARK, "immediately after set, get says rs_size is %d", *rs_size_test );
+ else
+ osrfLogDebug( OSRF_LOG_MARK, "immediately after set, get says rs_size is NULL!" );
+ }
+
if( dbi_result_first_row( result )) {
// Convert each row to a JSON_ARRAY of column values, and enclose those objects
free( pkey_val );
} else {
if( !enforce_pcrud || !need_to_verify ||
- verifyObjectPCRUD( ctx, class_meta, row_obj, 1 /* not at all sure about this 1 */ )) {
+ verifyObjectPCRUD( ctx, class_meta, row_obj, 0 /* means check user data for rs_size */ )) {
osrfHashSet( dedup, pkey_val, pkey_val );
jsonObjectPush( res_list, row_obj );
}
// If we're asked to flesh, and there's anything to flesh, then flesh it
// (formerly we would skip fleshing if in pcrud mode, but now we support
// fleshing even in PCRUD).
- if( res_list->size && query_hash ) {
- _tmp = jsonObjectGetKeyConst( query_hash, "flesh" );
- if( _tmp ) {
- // Get the flesh depth
- int flesh_depth = (int) jsonObjectGetNumber( _tmp );
- if( flesh_depth == -1 || flesh_depth > max_flesh_depth )
- flesh_depth = max_flesh_depth;
-
- // 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 && flesh_depth > 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" );
-
- // Make an osrfStringArray of the names of fields to be fleshed
- if( flesh_fields ) {
- if( flesh_fields->size == 1 ) {
- const char* _t = jsonObjectGetString(
- jsonObjectGetIndex( flesh_fields, 0 ) );
- if( !strcmp( _t, "*" ))
- link_fields = osrfHashKeys( links );
- }
+ if( res_list->size && query_hash && want_flesh ) {
+ // 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 && flesh_depth > 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" );
+
+ // Make an osrfStringArray of the names of fields to be fleshed
+ if( flesh_fields ) {
+ if( flesh_fields->size == 1 ) {
+ const char* _t = jsonObjectGetString(
+ jsonObjectGetIndex( flesh_fields, 0 ) );
+ if( !strcmp( _t, "*" ))
+ link_fields = osrfHashKeys( links );
+ }
- if( !link_fields ) {
- jsonObject* _f;
- link_fields = osrfNewStringArray( 1 );
- jsonIterator* _i = jsonNewIterator( flesh_fields );
- while ((_f = jsonIteratorNext( _i ))) {
- osrfStringArrayAdd( link_fields, jsonObjectGetString( _f ) );
- }
- jsonIteratorFree( _i );
+ if( !link_fields ) {
+ jsonObject* _f;
+ link_fields = osrfNewStringArray( 1 );
+ jsonIterator* _i = jsonNewIterator( flesh_fields );
+ while ((_f = jsonIteratorNext( _i ))) {
+ osrfStringArrayAdd( link_fields, jsonObjectGetString( _f ) );
}
+ jsonIteratorFree( _i );
}
+ }
- osrfHash* fields = osrfHashGet( class_meta, "fields" );
-
- // Iterate over the JSON_ARRAY of rows
- jsonObject* cur;
- unsigned long res_idx = 0;
- while((cur = jsonObjectGetIndex( res_list, res_idx++ ) )) {
+ osrfHash* fields = osrfHashGet( class_meta, "fields" );
- int i = 0;
- const char* link_field;
+ // Iterate over the JSON_ARRAY of rows
+ jsonObject* cur;
+ unsigned long res_idx = 0;
+ while((cur = jsonObjectGetIndex( res_list, res_idx++ ) )) {
- // Iterate over the list of fleshable fields
- while( (link_field = osrfStringArrayGetString(link_fields, i++)) ) {
+ int i = 0;
+ const char* link_field;
- osrfLogDebug( OSRF_LOG_MARK, "Starting to flesh %s", link_field );
+ // Iterate over the list of fleshable fields
+ while( (link_field = osrfStringArrayGetString(link_fields, i++)) ) {
- osrfHash* kid_link = osrfHashGet( links, link_field );
- if( !kid_link )
- continue; // Not a link field; skip it
+ osrfLogDebug( OSRF_LOG_MARK, "Starting to flesh %s", link_field );
- osrfHash* field = osrfHashGet( fields, link_field );
- if( !field )
- continue; // Not a field at all; skip it (IDL is ill-formed)
+ osrfHash* kid_link = osrfHashGet( links, link_field );
+ if( !kid_link )
+ continue; // Not a link field; skip it
- osrfHash* kid_idl = osrfHashGet( oilsIDL(),
- osrfHashGet( kid_link, "class" ));
- if( !kid_idl )
- continue; // The class it links to doesn't exist; skip it
+ osrfHash* field = osrfHashGet( fields, link_field );
+ if( !field )
+ continue; // Not a field at all; skip it (IDL is ill-formed)
- const char* reltype = osrfHashGet( kid_link, "reltype" );
- if( !reltype )
- continue; // No reltype; skip it (IDL is ill-formed)
+ osrfHash* kid_idl = osrfHashGet( oilsIDL(),
+ osrfHashGet( kid_link, "class" ));
+ if( !kid_idl )
+ continue; // The class it links to doesn't exist; skip it
- osrfHash* value_field = field;
+ const char* reltype = osrfHashGet( kid_link, "reltype" );
+ if( !reltype )
+ continue; // No reltype; skip it (IDL is ill-formed)
- if( !strcmp( reltype, "has_many" )
- || !strcmp( reltype, "might_have" ) ) { // has_many or might_have
- value_field = osrfHashGet(
- fields, osrfHashGet( class_meta, "primarykey" ) );
- }
+ osrfHash* value_field = field;
- osrfStringArray* link_map = osrfHashGet( kid_link, "map" );
+ if( !strcmp( reltype, "has_many" )
+ || !strcmp( reltype, "might_have" ) ) { // has_many or might_have
+ value_field = osrfHashGet(
+ fields, osrfHashGet( class_meta, "primarykey" ) );
+ }
- if( link_map->size > 0 ) {
- jsonObject* _kid_key = jsonNewObjectType( JSON_ARRAY );
- jsonObjectPush(
- _kid_key,
- jsonNewObject( osrfStringArrayGetString( link_map, 0 ) )
- );
+ osrfStringArray* link_map = osrfHashGet( kid_link, "map" );
- jsonObjectSetKey(
- flesh_blob,
- osrfHashGet( kid_link, "class" ),
- _kid_key
- );
- };
+ if( link_map->size > 0 ) {
+ jsonObject* _kid_key = jsonNewObjectType( JSON_ARRAY );
+ jsonObjectPush(
+ _kid_key,
+ jsonNewObject( osrfStringArrayGetString( link_map, 0 ) )
+ );
- osrfLogDebug(
- OSRF_LOG_MARK,
- "Link field: %s, remote class: %s, fkey: %s, reltype: %s",
- osrfHashGet( kid_link, "field" ),
+ jsonObjectSetKey(
+ flesh_blob,
osrfHashGet( kid_link, "class" ),
- osrfHashGet( kid_link, "key" ),
- osrfHashGet( kid_link, "reltype" )
+ _kid_key
);
+ };
- const char* search_key = jsonObjectGetString(
- jsonObjectGetIndex( cur,
- atoi( osrfHashGet( value_field, "array_position" ) )
- )
- );
+ osrfLogDebug(
+ OSRF_LOG_MARK,
+ "Link field: %s, remote class: %s, fkey: %s, reltype: %s",
+ osrfHashGet( kid_link, "field" ),
+ osrfHashGet( kid_link, "class" ),
+ osrfHashGet( kid_link, "key" ),
+ osrfHashGet( kid_link, "reltype" )
+ );
- if( !search_key ) {
- osrfLogDebug( OSRF_LOG_MARK, "Nothing to search for!" );
- continue;
- }
+ const char* search_key = jsonObjectGetString(
+ jsonObjectGetIndex( cur,
+ atoi( osrfHashGet( value_field, "array_position" ) )
+ )
+ );
- osrfLogDebug( OSRF_LOG_MARK, "Creating param objects..." );
+ if( !search_key ) {
+ osrfLogDebug( OSRF_LOG_MARK, "Nothing to search for!" );
+ continue;
+ }
- // construct WHERE clause
- jsonObject* where_clause = jsonNewObjectType( JSON_HASH );
- jsonObjectSetKey(
- where_clause,
- osrfHashGet( kid_link, "key" ),
- jsonNewObject( search_key )
- );
+ osrfLogDebug( OSRF_LOG_MARK, "Creating param objects..." );
+
+ // construct WHERE clause
+ jsonObject* where_clause = jsonNewObjectType( JSON_HASH );
+ jsonObjectSetKey(
+ where_clause,
+ osrfHashGet( kid_link, "key" ),
+ jsonNewObject( search_key )
+ );
- // construct the rest of the query, mostly
- // by copying pieces of the previous level of query
- jsonObject* rest_of_query = jsonNewObjectType( JSON_HASH );
- jsonObjectSetKey( rest_of_query, "flesh",
- jsonNewNumberObject( flesh_depth - 1 + link_map->size )
+ // construct the rest of the query, mostly
+ // by copying pieces of the previous level of query
+ jsonObject* rest_of_query = jsonNewObjectType( JSON_HASH );
+ jsonObjectSetKey( rest_of_query, "flesh",
+ jsonNewNumberObject( flesh_depth - 1 + link_map->size )
+ );
+
+ if( flesh_blob )
+ jsonObjectSetKey( rest_of_query, "flesh_fields",
+ jsonObjectClone( flesh_blob ));
+
+ if( jsonObjectGetKeyConst( query_hash, "order_by" )) {
+ jsonObjectSetKey( rest_of_query, "order_by",
+ jsonObjectClone( jsonObjectGetKeyConst( query_hash, "order_by" ))
);
+ }
- if( flesh_blob )
- jsonObjectSetKey( rest_of_query, "flesh_fields",
- jsonObjectClone( flesh_blob ));
+ if( jsonObjectGetKeyConst( query_hash, "select" )) {
+ jsonObjectSetKey( rest_of_query, "select",
+ jsonObjectClone( jsonObjectGetKeyConst( query_hash, "select" ))
+ );
+ }
- if( jsonObjectGetKeyConst( query_hash, "order_by" )) {
- jsonObjectSetKey( rest_of_query, "order_by",
- jsonObjectClone( jsonObjectGetKeyConst( query_hash, "order_by" ))
- );
- }
+ // do the query, recursively, to expand the fleshable field
+ jsonObject* kids = doFieldmapperSearch( ctx, kid_idl,
+ where_clause, rest_of_query, err );
- if( jsonObjectGetKeyConst( query_hash, "select" )) {
- jsonObjectSetKey( rest_of_query, "select",
- jsonObjectClone( jsonObjectGetKeyConst( query_hash, "select" ))
- );
- }
+ jsonObjectFree( where_clause );
+ jsonObjectFree( rest_of_query );
- // do the query, recursively, to expand the fleshable field
- jsonObject* kids = doFieldmapperSearch( ctx, kid_idl,
- where_clause, rest_of_query, err );
+ if( *err ) {
+ osrfStringArrayFree( link_fields );
+ jsonObjectFree( res_list );
+ jsonObjectFree( flesh_blob );
+ return NULL;
+ }
- jsonObjectFree( where_clause );
- jsonObjectFree( rest_of_query );
+ osrfLogDebug( OSRF_LOG_MARK, "Search for %s return %d linked objects",
+ osrfHashGet( kid_link, "class" ), kids->size );
- if( *err ) {
- osrfStringArrayFree( link_fields );
- jsonObjectFree( res_list );
- jsonObjectFree( flesh_blob );
- return NULL;
- }
+ // Traverse the result set
+ jsonObject* X = NULL;
+ if( link_map->size > 0 && kids->size > 0 ) {
+ X = kids;
+ kids = jsonNewObjectType( JSON_ARRAY );
- osrfLogDebug( OSRF_LOG_MARK, "Search for %s return %d linked objects",
- osrfHashGet( kid_link, "class" ), kids->size );
-
- // Traverse the result set
- jsonObject* X = NULL;
- if( link_map->size > 0 && kids->size > 0 ) {
- X = kids;
- kids = jsonNewObjectType( JSON_ARRAY );
-
- jsonObject* _k_node;
- unsigned long res_idx = 0;
- while((_k_node = jsonObjectGetIndex( X, res_idx++ ) )) {
- jsonObjectPush(
- kids,
- jsonObjectClone(
- jsonObjectGetIndex(
- _k_node,
- (unsigned long) atoi(
+ jsonObject* _k_node;
+ unsigned long res_idx = 0;
+ while((_k_node = jsonObjectGetIndex( X, res_idx++ ) )) {
+ jsonObjectPush(
+ kids,
+ jsonObjectClone(
+ jsonObjectGetIndex(
+ _k_node,
+ (unsigned long) atoi(
+ osrfHashGet(
osrfHashGet(
osrfHashGet(
osrfHashGet(
- osrfHashGet(
- oilsIDL(),
- osrfHashGet( kid_link, "class" )
- ),
- "fields"
+ oilsIDL(),
+ osrfHashGet( kid_link, "class" )
),
- osrfStringArrayGetString( link_map, 0 )
+ "fields"
),
- "array_position"
- )
+ osrfStringArrayGetString( link_map, 0 )
+ ),
+ "array_position"
)
)
)
- );
- } // end while loop traversing X
- }
-
- if( !strcmp( osrfHashGet( kid_link, "reltype" ), "has_a" )
- || !strcmp( osrfHashGet( kid_link, "reltype" ), "might_have" )) {
- osrfLogDebug(OSRF_LOG_MARK, "Storing fleshed objects in %s",
- osrfHashGet( kid_link, "field" ));
- jsonObjectSetIndex(
- cur,
- (unsigned long) atoi( osrfHashGet( field, "array_position" ) ),
- jsonObjectClone( jsonObjectGetIndex( kids, 0 ))
+ )
);
- }
+ } // end while loop traversing X
+ }
- if( !strcmp( osrfHashGet( kid_link, "reltype" ), "has_many" )) {
- // has_many
- osrfLogDebug( OSRF_LOG_MARK, "Storing fleshed objects in %s",
- osrfHashGet( kid_link, "field" ) );
- jsonObjectSetIndex(
- cur,
- (unsigned long) atoi( osrfHashGet( field, "array_position" ) ),
- jsonObjectClone( kids )
- );
- }
+ if( !strcmp( osrfHashGet( kid_link, "reltype" ), "has_a" )
+ || !strcmp( osrfHashGet( kid_link, "reltype" ), "might_have" )) {
+ osrfLogDebug(OSRF_LOG_MARK, "Storing fleshed objects in %s",
+ osrfHashGet( kid_link, "field" ));
+ jsonObjectSetIndex(
+ cur,
+ (unsigned long) atoi( osrfHashGet( field, "array_position" ) ),
+ jsonObjectClone( jsonObjectGetIndex( kids, 0 ))
+ );
+ }
- if( X ) {
- jsonObjectFree( kids );
- kids = X;
- }
+ if( !strcmp( osrfHashGet( kid_link, "reltype" ), "has_many" )) {
+ // has_many
+ osrfLogDebug( OSRF_LOG_MARK, "Storing fleshed objects in %s",
+ osrfHashGet( kid_link, "field" ) );
+ jsonObjectSetIndex(
+ cur,
+ (unsigned long) atoi( osrfHashGet( field, "array_position" ) ),
+ jsonObjectClone( kids )
+ );
+ }
+ if( X ) {
jsonObjectFree( kids );
+ kids = X;
+ }
- osrfLogDebug( OSRF_LOG_MARK, "Fleshing of %s complete",
- osrfHashGet( kid_link, "field" ) );
- osrfLogDebug( OSRF_LOG_MARK, "%s", jsonObjectToJSON( cur ));
+ jsonObjectFree( kids );
- } // end while loop traversing list of fleshable fields
- } // end while loop traversing res_list
- jsonObjectFree( flesh_blob );
- osrfStringArrayFree( link_fields );
- }
+ osrfLogDebug( OSRF_LOG_MARK, "Fleshing of %s complete",
+ osrfHashGet( kid_link, "field" ) );
+ osrfLogDebug( OSRF_LOG_MARK, "%s", jsonObjectToJSON( cur ));
+
+ } // end while loop traversing list of fleshable fields
+ } // end while loop traversing res_list
+ jsonObjectFree( flesh_blob );
+ osrfStringArrayFree( link_fields );
}
}