static char* searchJOIN ( const jsonObject*, const ClassInfo* left_info );
static char* searchWHERE ( const jsonObject* search_hash, const ClassInfo*, int, osrfMethodContext* );
static char* buildSELECT( const jsonObject*, jsonObject* rest_of_query,
- osrfHash* meta, osrfMethodContext* ctx, char** cursor_name );
+ osrfHash* meta, osrfMethodContext* ctx, char* cursor_name );
static char* buildOrderByFromArray( osrfMethodContext* ctx, const jsonObject* order_array );
char* buildQuery( osrfMethodContext* ctx, jsonObject* query, int flags );
The SELECT statements built here are distinct from those built for the json_query method.
*/
static char* buildSELECT ( const jsonObject* search_hash, jsonObject* rest_of_query,
- osrfHash* meta, osrfMethodContext* ctx, char** cursor_name ) {
+ osrfHash* meta, osrfMethodContext* ctx, char* cursor_name ) {
const char* locale = osrf_message_get_last_locale();
if( !table )
table = strdup( "(null)" );
- *cursor_name = random_cursor_name();
-
- buffer_fadd( sql_buf, "DECLARE \"%s\" NO SCROLL CURSOR WITH HOLD FOR SELECT %s FROM %s AS \"%s\"", *cursor_name, col_list, table, core_class );
+ if (cursor_name) buffer_fadd( sql_buf, "DECLARE \"%s\" NO SCROLL CURSOR WITH HOLD FOR ", cursor_name );
+ buffer_fadd( sql_buf, "SELECT %s FROM %s AS \"%s\"", col_list, table, core_class );
free( col_list );
free( table );
}
free( order_by_list );
+
+ }
+
+ if (!cursor_name) {
+ const jsonObject* limit = jsonObjectGetKeyConst( rest_of_query, "limit" );
+ if( limit ) {
+ const char* str = jsonObjectGetString( limit );
+ if (str) {
+ buffer_fadd( sql_buf, " LIMIT %d", atoi(str) );
+ }
+ }
+
+ const jsonObject* offset = jsonObjectGetKeyConst( rest_of_query, "offset" );
+ if( offset ) {
+ const char* str = jsonObjectGetString( offset );
+ if (str) {
+ buffer_fadd( sql_buf, " OFFSET %d", atoi(str) );
+ }
+ }
}
}
int offset = 0;
int limit = 0;
int cursor_page_size = 5;
- char* cursor_name;
+ char* cursor_name = NULL;
+
+ if (*methodtype != 'r') cursor_name = random_cursor_name(); /* Use a cursor for all but .retrieve */
- char* sql = buildSELECT( where_hash, query_hash, class_meta, ctx, &cursor_name );
+ char* sql = buildSELECT( where_hash, query_hash, class_meta, ctx, cursor_name );
if( !sql ) {
osrfLogDebug( OSRF_LOG_MARK, "Problem building query, returning NULL" );
*err = -1;
}
- const jsonObject* limit_o = jsonObjectGetKeyConst( query_hash, "limit" );
- if( limit_o ) {
- limit = (int) jsonObjectGetNumber( limit_o );
- } else {
- limit = -1;
- }
+ if (cursor_name) {
+ const jsonObject* limit_o = jsonObjectGetKeyConst( query_hash, "limit" );
+ if( limit_o ) {
+ limit = (int) jsonObjectGetNumber( limit_o );
+ } else {
+ limit = -1;
+ }
- const jsonObject* offset_o = jsonObjectGetKeyConst( query_hash, "offset" );
- if( offset_o ) {
- offset = (int) jsonObjectGetNumber( offset_o );
- } else {
- offset = -1;
- }
+ const jsonObject* offset_o = jsonObjectGetKeyConst( query_hash, "offset" );
+ if( offset_o ) {
+ offset = (int) jsonObjectGetNumber( offset_o );
+ } else {
+ offset = -1;
+ }
- // set cursor_page_size to the largest of the three
- if (cursor_page_size < offset) cursor_page_size = offset;
- if (cursor_page_size < limit) cursor_page_size = limit;
+ // set cursor_page_size to the largest of the three
+ if (cursor_page_size < offset) cursor_page_size = offset;
+ if (cursor_page_size < limit) cursor_page_size = limit;
+ }
- // Declares a cursor
+ // Declares a cursor or runs a retrieve-select
dbi_result result = dbi_conn_query( dbhandle, sql );
if( NULL == result ) {
rs_size = (int *) safe_malloc( sizeof(int) ); // will be freed by sessionDataFree()
unsigned long long result_count = cursor_page_size;
+ if (!cursor_name) {
+ result_count = dbi_result_get_numrows( result );
+ }
*rs_size = (int) result_count * (flesh_depth + 1); // yes, we could lose some bits, but come on
osrfHashSet( (osrfHash *) ctx->session->userData, rs_size, "rs_size_req_%d", ctx->request );
}
+ if (cursor_name) {
+ dbi_result_free( result ); // toss the declare result
+ result = dbi_conn_queryf( dbhandle, "FETCH %d FROM \"%s\";", cursor_page_size, cursor_name );
+
+ if( NULL == result ) {
+ const char* msg;
+ int errnum = dbi_conn_error( dbhandle, &msg );
+ osrfLogError(OSRF_LOG_MARK, "%s: Error retrieving %s with query [%s]: %d %s",
+ modulename, osrfHashGet( class_meta, "fieldmapper" ), sql, errnum,
+ msg ? msg : "(No description available)" );
+ if( !oilsIsDBConnected( dbhandle ))
+ osrfAppSessionPanic( ctx->session );
+ osrfAppSessionStatus(
+ ctx->session,
+ OSRF_STATUS_INTERNALSERVERERROR,
+ "osrfMethodException",
+ ctx->request,
+ "Severe query error -- see error log for more details"
+ );
+ *err = -1;
+ free( sql );
+ return NULL;
- dbi_result_free( result ); // toss the declare result
- result = dbi_conn_queryf( dbhandle, "FETCH %d FROM \"%s\";", cursor_page_size, cursor_name );
-
- if( NULL == result ) {
- const char* msg;
- int errnum = dbi_conn_error( dbhandle, &msg );
- osrfLogError(OSRF_LOG_MARK, "%s: Error retrieving %s with query [%s]: %d %s",
- modulename, osrfHashGet( class_meta, "fieldmapper" ), sql, errnum,
- msg ? msg : "(No description available)" );
- if( !oilsIsDBConnected( dbhandle ))
- osrfAppSessionPanic( ctx->session );
- osrfAppSessionStatus(
- ctx->session,
- OSRF_STATUS_INTERNALSERVERERROR,
- "osrfMethodException",
- ctx->request,
- "Severe query error -- see error log for more details"
- );
- *err = -1;
- free( sql );
- return NULL;
-
- }
+ }
+ }
if( dbi_result_first_row( result )) {
// eliminate the duplicates.
osrfLogDebug( OSRF_LOG_MARK, "Query returned at least one row" );
osrfHash* dedup = osrfNewHash();
- int cursor_page_remaining = cursor_page_size;
+ int cursor_page_remaining = cursor_page_size;
do {
- cursor_page_remaining--;
+ cursor_page_remaining--;
row_obj = oilsMakeFieldmapperFromResult( result, class_meta );
char* pkey_val = oilsFMGetString( row_obj, pkey );
if( osrfHashGet( dedup, pkey_val ) ) {
} else {
if( !enforce_pcrud || !need_to_verify ||
verifyObjectPCRUD( ctx, class_meta, row_obj, 0 /* means check user data for rs_size */ )) {
- if (offset > -1 && offset) {
- offset--;
- } else {
- if (limit > -1 && limit) limit--;
- osrfHashSet( dedup, pkey_val, pkey_val );
- jsonObjectPush( res_list, row_obj );
- }
+ if (cursor_name) {
+ if (offset > -1 && offset) {
+ offset--;
+ } else {
+ if (limit > -1 && limit) limit--;
+ osrfHashSet( dedup, pkey_val, pkey_val );
+ jsonObjectPush( res_list, row_obj );
+ }
+ } else {
+ osrfHashSet( dedup, pkey_val, pkey_val );
+ jsonObjectPush( res_list, row_obj );
+ }
}
}
- if (!cursor_page_remaining) { // fetch next page
+ if (cursor_name && !cursor_page_remaining) { // fetch next page
cursor_page_remaining = cursor_page_size;
dbi_result_free( result );
result = dbi_conn_queryf( dbhandle, "FETCH %d FROM \"%s\";", cursor_page_size, cursor_name );
}
}
} while(
- limit && ( // limit is -1 (none) or not yet decremented to 0
- (cursor_page_remaining == cursor_page_size && dbi_result_first_row(result)) || // on a new page, and there's a row
- (cursor_page_remaining != cursor_page_size && dbi_result_next_row(result)) // on the same page, and there's a row
+ (!cursor_name && dbi_result_next_row(result)) || (
+ cursor_name && limit && ( // limit is -1 (none) or not yet decremented to 0
+ (cursor_page_remaining == cursor_page_size && dbi_result_first_row(result)) || // on a new page, and there's a row
+ (cursor_page_remaining != cursor_page_size && dbi_result_next_row(result)) // on the same page, and there's a row
+ )
)
);
osrfHashFree( dedup );
/* clean up the query */
dbi_result_free( result );
- result = dbi_conn_queryf( dbhandle, "CLOSE \"%s\";", cursor_name );
- dbi_result_free( result );
+ if (cursor_name) {
+ result = dbi_conn_queryf( dbhandle, "CLOSE \"%s\";", cursor_name );
+ dbi_result_free( result );
+ }
+
free( sql );
// If we're asked to flesh, and there's anything to flesh, then flesh it