bool user_callback_wrapper(const as_val *val, void *udata) {
	zval retval;
	ZVAL_NULL(&retval);
	if (!val) {
		return false;
	}
	as_record* record = as_record_fromval(val);
	user_callback_function* callback_info = (user_callback_function*)udata;

	pthread_mutex_lock(callback_info->cb_mutex);
	callback_info->callback.retval = &retval;

	if (execute_user_callback(record, callback_info) != AEROSPIKE_OK) {
		as_error_update(callback_info->err, AEROSPIKE_ERR_PARAM, "Callback raised an error");
		pthread_mutex_unlock(callback_info->cb_mutex);
		return false;
	}

	if (callback_info->callback.retval &&
			Z_TYPE_P(callback_info->callback.retval) == IS_FALSE) {
		pthread_mutex_unlock(callback_info->cb_mutex);
		return false;
	}

	zval_dtor(&retval);
	pthread_mutex_unlock(callback_info->cb_mutex);
	return true;
}
Exemplo n.º 2
0
/*
 *******************************************************************************************************
 * Checks as_bytes->type.
 * Deserializes as_bytes into Py_Object (retval) using deserialization logic
 * based on as_bytes->type.
 *
 * @param bytes                 The as_bytes to be deserialized.
 * @param retval                The return zval to be populated with the
 *                              deserialized value of the input as_bytes.
 * @param error_p               The as_error to be populated by the function
 *                              with encountered error if any.
 *******************************************************************************************************
 */
extern PyObject * deserialize_based_on_as_bytes_type(AerospikeClient * self,
        as_bytes  *bytes,
		PyObject  **retval,
		as_error  *error_p)
{
	switch(as_bytes_get_type(bytes)) {
		case AS_BYTES_PYTHON: {
								  PyObject* sysmodules = PyImport_GetModuleDict();
								  PyObject* cpickle_module = NULL;
								  if(PyMapping_HasKeyString(sysmodules, "cPickle")) {
									  cpickle_module = PyMapping_GetItemString(sysmodules, "cPickle");
								  } else {
									  cpickle_module = PyImport_ImportModule("cPickle");
								  }

								  PyObject* initresult = NULL;
								  if(!cpickle_module) {
									  /* insert error handling here! and exit this function */
									  as_error_update(error_p, AEROSPIKE_ERR_CLIENT, "Unable to load cpickle module");
									  goto CLEANUP;
								  } else {
									  char*       bytes_val_p = (char*)bytes->value;
									  PyObject *py_value = PyStr_FromStringAndSize(bytes_val_p, as_bytes_size(bytes));
									  PyObject *py_funcname = PyStr_FromString("loads");

									  Py_INCREF(cpickle_module);
									  initresult = PyObject_CallMethodObjArgs(cpickle_module, py_funcname, py_value, NULL);
									  Py_DECREF(cpickle_module);
									  Py_DECREF(py_funcname);
									  Py_DECREF(py_value);
									  if(!initresult) {
										  /* more error handling &c */
										  as_error_update(error_p, AEROSPIKE_ERR_CLIENT, "Unable to call loads function");
										  goto CLEANUP;
									  } else {
										  *retval = initresult;
									  }
								  }
								  Py_XDECREF(cpickle_module);
							  }
							  break;
		case AS_BYTES_BLOB: {
                                if (self->user_deserializer_call_info.callback) {
						            execute_user_callback(&self->user_deserializer_call_info, &bytes, retval, false, error_p);
									if(AEROSPIKE_OK != (error_p->code)) {
									    uint32_t bval_size = as_bytes_size(bytes);
									    PyObject *py_val = PyByteArray_FromStringAndSize((char *) as_bytes_get(bytes), bval_size);
									    if (!py_val) {
										    as_error_update(error_p, AEROSPIKE_ERR_CLIENT, "Unable to deserialize bytes");
										    goto CLEANUP;
									    }
									    *retval = py_val;
										as_error_update(error_p, AEROSPIKE_OK, NULL);
                                    }
                                } else {
								    if (is_user_deserializer_registered) {
									    execute_user_callback(&user_deserializer_call_info, &bytes, retval, false, error_p);
									    if(AEROSPIKE_OK != (error_p->code)) {
									        uint32_t bval_size = as_bytes_size(bytes);
									        PyObject *py_val = PyByteArray_FromStringAndSize((char *) as_bytes_get(bytes), bval_size);
									        if (!py_val) {
										        as_error_update(error_p, AEROSPIKE_ERR_CLIENT, "Unable to deserialize bytes");
										        goto CLEANUP;
									        }
										    as_error_update(error_p, AEROSPIKE_OK, NULL);
									        *retval = py_val;
									    }
								    } else {
									    uint32_t bval_size = as_bytes_size(bytes);
									    PyObject *py_val = PyByteArray_FromStringAndSize((char *) as_bytes_get(bytes), bval_size);
									    if (!py_val) {
										as_error_update(error_p, AEROSPIKE_ERR_CLIENT, "Unable to deserialize bytes");
										goto CLEANUP;
									    }
									    *retval = py_val;
								    }
							    }
                            }
							break;
        case AS_BYTES_LDT:  {
                                Py_INCREF(Py_None);
                                *retval = Py_None;
                            }
                            break;
		default:

							as_error_update(error_p, AEROSPIKE_ERR,
									"Unable to deserialize bytes");
							goto CLEANUP;
	}

CLEANUP:

  	if ( error_p->code != AEROSPIKE_OK ) {
		PyObject * py_err = NULL;
		error_to_pyobject(error_p, &py_err);
		PyObject *exception_type = raise_exception(error_p);
		PyErr_SetObject(exception_type, py_err);
		Py_DECREF(py_err);
		return NULL;
	}

	return PyLong_FromLong(0);
}
Exemplo n.º 3
0
/*
 *******************************************************************************************************
 * Checks serializer_policy.
 * Serializes Py_Object (value) into as_bytes using serialization logic
 * based on serializer_policy.
 *
 * @param serializer_policy         The serializer_policy to be used to handle
 *                                  the serialization.
 * @param bytes                     The as_bytes to be set.
 * @param value                     The value to be serialized.
 * @param error_p                   The as_error to be populated by the function
 *                                  with encountered error if any.
 *******************************************************************************************************
 */
