diff --git a/aerospike-stubs/aerospike.pyi b/aerospike-stubs/aerospike.pyi index 9fc53f6c6b..5d852c5718 100644 --- a/aerospike-stubs/aerospike.pyi +++ b/aerospike-stubs/aerospike.pyi @@ -394,11 +394,11 @@ class Client: def index_string_create(self, ns: str, set: str, bin: str, name: str, policy: dict = ...) -> None: ... def index_blob_create(self, ns: str, set: str, bin: str, name: str, policy: dict = ...) -> None: ... - # Index creation for root-level CDTs # We cannot use aerospike_helpers's TypeExpression type because mypy's stubtest will complain - def index_list_create(self, ns: str, set: str, bin: str, index_datatype, name: str, policy: dict = ...) -> None: ... - def index_map_keys_create(self, ns: str, set: str, bin: str, index_datatype, name: str, policy: dict = ...) -> None: ... - def index_map_values_create(self, ns: str, set: str, bin: str, index_datatype, name: str, policy: dict = ...) -> None: ... + def index_single_value_create(self, ns: str, set: str, bin: str, index_datatype, name: str, policy: dict = ..., ctx: Optional[list] = ...) -> None: ... + def index_list_create(self, ns: str, set: str, bin: str, index_datatype, name: str, policy: dict = ..., ctx: Optional[list] = ...) -> None: ... + def index_map_keys_create(self, ns: str, set: str, bin: str, index_datatype, name: str, policy: dict = ..., ctx: Optional[list] = ...) -> None: ... + def index_map_values_create(self, ns: str, set: str, bin: str, index_datatype, name: str, policy: dict = ..., ctx: Optional[list] = ...) -> None: ... def index_cdt_create(self, ns: str, set: str, bin: str, index_type: int, index_datatype: int, name: str, ctx: list, policy: dict = ...) -> int: ... def index_expr_create(self, ns: str, set: str, index_type: int, index_datatype: int, expressions: list, name: str, policy: dict = ...) -> None: ... diff --git a/doc/aerospike.rst b/doc/aerospike.rst index ecdeab2ef3..fac19da4c3 100644 --- a/doc/aerospike.rst +++ b/doc/aerospike.rst @@ -1603,7 +1603,6 @@ Bin Types Index data types ---------------- - .. data:: INDEX_STRING An index whose values are of the aerospike string data type. @@ -1624,24 +1623,24 @@ Index data types .. _aerospike_index_types: -Index types +Index Types ----------- .. data:: INDEX_TYPE_DEFAULT - Index a bin that doesn't contain a complex data type. + Index a single scalar value. .. data:: INDEX_TYPE_LIST - Index a bin whose contents is an aerospike list. + Index all of a list's values. .. data:: INDEX_TYPE_MAPKEYS - Index the keys of a bin whose contents is an aerospike map. + Index all of a map's keys. .. data:: INDEX_TYPE_MAPVALUES - Index the values of a bin whose contents is an aerospike map. + Index all of a map's values. .. _aerospike_misc_constants: diff --git a/doc/client.rst b/doc/client.rst index beadae0fe4..7b264d80e8 100755 --- a/doc/client.rst +++ b/doc/client.rst @@ -838,42 +838,76 @@ Index Operations .. class:: Client :noindex: - .. method:: index_string_create(ns, set, bin, name[, policy: dict]) + .. method:: index_single_value_create(ns, set, bin, index_datatype, name, policy: dict = None, ctx: list = None) - Create a string index with *index_name* on the *bin* in the specified \ - *ns*, *set*. + Create a secondary index on a single value with a given type. + + :param str ns: the namespace containing the value. + :param str set: the set containing the value. + :param str bin: the name of the bin containing the value. + :param str index_datatype: the type of the value being indexed. See :ref:`aerospike_index_datatypes`. + :param str name: the name of the index. + :param dict policy: a dictionary defined by :ref:`aerospike_info_policies`. Defaults to :py:obj:`None`. + :param list ctx: a list of contexts to specify the location of a nested value in a collection data type. Defaults to :py:obj:`None`. + :raises: a subclass of :exc:`~aerospike.exception.AerospikeError`. + + .. method:: index_list_create(ns, set, bin, index_datatype, name, policy: dict = None, ctx: list = None) + + Create a secondary index for all of a list's values, where all the values are the same type. :param str ns: the namespace in the aerospike cluster. :param str set: the set name. :param str bin: the name of bin the secondary index is built on. + :param index_datatype: the type of the values being indexed. See :ref:`aerospike_index_datatypes`. :param str name: the name of the index. :param dict policy: optional :ref:`aerospike_info_policies`. + :param list ctx: a list of contexts to specify the location of a nested value in a collection data type. Defaults to :py:obj:`None`. :raises: a subclass of :exc:`~aerospike.exception.AerospikeError`. - .. method:: index_integer_create(ns, set, bin, name[, policy]) + .. method:: index_map_keys_create(ns, set, bin, index_datatype, name, policy: dict = None, ctx: list = None) - Create an integer index with *name* on the *bin* in the specified \ - *ns*, *set*. + Create a secondary index on all of a map's keys, where all of the keys are the same type. :param str ns: the namespace in the aerospike cluster. :param str set: the set name. :param str bin: the name of bin the secondary index is built on. + :param index_datatype: the type of the values being indexed. See :ref:`aerospike_index_datatypes`. :param str name: the name of the index. :param dict policy: optional :ref:`aerospike_info_policies`. + :param list ctx: a list of contexts to specify the location of a nested value in a collection data type. Defaults to :py:obj:`None`. :raises: a subclass of :exc:`~aerospike.exception.AerospikeError`. - .. method:: index_blob_create(ns, set, bin, name[, policy]) + .. note:: Requires server version >= 3.8.0 - Create an blob index with index name *name* on the *bin* in the specified \ - *ns*, *set*. + .. method:: index_map_values_create(ns, set, bin, index_datatype, name, policy: dict = None, ctx: list = None) + + Create a secondary index on all of a map's values, where all of the values are the same type. :param str ns: the namespace in the aerospike cluster. :param str set: the set name. - :param str bin: the name of the bin the secondary index is built on. + :param str bin: the name of bin the secondary index is built on. + :param index_datatype: the type of the values being indexed. See :ref:`aerospike_index_datatypes`. :param str name: the name of the index. :param dict policy: optional :ref:`aerospike_info_policies`. + :param list ctx: a list of contexts to specify the location of a nested value in a collection data type. Defaults to :py:obj:`None`. :raises: a subclass of :exc:`~aerospike.exception.AerospikeError`. + .. note:: Requires server version >= 3.8.0 + + .. code-block:: python + + import aerospike + + client = aerospike.client({ 'hosts': [ ('127.0.0.1', 3000)]}) + + # assume the bin fav_movies in the set test.demo bin should contain + # a dict { (str) _title_ : (int) _times_viewed_ } + # create a secondary index for string values of test.demo records whose 'fav_movies' bin is a map + client.index_map_keys_create('test', 'demo', 'fav_movies', aerospike.INDEX_STRING, 'demo_fav_movies_titles_idx') + # create a secondary index for integer values of test.demo records whose 'fav_movies' bin is a map + client.index_map_values_create('test', 'demo', 'fav_movies', aerospike.INDEX_NUMERIC, 'demo_fav_movies_views_idx') + client.close() + .. method:: index_expr_create(ns, set, index_type, index_datatype, expressions, name[, policy: dict]) Create secondary index on an expression. @@ -887,114 +921,75 @@ Index Operations :param dict policy: optional :ref:`aerospike_info_policies`. :raises: a subclass of :exc:`~aerospike.exception.AerospikeError`. - .. method:: index_list_create(ns, set, bin, index_datatype, name[, policy: dict]) + .. method:: index_remove(ns: str, name: str[, policy: dict]) - Create an index named *name* for numeric, string or GeoJSON values \ - (as defined by *index_datatype*) on records of the specified *ns*, *set* \ - whose *bin* is a list. + Remove the index with *name* from the namespace. :param str ns: the namespace in the aerospike cluster. - :param str set: the set name. - :param str bin: the name of bin the secondary index is built on. - :param index_datatype: See :ref:`aerospike_index_datatypes` for possible values. :param str name: the name of the index. :param dict policy: optional :ref:`aerospike_info_policies`. :raises: a subclass of :exc:`~aerospike.exception.AerospikeError`. - .. note:: Requires server version >= 3.8.0 + .. method:: get_cdtctx_base64(ctx: list) -> str + + Get the base64 representation of aerospike CDT ctx. + + See :ref:`aerospike_operation_helpers.cdt_ctx` for more details on CDT context. + + :param list ctx: Aerospike CDT context: generated by aerospike CDT ctx helper :mod:`aerospike_helpers`. + :raises: a subclass of :exc:`~aerospike.exception.AerospikeError`. + + .. include:: examples/get_cdtctx_base64.py + :code: python - .. method:: index_map_keys_create(ns, set, bin, index_datatype, name[, policy: dict]) + .. versionchanged:: 7.1.1 + + .. method:: index_string_create(ns, set, bin, name[, policy: dict]) - Create an index named *name* for numeric, string or GeoJSON values \ - (as defined by *index_datatype*) on records of the specified *ns*, *set* \ - whose *bin* is a map. The index will include the keys of the map. + .. deprecated:: 19.0.0 :meth:`index_single_value_create` should be used instead. + + Create a string index with *index_name* on the *bin* in the specified \ + *ns*, *set*. :param str ns: the namespace in the aerospike cluster. :param str set: the set name. :param str bin: the name of bin the secondary index is built on. - :param index_datatype: See :ref:`aerospike_index_datatypes` for possible values. :param str name: the name of the index. :param dict policy: optional :ref:`aerospike_info_policies`. :raises: a subclass of :exc:`~aerospike.exception.AerospikeError`. - .. note:: Requires server version >= 3.8.0 + .. method:: index_integer_create(ns, set, bin, name[, policy]) - .. method:: index_map_values_create(ns, set, bin, index_datatype, name[, policy: dict]) + .. deprecated:: 19.0.0 :meth:`index_single_value_create` should be used instead. - Create an index named *name* for numeric, string or GeoJSON values \ - (as defined by *index_datatype*) on records of the specified *ns*, *set* \ - whose *bin* is a map. The index will include the values of the map. + Create an integer index with *name* on the *bin* in the specified \ + *ns*, *set*. :param str ns: the namespace in the aerospike cluster. :param str set: the set name. :param str bin: the name of bin the secondary index is built on. - :param index_datatype: See :ref:`aerospike_index_datatypes` for possible values. :param str name: the name of the index. :param dict policy: optional :ref:`aerospike_info_policies`. :raises: a subclass of :exc:`~aerospike.exception.AerospikeError`. - .. note:: Requires server version >= 3.8.0 - - .. code-block:: python - - import aerospike - - client = aerospike.client({ 'hosts': [ ('127.0.0.1', 3000)]}) - - # assume the bin fav_movies in the set test.demo bin should contain - # a dict { (str) _title_ : (int) _times_viewed_ } - # create a secondary index for string values of test.demo records whose 'fav_movies' bin is a map - client.index_map_keys_create('test', 'demo', 'fav_movies', aerospike.INDEX_STRING, 'demo_fav_movies_titles_idx') - # create a secondary index for integer values of test.demo records whose 'fav_movies' bin is a map - client.index_map_values_create('test', 'demo', 'fav_movies', aerospike.INDEX_NUMERIC, 'demo_fav_movies_views_idx') - client.close() + .. method:: index_blob_create(ns, set, bin, name[, policy]) - .. method:: index_cdt_create(ns, set, bin, index_type, index_datatype, name, ctx[, policy: dict]) + .. deprecated:: 19.0.0 :meth:`index_single_value_create` should be used instead. - Create an index named *name* for a data type (as defined by *index_datatype*) on records of the specified *ns*, - *set*, *bin*, and *ctx*. + Create a blob index with *name* on the *bin* in the specified \ + *ns*, *set*. :param str ns: the namespace in the aerospike cluster. :param str set: the set name. :param str bin: the name of bin the secondary index is built on. - :param index_type: See :ref:`aerospike_index_types` for possible values. - :param index_datatype: See :ref:`aerospike_index_datatypes` for possible values. :param str name: the name of the index. - :param dict ctx: a :class:`list` of contexts produced by :mod:`aerospike_helpers.cdt_ctx` methods. :param dict policy: optional :ref:`aerospike_info_policies`. :raises: a subclass of :exc:`~aerospike.exception.AerospikeError`. - .. note:: Requires server version >= 4.6.0 - - .. code-block:: python - - import aerospike - from aerospike_helpers import cdt_ctx - - client = aerospike.client( - { - 'hosts': [ ('127.0.0.1', 3000)] - } - ) - - # assume the bin fav_movies in the set test.demo bin should contain - # a dict { (str) _title_ : (int) _times_viewed_ } - ctx_map_rank = [ - cdt_ctx.cdt_ctx_map_rank(-1) - ] - client.index_cdt_create( - ns="test", - set="demo", - bin="fav_movies", - index_type=aerospike.INDEX_TYPE_MAPKEYS, - index_datatype=aerospike.INDEX_STRING, - ctx=ctx_map_rank, - name="demo_fav_movies_titles_idx" - ) - client.close() - .. method:: index_geo2dsphere_create(ns, set, bin, name[, policy: dict]) + .. deprecated:: 19.0.0 :meth:`index_single_value_create` should be used instead. + Create a geospatial 2D spherical index with *name* on the *bin* \ in the specified *ns*, *set*. @@ -1017,30 +1012,23 @@ Index Operations client.index_geo2dsphere_create('test', 'pads', 'loc', 'pads_loc_geo') client.close() +.. method:: index_cdt_create(ns: str, set: str, bin: str, index_type, index_datatype, index_name: str, ctx: dict[, policy: dict]) - .. method:: index_remove(ns: str, name: str[, policy: dict]) - - Remove the index with *name* from the namespace. - - :param str ns: the namespace in the aerospike cluster. - :param str name: the name of the index. - :param dict policy: optional :ref:`aerospike_info_policies`. - :raises: a subclass of :exc:`~aerospike.exception.AerospikeError`. - - .. method:: get_cdtctx_base64(ctx: list) -> str - - Get the base64 representation of aerospike CDT ctx. - - See :ref:`aerospike_operation_helpers.cdt_ctx` for more details on CDT context. - - :param list ctx: Aerospike CDT context: generated by aerospike CDT ctx helper :mod:`aerospike_helpers`. - :raises: a subclass of :exc:`~aerospike.exception.AerospikeError`. + .. deprecated:: 19.0.0 Use the other non-deprecated index methods to create an index with a list of contexts. - .. include:: examples/get_cdtctx_base64.py - :code: python - - .. versionchanged:: 7.1.1 + Create an collection data type (CDT) index named *index_name* for a scalar, list values, map keys, or map values (as defined by *index_type*) and for + numeric, string, or GeoJSON values (as defined by *index_datatype*) + on records of the specified *ns*, *set* whose bin is a list or map. + :param str ns: the namespace in the aerospike cluster. + :param str set: the set name. + :param str bin: the name of bin the secondary index is built on. + :param index_type: whether we are querying a single scalar value or specific values of a CDT type. See :ref:`aerospike_index_types`. + :param index_datatype: the type of value being queried on. See :ref:`aerospike_index_datatypes`. + :param str index_name: the name of the index. + :param dict ctx: a dictionary containing the ``"ctx"`` key mapping to a list of contexts. + :param dict policy: optional :ref:`aerospike_info_policies`. + :raises: a subclass of :exc:`~aerospike.exception.AerospikeError`. .. index:: single: Admin Operations diff --git a/src/include/client.h b/src/include/client.h index 800c4c64dc..e41ddcc5fd 100644 --- a/src/include/client.h +++ b/src/include/client.h @@ -391,6 +391,11 @@ PyObject *AerospikeClient_Index_2dsphere_Create(AerospikeClient *self, */ PyObject *AerospikeClient_Index_Remove(AerospikeClient *self, PyObject *args, PyObject *kwds); + +PyObject *AerospikeClient_Index_Single_Value_Create(AerospikeClient *self, + PyObject *args, + PyObject *kwds); + /** * Create secondary list index * diff --git a/src/main/client/sec_index.c b/src/main/client/sec_index.c index 1b22db2257..d95fbbd818 100644 --- a/src/main/client/sec_index.c +++ b/src/main/client/sec_index.c @@ -30,127 +30,191 @@ #include "exceptions.h" #include "policy.h" -static bool getTypeFromPyObject(PyObject *py_datatype, int *idx_datatype, - as_error *err); - -static PyObject *createIndexWithCollectionType( - AerospikeClient *self, PyObject *py_policy, PyObject *py_ns, - PyObject *py_set, PyObject *py_bin, PyObject *py_name, - PyObject *py_datatype, as_index_type index_type, as_cdt_ctx *ctx); +#define CTX_PARSE_ERROR_MESSAGE "Unable to parse ctx" -static PyObject *createIndexWithDataAndCollectionType( +/* + * Create a complex index on the specified ns/set/bin with the given name and index and data_type. Return PyObject(0) on success + * else return NULL with an error raised. + */ +// expr is optional and can be NULL. +// If expr is non-NULL (i.e we are indexing an expression), py_bin should be NULL. +// This is permissive and allows py_ctx to be None or NULL +// +// NOTE: data_type and index_type are integers because some index creation methods i.e index_expr_create +// take in an C integer directly as an argument, but the rest of the index creation methods take in a PyObject +// that needs to be converted to a C integer on our end. +// To handle both cases, we just have each individual index creation method convert those parameters to C integers +// if needed. +static PyObject *convert_python_args_to_c_and_create_index( AerospikeClient *self, PyObject *py_policy, PyObject *py_ns, PyObject *py_set, PyObject *py_bin, PyObject *py_name, - as_index_type index_type, as_index_datatype data_type, as_cdt_ctx *ctx, - as_exp *exp); - -/** - ******************************************************************************************************* - * Creates an integer index for a bin in the Aerospike DB. - * - * @param self AerospikeClient object - * @param args The args is a tuple object containing an argument - * list passed from Python to a C function - * @param kwds Dictionary of keywords - * - * Returns an integer status. 0(Zero) is success value. - * In case of error,appropriate exceptions will be raised. - ******************************************************************************************************* - */ -PyObject *AerospikeClient_Index_Integer_Create(AerospikeClient *self, - PyObject *args, PyObject *kwds) + as_index_type index_type, as_index_datatype data_type, PyObject *py_ctx, + PyObject *py_expr) { + // Initialize error as_error err; as_error_init(&err); - // Python Function Arguments - PyObject *py_policy = NULL; - PyObject *py_ns = NULL; - PyObject *py_set = NULL; - PyObject *py_bin = NULL; - PyObject *py_name = NULL; + PyObject *py_ustr_set = NULL; + PyObject *py_ustr_bin = NULL; + PyObject *py_ustr_name = NULL; - // Python Function Keyword Arguments - static char *kwlist[] = {"ns", "set", "bin", "name", "policy", NULL}; + as_policy_info info_policy; + as_policy_info *info_policy_p = NULL; + as_index_task task; - // Python Function Argument Parsing - if (PyArg_ParseTupleAndKeywords(args, kwds, "OOOO|O:index_integer_create", - kwlist, &py_ns, &py_set, &py_bin, &py_name, - &py_policy) == false) { - return NULL; + if (!self || !self->as) { + as_error_update(&err, AEROSPIKE_ERR_PARAM, "Invalid aerospike object"); + goto CLEANUP; } - return createIndexWithDataAndCollectionType( - self, py_policy, py_ns, py_set, py_bin, py_name, AS_INDEX_TYPE_DEFAULT, - AS_INDEX_NUMERIC, NULL, NULL); -} + if (!self->is_conn_16) { + as_error_update(&err, AEROSPIKE_ERR_CLUSTER, + "No connection to aerospike cluster"); + goto CLEANUP; + } -/** - ******************************************************************************************************* - * Creates a string index for a bin in the Aerospike DB. - * - * @param self AerospikeClient object - * @param args The args is a tuple object containing an argument - * list passed from Python to a C function - * @param kwds Dictionary of keywords - * - * Returns an integer status. 0(Zero) is success value. - * In case of error,appropriate exceptions will be raised. - ******************************************************************************************************* - */ -PyObject *AerospikeClient_Index_String_Create(AerospikeClient *self, - PyObject *args, PyObject *kwds) -{ - // Initialize error - as_error err; - as_error_init(&err); + // Convert python object to policy_info + pyobject_to_policy_info(&err, py_policy, &info_policy, &info_policy_p, + &self->as->config.policies.info, + self->validate_keys, SECOND_AS_POLICY_NONE); + if (err.code != AEROSPIKE_OK) { + goto CLEANUP; + } - // Python Function Arguments - PyObject *py_policy = NULL; - PyObject *py_ns = NULL; - PyObject *py_set = NULL; - PyObject *py_bin = NULL; - PyObject *py_name = NULL; + // Convert python object into namespace string + if (!PyUnicode_Check(py_ns)) { + as_error_update(&err, AEROSPIKE_ERR_PARAM, + "Namespace should be a string"); + goto CLEANUP; + } + char *namespace = (char *)PyUnicode_AsUTF8(py_ns); - // Python Function Keyword Arguments - static char *kwlist[] = {"ns", "set", "bin", "name", "policy", NULL}; + // Convert python object into set string + char *set_ptr = NULL; + if (PyUnicode_Check(py_set)) { + py_ustr_set = PyUnicode_AsUTF8String(py_set); + set_ptr = PyBytes_AsString(py_ustr_set); + } + else if (py_set != Py_None) { + as_error_update(&err, AEROSPIKE_ERR_PARAM, + "Set should be string, unicode or None"); + goto CLEANUP; + } - // Python Function Argument Parsing - if (PyArg_ParseTupleAndKeywords(args, kwds, "OOOO|O:index_string_create", - kwlist, &py_ns, &py_set, &py_bin, &py_name, - &py_policy) == false) { - return NULL; + // Convert python object into bin string + char *bin_ptr = NULL; + if (py_bin) { + if (PyUnicode_Check(py_bin)) { + py_ustr_bin = PyUnicode_AsUTF8String(py_bin); + bin_ptr = PyBytes_AsString(py_ustr_bin); + } + else if (PyByteArray_Check(py_bin)) { + bin_ptr = PyByteArray_AsString(py_bin); + } + else { + as_error_update(&err, AEROSPIKE_ERR_PARAM, + "Bin should be a string"); + goto CLEANUP; + } } - return createIndexWithDataAndCollectionType( - self, py_policy, py_ns, py_set, py_bin, py_name, AS_INDEX_TYPE_DEFAULT, - AS_INDEX_STRING, NULL, NULL); -} + // Convert PyObject into the name of the index + char *name = NULL; + if (PyUnicode_Check(py_name)) { + py_ustr_name = PyUnicode_AsUTF8String(py_name); + name = PyBytes_AsString(py_ustr_name); + } + else { + as_error_update(&err, AEROSPIKE_ERR_PARAM, + "Index name should be string or unicode"); + goto CLEANUP; + } -PyObject *AerospikeClient_Index_Blob_Create(AerospikeClient *self, - PyObject *args, PyObject *kwds) -{ - // Python Function Arguments - PyObject *py_policy = NULL; - PyObject *py_ns = NULL; - PyObject *py_set = NULL; - PyObject *py_bin = NULL; - PyObject *py_name = NULL; + // TODO: this should be refactored by using a new helper function to parse a ctx list instead of get_cdt_ctx() + // which only parses a dictionary containing a ctx list + as_cdt_ctx ctx; + bool ctx_in_use = false; + PyObject *py_ctx_dict = NULL; + if (py_ctx && !Py_IsNone(py_ctx)) { + py_ctx_dict = PyDict_New(); + if (!py_ctx_dict) { + as_error_update(&err, AEROSPIKE_ERR_CLIENT, + CTX_PARSE_ERROR_MESSAGE); + goto CLEANUP; + } + int retval = PyDict_SetItemString(py_ctx_dict, "ctx", py_ctx); + if (retval == -1) { + as_error_update(&err, AEROSPIKE_ERR_CLIENT, + CTX_PARSE_ERROR_MESSAGE); + goto CLEANUP2; + } - // Python Function Keyword Arguments - static char *kwlist[] = {"ns", "set", "bin", "name", "policy", NULL}; + as_static_pool static_pool; + memset(&static_pool, 0, sizeof(static_pool)); - // Python Function Argument Parsing - if (PyArg_ParseTupleAndKeywords(args, kwds, "OOOO|O:index_blob_create", - kwlist, &py_ns, &py_set, &py_bin, &py_name, - &py_policy) == false) { + if (get_cdt_ctx(self, &err, &ctx, py_ctx_dict, &ctx_in_use, + &static_pool, SERIALIZER_PYTHON) != AEROSPIKE_OK) { + goto CLEANUP2; + } + } + + as_cdt_ctx *ctx_ref = ctx_in_use ? &ctx : NULL; + + as_exp *expr = NULL; + if (py_expr && as_exp_new_from_pyobject(self, py_expr, &expr, &err, + false) != AEROSPIKE_OK) { + goto CLEANUP3; + } + + // Invoke operation + Py_BEGIN_ALLOW_THREADS + if (expr) { + aerospike_index_create_exp(self->as, &err, &task, info_policy_p, + namespace, set_ptr, name, index_type, + data_type, expr); + } + else { + aerospike_index_create_ctx(self->as, &err, &task, info_policy_p, + namespace, set_ptr, bin_ptr, name, + index_type, data_type, ctx_ref); + } + Py_END_ALLOW_THREADS + if (err.code == AEROSPIKE_OK) { + Py_BEGIN_ALLOW_THREADS + aerospike_index_create_wait(&err, &task, 2000); + Py_END_ALLOW_THREADS + } + + if (expr) { + as_exp_destroy(expr); + } + +CLEANUP3: + if (ctx_ref) { + as_cdt_ctx_destroy(ctx_ref); + } + +CLEANUP2: + Py_XDECREF(py_ctx_dict); + +CLEANUP: + if (py_ustr_set) { + Py_DECREF(py_ustr_set); + } + if (py_ustr_bin) { + Py_DECREF(py_ustr_bin); + } + if (py_ustr_name) { + Py_DECREF(py_ustr_name); + } + if (err.code != AEROSPIKE_OK) { + raise_exception(&err); return NULL; } - return createIndexWithDataAndCollectionType( - self, py_policy, py_ns, py_set, py_bin, py_name, AS_INDEX_TYPE_DEFAULT, - AS_INDEX_BLOB, NULL, NULL); + return PyLong_FromLong(0); } PyObject *AerospikeClient_Index_Expr_Create(AerospikeClient *self, @@ -162,7 +226,6 @@ PyObject *AerospikeClient_Index_Expr_Create(AerospikeClient *self, PyObject *py_expr = NULL; as_index_type index_type; as_index_datatype data_type; - as_exp *expr = NULL; PyObject *py_name = NULL; PyObject *py_policy = NULL; @@ -178,20 +241,13 @@ PyObject *AerospikeClient_Index_Expr_Create(AerospikeClient *self, return NULL; } - as_error err; - as_error_init(&err); - if (as_exp_new_from_pyobject(self, py_expr, &expr, &err, false) != - AEROSPIKE_OK) { - raise_exception(&err); - return NULL; - } - - return createIndexWithDataAndCollectionType(self, py_policy, py_ns, py_set, - NULL, py_name, index_type, - data_type, NULL, expr); + return convert_python_args_to_c_and_create_index( + self, py_policy, py_ns, py_set, NULL, py_name, index_type, data_type, + NULL, py_expr); } -#define CTX_PARSE_ERROR_MESSAGE "Unable to parse ctx" +// This allows people to see the function calling the Python client API that issues a warning +#define STACK_LEVEL 2 /** ******************************************************************************************************* @@ -209,6 +265,11 @@ PyObject *AerospikeClient_Index_Expr_Create(AerospikeClient *self, PyObject *AerospikeClient_Index_Cdt_Create(AerospikeClient *self, PyObject *args, PyObject *kwds) { + PyErr_WarnEx(PyExc_DeprecationWarning, + "index_cdt_create() is deprecated. Please use one of the " + "other non-deprecated index_*_create() methods instead", + STACK_LEVEL); + // Initialize error as_error err; as_error_init(&err); @@ -223,11 +284,7 @@ PyObject *AerospikeClient_Index_Cdt_Create(AerospikeClient *self, PyObject *py_name = NULL; PyObject *py_ctx = NULL; - as_cdt_ctx ctx; - bool ctx_in_use = false; - PyObject *py_ctx_dict = NULL; - PyObject *py_obj = NULL; as_index_datatype data_type; as_index_type index_type; @@ -244,69 +301,40 @@ PyObject *AerospikeClient_Index_Cdt_Create(AerospikeClient *self, return NULL; } - if (!getTypeFromPyObject(py_indextype, (int *)&index_type, &err)) { - goto CLEANUP; - } - - if (!getTypeFromPyObject(py_datatype, (int *)&data_type, &err)) { - goto CLEANUP; + if (get_int_from_py_int(&err, py_indextype, (int *)&index_type, + "index_type") != AEROSPIKE_OK) { + goto CLEANUP_ON_ERROR; } - // TODO: this should be refactored by using a new helper function to parse a ctx list instead of get_cdt_ctx() - // which only parses a dictionary containing a ctx list - py_ctx_dict = PyDict_New(); - if (!py_ctx_dict) { - as_error_update(&err, AEROSPIKE_ERR_CLIENT, CTX_PARSE_ERROR_MESSAGE); - goto CLEANUP; - } - int retval = PyDict_SetItemString(py_ctx_dict, "ctx", py_ctx); - if (retval == -1) { - Py_DECREF(py_ctx_dict); - as_error_update(&err, AEROSPIKE_ERR_CLIENT, CTX_PARSE_ERROR_MESSAGE); - goto CLEANUP; + if (get_int_from_py_int(&err, py_datatype, (int *)&data_type, + "index_datatype") != AEROSPIKE_OK) { + goto CLEANUP_ON_ERROR; } - as_static_pool static_pool; - memset(&static_pool, 0, sizeof(static_pool)); - - if (get_cdt_ctx(self, &err, &ctx, py_ctx_dict, &ctx_in_use, &static_pool, - SERIALIZER_PYTHON) != AEROSPIKE_OK) { - goto CLEANUP; + // convert_python_args_to_c_and_create_index, which is called by the new index create method API's, + // accepts an optional value of None for ctx + // This API call is the only exception where a list of ctx's is required + if (Py_IsNone(py_ctx)) { + as_error_update(&err, AEROSPIKE_ERR_PARAM, "ctx cannot be None"); + goto CLEANUP_ON_ERROR; } // Even if this call fails, it will raise its own exception // and the err object here will not be set. We don't raise an exception twice - py_obj = createIndexWithDataAndCollectionType( + return convert_python_args_to_c_and_create_index( self, py_policy, py_ns, py_set, py_bin, py_name, index_type, data_type, - &ctx, NULL); - - as_cdt_ctx_destroy(&ctx); - -CLEANUP: - Py_XDECREF(py_ctx_dict); + py_ctx, NULL); - if (err.code != AEROSPIKE_OK) { - raise_exception_base(&err, Py_None, Py_None, Py_None, Py_None, py_name); - return NULL; - } - return py_obj; +CLEANUP_ON_ERROR: + raise_exception_base(&err, Py_None, Py_None, Py_None, Py_None, py_name); + return NULL; } -/** - ******************************************************************************************************* - * Removes an index in the Aerospike database. - * - * @param self AerospikeClient object - * @param args The args is a tuple object containing an argument - * list passed from Python to a C function - * @param kwds Dictionary of keywords - * - * Returns an integer status. 0(Zero) is success value. - * In case of error,appropriate exceptions will be raised. - ******************************************************************************************************* - */ -PyObject *AerospikeClient_Index_Remove(AerospikeClient *self, PyObject *args, - PyObject *kwds) +// TODO: way to get method name dynamically for error message? +static inline PyObject * +create_index_with_known_index_type(AerospikeClient *self, PyObject *args, + PyObject *kwds, as_index_type index_type, + const char *ml_name) { // Initialize error as_error err; @@ -315,11 +343,96 @@ PyObject *AerospikeClient_Index_Remove(AerospikeClient *self, PyObject *args, // Python Function Arguments PyObject *py_policy = NULL; PyObject *py_ns = NULL; + PyObject *py_set = NULL; + PyObject *py_bin = NULL; PyObject *py_name = NULL; - PyObject *py_ustr_name = NULL; + PyObject *py_datatype = NULL; + PyObject *py_ctx = NULL; - as_policy_info info_policy; - as_policy_info *info_policy_p = NULL; + static char *kwlist[] = {"ns", "set", "bin", "index_datatype", + "name", "policy", "ctx", NULL}; + + char format[256]; + snprintf(format, 256, "OOOOO|OO:%s", ml_name); + if (PyArg_ParseTupleAndKeywords(args, kwds, format, kwlist, &py_ns, &py_set, + &py_bin, &py_datatype, &py_name, &py_policy, + &py_ctx) == false) { + return NULL; + } + + as_index_datatype index_datatype = AS_INDEX_STRING; + if (get_int_from_py_int(&err, py_datatype, (int *)&index_datatype, + "index_datatype") != AEROSPIKE_OK) { + goto CLEANUP_ON_ERROR; + } + + return convert_python_args_to_c_and_create_index( + self, py_policy, py_ns, py_set, py_bin, py_name, index_type, + index_datatype, py_ctx, NULL); + +CLEANUP_ON_ERROR: + raise_exception_base(&err, Py_None, Py_None, Py_None, Py_None, py_name); + return NULL; +} + +PyObject *AerospikeClient_Index_Single_Value_Create(AerospikeClient *self, + PyObject *args, + PyObject *kwds) +{ + return create_index_with_known_index_type( + self, args, kwds, AS_INDEX_TYPE_DEFAULT, "index_single_value_create"); +} + +PyObject *AerospikeClient_Index_List_Create(AerospikeClient *self, + PyObject *args, PyObject *kwds) +{ + return create_index_with_known_index_type( + self, args, kwds, AS_INDEX_TYPE_LIST, "index_list_create"); +} + +PyObject *AerospikeClient_Index_Map_Keys_Create(AerospikeClient *self, + PyObject *args, PyObject *kwds) +{ + return create_index_with_known_index_type( + self, args, kwds, AS_INDEX_TYPE_MAPKEYS, "index_map_keys_create"); +} + +PyObject *AerospikeClient_Index_Map_Values_Create(AerospikeClient *self, + PyObject *args, + PyObject *kwds) +{ + return create_index_with_known_index_type( + self, args, kwds, AS_INDEX_TYPE_MAPVALUES, "index_map_values_create"); +} + +/** + ******************************************************************************************************* + * Removes an index in the Aerospike database. + * + * @param self AerospikeClient object + * @param args The args is a tuple object containing an argument + * list passed from Python to a C function + * @param kwds Dictionary of keywords + * + * Returns an integer status. 0(Zero) is success value. + * In case of error,appropriate exceptions will be raised. + ******************************************************************************************************* + */ +PyObject *AerospikeClient_Index_Remove(AerospikeClient *self, PyObject *args, + PyObject *kwds) +{ + // Initialize error + as_error err; + as_error_init(&err); + + // Python Function Arguments + PyObject *py_policy = NULL; + PyObject *py_ns = NULL; + PyObject *py_name = NULL; + PyObject *py_ustr_name = NULL; + + as_policy_info info_policy; + as_policy_info *info_policy_p = NULL; // Python Function Keyword Arguments static char *kwlist[] = {"ns", "name", "policy", NULL}; @@ -387,317 +500,94 @@ PyObject *AerospikeClient_Index_Remove(AerospikeClient *self, PyObject *args, return PyLong_FromLong(0); } -PyObject *AerospikeClient_Index_List_Create(AerospikeClient *self, - PyObject *args, PyObject *kwds) -{ - // Initialize error - as_error err; - as_error_init(&err); +// Deprecated API's - // Python Function Arguments - PyObject *py_policy = NULL; - PyObject *py_ns = NULL; - PyObject *py_set = NULL; - PyObject *py_bin = NULL; - PyObject *py_name = NULL; - PyObject *py_datatype = NULL; +#define DEPRECATION_NOTICE_TO_USE_INDEX_SINGLE_VALUE_CREATE \ + "%s() is deprecated. Please use index_single_value_create() instead" - // Python Function Keyword Arguments - static char *kwlist[] = {"ns", "set", "bin", "index_datatype", - "name", "policy", NULL}; - - // Python Function Argument Parsing - if (PyArg_ParseTupleAndKeywords( - args, kwds, "OOOOO|O:index_list_create", kwlist, &py_ns, &py_set, - &py_bin, &py_datatype, &py_name, &py_policy) == false) { - return NULL; - } - - return createIndexWithCollectionType(self, py_policy, py_ns, py_set, py_bin, - py_name, py_datatype, - AS_INDEX_TYPE_LIST, NULL); -} - -PyObject *AerospikeClient_Index_Map_Keys_Create(AerospikeClient *self, - PyObject *args, PyObject *kwds) +static PyObject * +deprecated_index_create_helper(AerospikeClient *self, PyObject *args, + PyObject *kwds, const char *ml_name, + as_index_datatype index_datatype) { - // Initialize error - as_error err; - as_error_init(&err); - - // Python Function Arguments - PyObject *py_policy = NULL; - PyObject *py_ns = NULL; - PyObject *py_set = NULL; - PyObject *py_bin = NULL; - PyObject *py_name = NULL; - PyObject *py_datatype = NULL; - - // Python Function Keyword Arguments - static char *kwlist[] = {"ns", "set", "bin", "index_datatype", - "name", "policy", NULL}; + PyErr_WarnFormat(PyExc_DeprecationWarning, STACK_LEVEL, + DEPRECATION_NOTICE_TO_USE_INDEX_SINGLE_VALUE_CREATE, + ml_name); - // Python Function Argument Parsing - if (PyArg_ParseTupleAndKeywords( - args, kwds, "OOOOO|O:index_map_keys_create", kwlist, &py_ns, - &py_set, &py_bin, &py_datatype, &py_name, &py_policy) == false) { - return NULL; - } - - return createIndexWithCollectionType(self, py_policy, py_ns, py_set, py_bin, - py_name, py_datatype, - AS_INDEX_TYPE_MAPKEYS, NULL); -} - -PyObject *AerospikeClient_Index_Map_Values_Create(AerospikeClient *self, - PyObject *args, - PyObject *kwds) -{ - // Initialize error as_error err; as_error_init(&err); // Python Function Arguments - PyObject *py_policy = NULL; PyObject *py_ns = NULL; PyObject *py_set = NULL; PyObject *py_bin = NULL; PyObject *py_name = NULL; - PyObject *py_datatype = NULL; - - // Python Function Keyword Arguments - static char *kwlist[] = {"ns", "set", "bin", "index_datatype", - "name", "policy", NULL}; - - // Python Function Argument Parsing - if (PyArg_ParseTupleAndKeywords( - args, kwds, "OOOOO|O:index_map_values_create", kwlist, &py_ns, - &py_set, &py_bin, &py_datatype, &py_name, &py_policy) == false) { - return NULL; - } - - return createIndexWithCollectionType(self, py_policy, py_ns, py_set, py_bin, - py_name, py_datatype, - AS_INDEX_TYPE_MAPVALUES, NULL); -} - -PyObject *AerospikeClient_Index_2dsphere_Create(AerospikeClient *self, - PyObject *args, PyObject *kwds) -{ - // Initialize error - as_error err; - as_error_init(&err); - - // Python Function Arguments PyObject *py_policy = NULL; - PyObject *py_ns = NULL; - PyObject *py_set = NULL; - PyObject *py_bin = NULL; - PyObject *py_name = NULL; - // Python Function Keyword Arguments static char *kwlist[] = {"ns", "set", "bin", "name", "policy", NULL}; // Python Function Argument Parsing - if (PyArg_ParseTupleAndKeywords( - args, kwds, "OOOO|O:index_geo2dsphere_create", kwlist, &py_ns, - &py_set, &py_bin, &py_name, &py_policy) == false) { + if (PyArg_ParseTupleAndKeywords(args, kwds, "OOOO|O:index_integer_create", + kwlist, &py_ns, &py_set, &py_bin, &py_name, + &py_policy) == false) { return NULL; } - return createIndexWithDataAndCollectionType( + return convert_python_args_to_c_and_create_index( self, py_policy, py_ns, py_set, py_bin, py_name, AS_INDEX_TYPE_DEFAULT, - AS_INDEX_GEO2DSPHERE, NULL, NULL); + index_datatype, NULL, NULL); } -/* - * Convert a PyObject into an as_index_datatype, return False if the conversion fails for any reason. +/** + ******************************************************************************************************* + * Creates an integer index for a bin in the Aerospike DB. + * + * @param self AerospikeClient object + * @param args The args is a tuple object containing an argument + * list passed from Python to a C function + * @param kwds Dictionary of keywords + * + * Returns an integer status. 0(Zero) is success value. + * In case of error,appropriate exceptions will be raised. + ******************************************************************************************************* */ -static bool getTypeFromPyObject(PyObject *py_datatype, int *idx_datatype, - as_error *err) +PyObject *AerospikeClient_Index_Integer_Create(AerospikeClient *self, + PyObject *args, PyObject *kwds) { - - long type = 0; - if (PyLong_Check(py_datatype)) { - type = PyLong_AsLong(py_datatype); - if (type == -1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) { - as_error_update(err, AEROSPIKE_ERR_PARAM, - "integer value exceeds sys.maxsize"); - goto CLEANUP; - } - } - } - else { - as_error_update(err, AEROSPIKE_ERR_PARAM, - "Index type must be an integer"); - goto CLEANUP; - } - - *idx_datatype = type; - -CLEANUP: - if (err->code != AEROSPIKE_OK) { - raise_exception(err); - return false; - } - return true; + return deprecated_index_create_helper( + self, args, kwds, "index_integer_create", AS_INDEX_NUMERIC); } -/* - * Figure out the data_type from a PyObject and call createIndexWithDataAndCollectionType. +/** + ******************************************************************************************************* + * Creates a string index for a bin in the Aerospike DB. + * + * @param self AerospikeClient object + * @param args The args is a tuple object containing an argument + * list passed from Python to a C function + * @param kwds Dictionary of keywords + * + * Returns an integer status. 0(Zero) is success value. + * In case of error,appropriate exceptions will be raised. + ******************************************************************************************************* */ -static PyObject *createIndexWithCollectionType( - AerospikeClient *self, PyObject *py_policy, PyObject *py_ns, - PyObject *py_set, PyObject *py_bin, PyObject *py_name, - PyObject *py_datatype, as_index_type index_type, as_cdt_ctx *ctx) +PyObject *AerospikeClient_Index_String_Create(AerospikeClient *self, + PyObject *args, PyObject *kwds) { - - as_index_datatype data_type = AS_INDEX_STRING; - - as_error err; - as_error_init(&err); - - if (!getTypeFromPyObject(py_datatype, (int *)&data_type, &err)) { - return NULL; - } - - return createIndexWithDataAndCollectionType(self, py_policy, py_ns, py_set, - py_bin, py_name, index_type, - data_type, ctx, NULL); + return deprecated_index_create_helper( + self, args, kwds, "index_string_create", AS_INDEX_STRING); } -/* - * Create a complex index on the specified ns/set/bin with the given name and index and data_type. Return PyObject(0) on success - * else return NULL with an error raised. - */ - -// exp is optional and can be NULL. -// If exp is non-NULL (i.e we are indexing an expression), py_bin should be NULL. -static PyObject *createIndexWithDataAndCollectionType( - AerospikeClient *self, PyObject *py_policy, PyObject *py_ns, - PyObject *py_set, PyObject *py_bin, PyObject *py_name, - as_index_type index_type, as_index_datatype data_type, as_cdt_ctx *ctx, - as_exp *exp) +PyObject *AerospikeClient_Index_Blob_Create(AerospikeClient *self, + PyObject *args, PyObject *kwds) { + return deprecated_index_create_helper(self, args, kwds, "index_blob_create", + AS_INDEX_BLOB); +} - // Initialize error - as_error err; - as_error_init(&err); - - PyObject *py_ustr_set = NULL; - PyObject *py_ustr_bin = NULL; - PyObject *py_ustr_name = NULL; - - as_policy_info info_policy; - as_policy_info *info_policy_p = NULL; - as_index_task task; - - if (!self || !self->as) { - as_error_update(&err, AEROSPIKE_ERR_PARAM, "Invalid aerospike object"); - //raise_exception(&err, -2, "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 object to policy_info - pyobject_to_policy_info(&err, py_policy, &info_policy, &info_policy_p, - &self->as->config.policies.info, - self->validate_keys, SECOND_AS_POLICY_NONE); - if (err.code != AEROSPIKE_OK) { - goto CLEANUP; - } - - // Convert python object into namespace string - if (!PyUnicode_Check(py_ns)) { - as_error_update(&err, AEROSPIKE_ERR_PARAM, - "Namespace should be a string"); - goto CLEANUP; - } - char *namespace = (char *)PyUnicode_AsUTF8(py_ns); - - // Convert python object into set string - char *set_ptr = NULL; - if (PyUnicode_Check(py_set)) { - py_ustr_set = PyUnicode_AsUTF8String(py_set); - set_ptr = PyBytes_AsString(py_ustr_set); - } - else if (py_set != Py_None) { - as_error_update(&err, AEROSPIKE_ERR_PARAM, - "Set should be string, unicode or None"); - goto CLEANUP; - } - - // Convert python object into bin string - char *bin_ptr = NULL; - if (py_bin) { - if (PyUnicode_Check(py_bin)) { - py_ustr_bin = PyUnicode_AsUTF8String(py_bin); - bin_ptr = PyBytes_AsString(py_ustr_bin); - } - else if (PyByteArray_Check(py_bin)) { - bin_ptr = PyByteArray_AsString(py_bin); - } - else { - as_error_update(&err, AEROSPIKE_ERR_PARAM, - "Bin should be a string"); - goto CLEANUP; - } - } - - // Convert PyObject into the name of the index - char *name = NULL; - if (PyUnicode_Check(py_name)) { - py_ustr_name = PyUnicode_AsUTF8String(py_name); - name = PyBytes_AsString(py_ustr_name); - } - else { - as_error_update(&err, AEROSPIKE_ERR_PARAM, - "Index name should be string or unicode"); - goto CLEANUP; - } - - // Invoke operation - Py_BEGIN_ALLOW_THREADS - if (exp) { - aerospike_index_create_exp(self->as, &err, &task, info_policy_p, - namespace, set_ptr, name, index_type, - data_type, exp); - } - else { - aerospike_index_create_ctx(self->as, &err, &task, info_policy_p, - namespace, set_ptr, bin_ptr, name, - index_type, data_type, ctx); - } - Py_END_ALLOW_THREADS - if (err.code == AEROSPIKE_OK) { - Py_BEGIN_ALLOW_THREADS - aerospike_index_create_wait(&err, &task, 2000); - Py_END_ALLOW_THREADS - } - -CLEANUP: - if (py_ustr_set) { - Py_DECREF(py_ustr_set); - } - if (py_ustr_bin) { - Py_DECREF(py_ustr_bin); - } - if (py_ustr_name) { - Py_DECREF(py_ustr_name); - } - if (exp) { - as_exp_destroy(exp); - } - if (err.code != AEROSPIKE_OK) { - raise_exception(&err); - return NULL; - } - - return PyLong_FromLong(0); +PyObject *AerospikeClient_Index_2dsphere_Create(AerospikeClient *self, + PyObject *args, PyObject *kwds) +{ + return deprecated_index_create_helper( + self, args, kwds, "index_geo2dsphere_create", AS_INDEX_GEO2DSPHERE); } diff --git a/src/main/client/type.c b/src/main/client/type.c index 842f4cd90c..b77e5a3290 100644 --- a/src/main/client/type.c +++ b/src/main/client/type.c @@ -474,6 +474,10 @@ static PyMethodDef AerospikeClient_Type_Methods[] = { METH_VARARGS | METH_KEYWORDS, get_cdtctx_base64_doc}, {"index_remove", (PyCFunction)AerospikeClient_Index_Remove, METH_VARARGS | METH_KEYWORDS, index_remove_doc}, + + {"index_single_value_create", + (PyCFunction)AerospikeClient_Index_Single_Value_Create, + METH_VARARGS | METH_KEYWORDS, NULL}, {"index_list_create", (PyCFunction)AerospikeClient_Index_List_Create, METH_VARARGS | METH_KEYWORDS, index_list_create_doc}, {"index_map_keys_create", @@ -482,6 +486,7 @@ static PyMethodDef AerospikeClient_Type_Methods[] = { {"index_map_values_create", (PyCFunction)AerospikeClient_Index_Map_Values_Create, METH_VARARGS | METH_KEYWORDS, index_map_values_create_doc}, + {"index_geo2dsphere_create", (PyCFunction)AerospikeClient_Index_2dsphere_Create, METH_VARARGS | METH_KEYWORDS, index_geo2dsphere_create_doc}, diff --git a/src/main/conversions.c b/src/main/conversions.c index 23065d51c7..e869275af0 100644 --- a/src/main/conversions.c +++ b/src/main/conversions.c @@ -2664,7 +2664,7 @@ as_status get_int_from_py_int(as_error *err, PyObject *py_long, "%s must be an integer.", py_object_name); } - int int_to_return = PyLong_AsLong(py_long); + long int_to_return = PyLong_AsLong(py_long); if (PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_OverflowError)) { return as_error_update(err, AEROSPIKE_ERR_PARAM, @@ -2680,7 +2680,7 @@ as_status get_int_from_py_int(as_error *err, PyObject *py_long, "%s too large for C int.", py_object_name); } - *int_pointer = int_to_return; + *int_pointer = (int)int_to_return; return AEROSPIKE_OK; } diff --git a/test/new_tests/test_aggregate.py b/test/new_tests/test_aggregate.py index 6109c0869c..e7255afc97 100644 --- a/test/new_tests/test_aggregate.py +++ b/test/new_tests/test_aggregate.py @@ -16,7 +16,7 @@ def remove_stream_udf(client): def add_required_index(client): - client.index_integer_create("test", "demo", "test_age", "age_index") + client.index_single_value_create("test", "demo", "test_age", aerospike.INDEX_NUMERIC, "age_index") def remove_index(client): diff --git a/test/new_tests/test_apply.py b/test/new_tests/test_apply.py index cb5ff0da82..7c54110228 100644 --- a/test/new_tests/test_apply.py +++ b/test/new_tests/test_apply.py @@ -53,11 +53,11 @@ def add_indexes_and_udfs(client): """ policy = {} try: - client.index_integer_create("test", "demo", "age", "age_index", policy) + client.index_single_value_create("test", "demo", "age", aerospike.INDEX_NUMERIC, "age_index", policy) except e.IndexFoundError: pass try: - client.index_integer_create("test", "demo", "age1", "age_index1", policy) + client.index_single_value_create("test", "demo", "age1", aerospike.INDEX_NUMERIC, "age_index1", policy) except e.IndexFoundError: pass diff --git a/test/new_tests/test_batch_apply.py b/test/new_tests/test_batch_apply.py index 742c10d23c..bef6e9a5f8 100644 --- a/test/new_tests/test_batch_apply.py +++ b/test/new_tests/test_batch_apply.py @@ -18,11 +18,11 @@ def add_indexes_and_udfs(client): """ policy = {} try: - client.index_integer_create("test", "demo", "age", "age_index", policy) + client.index_single_value_create("test", "demo", "age", aerospike.INDEX_NUMERIC, "age_index", policy) except e.IndexFoundError: pass try: - client.index_integer_create("test", "demo", "age1", "age_index1", policy) + client.index_single_value_create("test", "demo", "age1", aerospike.INDEX_NUMERIC, "age_index1", policy) except e.IndexFoundError: pass diff --git a/test/new_tests/test_geospatial.py b/test/new_tests/test_geospatial.py index 5e010ebc53..a9a173a065 100644 --- a/test/new_tests/test_geospatial.py +++ b/test/new_tests/test_geospatial.py @@ -31,17 +31,17 @@ def get_geo_object(): def add_geo_indexes(connection): try: - connection.index_geo2dsphere_create("test", "demo", "loc", "loc_index") + connection.index_geo2dsphere_create("test", "demo", "loc", aerospike.INDEX_GEO2DSPHERE, "loc_index") except (e.IndexFoundError): pass try: - connection.index_geo2dsphere_create("test", "demo", "loc_polygon", "loc_polygon_index") + connection.index_geo2dsphere_create("test", "demo", "loc_polygon", aerospike.INDEX_GEO2DSPHERE, "loc_polygon_index") except (e.IndexFoundError): pass try: - connection.index_geo2dsphere_create("test", "demo", "loc_circle", "loc_circle_index") + connection.index_geo2dsphere_create("test", "demo", "loc_circle", aerospike.INDEX_GEO2DSPHERE, "loc_circle_index") except (e.IndexFoundError): pass @@ -343,7 +343,7 @@ def test_geospatial_positive_query_without_set(self): keys.append(key) try: - self.as_connection.index_geo2dsphere_create("test", None, "loc", "loc_index_no_set") + self.as_connection.index_geo2dsphere_create("test", None, "loc", aerospike.INDEX_GEO2DSPHERE, "loc_index_no_set") except (e.IndexFoundError): pass @@ -780,7 +780,7 @@ def test_geospatial_2dindex_positive(self): except Exception: pass - status = self.as_connection.index_geo2dsphere_create("test", "demo", "loc", "loc_index") + status = self.as_connection.index_geo2dsphere_create("test", "demo", "loc", aerospike.INDEX_GEO2DSPHERE, "loc_index") assert status == 0 @@ -794,7 +794,7 @@ def test_geospatial_2dindex_positive_with_policy(self): except Exception: pass - status = self.as_connection.index_geo2dsphere_create("test", "demo", "loc", "loc_index", {"timeout": 180000}) + status = self.as_connection.index_geo2dsphere_create("test", "demo", "loc", aerospike.INDEX_GEO2DSPHERE, "loc_index", {"timeout": 180000}) assert status == 0 @@ -1154,7 +1154,7 @@ def test_geospatial_2dindex_set_length_extra(self): set_name = "a" * 100 with pytest.raises(e.InvalidRequest) as err_info: - self.as_connection.index_geo2dsphere_create("test", set_name, "loc", "loc_index_creation_should_fail") + self.as_connection.index_geo2dsphere_create("test", set_name, "loc", aerospike.INDEX_GEO2DSPHERE, "loc_index_creation_should_fail") err_code = err_info.value.code assert err_code == AerospikeStatus.AEROSPIKE_ERR_REQUEST_INVALID diff --git a/test/new_tests/test_index.py b/test/new_tests/test_index.py index 5d9a0e9628..1ff93fae78 100644 --- a/test/new_tests/test_index.py +++ b/test/new_tests/test_index.py @@ -40,7 +40,7 @@ def test_create_indexes_with_no_parameters(self): assert "argument 'ns' (pos 1)" in str(typeError.value) with pytest.raises(TypeError) as typeError: - self.as_connection.index_integer_create() + self.as_connection.index_single_value_create() assert "argument 'ns' (pos 1)" in str(typeError.value) @@ -49,7 +49,7 @@ def test_create_integer_index_with_correct_parameters(self): Invoke createindex() with correct arguments """ policy = {} - retobj = self.as_connection.index_integer_create("test", "demo", "age", "age_index", policy) + retobj = self.as_connection.index_single_value_create("test", "demo", "age", aerospike.INDEX_NUMERIC, "age_index", policy) assert retobj == AerospikeStatus.AEROSPIKE_OK self.as_connection.index_remove("test", "age_index", policy) @@ -61,7 +61,7 @@ def test_create_integer_index_with_set_name_too_long(self): policy = {} with pytest.raises(e.InvalidRequest) as err_info: - self.as_connection.index_integer_create("test", set_name, "age", "age_index", policy) + self.as_connection.index_single_value_create("test", set_name, "age", aerospike.INDEX_NUMERIC, "age_index", policy) err_code = err_info.value.code assert err_code is AerospikeStatus.AEROSPIKE_ERR_REQUEST_INVALID @@ -72,7 +72,7 @@ def test_create_integer_index_with_incorrect_namespace(self): """ policy = {} with pytest.raises(e.NamespaceNotFound) as err_info: - self.as_connection.index_integer_create("fake_namespace", "demo", "age", "age_index", policy) + self.as_connection.index_single_value_create("fake_namespace", "demo", "age", aerospike.INDEX_NUMERIC, "age_index", policy) err_code = err_info.value.code assert err_code is AerospikeStatus.AEROSPIKE_ERR_NAMESPACE_NOT_FOUND @@ -83,7 +83,7 @@ def test_create_integer_index_with_incorrect_set(self): It should succeed """ policy = {} - retobj = self.as_connection.index_integer_create("test", "demo1", "age", "age_index", policy) + retobj = self.as_connection.index_single_value_create("test", "demo1", "age", aerospike.INDEX_NUMERIC, "age_index", policy) assert retobj == AerospikeStatus.AEROSPIKE_OK self.as_connection.index_remove("test", "age_index", policy) @@ -94,7 +94,7 @@ def test_create_integer_index_with_incorrect_bin(self): Invoke createindex() with a nonexistent bin """ policy = {} - retobj = self.as_connection.index_integer_create("test", "demo", "fake_bin", "age_index", policy) + retobj = self.as_connection.index_single_value_create("test", "demo", "fake_bin", aerospike.INDEX_NUMERIC, "age_index", policy) assert retobj == AerospikeStatus.AEROSPIKE_OK self.as_connection.index_remove("test", "age_index", policy) @@ -106,7 +106,7 @@ def test_create_integer_index_with_namespace_is_none(self): """ policy = {} with pytest.raises(e.ParamError) as err_info: - self.as_connection.index_integer_create(None, "demo", "age", "age_index", policy) + self.as_connection.index_single_value_create(None, "demo", "age", aerospike.INDEX_NUMERIC, "age_index", policy) err_code = err_info.value.code assert err_code is AerospikeStatus.AEROSPIKE_ERR_PARAM @@ -115,7 +115,7 @@ def test_creat_integer_eindex_with_set_is_none(self): # Invoke createindex() with set is None policy = {} - retobj = self.as_connection.index_integer_create("test", None, "age", "age_index", policy) + retobj = self.as_connection.index_single_value_create("test", None, "age", aerospike.INDEX_NUMERIC, "age_index", policy) assert retobj == AerospikeStatus.AEROSPIKE_OK self.as_connection.index_remove("test", "age_index", policy) @@ -126,7 +126,7 @@ def test_create_integer_index_with_set_is_int(self): policy = {} with pytest.raises(e.ParamError) as err_info: - self.as_connection.index_integer_create("test", 1, "age", "age_index", policy) + self.as_connection.index_single_value_create("test", 1, "age", aerospike.INDEX_NUMERIC, "age_index", policy) err_code = err_info.value.code assert err_code is AerospikeStatus.AEROSPIKE_ERR_PARAM @@ -136,7 +136,7 @@ def test_create_integer_index_with_bin_is_none(self): """ policy = {} with pytest.raises(e.ParamError) as err_info: - self.as_connection.index_integer_create("test", "demo", None, "age_index", policy) + self.as_connection.index_single_value_create("test", "demo", None, aerospike.INDEX_NUMERIC, "age_index", policy) err_code = err_info.value.code assert err_code is AerospikeStatus.AEROSPIKE_ERR_PARAM @@ -147,7 +147,7 @@ def test_create_integer_index_with_index_is_none(self): """ policy = {} with pytest.raises(e.ParamError) as err_info: - self.as_connection.index_integer_create("test", "demo", "age", None, policy) + self.as_connection.index_single_value_create("test", "demo", "age", aerospike.INDEX_NUMERIC, None, policy) err_code = err_info.value.code assert err_code is AerospikeStatus.AEROSPIKE_ERR_PARAM @@ -159,10 +159,10 @@ def test_create_same_integer_index_multiple_times(self): """ policy = {} - retobj = self.as_connection.index_integer_create("test", "demo", "age", "age_index", policy) + retobj = self.as_connection.index_single_value_create("test", "demo", "age", aerospike.INDEX_NUMERIC, "age_index", policy) assert retobj == AerospikeStatus.AEROSPIKE_OK try: - retobj = self.as_connection.index_integer_create("test", "demo", "age", "age_index", policy) + retobj = self.as_connection.index_single_value_create("test", "demo", "age", aerospike.INDEX_NUMERIC, "age_index", policy) except e.IndexFoundError: assert self.server_version <= [6, 0] @@ -175,12 +175,12 @@ def test_create_same_integer_index_multiple_times_different_bin(self): multiple times on different bin names """ policy = {} - retobj = self.as_connection.index_integer_create("test", "demo", "age", "age_index", policy) + retobj = self.as_connection.index_single_value_create("test", "demo", "age", aerospike.INDEX_NUMERIC, "age_index", policy) assert retobj == AerospikeStatus.AEROSPIKE_OK with pytest.raises(e.IndexFoundError): - retobj = self.as_connection.index_integer_create("test", "demo", "no", "age_index", policy) + retobj = self.as_connection.index_single_value_create("test", "demo", "no", aerospike.INDEX_NUMERIC, "age_index", policy) self.as_connection.index_remove("test", "age_index", policy) ensure_dropped_index(self.as_connection, "test", "age_index") @@ -191,10 +191,10 @@ def test_create_different_integer_index_multiple_times_same_bin(self): name """ policy = {} - retobj = self.as_connection.index_integer_create("test", "demo", "age", "age_index", policy) + retobj = self.as_connection.index_single_value_create("test", "demo", "age", aerospike.INDEX_NUMERIC, "age_index", policy) assert retobj == AerospikeStatus.AEROSPIKE_OK try: - retobj = self.as_connection.index_integer_create("test", "demo", "age", "age_index1", policy) + retobj = self.as_connection.index_single_value_create("test", "demo", "age", aerospike.INDEX_NUMERIC, "age_index1", policy) self.as_connection.index_remove("test", "age_index1", policy) except e.IndexFoundError: assert self.server_version <= [6, 0] @@ -206,7 +206,7 @@ def test_create_integer_index_with_policy(self): Invoke createindex() with policy """ policy = {"timeout": 180000} - retobj = self.as_connection.index_integer_create("test", "demo", "age", "age_index", policy) + retobj = self.as_connection.index_single_value_create("test", "demo", "age", aerospike.INDEX_NUMERIC, "age_index", policy) ensure_dropped_index(self.as_connection, "test", "age_index") assert retobj == AerospikeStatus.AEROSPIKE_OK @@ -215,7 +215,7 @@ def test_create_blob_index(self): if self.server_version < [7, 0]: pytest.skip("Blob secondary indexes are only supported in server 7.0+") - self.as_connection.index_blob_create(ns="test", set="demo", bin="bytes", name="bytes_index", policy={}) + self.as_connection.index_single_value_create(ns="test", set="demo", bin="bytes", index_datatype=aerospike.INDEX_BLOB, name="bytes_index", policy={}) ensure_dropped_index(self.as_connection, "test", "bytes_index") @@ -224,7 +224,7 @@ def test_create_string_index_positive(self): Invoke create string index() with correct arguments """ policy = {} - retobj = self.as_connection.index_string_create("test", "demo", "name", "name_index", policy) + retobj = self.as_connection.index_string_create("test", "demo", "name", aerospike.INDEX_STRING, "name_index", policy) self.as_connection.index_remove("test", "name_index", policy) ensure_dropped_index(self.as_connection, "test", "name_index") @@ -237,7 +237,7 @@ def test_create_string_index_with_set_length_too_long(self): policy = {} with pytest.raises(e.InvalidRequest) as err_info: - self.as_connection.index_string_create("test", set_name, "name", "name_index", policy) + self.as_connection.index_string_create("test", set_name, "name", aerospike.INDEX_STRING, "name_index", policy) err_code = err_info.value.code assert err_code is AerospikeStatus.AEROSPIKE_ERR_REQUEST_INVALID @@ -247,7 +247,7 @@ def test_create_string_index_with_correct_parameters_ns_length_extra(self): policy = {} with pytest.raises((e.InvalidRequest, e.NamespaceNotFound)) as err_info: - self.as_connection.index_string_create(ns_name, "demo", "name", "name_index", policy) + self.as_connection.index_string_create(ns_name, "demo", "name", aerospike.INDEX_STRING, "name_index", policy) err_code = err_info.value.code if (TestBaseClass.major_ver, TestBaseClass.minor_ver) >= (7, 2): @@ -262,7 +262,7 @@ def test_create_string_index_with_incorrect_namespace(self): policy = {} with pytest.raises(e.NamespaceNotFound) as err_info: - self.as_connection.index_string_create("fake_namespace", "demo", "name", "name_index", policy) + self.as_connection.index_string_create("fake_namespace", "demo", "name", aerospike.INDEX_STRING, "name_index", policy) err_code = err_info.value.code assert err_code is AerospikeStatus.AEROSPIKE_ERR_NAMESPACE_NOT_FOUND @@ -272,7 +272,7 @@ def test_create_string_index_with_incorrect_set(self): Invoke create string index() with incorrect set """ policy = {} - retobj = self.as_connection.index_string_create("test", "demo1", "name", "name_index", policy) + retobj = self.as_connection.index_string_create("test", "demo1", "name", aerospike.INDEX_STRING, "name_index", policy) self.as_connection.index_remove("test", "name_index", policy) ensure_dropped_index(self.as_connection, "test", "name_index") @@ -283,7 +283,7 @@ def test_create_string_index_with_incorrect_bin(self): Invoke create string index() with incorrect bin """ policy = {} - retobj = self.as_connection.index_string_create("test", "demo", "name1", "name_index", policy) + retobj = self.as_connection.index_string_create("test", "demo", "name1", aerospike.INDEX_STRING, "name_index", policy) self.as_connection.index_remove("test", "name_index", policy) ensure_dropped_index(self.as_connection, "test", "name_index") @@ -295,7 +295,7 @@ def test_create_string_index_with_namespace_is_none(self): """ policy = {} with pytest.raises(e.ParamError) as err_info: - self.as_connection.index_string_create(None, "demo", "name", "name_index", policy) + self.as_connection.index_string_create(None, "demo", "name", aerospike.INDEX_STRING, "name_index", policy) err_code = err_info.value.code assert err_code is AerospikeStatus.AEROSPIKE_ERR_PARAM @@ -303,7 +303,7 @@ def test_create_string_index_with_namespace_is_none(self): def test_create_string_index_with_set_is_none(self): # Invoke create string index() with set is None policy = {} - retobj = self.as_connection.index_string_create("test", None, "name", "name_index", policy) + retobj = self.as_connection.index_string_create("test", None, "name", aerospike.INDEX_STRING, "name_index", policy) self.as_connection.index_remove("test", "name_index", policy) ensure_dropped_index(self.as_connection, "test", "name_index") @@ -315,7 +315,7 @@ def test_create_string_index_with_bin_is_none(self): """ policy = {} with pytest.raises(e.ParamError) as err_info: - self.as_connection.index_string_create("test", "demo", None, "name_index", policy) + self.as_connection.index_string_create("test", "demo", None, aerospike.INDEX_STRING, "name_index", policy) err_code = err_info.value.code assert err_code is AerospikeStatus.AEROSPIKE_ERR_PARAM @@ -326,7 +326,7 @@ def test_create_string_index_with_index_is_none(self): """ policy = {} with pytest.raises(e.ParamError) as err_info: - self.as_connection.index_string_create("test", "demo", "name", None, policy) + self.as_connection.index_string_create("test", "demo", "name", aerospike.INDEX_STRING, None, policy) err_code = err_info.value.code assert err_code is AerospikeStatus.AEROSPIKE_ERR_PARAM @@ -336,10 +336,10 @@ def test_create_same_string_index_multiple_times(self): Invoke create string index() with multiple times on same bin """ policy = {} - retobj = self.as_connection.index_string_create("test", "demo", "name", "name_index", policy) + retobj = self.as_connection.index_string_create("test", "demo", "name", aerospike.INDEX_STRING, "name_index", policy) assert retobj == AerospikeStatus.AEROSPIKE_OK try: - retobj = self.as_connection.index_string_create("test", "demo", "name", "name_index", policy) + retobj = self.as_connection.index_string_create("test", "demo", "name", aerospike.INDEX_STRING, "name_index", policy) except e.IndexFoundError: assert self.server_version <= [6, 0] @@ -351,11 +351,11 @@ def test_create_same_string_index_multiple_times_different_bin(self): Invoke create string index() with multiple times on different bin """ policy = {} - retobj = self.as_connection.index_string_create("test", "demo", "name", "name_index", policy) + retobj = self.as_connection.index_string_create("test", "demo", "name", aerospike.INDEX_STRING, "name_index", policy) assert retobj == AerospikeStatus.AEROSPIKE_OK with pytest.raises(e.IndexFoundError): - retobj = self.as_connection.index_string_create("test", "demo", "addr", "name_index", policy) + retobj = self.as_connection.index_string_create("test", "demo", "addr", aerospike.INDEX_STRING, "name_index", policy) self.as_connection.index_remove("test", "name_index", policy) ensure_dropped_index(self.as_connection, "test", "name_index") @@ -370,10 +370,10 @@ def test_create_different_string_index_multiple_times_same_bin(self): bin with different name """ policy = {} - retobj = self.as_connection.index_string_create("test", "demo", "name", "name_index", policy) + retobj = self.as_connection.index_string_create("test", "demo", "name", aerospike.INDEX_STRING, "name_index", policy) assert retobj == AerospikeStatus.AEROSPIKE_OK try: - retobj = self.as_connection.index_string_create("test", "demo", "name", "name_index1", policy) + retobj = self.as_connection.index_string_create("test", "demo", "name", aerospike.INDEX_STRING, "name_index1", policy) self.as_connection.index_remove("test", "name_index1", policy) except e.IndexFoundError: assert self.server_version <= [6, 0] @@ -385,7 +385,7 @@ def test_create_string_index_with_policy(self): Invoke create string index() with policy """ policy = {"timeout": 180000} - retobj = self.as_connection.index_string_create("test", "demo", "name", "name_index", policy) + retobj = self.as_connection.index_string_create("test", "demo", "name", aerospike.INDEX_STRING, "name_index", policy) assert retobj == AerospikeStatus.AEROSPIKE_OK self.as_connection.index_remove("test", "name_index", policy) @@ -406,7 +406,7 @@ def test_drop_valid_index(self): Invoke drop valid index() """ policy = {} - self.as_connection.index_integer_create("test", "demo", "age", "age_index", policy) + self.as_connection.index_single_value_create("test", "demo", "age", aerospike.INDEX_NUMERIC, "age_index", policy) retobj = self.as_connection.index_remove("test", "age_index", policy) ensure_dropped_index(self.as_connection, "test", "age_index") assert retobj == AerospikeStatus.AEROSPIKE_OK @@ -416,7 +416,7 @@ def test_drop_valid_index_policy(self): Invoke drop valid index() policy """ policy = {"timeout": 180000} - self.as_connection.index_integer_create("test", "demo", "age", "age_index", policy) + self.as_connection.index_single_value_create("test", "demo", "age", aerospike.INDEX_NUMERIC, "age_index", policy) retobj = self.as_connection.index_remove("test", "age_index", policy) ensure_dropped_index(self.as_connection, "test", "age_index") assert retobj == AerospikeStatus.AEROSPIKE_OK @@ -425,14 +425,14 @@ def test_createindex_with_long_index_name(self): # Invoke createindex() with long index name policy = {} with pytest.raises(e.InvalidRequest): - self.as_connection.index_integer_create("test", "demo", "age", "index" * 100, policy) + self.as_connection.index_single_value_create("test", "demo", "age", aerospike.INDEX_NUMERIC, "index" * 100, policy) def test_create_string_index_unicode_positive(self): """ Invoke create string index() with correct arguments """ policy = {} - retobj = self.as_connection.index_string_create("test", "demo", "name", "uni_name_index", policy) + retobj = self.as_connection.index_string_create("test", "demo", "name", aerospike.INDEX_STRING, "uni_name_index", policy) self.as_connection.index_remove("test", "uni_name_index", policy) ensure_dropped_index(self.as_connection, "test", "uni_name_index") @@ -443,7 +443,7 @@ def test_createindex_integer_unicode(self): Invoke createindex() with correct arguments """ policy = {} - retobj = self.as_connection.index_integer_create("test", "demo", "age", "uni_age_index", policy) + retobj = self.as_connection.index_single_value_create("test", "demo", "age", aerospike.INDEX_NUMERIC, "uni_age_index", policy) assert retobj == AerospikeStatus.AEROSPIKE_OK self.as_connection.index_remove("test", "uni_age_index", policy) @@ -457,7 +457,7 @@ def test_createindex_with_correct_parameters_without_connection(self): client1.close() with pytest.raises(e.ClusterError) as err_info: - client1.index_integer_create("test", "demo", "age", "age_index", policy) + client1.index_single_value_create("test", "demo", "age", aerospike.INDEX_NUMERIC, "age_index", policy) err_code = err_info.value.code assert err_code is AerospikeStatus.AEROSPIKE_CLUSTER_ERROR diff --git a/test/new_tests/test_index_deprecated.py b/test/new_tests/test_index_deprecated.py new file mode 100644 index 0000000000..f5f3a73077 --- /dev/null +++ b/test/new_tests/test_index_deprecated.py @@ -0,0 +1,29 @@ +import pytest +import aerospike +from aerospike import exception as e +import warnings + +INDEX_NAME = "deprecated_index" + +@pytest.mark.usefixtures("as_connection") +class TestDeprecatedIndexCreationMethods: + @pytest.fixture(autouse=True) + def setup(self): + yield + self.as_connection.index_remove("test", INDEX_NAME) + + @pytest.mark.parametrize( + "index_create_method", + [ + aerospike.Client.index_blob_create, + aerospike.Client.index_integer_create, + aerospike.Client.index_string_create, + aerospike.Client.index_geo2dsphere_create, + ] + ) + def test_deprecated_index_creation_methods(self, index_create_method): + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter(action="always", category=DeprecationWarning) + with pytest.raises(e.ParamError): + index_create_method(self.as_connection, 1, "demo", "bin_name", INDEX_NAME) + assert len(w) == 1 diff --git a/test/new_tests/test_kv.py b/test/new_tests/test_kv.py index 3a5bc1fd52..f1acf78a3c 100644 --- a/test/new_tests/test_kv.py +++ b/test/new_tests/test_kv.py @@ -1,5 +1,6 @@ import pytest from aerospike import exception as e +import aerospike def get_key_with_digest_only(key): @@ -200,7 +201,7 @@ def count_records_false(tuple): rec = {"name": "name%s" % (str(i)), "addr": "name%s" % (str(i)), "age": i, "no": i} self.as_connection.put(key, rec) - self.as_connection.index_integer_create("test", "unittest", "age", "age_index", {}) + self.as_connection.index_single_value_create("test", "unittest", "age", aerospike.INDEX_NUMERIC, "age_index", {}) query = self.as_connection.query("test", "unittest") diff --git a/test/new_tests/test_mapkeys_index.py b/test/new_tests/test_mapkeys_index.py index 3d1bc4147e..d280779a92 100644 --- a/test/new_tests/test_mapkeys_index.py +++ b/test/new_tests/test_mapkeys_index.py @@ -52,7 +52,7 @@ def test_mapkeysindex_with_extra_paramters(self): policy = {} with pytest.raises(TypeError): self.as_connection.index_map_keys_create( - "test", "demo", "string_map", aerospike.INDEX_STRING, "test_string_map_index", policy, 1 + "test", "demo", "string_map", aerospike.INDEX_STRING, "test_string_map_index", policy, None, 1 ) def test_mapkeysindex_with_correct_parameters(self): diff --git a/test/new_tests/test_query.py b/test/new_tests/test_query.py index c65cbada91..6c6f6cc7fa 100644 --- a/test/new_tests/test_query.py +++ b/test/new_tests/test_query.py @@ -66,17 +66,17 @@ class TestQuery(TestBaseClass): @pytest.fixture(autouse=True, scope="class") def setupClass(self, as_connection): try: - as_connection.index_integer_create("test", "demo", "test_age", "age_index") + as_connection.index_single_value_create("test", "demo", "test_age", aerospike.INDEX_NUMERIC, "age_index") except e.IndexFoundError: pass try: - as_connection.index_string_create("test", "demo", "addr", "addr_index") + as_connection.index_string_create("test", "demo", "addr", aerospike.INDEX_STRING, "addr_index") except e.IndexFoundError: pass try: - as_connection.index_integer_create("test", "demo", "age1", "age_index1") + as_connection.index_single_value_create("test", "demo", "age1", aerospike.INDEX_NUMERIC, "age_index1") except e.IndexFoundError: pass @@ -115,12 +115,12 @@ def setupClass(self, as_connection): pass try: - as_connection.index_integer_create("test", None, "test_age_none", "age_index_none") + as_connection.index_single_value_create("test", None, "test_age_none", aerospike.INDEX_NUMERIC, "age_index_none") except e.IndexFoundError: pass try: - as_connection.index_integer_create("test", "demo", bytearray("sal\0kj", "utf-8"), "sal_index") + as_connection.index_single_value_create("test", "demo", bytearray("sal\0kj", "utf-8"), aerospike.INDEX_NUMERIC, "sal_index") except e.IndexFoundError: pass @@ -144,26 +144,26 @@ def setupClass(self, as_connection): pass try: - as_connection.index_cdt_create( + as_connection.index_single_value_create( "test", "demo", "numeric_list", - aerospike.INDEX_TYPE_DEFAULT, aerospike.INDEX_NUMERIC, "numeric_list_cdt_index", + None, ctx_list_index, ) except e.IndexFoundError: pass try: - as_connection.index_cdt_create( + as_connection.index_single_value_create( "test", "demo", "numeric_map", - aerospike.INDEX_TYPE_DEFAULT, aerospike.INDEX_NUMERIC, "numeric_map_cdt_index", + None, ctx_map_index, ) except e.IndexFoundError: @@ -1129,7 +1129,7 @@ def test_query_blob_bin_equal(self): if (TestBaseClass.major_ver, TestBaseClass.minor_ver) < (7, 0): pytest.skip("Blob indexes are only supported in server 7.0+") - self.as_connection.index_blob_create("test", "demo", "blob", "blob_index") + self.as_connection.index_single_value_create("test", "demo", "blob", aerospike.INDEX_BLOB, "blob_index") query = self.as_connection.query("test", "demo") blob_val = int.to_bytes(4, length=1, byteorder='big') diff --git a/test/new_tests/test_query_apply.py b/test/new_tests/test_query_apply.py index dc3ded8cbe..305e52e4c4 100644 --- a/test/new_tests/test_query_apply.py +++ b/test/new_tests/test_query_apply.py @@ -13,12 +13,12 @@ def add_indexes_to_client(client): try: - client.index_integer_create("test", "demo", "age", "test_demo_age_idx") + client.index_single_value_create("test", "demo", "age", aerospike.INDEX_NUMERIC, "test_demo_age_idx") except e.IndexFoundError: pass try: - client.index_integer_create("test", None, "age", "test_null_age_idx") + client.index_single_value_create("test", None, "age", aerospike.INDEX_NUMERIC, "test_null_age_idx") except e.IndexFoundError: pass diff --git a/test/new_tests/test_query_execute_background.py b/test/new_tests/test_query_execute_background.py index 9aa30f5a71..07b167ca54 100644 --- a/test/new_tests/test_query_execute_background.py +++ b/test/new_tests/test_query_execute_background.py @@ -20,7 +20,7 @@ def add_indexes_to_client(client): try: - client.index_integer_create(TEST_NS, TEST_SET, "number", "test_background_number_idx") + client.index_single_value_create(TEST_NS, TEST_SET, "number", aerospike.INDEX_NUMERIC, "test_background_number_idx") except exception.IndexFoundError: pass diff --git a/test/new_tests/test_query_partition.py b/test/new_tests/test_query_partition.py index 05a5ffbe9a..a721fb8858 100644 --- a/test/new_tests/test_query_partition.py +++ b/test/new_tests/test_query_partition.py @@ -17,7 +17,7 @@ def add_sindex(client): Load the sindex used in the tests """ try: - client.index_string_create("test", "demo", "s", "string") + client.index_string_create("test", "demo", "s", aerospike.INDEX_STRING, "string") except e.IndexFoundError: pass