[open-ils-commits] r11179 - branches/rel_1_4/Open-ILS/src/c-apps
svn at svn.open-ils.org
svn at svn.open-ils.org
Thu Nov 13 23:02:03 EST 2008
Author: miker
Date: 2008-11-13 23:02:01 -0500 (Thu, 13 Nov 2008)
New Revision: 11179
Modified:
branches/rel_1_4/Open-ILS/src/c-apps/oils_cstore.c
Log:
backporting EXISTS/NOT EXISTS/subquery/better-aggregate from trunk
Modified: branches/rel_1_4/Open-ILS/src/c-apps/oils_cstore.c
===================================================================
--- branches/rel_1_4/Open-ILS/src/c-apps/oils_cstore.c 2008-11-14 03:55:50 UTC (rev 11178)
+++ branches/rel_1_4/Open-ILS/src/c-apps/oils_cstore.c 2008-11-14 04:02:01 UTC (rev 11179)
@@ -18,6 +18,7 @@
# define MODULENAME "open-ils.cstore"
#endif
+#define SUBSELECT 4
#define DISABLE_I18N 2
#define SELECT_DISTINCT 1
#define AND_OP_JOIN 0
@@ -59,7 +60,7 @@
static char* searchINPredicate ( const char*, osrfHash*, const jsonObject*, const char* );
static char* searchPredicate ( const char*, osrfHash*, jsonObject* );
static char* searchJOIN ( const jsonObject*, osrfHash* );
-static char* searchWHERE ( const jsonObject*, osrfHash*, int );
+static char* searchWHERE ( const jsonObject*, osrfHash*, int, osrfMethodContext* );
static char* buildSELECT ( jsonObject*, jsonObject*, osrfHash*, osrfMethodContext* );
static char* SELECT ( osrfMethodContext*, jsonObject*, jsonObject*, jsonObject*, jsonObject*, jsonObject*, jsonObject*, jsonObject*, int );
@@ -1235,11 +1236,11 @@
char* value = NULL;
if (!jsonObjectGetKeyConst( node, "value" )) {
- value = searchWHERE( node, osrfHashGet( oilsIDL(), class ), AND_OP_JOIN );
+ value = searchWHERE( node, osrfHashGet( oilsIDL(), class ), AND_OP_JOIN, NULL );
} else if (jsonObjectGetKeyConst( node, "value" )->type == JSON_ARRAY) {
value = searchValueTransform(jsonObjectGetKeyConst( node, "value" ));
} else if (jsonObjectGetKeyConst( node, "value" )->type == JSON_HASH) {
- value = searchWHERE( jsonObjectGetKeyConst( node, "value" ), osrfHashGet( oilsIDL(), class ), AND_OP_JOIN );
+ value = searchWHERE( jsonObjectGetKeyConst( node, "value" ), osrfHashGet( oilsIDL(), class ), AND_OP_JOIN, NULL );
} else if (jsonObjectGetKeyConst( node, "value" )->type != JSON_NULL) {
if ( !strcmp(osrfHashGet(field, "primitive"), "number") ) {
value = jsonNumberToDBString( field, jsonObjectGetKeyConst( node, "value" ) );
@@ -1570,7 +1571,7 @@
buffer_add( join_buf, " AND " );
}
- char* jpred = searchWHERE( filter, idlClass, AND_OP_JOIN );
+ char* jpred = searchWHERE( filter, idlClass, AND_OP_JOIN, NULL );
buffer_fadd( join_buf, " %s", jpred );
free(jpred);
free(filter_op);
@@ -1601,8 +1602,9 @@
[ { +class : { -or|-and : [ { field : { op : value }, ... }, ...] ... }, ... }, ... ]
*/
-static char* searchWHERE ( const jsonObject* search_hash, osrfHash* meta, int opjoin_type ) {
+static char* searchWHERE ( const jsonObject* search_hash, osrfHash* meta, int opjoin_type, osrfMethodContext* ctx ) {
+
growing_buffer* sql_buf = buffer_init(128);
jsonObject* node = NULL;
@@ -1618,7 +1620,7 @@
else buffer_add(sql_buf, " AND ");
}
- char* subpred = searchWHERE( node, meta, opjoin_type );
+ char* subpred = searchWHERE( node, meta, opjoin_type, ctx );
buffer_fadd(sql_buf, "( %s )", subpred);
free(subpred);
}
@@ -1641,18 +1643,48 @@
buffer_fadd(sql_buf, " \"%s\".%s ", search_itr->key + 1, subpred);
free(subpred);
} else {
- char* subpred = searchWHERE( node, osrfHashGet( oilsIDL(), search_itr->key + 1 ), AND_OP_JOIN );
+ char* subpred = searchWHERE( node, osrfHashGet( oilsIDL(), search_itr->key + 1 ), AND_OP_JOIN, ctx );
buffer_fadd(sql_buf, "( %s )", subpred);
free(subpred);
}
} else if ( !strcasecmp("-or",search_itr->key) ) {
- char* subpred = searchWHERE( node, meta, OR_OP_JOIN );
+ char* subpred = searchWHERE( node, meta, OR_OP_JOIN, ctx );
buffer_fadd(sql_buf, "( %s )", subpred);
free(subpred);
} else if ( !strcasecmp("-and",search_itr->key) ) {
- char* subpred = searchWHERE( node, meta, AND_OP_JOIN );
+ char* subpred = searchWHERE( node, meta, AND_OP_JOIN, ctx );
buffer_fadd(sql_buf, "( %s )", subpred);
free(subpred);
+ } else if ( !strcasecmp("-exists",search_itr->key) ) {
+ char* subpred = SELECT(
+ ctx,
+ jsonObjectGetKey( node, "select" ),
+ jsonObjectGetKey( node, "from" ),
+ jsonObjectGetKey( node, "where" ),
+ jsonObjectGetKey( node, "having" ),
+ jsonObjectGetKey( node, "order_by" ),
+ jsonObjectGetKey( node, "limit" ),
+ jsonObjectGetKey( node, "offset" ),
+ SUBSELECT
+ );
+
+ buffer_fadd(sql_buf, "EXISTS ( %s )", subpred);
+ free(subpred);
+ } else if ( !strcasecmp("-not-exists",search_itr->key) ) {
+ char* subpred = SELECT(
+ ctx,
+ jsonObjectGetKey( node, "select" ),
+ jsonObjectGetKey( node, "from" ),
+ jsonObjectGetKey( node, "where" ),
+ jsonObjectGetKey( node, "having" ),
+ jsonObjectGetKey( node, "order_by" ),
+ jsonObjectGetKey( node, "limit" ),
+ jsonObjectGetKey( node, "offset" ),
+ SUBSELECT
+ );
+
+ buffer_fadd(sql_buf, "NOT EXISTS ( %s )", subpred);
+ free(subpred);
} else {
char* class = osrfHashGet(meta, "classname");
@@ -1936,7 +1968,11 @@
if (is_agg->size || (flags & SELECT_DISTINCT)) {
- if (!jsonBoolIsTrue( jsonObjectGetKey( selfield, "aggregate" ) )) {
+ if ( !(
+ jsonBoolIsTrue( jsonObjectGetKey( selfield, "aggregate" ) ) ||
+ ((int)jsonObjectGetNumber(jsonObjectGetKey( selfield, "aggregate" ))) == 1 // support 1/0 for perl's sake
+ )
+ ) {
if (gfirst) {
gfirst = 0;
} else {
@@ -1998,16 +2034,18 @@
buffer_add(sql_buf, " WHERE ");
// and it's on the the WHERE clause
- char* pred = searchWHERE( search_hash, core_meta, AND_OP_JOIN );
+ char* pred = searchWHERE( search_hash, core_meta, AND_OP_JOIN, ctx );
if (!pred) {
- osrfAppSessionStatus(
- ctx->session,
- OSRF_STATUS_INTERNALSERVERERROR,
- "osrfMethodException",
- ctx->request,
- "Severe query error in WHERE predicate -- see error log for more details"
- );
+ if (ctx) {
+ osrfAppSessionStatus(
+ ctx->session,
+ OSRF_STATUS_INTERNALSERVERERROR,
+ "osrfMethodException",
+ ctx->request,
+ "Severe query error in WHERE predicate -- see error log for more details"
+ );
+ }
free(core_class);
buffer_free(having_buf);
buffer_free(group_buf);
@@ -2025,16 +2063,18 @@
buffer_add(sql_buf, " HAVING ");
// and it's on the the WHERE clause
- char* pred = searchWHERE( having_hash, core_meta, AND_OP_JOIN );
+ char* pred = searchWHERE( having_hash, core_meta, AND_OP_JOIN, ctx );
if (!pred) {
- osrfAppSessionStatus(
- ctx->session,
- OSRF_STATUS_INTERNALSERVERERROR,
- "osrfMethodException",
- ctx->request,
- "Severe query error in HAVING predicate -- see error log for more details"
- );
+ if (ctx) {
+ osrfAppSessionStatus(
+ ctx->session,
+ OSRF_STATUS_INTERNALSERVERERROR,
+ "osrfMethodException",
+ ctx->request,
+ "Severe query error in HAVING predicate -- see error log for more details"
+ );
+ }
free(core_class);
buffer_free(having_buf);
buffer_free(group_buf);
@@ -2142,13 +2182,15 @@
// IT'S THE OOOOOOOOOOOLD STYLE!
} else {
osrfLogError(OSRF_LOG_MARK, "%s: Possible SQL injection attempt; direct order by is not allowed", MODULENAME);
- osrfAppSessionStatus(
- ctx->session,
- OSRF_STATUS_INTERNALSERVERERROR,
- "osrfMethodException",
- ctx->request,
- "Severe query error -- see error log for more details"
- );
+ if (ctx) {
+ osrfAppSessionStatus(
+ ctx->session,
+ OSRF_STATUS_INTERNALSERVERERROR,
+ "osrfMethodException",
+ ctx->request,
+ "Severe query error -- see error log for more details"
+ );
+ }
free(core_class);
buffer_free(having_buf);
@@ -2213,7 +2255,7 @@
free(string);
}
- buffer_add(sql_buf, ";");
+ if (!(flags & SUBSELECT)) buffer_add(sql_buf, ";");
free(core_class);
if (defaultselhash) jsonObjectFree(defaultselhash);
@@ -2298,8 +2340,11 @@
if (locale) {
char* i18n = osrfHashGet(field, "i18n");
- if (jsonBoolIsTrue(jsonObjectGetKey( order_hash, "no_i18n" )))
- i18n = NULL;
+ if ( !(
+ jsonBoolIsTrue( jsonObjectGetKey( order_hash, "no_i18n" ) ) ||
+ ((int)jsonObjectGetNumber(jsonObjectGetKey( order_hash, "no_i18n" ))) == 1 // support 1/0 for perl's sake
+ )
+ ) i18n = NULL;
if ( i18n && !strncasecmp("true", i18n, 4)) {
char* pkey = osrfHashGet(idlClass, "primarykey");
@@ -2338,7 +2383,7 @@
buffer_add(sql_buf, " WHERE ");
- char* pred = searchWHERE( search_hash, meta, AND_OP_JOIN );
+ char* pred = searchWHERE( search_hash, meta, AND_OP_JOIN, ctx );
if (!pred) {
osrfAppSessionStatus(
ctx->session,
More information about the open-ils-commits
mailing list