/** *********************************************************************** * * Callback method, invoked by aerospike_batch_get_bins * * ********************************************************************* **/ static bool batch_select_cb(const as_batch_read* results, uint32_t n, void* udata) { // Typecast udata back to PyObject PyObject * py_recs = (PyObject *) udata; // Initialize error object as_error err; as_error_init(&err); // Loop over results array for ( uint32_t i =0; i < n; i++ ){ PyObject * rec = NULL; PyObject * p_key = NULL; if(results[i].key->valuep) { switch(((as_val*)(results[i].key->valuep))->type){ case AS_INTEGER: p_key = PyInt_FromLong((long)results[i].key->value.integer.value); break; case AS_STRING: p_key = PyString_FromString((const char *)results[i].key->value.string.value); break; default: break; } } else { Py_INCREF(Py_None); p_key = Py_None; } // Check record status if ( results[i].result == AEROSPIKE_OK ){ record_to_pyobject(&err, &results[i].record, results[i].key, &rec); // Set return value in return Dict if ( PyDict_SetItem( py_recs, p_key, rec ) ){ return false; } Py_DECREF(rec); } else if( results[i].result == AEROSPIKE_ERR_RECORD_NOT_FOUND ){ Py_INCREF(Py_None); if ( PyDict_SetItem( py_recs, p_key, Py_None)){ return false; } } Py_DECREF(p_key); } return true; }
/** ******************************************************************************************************* * This function invokes csdk's API's. * * @param self AerospikeClient object * @param err The as_error to be populated by the function * with the encountered error if any. * @param key The C client's as_key that identifies the record. * @param py_list The list containing op, bin and value. * @param py_meta The metadata for the operation. * @param operate_policy_p The value for operate policy. ******************************************************************************************************* */ static PyObject * AerospikeClient_Operate_Invoke( AerospikeClient * self, as_error *err, as_key * key, PyObject * py_list, PyObject * py_meta, as_policy_operate * operate_policy_p) { as_val* put_val = NULL; char* bin = NULL; char* val = NULL; long offset = 0; double double_offset = 0.0; uint32_t ttl = 0; long operation = 0; int i = 0; PyObject * py_rec = NULL; PyObject * py_ustr = NULL; PyObject * py_ustr1 = NULL; PyObject * py_bin = NULL; as_record * rec = NULL; as_static_pool static_pool; memset(&static_pool, 0, sizeof(static_pool)); as_operations ops; Py_ssize_t size = PyList_Size(py_list); as_operations_inita(&ops, size); if (!self || !self->as) { as_error_update(err, AEROSPIKE_ERR_PARAM, "Invalid aerospike object"); goto CLEANUP; } if(py_meta) { AerospikeClient_CheckForMeta(py_meta, &ops, err); } if (err->code != AEROSPIKE_OK) { goto CLEANUP; } for ( i = 0; i < size; i++) { PyObject * py_val = PyList_GetItem(py_list, i); operation = -1; offset = 0; double_offset = 0.0; if ( PyDict_Check(py_val) ) { PyObject *key_op = NULL, *value = NULL; PyObject * py_value = NULL; Py_ssize_t pos = 0; while (PyDict_Next(py_val, &pos, &key_op, &value)) { if ( ! PyString_Check(key_op) ) { as_error_update(err, AEROSPIKE_ERR_CLIENT, "A operation key must be a string."); goto CLEANUP; } else { char * name = PyString_AsString(key_op); if(!strcmp(name,"op") && (PyInt_Check(value) || PyLong_Check(value))) { operation = PyInt_AsLong(value); } else if (!strcmp(name, "bin")) { py_bin = value; } else if(!strcmp(name, "val")) { py_value = value; } else { as_error_update(err, AEROSPIKE_ERR_PARAM, "operation can contain only op, bin and val keys"); goto CLEANUP; } } } if (py_bin) { if (PyUnicode_Check(py_bin)) { py_ustr = PyUnicode_AsUTF8String(py_bin); bin = PyString_AsString(py_ustr); } else if (PyString_Check(py_bin)) { bin = PyString_AsString(py_bin); } else { as_error_update(err, AEROSPIKE_ERR_PARAM, "Bin name should be of type string"); goto CLEANUP; } } else if (!py_bin && operation != AS_OPERATOR_TOUCH) { as_error_update(err, AEROSPIKE_ERR_PARAM, "Bin is not given"); goto CLEANUP; } if (py_value) { if (check_type(self, py_value, operation, err)) { goto CLEANUP; } else if (PyString_Check(py_value) && (operation == AS_OPERATOR_INCR)) { char * incr_string = PyString_AsString(py_value); int incr_value = 0, sign = 1; if (strlen(incr_string) > 15) { as_error_update(err, AEROSPIKE_ERR_PARAM, "Unsupported string length for increment operation"); goto CLEANUP; } if (*incr_string == '-') { incr_string = incr_string + 1; sign = -1; } else if (*incr_string == '+') { incr_string = incr_string + 1; sign = 1; } while (*incr_string != '\0') { if (*incr_string >= 48 && *incr_string <= 57) { incr_value = (incr_value * 10) + (*incr_string ^ 0x30); } else { as_error_update(err, AEROSPIKE_ERR_PARAM, "Unsupported operand type(s) for +: 'int' and 'str'"); goto CLEANUP; } incr_string = incr_string + 1; } incr_value = incr_value * sign; py_value = PyInt_FromLong(incr_value); } } else if ((!py_value) && (operation != AS_OPERATOR_READ)) { as_error_update(err, AEROSPIKE_ERR_PARAM, "Value should be given"); goto CLEANUP; } switch(operation) { case AS_OPERATOR_APPEND: if (PyUnicode_Check(py_value)) { py_ustr1 = PyUnicode_AsUTF8String(py_value); val = PyString_AsString(py_ustr1); } else { val = PyString_AsString(py_value); } as_operations_add_append_str(&ops, bin, val); break; case AS_OPERATOR_PREPEND: if (PyUnicode_Check(py_value)) { py_ustr1 = PyUnicode_AsUTF8String(py_value); val = PyString_AsString(py_ustr1); } else { val = PyString_AsString(py_value); } as_operations_add_prepend_str(&ops, bin, val); break; case AS_OPERATOR_INCR: if (PyInt_Check(py_value)) { offset = PyInt_AsLong(py_value); as_operations_add_incr(&ops, bin, offset); } else if ( PyLong_Check(py_value) ) { offset = PyLong_AsLong(py_value); if(-1 == offset) { as_error_update(err, AEROSPIKE_ERR_PARAM, "integer value exceeds sys.maxsize"); goto CLEANUP; } as_operations_add_incr(&ops, bin, offset); } else if (PyFloat_Check(py_value)) { double_offset = PyFloat_AsDouble(py_value); as_operations_add_incr_double(&ops, bin, double_offset); } break; case AS_OPERATOR_TOUCH: if (PyInt_Check(py_value)) { ops.ttl = PyInt_AsLong(py_value); } else if ( PyLong_Check(py_value) ) { ttl = PyLong_AsLong(py_value); if((uint32_t)-1 == ttl) { as_error_update(err, AEROSPIKE_ERR_PARAM, "integer value for ttl exceeds sys.maxsize"); goto CLEANUP; } ops.ttl = ttl; } as_operations_add_touch(&ops); break; case AS_OPERATOR_READ: as_operations_add_read(&ops, bin); break; case AS_OPERATOR_WRITE: pyobject_to_astype_write(self, err, bin, py_value, &put_val, &ops, &static_pool, SERIALIZER_PYTHON); if (err->code != AEROSPIKE_OK) { goto CLEANUP; } as_operations_add_write(&ops, bin, (as_bin_value *) put_val); break; default: as_error_update(err, AEROSPIKE_ERR_PARAM, "Invalid operation given"); } } } // Initialize record as_record_init(rec, 0); aerospike_key_operate(self->as, err, operate_policy_p, key, &ops, &rec); if (err->code != AEROSPIKE_OK) { as_error_update(err, err->code, NULL); goto CLEANUP; } if(rec) { record_to_pyobject(err, rec, key, &py_rec); } CLEANUP: if (py_ustr) { Py_DECREF(py_ustr); } if (py_ustr1) { Py_DECREF(py_ustr1); } if (rec) { as_record_destroy(rec); } if (key->valuep) { as_key_destroy(key); } if (put_val) { as_val_destroy(put_val); } if ( err->code != AEROSPIKE_OK ) { PyObject * py_err = NULL; error_to_pyobject(err, &py_err); PyObject *exception_type = raise_exception(err); PyErr_SetObject(exception_type, py_err); Py_DECREF(py_err); return NULL; } if (py_rec) { return py_rec; } else { return PyLong_FromLong(0); } }
/** *********************************************************************** * * Callback method, invoked by aerospike_batch_get_bins * * ********************************************************************* **/ static bool batch_select_cb(const as_batch_read* results, uint32_t n, void* udata) { // Typecast udata back to PyObject LocalData *data = (LocalData *) udata; PyObject * py_recs = data->py_recs; // Initialize error object as_error err; as_error_init(&err); // Lock Python State PyGILState_STATE gstate; gstate = PyGILState_Ensure(); // Loop over results array for ( uint32_t i =0; i < n; i++ ){ PyObject * rec = NULL; PyObject * py_rec = NULL; PyObject * p_key = NULL; py_rec = PyTuple_New(3); p_key = PyTuple_New(4); if ( results[i].key->ns && strlen(results[i].key->ns) > 0 ) { PyTuple_SetItem(p_key, 0, PyString_FromString(results[i].key->ns)); } if ( results[i].key->set && strlen(results[i].key->set) > 0 ) { PyTuple_SetItem(p_key, 1, PyString_FromString(results[i].key->set)); } if(results[i].key->valuep) { switch(((as_val*)(results[i].key->valuep))->type){ case AS_INTEGER: PyTuple_SetItem(p_key, 2, PyInt_FromLong((long)results[i].key->value.integer.value)); break; case AS_STRING: PyTuple_SetItem(p_key, 2, PyString_FromString((const char *)results[i].key->value.string.value)); break; default: break; } } else { Py_INCREF(Py_None); PyTuple_SetItem(p_key, 2, Py_None); } if (results[i].key->digest.init) { PyTuple_SetItem(p_key, 3, PyByteArray_FromStringAndSize((char *) results[i].key->digest.value, AS_DIGEST_VALUE_SIZE)); } PyTuple_SetItem(py_rec, 0, p_key); // Check record status if ( results[i].result == AEROSPIKE_OK ){ record_to_pyobject(data->client, &err, &results[i].record, results[i].key, &rec); PyObject *py_obj = PyTuple_GetItem(rec, 1); Py_INCREF(py_obj); PyTuple_SetItem(py_rec, 1, py_obj); py_obj = PyTuple_GetItem(rec, 2); Py_INCREF(py_obj); PyTuple_SetItem(py_rec, 2, py_obj); // Set return value in return Dict if ( PyList_SetItem( py_recs, i, py_rec ) ){ // Release Python State PyGILState_Release(gstate); return false; } Py_DECREF(rec); } else if( results[i].result == AEROSPIKE_ERR_RECORD_NOT_FOUND ){ Py_INCREF(Py_None); PyTuple_SetItem(py_rec, 1, Py_None); Py_INCREF(Py_None); PyTuple_SetItem(py_rec, 2, Py_None); if ( PyList_SetItem( py_recs, i, py_rec)){ // Release Python State PyGILState_Release(gstate); return false; } } } // Release Python State PyGILState_Release(gstate); return true; }
/** ******************************************************************************************************* * This function will be called with the results with aerospike_batch_read(). * * @param records A vector list of as_batch_read_record entries * @param py_recs The pyobject to be filled with. * ******************************************************************************************************* */ static void batch_select_recs(AerospikeClient *self, as_error *err, as_batch_read_records* records, PyObject **py_recs) { as_vector* list = &records->list; for (uint32_t i = 0; i < list->size; i++) { as_batch_read_record* batch = as_vector_get(list, i); PyObject * rec = NULL; PyObject * py_rec = NULL; PyObject * p_key = NULL; py_rec = PyTuple_New(3); p_key = PyTuple_New(4); if ( batch->key.ns && strlen(batch->key.ns) > 0 ) { PyTuple_SetItem(p_key, 0, PyString_FromString(batch->key.ns)); } if ( batch->key.set && strlen(batch->key.set) > 0 ) { PyTuple_SetItem(p_key, 1, PyString_FromString(batch->key.set)); } if(batch->key.valuep) { switch(((as_val*)(batch->key.valuep))->type){ case AS_INTEGER: PyTuple_SetItem(p_key, 2, PyInt_FromLong((long)batch->key.value.integer.value)); break; case AS_STRING: PyTuple_SetItem(p_key, 2, PyString_FromString((const char *)batch->key.value.string.value)); break; default: break; } } else { Py_INCREF(Py_None); PyTuple_SetItem(p_key, 2, Py_None); } if (batch->key.digest.init) { PyTuple_SetItem(p_key, 3, PyByteArray_FromStringAndSize((char *) batch->key.digest.value, AS_DIGEST_VALUE_SIZE)); } PyTuple_SetItem(py_rec, 0, p_key); if ( batch->result == AEROSPIKE_OK ){ record_to_pyobject(self, err, &batch->record, &batch->key, &rec); PyObject *py_obj = PyTuple_GetItem(rec, 1); Py_INCREF(py_obj); PyTuple_SetItem(py_rec, 1, py_obj); py_obj = PyTuple_GetItem(rec, 2); Py_INCREF(py_obj); PyTuple_SetItem(py_rec, 2, py_obj); PyList_SetItem( *py_recs, i, py_rec ); Py_DECREF(rec); } else if (batch->result == AEROSPIKE_ERR_RECORD_NOT_FOUND) { Py_INCREF(Py_None); PyTuple_SetItem(py_rec, 1, Py_None); Py_INCREF(Py_None); PyTuple_SetItem(py_rec, 2, Py_None); PyList_SetItem( *py_recs, i, py_rec); } } }
/** ******************************************************************************************************* * This function read a record with a given key, and return the record. * * @param self AerospikeClient object * @param py_key The key under which to store the record. * @param py_policy The dictionary of policies to be given while * reading a record. * * Returns the record on success. * In case of error,appropriate exceptions will be raised. ******************************************************************************************************* */ PyObject * AerospikeClient_Get_Invoke( AerospikeClient * self, PyObject * py_key, PyObject * py_policy) { // Python Return Value PyObject * py_rec = NULL; // Aerospike Client Arguments as_error err; as_policy_read read_policy; as_policy_read * read_policy_p = NULL; as_key key; as_record * rec = NULL; // Initialised flags bool key_initialised = false; bool record_initialised = false; // Initialize error as_error_init(&err); if (!self || !self->as) { as_error_update(&err, AEROSPIKE_ERR_PARAM, "Invalid aerospike object"); goto CLEANUP; } if (!self->is_conn_16) { as_error_update(&err, AEROSPIKE_ERR_CLUSTER, "No connection to aerospike cluster"); goto CLEANUP; } // Convert python key object to as_key pyobject_to_key(&err, py_key, &key); if ( err.code != AEROSPIKE_OK ) { goto CLEANUP; } // Key is successfully initialised. key_initialised = true; // Convert python policy object to as_policy_exists pyobject_to_policy_read(&err, py_policy, &read_policy, &read_policy_p, &self->as->config.policies.read); if ( err.code != AEROSPIKE_OK ) { goto CLEANUP; } // Initialize record as_record_init(rec, 0); // Record initialised successfully. record_initialised = true; // Invoke operation aerospike_key_get(self->as, &err, read_policy_p, &key, &rec); if ( err.code == AEROSPIKE_OK ) { record_to_pyobject(&err, rec, &key, &py_rec); if ( read_policy_p == NULL || ( read_policy_p != NULL && read_policy_p->key == AS_POLICY_KEY_DIGEST)){ // This is a special case. // C-client returns NULL key, so to the user // response will be (<ns>, <set>, None, <digest>) // Using the same input key, just making primary key part to be None // Only in case of POLICY_KEY_DIGEST or no policy specified PyObject * p_key = PyTuple_GetItem( py_rec, 0 ); Py_INCREF(Py_None); PyTuple_SetItem(p_key, 2, Py_None); } } else if( err.code == AEROSPIKE_ERR_RECORD_NOT_FOUND ) { as_error_reset(&err); PyObject * py_rec_key = NULL; PyObject * py_rec_meta = Py_None; PyObject * py_rec_bins = Py_None; key_to_pyobject(&err, &key, &py_rec_key); py_rec = PyTuple_New(3); PyTuple_SetItem(py_rec, 0, py_rec_key); PyTuple_SetItem(py_rec, 1, py_rec_meta); PyTuple_SetItem(py_rec, 2, py_rec_bins); Py_INCREF(py_rec_meta); Py_INCREF(py_rec_bins); } else { as_error_update(&err, err.code, NULL); } CLEANUP: if (key_initialised == true){ // Destroy key only if it is initialised. as_key_destroy(&key); } if (record_initialised == true){ // Destroy record only if it is initialised. as_record_destroy(rec); } if ( err.code != AEROSPIKE_OK ) { PyObject * py_err = NULL; error_to_pyobject(&err, &py_err); PyObject *exception_type = raise_exception(&err); if(PyObject_HasAttrString(exception_type, "key")) { PyObject_SetAttrString(exception_type, "key", py_key); } if(PyObject_HasAttrString(exception_type, "bin")) { PyObject_SetAttrString(exception_type, "bin", Py_None); } PyErr_SetObject(exception_type, py_err); Py_DECREF(py_err); return NULL; } return py_rec; }
PyObject * AerospikeClient_Get_Invoke( AerospikeClient * self, PyObject * py_key, PyObject * py_policy) { // Python Return Value PyObject * py_rec = NULL; // Aerospike Client Arguments as_error err; as_policy_read policy; as_policy_read * policy_p = NULL; as_key key; as_record * rec = NULL; // Initialize error as_error_init(&err); // Convert python key object to as_key pyobject_to_key(&err, py_key, &key); if ( err.code != AEROSPIKE_OK ) { goto CLEANUP; } // Convert python policy object to as_policy_exists pyobject_to_policy_read(&err, py_policy, &policy, &policy_p); if ( err.code != AEROSPIKE_OK ) { goto CLEANUP; } // Initialize record as_record_init(rec, 0); // Invoke operation aerospike_key_get(self->as, &err, policy_p, &key, &rec); if ( err.code == AEROSPIKE_OK ) { record_to_pyobject(&err, rec, &key, &py_rec); } else if ( err.code == AEROSPIKE_ERR_RECORD_NOT_FOUND ) { as_error_reset(&err); PyObject * py_rec_key = NULL; PyObject * py_rec_meta = Py_None; PyObject * py_rec_bins = Py_None; key_to_pyobject(&err, &key, &py_rec_key); py_rec = PyTuple_New(3); PyTuple_SetItem(py_rec, 0, py_rec_key); PyTuple_SetItem(py_rec, 1, py_rec_meta); PyTuple_SetItem(py_rec, 2, py_rec_bins); Py_INCREF(py_rec_meta); Py_INCREF(py_rec_bins); } CLEANUP: // as_key_destroy(&key); as_record_destroy(rec); if ( err.code != AEROSPIKE_OK ) { PyObject * py_err = NULL; error_to_pyobject(&err, &py_err); PyErr_SetObject(PyExc_Exception, py_err); return NULL; } return py_rec; }
/** ******************************************************************************************************* * This function invokes csdk's API's. * * @param self AerospikeClient object * @param err The as_error to be populated by the function * with the encountered error if any. * @param key The C client's as_key that identifies the record. * @param py_list The list containing op, bin and value. * @param py_meta The metadata for the operation. * @param operate_policy_p The value for operate policy. ******************************************************************************************************* */ static PyObject * AerospikeClient_Operate_Invoke( AerospikeClient * self, as_error *err, as_key * key, PyObject * py_list, PyObject * py_meta, as_policy_operate * operate_policy_p) { as_val* put_val = NULL; char* bin = NULL; char* val = NULL; long offset = 0; double double_offset = 0.0; uint32_t ttl = 0; long operation = 0; int i = 0; PyObject * py_rec = NULL; PyObject * py_ustr = NULL; PyObject * py_ustr1 = NULL; PyObject * py_bin = NULL; as_record * rec = NULL; as_static_pool static_pool; memset(&static_pool, 0, sizeof(static_pool)); as_operations ops; Py_ssize_t size = PyList_Size(py_list); as_operations_inita(&ops, size); if (!self || !self->as) { as_error_update(err, AEROSPIKE_ERR_PARAM, "Invalid aerospike object"); goto CLEANUP; } if(py_meta) { AerospikeClient_CheckForMeta(py_meta, &ops, err); } if (err->code != AEROSPIKE_OK) { goto CLEANUP; } for ( i = 0; i < size; i++) { PyObject * py_val = PyList_GetItem(py_list, i); operation = -1; offset = 0; double_offset = 0.0; if ( PyDict_Check(py_val) ) { PyObject *key_op = NULL, *value = NULL; PyObject * py_value = NULL; Py_ssize_t pos = 0; while (PyDict_Next(py_val, &pos, &key_op, &value)) { if ( ! PyString_Check(key_op) ) { as_error_update(err, AEROSPIKE_ERR_CLIENT, "A operation key must be a string."); goto CLEANUP; } else { char * name = PyString_AsString(key_op); if(!strcmp(name,"op") && (PyInt_Check(value) || PyLong_Check(value))) { operation = PyInt_AsLong(value); } else if (!strcmp(name, "bin")) { py_bin = value; } else if(!strcmp(name, "val")) { py_value = value; } else { as_error_update(err, AEROSPIKE_ERR_PARAM, "operation can contain only op, bin and val keys"); goto CLEANUP; } } } if (py_bin) { if (PyUnicode_Check(py_bin)) { py_ustr = PyUnicode_AsUTF8String(py_bin); bin = PyString_AsString(py_ustr); } else if (PyString_Check(py_bin)) { bin = PyString_AsString(py_bin); } else if (PyByteArray_Check(py_bin)) { bin = PyByteArray_AsString(py_bin); } else { as_error_update(err, AEROSPIKE_ERR_PARAM, "Bin name should be of type string"); goto CLEANUP; } if (self->strict_types) { if (strlen(bin) > AS_BIN_NAME_MAX_LEN) { if (py_ustr) { Py_DECREF(py_ustr); py_ustr = NULL; } as_error_update(err, AEROSPIKE_ERR_BIN_NAME, "A bin name should not exceed 14 characters limit"); goto CLEANUP; } } } else if (!py_bin && operation != AS_OPERATOR_TOUCH) { as_error_update(err, AEROSPIKE_ERR_PARAM, "Bin is not given"); goto CLEANUP; } if (py_value) { if (self->strict_types) { if (check_type(self, py_value, operation, err)) { goto CLEANUP; } } } else if ((!py_value) && (operation != AS_OPERATOR_READ && operation != AS_OPERATOR_TOUCH)) { as_error_update(err, AEROSPIKE_ERR_PARAM, "Value should be given"); goto CLEANUP; } switch(operation) { case AS_OPERATOR_APPEND: if (PyUnicode_Check(py_value)) { py_ustr1 = PyUnicode_AsUTF8String(py_value); val = PyString_AsString(py_ustr1); as_operations_add_append_str(&ops, bin, val); } else if (PyString_Check(py_value)) { val = PyString_AsString(py_value); as_operations_add_append_str(&ops, bin, val); } else if (PyByteArray_Check(py_value)) { as_bytes *bytes; GET_BYTES_POOL(bytes, &static_pool, err); serialize_based_on_serializer_policy(self, SERIALIZER_PYTHON, &bytes, py_value, err); as_operations_add_append_raw(&ops, bin, bytes->value, bytes->size); } else { if (!self->strict_types || !strcmp(py_value->ob_type->tp_name, "aerospike.null")) { as_operations *pointer_ops = &ops; as_binop *binop = &pointer_ops->binops.entries[pointer_ops->binops.size++]; binop->op = AS_OPERATOR_APPEND; initialize_bin_for_strictypes(self, err, py_value, binop, bin, &static_pool); } } break; case AS_OPERATOR_PREPEND: if (PyUnicode_Check(py_value)) { py_ustr1 = PyUnicode_AsUTF8String(py_value); val = PyString_AsString(py_ustr1); as_operations_add_prepend_str(&ops, bin, val); } else if (PyString_Check(py_value)) { val = PyString_AsString(py_value); as_operations_add_prepend_str(&ops, bin, val); } else if (PyByteArray_Check(py_value)) { as_bytes *bytes; GET_BYTES_POOL(bytes, &static_pool, err); serialize_based_on_serializer_policy(self, SERIALIZER_PYTHON, &bytes, py_value, err); as_operations_add_prepend_raw(&ops, bin, bytes->value, bytes->size); } else { if (!self->strict_types || !strcmp(py_value->ob_type->tp_name, "aerospike.null")) { as_operations *pointer_ops = &ops; as_binop *binop = &pointer_ops->binops.entries[pointer_ops->binops.size++]; binop->op = AS_OPERATOR_PREPEND; initialize_bin_for_strictypes(self, err, py_value, binop, bin, &static_pool); } } break; case AS_OPERATOR_INCR: if (PyInt_Check(py_value)) { offset = PyInt_AsLong(py_value); as_operations_add_incr(&ops, bin, offset); } else if ( PyLong_Check(py_value) ) { offset = PyLong_AsLong(py_value); if (offset == -1 && PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_OverflowError)) { as_error_update(err, AEROSPIKE_ERR_PARAM, "integer value exceeds sys.maxsize"); goto CLEANUP; } } as_operations_add_incr(&ops, bin, offset); } else if (PyFloat_Check(py_value)) { double_offset = PyFloat_AsDouble(py_value); as_operations_add_incr_double(&ops, bin, double_offset); } else { if (!self->strict_types || !strcmp(py_value->ob_type->tp_name, "aerospike.null")) { as_operations *pointer_ops = &ops; as_binop *binop = &pointer_ops->binops.entries[pointer_ops->binops.size++]; binop->op = AS_OPERATOR_INCR; initialize_bin_for_strictypes(self, err, py_value, binop, bin, &static_pool); } } break; case AS_OPERATOR_TOUCH: ops.ttl = 0; if (py_value && PyInt_Check(py_value)) { ops.ttl = PyInt_AsLong(py_value); } else if (py_value && PyLong_Check(py_value)) { ttl = PyLong_AsLong(py_value); if((uint32_t)-1 == ttl) { as_error_update(err, AEROSPIKE_ERR_PARAM, "integer value for ttl exceeds sys.maxsize"); goto CLEANUP; } ops.ttl = ttl; } as_operations_add_touch(&ops); break; case AS_OPERATOR_READ: as_operations_add_read(&ops, bin); break; case AS_OPERATOR_WRITE: pyobject_to_astype_write(self, err, bin, py_value, &put_val, &ops, &static_pool, SERIALIZER_PYTHON); if (err->code != AEROSPIKE_OK) { goto CLEANUP; } as_operations_add_write(&ops, bin, (as_bin_value *) put_val); break; default: if (self->strict_types) { as_error_update(err, AEROSPIKE_ERR_PARAM, "Invalid operation given"); goto CLEANUP; } } } } // Initialize record as_record_init(rec, 0); Py_BEGIN_ALLOW_THREADS aerospike_key_operate(self->as, err, operate_policy_p, key, &ops, &rec); Py_END_ALLOW_THREADS if (err->code != AEROSPIKE_OK) { as_error_update(err, err->code, NULL); goto CLEANUP; } if(rec) { record_to_pyobject(self, err, rec, key, &py_rec); } CLEANUP: if (py_ustr) { Py_DECREF(py_ustr); } if (py_ustr1) { Py_DECREF(py_ustr1); } if (rec) { as_record_destroy(rec); } if (key->valuep) { as_key_destroy(key); } if (put_val) { as_val_destroy(put_val); } if ( err->code != AEROSPIKE_OK ) { PyObject * py_err = NULL; error_to_pyobject(err, &py_err); PyObject *exception_type = raise_exception(err); PyErr_SetObject(exception_type, py_err); Py_DECREF(py_err); return NULL; } if (py_rec) { return py_rec; } else { return PyLong_FromLong(0); } }