extern PyObject * serialize_based_on_serializer_policy(AerospikeClient * self,
        int32_t serializer_policy,
		as_bytes **bytes,
		PyObject *value,
		as_error *error_p)
{
    uint8_t use_client_serializer = true;
	PyObject* initresult = NULL;

    if (self->is_client_put_serializer) {
        if (serializer_policy == SERIALIZER_USER) {
            if (!self->user_serializer_call_info.callback) {
                use_client_serializer = false;
            }
        }
    } else if (self->user_serializer_call_info.callback) {
        serializer_policy = SERIALIZER_USER;
    }

	switch(serializer_policy) {
		case SERIALIZER_NONE:
			as_error_update(error_p, AEROSPIKE_ERR_PARAM,
					"Cannot serialize: SERIALIZER_NONE selected");
			goto CLEANUP;
		case SERIALIZER_PYTHON:
			{
				/*
				 * Serialize bytearray as is and store them into database with
				 * type AS_BYTES_BLOB, unlike other values in case of 
				 * SERIALIZER_PYTHON.
				 * This is a special case.
				 * Refer: AER-3589 for more details.
				 */
				if (PyByteArray_Check(value)) {
					uint8_t *bytes_array = (uint8_t *) PyByteArray_AsString(value);
					uint32_t bytes_array_len  = (uint32_t)  PyByteArray_Size(value);

					set_as_bytes(bytes, bytes_array, bytes_array_len, AS_BYTES_BLOB, error_p);

				} else {

					/* get the sys.modules dictionary */
					PyObject* sysmodules = PyImport_GetModuleDict();
					PyObject* cpickle_module = NULL;
					if(PyMapping_HasKeyString(sysmodules, "cPickle")) {
						cpickle_module = PyMapping_GetItemString(sysmodules, "cPickle");
					} else {
						cpickle_module = PyImport_ImportModule("cPickle");
					}

					if(!cpickle_module) {
						/* insert error handling here! and exit this function */
						as_error_update(error_p, AEROSPIKE_ERR_CLIENT, "Unable to load cpickle module");
						goto CLEANUP;
					} else {
						PyObject * py_funcname = PyStr_FromString("dumps");

						Py_INCREF(cpickle_module);
						initresult = PyObject_CallMethodObjArgs(cpickle_module,
								py_funcname, value, NULL);
						Py_DECREF(cpickle_module);
						Py_DECREF(py_funcname);

						if(!initresult) {
							/* more error handling &c */
							as_error_update(error_p, AEROSPIKE_ERR_CLIENT, "Unable to call dumps function");
							goto CLEANUP;
						} else {
							Py_INCREF(initresult);
							char *return_value = PyStr_AsString(initresult);
							Py_ssize_t len = PyBytes_GET_SIZE(initresult);
                            set_as_bytes(bytes, (uint8_t *) return_value,
									len, AS_BYTES_PYTHON, error_p);
							Py_DECREF(initresult);
						}
					}
					Py_XDECREF(cpickle_module);
				}
			}
			break;
		case SERIALIZER_JSON:
			/*
			 *   TODO:
			 *     Handle JSON serialization after support for AS_BYTES_JSON
			 *     is added in aerospike-client-c
			 */
			as_error_update(error_p, AEROSPIKE_ERR,
					"Unable to serialize using standard json serializer");
			goto CLEANUP;

		case SERIALIZER_USER:
            if (use_client_serializer) {
                execute_user_callback(&self->user_serializer_call_info, bytes, &value, true, error_p);
				if (AEROSPIKE_OK != (error_p->code)) {
					goto CLEANUP;
				}
            } else {
			    if (is_user_serializer_registered) {
                    execute_user_callback(&user_serializer_call_info, bytes, &value, true, error_p);
				    if (AEROSPIKE_OK != (error_p->code)) {
					    goto CLEANUP;
				    }
			    } else if (self->user_serializer_call_info.callback) {
                    execute_user_callback(&self->user_serializer_call_info, bytes, &value, true, error_p);
				    if (AEROSPIKE_OK != (error_p->code)) {
					    goto CLEANUP;
				    }
                } else {
				    as_error_update(error_p, AEROSPIKE_ERR,
						"No serializer callback registered");
				    goto CLEANUP;
			    }
            }
		    break;
		default:
			as_error_update(error_p, AEROSPIKE_ERR,
					"Unsupported serializer");
			goto CLEANUP;
	}

CLEANUP:

	Py_XDECREF(initresult);
  	if ( error_p->code != AEROSPIKE_OK ) {
		PyObject * py_err = NULL;
		error_to_pyobject(error_p, &py_err);
		PyObject *exception_type = raise_exception(error_p);
		PyErr_SetObject(exception_type, py_err);
		Py_DECREF(py_err);
		return NULL;
	}

	return PyLong_FromLong(0);
}