From c5d0c63051ce7506bd57cb3c138716d4a0046244 Mon Sep 17 00:00:00 2001 From: Dominic Pelini <111786059+DomPeliniAerospike@users.noreply.github.com> Date: Wed, 1 Nov 2023 10:49:34 -0600 Subject: [PATCH] Added maps.create method CLIENT-2617 Added maps.create method Added persitIndex as a parameter --- lib/maps.js | 26 ++++++++++++++++++++++++++ src/main/map_operations.cc | 27 +++++++++++++++++++++++++-- test/maps.js | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 2 deletions(-) diff --git a/lib/maps.js b/lib/maps.js index 0b9c40987..8c6c52e7a 100644 --- a/lib/maps.js +++ b/lib/maps.js @@ -1275,3 +1275,29 @@ exports.getByRankRange = function (bin, rank, count, returnType) { op.returnType = returnType return op } + +/** + * @summary Retrieves one or more items in the specified rank range from the + * map. + * + * @description This operation returns the data specified by + * returnType. + * + * @param {string} bin - The name of the bin, which must contain a Map value. + * @param {number} index - Starting rank. + * @param {number} count - Number of items to delete; if not specified, the + * range includes all items starting from rank. + * @param {number} [returnType] - The {@link module:aerospike/maps.returnType|return type} + * indicating what data of the selected item(s) to return. + * @returns {Object} Operation that can be passed to the {@link Client#operate} command. + * + * @see Instead of passing returnType, you can also use + * {@link module:aerospike/maps~MapOperation#andReturn|MapOperation#andReturn} to + * select what data to return. + */ +exports.create = function (bin, order, persistIndex=false) { + const op = new MapOperation(opcodes.MAP_CREATE, bin) + op.order = order + op.persistIndex = persistIndex + return op +} diff --git a/src/main/map_operations.cc b/src/main/map_operations.cc index ab244d5a9..afc51f6da 100644 --- a/src/main/map_operations.cc +++ b/src/main/map_operations.cc @@ -1027,6 +1027,28 @@ bool add_map_get_by_rank_range_op(as_operations *ops, const char *bin, return true; } +bool add_map_create_op(as_operations *ops, const char *bin, + as_cdt_ctx *context, Local obj, + LogInfo *log) +{ + as_map_order order; + if (get_uint32_property((uint32_t*)&order, obj, "order", log) != AS_NODE_PARAM_OK) { + return false; + } + + bool persist_index; + if (get_bool_property(&persist_index, obj, "persistIndex", log) != AS_NODE_PARAM_OK) { + return false; + } + + + as_v8_debug(log, "order=%i, persist_index=%s", order, persist_index ? "true" : "false"); + as_operations_map_create_all(ops, bin, context, order, persist_index); + + + return true; +} + typedef bool (*MapOperation)(as_operations *ops, const char *bin, as_cdt_ctx *context, Local op, LogInfo *log); @@ -1069,7 +1091,8 @@ const ops_table_entry ops_table[] = { {"MAP_GET_BY_INDEX", add_map_get_by_index_op}, {"MAP_GET_BY_INDEX_RANGE", add_map_get_by_index_range_op}, {"MAP_GET_BY_RANK", add_map_get_by_rank_op}, - {"MAP_GET_BY_RANK_RANGE", add_map_get_by_rank_range_op}}; + {"MAP_GET_BY_RANK_RANGE", add_map_get_by_rank_range_op}, + {"MAP_CREATE", add_map_create_op}}; int add_map_op(as_operations *ops, uint32_t opcode, Local op, LogInfo *log) @@ -1120,4 +1143,4 @@ Local map_opcode_values() } return scope.Escape(obj); -} +} \ No newline at end of file diff --git a/test/maps.js b/test/maps.js index 2455db4eb..f1891a6d9 100644 --- a/test/maps.js +++ b/test/maps.js @@ -21,7 +21,11 @@ const Aerospike = require('../lib/aerospike') const helper = require('./test_helper') +const { Buffer } = require('node:buffer'); + + const maps = Aerospike.maps +const op = Aerospike.operations const Context = Aerospike.cdt.Context const status = Aerospike.status @@ -62,6 +66,36 @@ describe('client.operate() - CDT Map operations', function () { }) }) + describe('maps.create', function () { + it('Creates a new map', function () { + return initState() + .then(createRecord({ map: { c: 1, b: 2, a: 3 } })) + .then(orderByKey('map')) + .then(operate(maps.create('emptyMap', maps.order.KEY_ORDERED))) + .then(operate(op.read('dap'))) + .then(assertRecordEql({emptyMap: {}, map: {a: 3, b: 2, c: 1}})) + .then(cleanup()) + }) + + it('Creates a new map from a cdt context', function () { + return initState() + .then(createRecord({ map: { c: 1, b: 2, a: 3 } })) + .then(orderByKey('map')) + .then(operate(maps.create('map', maps.order.KEY_ORDERED).withContext(ctx => ctx.addMapKeyCreate('nested')))) + .then(assertRecordEql({map: {a: 3, b: 2, c: 1, nested: {}}})) + .then(cleanup()) + }) + + it('Creates a new map with persistent index', function () { + return initState() + .then(createRecord({ map: { c: 1, b: 2, a: 3 } })) + .then(orderByKey('map')) + .then(operate(maps.create('emptyMap', maps.order.KEY_ORDERED, true))) + .then(assertRecordEql({ emptyMap: {}, map: {a: 3, b: 2, c: 1}})) + .then(cleanup()) + }) + }) + describe('maps.put', function () { it('adds the item to the map and returns the size of the map', function () { return initState()