/** * Initialize udf_def data structure from the transaction over the wire. */ udf_def * udf_def_init_from_msg(udf_def * def, const as_transaction * tr) { as_msg *m = &tr->msgp->msg; as_msg_field *filename = as_msg_field_get(m, AS_MSG_FIELD_TYPE_UDF_FILENAME); if (! filename) { return NULL; } as_msg_field *function = as_msg_field_get(m, AS_MSG_FIELD_TYPE_UDF_FUNCTION); if (! function) { return NULL; } as_msg_field *arglist = as_msg_field_get(m, AS_MSG_FIELD_TYPE_UDF_ARGLIST); if (! arglist) { return NULL; } as_msg_field_get_strncpy(filename, def->filename, sizeof(def->filename)); as_msg_field_get_strncpy(function, def->function, sizeof(def->function)); def->arglist = arglist; as_msg_field *op = as_transaction_has_udf_op(tr) ? as_msg_field_get(m, AS_MSG_FIELD_TYPE_UDF_OP) : NULL; def->type = op ? *op->data : AS_UDF_OP_KVS; return def; }
/** * Initialize udf_call data structure from the msg over the wire * * Returns: * 0 on success * -1 on failure */ int udf_rw_call_init_from_msg(udf_call * call, as_msg *msg) { call->def.type = AS_UDF_OP_KVS; as_msg_field * filename = NULL; as_msg_field * function = NULL; as_msg_field * arglist = NULL; // Check the type of udf as_msg_field * op = NULL; op = as_msg_field_get(msg, AS_MSG_FIELD_TYPE_UDF_OP); if ( op ) { memcpy(&call->def.type, (byte *)op->data, sizeof(as_udf_op)); } filename = as_msg_field_get(msg, AS_MSG_FIELD_TYPE_UDF_FILENAME); if ( filename ) { function = as_msg_field_get(msg, AS_MSG_FIELD_TYPE_UDF_FUNCTION); if ( function ) { arglist = as_msg_field_get(msg, AS_MSG_FIELD_TYPE_UDF_ARGLIST); if ( arglist ) { as_msg_field_get_strncpy(filename, &call->def.filename[0], sizeof(call->def.filename)); as_msg_field_get_strncpy(function, &call->def.function[0], sizeof(call->def.function)); call->def.arglist = arglist; return 0; } } } call->tr = NULL; call->def.filename[0] = 0; call->def.function[0] = 0; call->def.arglist = NULL; return -1; }
/** * Initialize a new UDF. This populates the udf_call from information * in the current transaction. If passed in transaction has req_data it is * assumed to be internal and the UDF information is picked from the udata * associated with it. TODO: Do not overload please define flag for this. * * * Parameter: * tr the transaction to build a udf_call from * * Returns" * return a new udf_call (Caller needs to free it up) * NULL in case of failure */ int udf_call_init(udf_call * call, as_transaction * tr) { call->active = false; call->udf_type = AS_SCAN_UDF_NONE; as_msg_field * filename = NULL; as_msg_field * function = NULL; as_msg_field * arglist = NULL; if (tr->udata.req_udata) { udf_call *ucall = NULL; if (tr->udata.req_type == UDF_SCAN_REQUEST) { ucall = &((tscan_job *)(tr->udata.req_udata))->call; } else if (tr->udata.req_type == UDF_QUERY_REQUEST) { ucall = as_query_get_udf_call(tr->udata.req_udata); } if (ucall) { strncpy(call->filename, ucall->filename, sizeof(ucall->filename)); strncpy(call->function, ucall->function, sizeof(ucall->function)); call->transaction = tr; call->active = true; call->arglist = ucall->arglist; call->udf_type = ucall->udf_type; if (tr->udata.req_type == UDF_SCAN_REQUEST) { cf_atomic_int_incr(&g_config.udf_scan_rec_reqs); } else if (tr->udata.req_type == UDF_QUERY_REQUEST) { cf_atomic_int_incr(&g_config.udf_query_rec_reqs); } } // TODO: return proper macros return 0; } // Check the type of udf as_msg_field * op = NULL; op = as_msg_field_get(&tr->msgp->msg, AS_MSG_FIELD_TYPE_UDF_OP); if (!op) { // Normal udf operation, no special type call->udf_type = 0; } else { // We got a udf type from the server byte optype; memcpy(&optype, (byte *)op->data, sizeof(optype)); if(optype == AS_SCAN_UDF_OP_UDF) { cf_debug(AS_UDF, "UDF scan op received"); call->udf_type = AS_SCAN_UDF_OP_UDF; } else if(optype == AS_SCAN_UDF_OP_BACKGROUND) { cf_debug(AS_UDF, "UDF scan background op received"); call->udf_type = AS_SCAN_UDF_OP_BACKGROUND; } else { cf_warning(AS_UDF, "Undefined udf type received over protocol"); goto Cleanup; } } filename = as_msg_field_get(&tr->msgp->msg, AS_MSG_FIELD_TYPE_UDF_FILENAME); if ( filename ) { function = as_msg_field_get(&tr->msgp->msg, AS_MSG_FIELD_TYPE_UDF_FUNCTION); if ( function ) { arglist = as_msg_field_get(&tr->msgp->msg, AS_MSG_FIELD_TYPE_UDF_ARGLIST); if ( arglist ) { call->transaction = tr; as_msg_field_get_strncpy(filename, &call->filename[0], sizeof(call->filename)); as_msg_field_get_strncpy(function, &call->function[0], sizeof(call->function)); call->arglist = arglist; call->active = true; cf_detail(AS_UDF, "UDF Request Unpacked %s %s", call->filename, call->function); return 0; } } } Cleanup: call->transaction = NULL; call->filename[0] = 0; call->function[0] = 0; call->arglist = NULL; return 1; }