Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev' into CLIENT-2992-python-3.13
Browse files Browse the repository at this point in the history
  • Loading branch information
juliannguyen4 committed Oct 18, 2024
2 parents 46d8945 + a1c9e42 commit 9a038ad
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 101 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
15.2.0rc1
15.2.0rc2.dev1
1 change: 1 addition & 0 deletions src/main/aerospike.c
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,7 @@ PyMODINIT_FUNC PyInit_aerospike(void)
.m_name = AEROSPIKE_MODULE_NAME,
.m_doc = "Aerospike Python Client",
.m_methods = aerospike_methods,
.m_size = -1,
};

PyObject *py_aerospike_module = PyModule_Create(&moduledef);
Expand Down
208 changes: 108 additions & 100 deletions src/main/policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,26 +52,42 @@

#define POLICY_UPDATE() *policy_p = policy;

// TODO: Python exceptions should be propagated up instead of being cleared
// but the policy helper functions don't handle this case and they only populate
// an as_error object and return a status code.
// That will take too much time to refactor, so just clear the exception and
// populate the as_error object instead. This currently makes it harder to
// debug why a C-API call failed though, because we don't have the exact
// exception that was thrown
#define POLICY_SET_FIELD(__field, __type) \
{ \
PyObject *py_field = PyDict_GetItemString(py_policy, #__field); \
if (py_field) { \
if (PyLong_Check(py_field)) { \
policy->__field = (__type)PyLong_AsLong(py_field); \
} \
else { \
return as_error_update(err, AEROSPIKE_ERR_PARAM, \
"%s is invalid", #__field); \
} \
PyObject *py_field_name = PyUnicode_FromString(#__field); \
if (py_field_name == NULL) { \
PyErr_Clear(); \
return as_error_update(err, AEROSPIKE_ERR_CLIENT, \
"Unable to create Python unicode object"); \
} \
}

#define POLICY_SET_BASE_FIELD(__field, __type) \
{ \
PyObject *py_field = PyDict_GetItemString(py_policy, #__field); \
PyObject *py_field = \
PyDict_GetItemWithError(py_policy, py_field_name); \
if (py_field == NULL && PyErr_Occurred()) { \
PyErr_Clear(); \
Py_DECREF(py_field_name); \
return as_error_update( \
err, AEROSPIKE_ERR_CLIENT, \
"Unable to fetch field from policy dictionary"); \
} \
Py_DECREF(py_field_name); \
\
if (py_field) { \
if (PyLong_Check(py_field)) { \
policy->base.__field = (__type)PyLong_AsLong(py_field); \
long field_val = PyLong_AsLong(py_field); \
if (field_val == -1 && PyErr_Occurred()) { \
PyErr_Clear(); \
return as_error_update( \
err, AEROSPIKE_ERR_CLIENT, \
"Unable to fetch long value from policy field"); \
} \
policy->__field = (__type)field_val; \
} \
else { \
return as_error_update(err, AEROSPIKE_ERR_PARAM, \
Expand All @@ -80,30 +96,35 @@
} \
}

#define POLICY_SET_EXPRESSIONS_BASE_FIELD() \
#define POLICY_SET_EXPRESSIONS_FIELD() \
{ \
if (exp_list) { \
PyObject *py_field_name = PyUnicode_FromString("expressions"); \
if (py_field_name == NULL) { \
PyErr_Clear(); \
return as_error_update( \
err, AEROSPIKE_ERR_CLIENT, \
"Unable to create Python unicode object"); \
} \
PyObject *py_exp_list = \
PyDict_GetItemString(py_policy, "expressions"); \
PyDict_GetItemWithError(py_policy, py_field_name); \
if (py_exp_list == NULL && PyErr_Occurred()) { \
PyErr_Clear(); \
Py_DECREF(py_field_name); \
return as_error_update(err, AEROSPIKE_ERR_CLIENT, \
"Unable to fetch expressions field " \
"from policy dictionary"); \
} \
Py_DECREF(py_field_name); \
if (py_exp_list) { \
if (convert_exp_list(self, py_exp_list, &exp_list, err) == \
AEROSPIKE_OK) { \
policy->base.filter_exp = exp_list; \
policy->filter_exp = exp_list; \
*exp_list_p = exp_list; \
} \
} \
} \
}

#define POLICY_SET_EXPRESSIONS_FIELD() \
{ \
PyObject *py_exp_list = \
PyDict_GetItemString(py_policy, "expressions"); \
if (py_exp_list) { \
if (convert_exp_list(self, py_exp_list, &exp_list, err) == \
AEROSPIKE_OK) { \
policy->filter_exp = exp_list; \
*exp_list_p = exp_list; \
else { \
return err->code; \
} \
} \
} \
}
Expand Down Expand Up @@ -219,8 +240,7 @@ as_status set_query_options(as_error *err, PyObject *query_options,
* and initialized (although, we do reset the error object here).
*/
as_status pyobject_to_policy_admin(AerospikeClient *self, as_error *err,
PyObject *py_policy, // remove self
as_policy_admin *policy,
PyObject *py_policy, as_policy_admin *policy,
as_policy_admin **policy_p,
as_policy_admin *config_admin_policy)
{
Expand All @@ -242,6 +262,21 @@ as_status pyobject_to_policy_admin(AerospikeClient *self, as_error *err,
return err->code;
}

static inline as_status
pyobject_to_policy_base(AerospikeClient *self, as_error *err,
PyObject *py_policy, as_policy_base *policy,
as_exp *exp_list, as_exp **exp_list_p)
{
POLICY_SET_FIELD(total_timeout, uint32_t);
POLICY_SET_FIELD(socket_timeout, uint32_t);
POLICY_SET_FIELD(max_retries, uint32_t);
POLICY_SET_FIELD(sleep_between_retries, uint32_t);
POLICY_SET_FIELD(compress, bool);

POLICY_SET_EXPRESSIONS_FIELD();
return AEROSPIKE_OK;
}

/**
* Converts a PyObject into an as_policy_apply object.
* Returns AEROSPIKE_OK on success. On error, the err argument is populated.
Expand All @@ -263,21 +298,18 @@ as_status pyobject_to_policy_apply(AerospikeClient *self, as_error *err,

if (py_policy && py_policy != Py_None) {
// Set policy fields
POLICY_SET_BASE_FIELD(total_timeout, uint32_t);
POLICY_SET_BASE_FIELD(socket_timeout, uint32_t);
POLICY_SET_BASE_FIELD(max_retries, uint32_t);
POLICY_SET_BASE_FIELD(sleep_between_retries, uint32_t);
POLICY_SET_BASE_FIELD(compress, bool);
as_status retval = pyobject_to_policy_base(
self, err, py_policy, &policy->base, exp_list, exp_list_p);
if (retval != AEROSPIKE_OK) {
return retval;
}

POLICY_SET_FIELD(key, as_policy_key);
POLICY_SET_FIELD(replica, as_policy_replica);
//POLICY_SET_FIELD(gen, as_policy_gen); removed
POLICY_SET_FIELD(commit_level, as_policy_commit_level);
POLICY_SET_FIELD(durable_delete, bool);
POLICY_SET_FIELD(ttl, uint32_t);

// C client 5.0 new expressions
POLICY_SET_EXPRESSIONS_BASE_FIELD();
}

// Update the policy
Expand Down Expand Up @@ -337,19 +369,14 @@ as_status pyobject_to_policy_query(AerospikeClient *self, as_error *err,
as_policy_query_copy(config_query_policy, policy);

if (py_policy && py_policy != Py_None) {
// Set policy fields
POLICY_SET_BASE_FIELD(total_timeout, uint32_t);
POLICY_SET_BASE_FIELD(socket_timeout, uint32_t);
POLICY_SET_BASE_FIELD(max_retries, uint32_t);
POLICY_SET_BASE_FIELD(sleep_between_retries, uint32_t);
POLICY_SET_BASE_FIELD(compress, bool);

as_status retval = pyobject_to_policy_base(
self, err, py_policy, &policy->base, exp_list, exp_list_p);
if (retval != AEROSPIKE_OK) {
return retval;
}
POLICY_SET_FIELD(deserialize, bool);
POLICY_SET_FIELD(replica, as_policy_replica);

// C client 5.0 new expressions
POLICY_SET_EXPRESSIONS_BASE_FIELD();

// C client 6.0.0
POLICY_SET_FIELD(short_query, bool);

Expand Down Expand Up @@ -384,11 +411,11 @@ as_status pyobject_to_policy_read(AerospikeClient *self, as_error *err,

if (py_policy && py_policy != Py_None) {
// Set policy fields
POLICY_SET_BASE_FIELD(total_timeout, uint32_t);
POLICY_SET_BASE_FIELD(socket_timeout, uint32_t);
POLICY_SET_BASE_FIELD(max_retries, uint32_t);
POLICY_SET_BASE_FIELD(sleep_between_retries, uint32_t);
POLICY_SET_BASE_FIELD(compress, bool);
as_status retval = pyobject_to_policy_base(
self, err, py_policy, &policy->base, exp_list, exp_list_p);
if (retval != AEROSPIKE_OK) {
return retval;
}

POLICY_SET_FIELD(key, as_policy_key);
POLICY_SET_FIELD(replica, as_policy_replica);
Expand All @@ -398,9 +425,6 @@ as_status pyobject_to_policy_read(AerospikeClient *self, as_error *err,
// 4.0.0 new policies
POLICY_SET_FIELD(read_mode_ap, as_policy_read_mode_ap);
POLICY_SET_FIELD(read_mode_sc, as_policy_read_mode_sc);

// C client 5.0 new expressions
POLICY_SET_EXPRESSIONS_BASE_FIELD();
}

// Update the policy
Expand Down Expand Up @@ -431,11 +455,11 @@ as_status pyobject_to_policy_remove(AerospikeClient *self, as_error *err,

if (py_policy && py_policy != Py_None) {
// Set policy fields
POLICY_SET_BASE_FIELD(total_timeout, uint32_t);
POLICY_SET_BASE_FIELD(socket_timeout, uint32_t);
POLICY_SET_BASE_FIELD(max_retries, uint32_t);
POLICY_SET_BASE_FIELD(sleep_between_retries, uint32_t);
POLICY_SET_BASE_FIELD(compress, bool);
as_status retval = pyobject_to_policy_base(
self, err, py_policy, &policy->base, exp_list, exp_list_p);
if (retval != AEROSPIKE_OK) {
return retval;
}

POLICY_SET_FIELD(generation, uint16_t);

Expand All @@ -444,9 +468,6 @@ as_status pyobject_to_policy_remove(AerospikeClient *self, as_error *err,
POLICY_SET_FIELD(commit_level, as_policy_commit_level);
POLICY_SET_FIELD(replica, as_policy_replica);
POLICY_SET_FIELD(durable_delete, bool);

// C client 5.0 new expressions
POLICY_SET_EXPRESSIONS_BASE_FIELD();
}

// Update the policy
Expand Down Expand Up @@ -476,19 +497,16 @@ as_status pyobject_to_policy_scan(AerospikeClient *self, as_error *err,

if (py_policy && py_policy != Py_None) {
// Set policy fields
POLICY_SET_BASE_FIELD(total_timeout, uint32_t);
POLICY_SET_BASE_FIELD(socket_timeout, uint32_t);
POLICY_SET_BASE_FIELD(max_retries, uint32_t);
POLICY_SET_BASE_FIELD(sleep_between_retries, uint32_t);
POLICY_SET_BASE_FIELD(compress, bool);
as_status retval = pyobject_to_policy_base(
self, err, py_policy, &policy->base, exp_list, exp_list_p);
if (retval != AEROSPIKE_OK) {
return retval;
}

POLICY_SET_FIELD(durable_delete, bool);
POLICY_SET_FIELD(records_per_second, uint32_t);
POLICY_SET_FIELD(max_records, uint64_t);
POLICY_SET_FIELD(replica, as_policy_replica);

// C client 5.0 new expressions
POLICY_SET_EXPRESSIONS_BASE_FIELD();
}

// Update the policy
Expand Down Expand Up @@ -518,12 +536,11 @@ as_status pyobject_to_policy_write(AerospikeClient *self, as_error *err,

if (py_policy && py_policy != Py_None) {
// Set policy fields
// Base policy_fields
POLICY_SET_BASE_FIELD(total_timeout, uint32_t);
POLICY_SET_BASE_FIELD(socket_timeout, uint32_t);
POLICY_SET_BASE_FIELD(max_retries, uint32_t);
POLICY_SET_BASE_FIELD(sleep_between_retries, uint32_t);
POLICY_SET_BASE_FIELD(compress, bool);
as_status retval = pyobject_to_policy_base(
self, err, py_policy, &policy->base, exp_list, exp_list_p);
if (retval != AEROSPIKE_OK) {
return retval;
}

POLICY_SET_FIELD(key, as_policy_key);
POLICY_SET_FIELD(gen, as_policy_gen);
Expand All @@ -532,9 +549,6 @@ as_status pyobject_to_policy_write(AerospikeClient *self, as_error *err,
POLICY_SET_FIELD(durable_delete, bool);
POLICY_SET_FIELD(replica, as_policy_replica);
POLICY_SET_FIELD(compression_threshold, uint32_t);

// C client 5.0 new expressions
POLICY_SET_EXPRESSIONS_BASE_FIELD();
}

// Update the policy
Expand Down Expand Up @@ -565,11 +579,11 @@ as_status pyobject_to_policy_operate(AerospikeClient *self, as_error *err,

if (py_policy && py_policy != Py_None) {
// Set policy fields
POLICY_SET_BASE_FIELD(total_timeout, uint32_t);
POLICY_SET_BASE_FIELD(socket_timeout, uint32_t);
POLICY_SET_BASE_FIELD(max_retries, uint32_t);
POLICY_SET_BASE_FIELD(sleep_between_retries, uint32_t);
POLICY_SET_BASE_FIELD(compress, bool);
as_status retval = pyobject_to_policy_base(
self, err, py_policy, &policy->base, exp_list, exp_list_p);
if (retval != AEROSPIKE_OK) {
return retval;
}

POLICY_SET_FIELD(key, as_policy_key);
POLICY_SET_FIELD(gen, as_policy_gen);
Expand All @@ -583,9 +597,6 @@ as_status pyobject_to_policy_operate(AerospikeClient *self, as_error *err,
// 4.0.0 new policies
POLICY_SET_FIELD(read_mode_ap, as_policy_read_mode_ap);
POLICY_SET_FIELD(read_mode_sc, as_policy_read_mode_sc);

// C client 5.0 new expressions
POLICY_SET_EXPRESSIONS_BASE_FIELD();
}

// Update the policy
Expand Down Expand Up @@ -615,11 +626,11 @@ as_status pyobject_to_policy_batch(AerospikeClient *self, as_error *err,

if (py_policy && py_policy != Py_None) {
// Set policy fields
POLICY_SET_BASE_FIELD(total_timeout, uint32_t);
POLICY_SET_BASE_FIELD(socket_timeout, uint32_t);
POLICY_SET_BASE_FIELD(max_retries, uint32_t);
POLICY_SET_BASE_FIELD(sleep_between_retries, uint32_t);
POLICY_SET_BASE_FIELD(compress, bool);
as_status retval = pyobject_to_policy_base(
self, err, py_policy, &policy->base, exp_list, exp_list_p);
if (retval != AEROSPIKE_OK) {
return retval;
}

POLICY_SET_FIELD(concurrent, bool);
POLICY_SET_FIELD(allow_inline, bool);
Expand All @@ -631,9 +642,6 @@ as_status pyobject_to_policy_batch(AerospikeClient *self, as_error *err,
POLICY_SET_FIELD(read_mode_ap, as_policy_read_mode_ap);
POLICY_SET_FIELD(read_mode_sc, as_policy_read_mode_sc);

// C client 5.0 new expressions
POLICY_SET_EXPRESSIONS_BASE_FIELD();

// C client 6.0.0 (batch writes)
POLICY_SET_FIELD(allow_inline_ssd, bool);
POLICY_SET_FIELD(respond_all_keys, bool);
Expand Down

0 comments on commit 9a038ad

Please sign in to comment.