├── .husky ├── .gitignore └── pre-commit ├── examples ├── .npmignore ├── lua │ ├── sample.lua │ ├── monte_carlo.lua │ └── scan.lua ├── shared │ ├── streams.js │ ├── random.js │ ├── run.js │ ├── cli.js │ ├── index.js │ └── client.js ├── example_config │ └── config.yml ├── package.json ├── typescript.ts ├── remove.js ├── exists.js ├── add.js ├── append.js ├── get.js ├── operate.js ├── apply.js ├── connect.js ├── udf.js ├── batch.js ├── dynamicConfig.js ├── mrtAbort.js ├── mrtCommit.js └── put_test.js ├── benchmarks ├── .npmignore ├── package.json ├── logging.js └── config.json ├── .mocharc.yml ├── lua.sha256 ├── .github ├── workflows │ ├── requirements.txt │ ├── config.conf.template │ ├── releasebundle-filespec.json │ ├── docker-build-context │ │ ├── roster.smd │ │ └── security.smd │ ├── master-bump-version.js │ ├── Dockerfile │ ├── stage-bump-version.js │ ├── stage-tests.yml │ ├── dev-bump-version.js │ ├── fast-forward-merge.yml │ ├── dev-workflow.yml │ ├── stage-workflow.yml │ ├── stage-get-jfrog-version.yml │ ├── master-get-jfrog-version.yml │ ├── master-verify-npm-install.yml │ ├── get-jfrog-stage-version.yml │ ├── dev-build-node-cpp-addons.yml │ └── dev-test-install-script.yaml ├── actions │ ├── update-version │ │ └── action.yml │ ├── setup-docker-on-macos │ │ └── action.yml │ ├── wait-for-as-server-to-start │ │ └── action.yml │ └── run-ee-server-for-ext-container │ │ └── action.yml ├── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md └── dependabot.yml ├── libyaml.sha256 ├── lua.ini ├── test ├── util │ ├── index.js │ └── sleep.js ├── generators │ ├── metadata.js │ ├── util.js │ ├── record.js │ └── key.js ├── udf.lua ├── README.md ├── command.js ├── bigint.js ├── remove_bin.js ├── double.js ├── aerospike.js └── stats.js ├── openssl-native.sha256 ├── libyaml.ini ├── openssl-native.ini ├── ts-test ├── .npmignore ├── tests │ ├── util │ │ ├── sleep.ts │ │ └── index.ts │ ├── dyn_config.yml │ ├── dyn_config_edit.yml │ ├── dyn_config_send_key_true.yml │ ├── dyn_config_metrics_disabled.yml │ ├── dyn_config_permissions.yml │ ├── generators │ │ ├── metadata.ts │ │ ├── record.ts │ │ └── key.ts │ ├── bigint.ts │ ├── README.md │ ├── udf.lua │ ├── types │ │ └── generators.types.ts │ ├── command.js │ ├── remove_bin.ts │ ├── double.ts │ ├── config_pki.ts │ └── aerospike.ts ├── tsconfig.json ├── scripts │ └── three_node.sh └── package.json ├── aerospike-client-c.sha256 ├── aerospike-client-c.ini ├── .gitmodules ├── .jfrog └── projects │ └── npm.yaml ├── scripts ├── build_apidocs ├── watch_tests ├── check-install-script-results.js ├── build-package.sh-cclient-output.log ├── change-install-command.js ├── wait-for-node.sh ├── validate-c-client.sh ├── build-c-client.sh ├── verify-aerospike-npm-scripts.js ├── basic_test.js └── build-package.sh ├── .editorconfig ├── docker └── README.md ├── .gitignore ├── lib ├── features.js ├── txn_capacity.js ├── txn_state.js ├── commands │ ├── connect_command.js │ ├── write_record_command.js │ ├── read_record_command.js │ ├── batch_command.js │ ├── stream_command.js │ ├── exists_command.js │ └── query_background_command.js ├── abort_status.js ├── metrics_listeners.js ├── privilege.js ├── user.js ├── role.js ├── commit_status.js ├── bigint.js ├── policies │ ├── metrics_policy.js │ ├── admin_policy.js │ ├── hll_policy.js │ ├── bitwise_policy.js │ ├── list_policy.js │ └── info_policy.js ├── admin.js ├── utils.js ├── batch_type.js └── bin.js ├── tsconfig.json ├── src ├── include │ ├── expressions.h │ ├── config.h │ ├── events.h │ ├── scan.h │ ├── query.h │ ├── enums.h │ └── transaction.h └── main │ ├── enums │ ├── scanPriority.cc │ ├── udf_languages.cc │ ├── predicates.cc │ ├── exp_read_flags.cc │ ├── txn_capacity.cc │ ├── job_status.cc │ ├── query_duration.cc │ ├── ttl.cc │ ├── txn_state.cc │ ├── batch_type.cc │ ├── abort_status.cc │ ├── exp_write_flags.cc │ ├── commit_status.cc │ ├── index.cc │ ├── privilege_code.cc │ └── config_enum.cc │ └── commands │ ├── disable_metrics.cc │ ├── transaction_abort.cc │ └── transaction_commit.cc ├── jsdoc.json └── Makefile /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /examples/.npmignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /benchmarks/.npmignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /.mocharc.yml: -------------------------------------------------------------------------------- 1 | require: 2 | - choma 3 | - mocha-clean 4 | -------------------------------------------------------------------------------- /lua.sha256: -------------------------------------------------------------------------------- 1 | D8D6B5CCA02B3E11C38DD9A4373CAC62E968C35DFAD750C7CDDD88EAA9223034 lua.5.4.6.zip 2 | -------------------------------------------------------------------------------- /.github/workflows/requirements.txt: -------------------------------------------------------------------------------- 1 | parver==0.5 2 | crudini==0.9.4 3 | delocate==0.10.4 4 | mypy==1.10.0 5 | -------------------------------------------------------------------------------- /libyaml.sha256: -------------------------------------------------------------------------------- 1 | DA3A142BD072B0FFEBA67FE0C178D152EF8276A6469D6F80D6FE497C905C48EC libyaml.0.2.5.12.zip 2 | -------------------------------------------------------------------------------- /lua.ini: -------------------------------------------------------------------------------- 1 | 2 | # Version number of the dependencies package for C client (Windows only) 3 | LUA_VERSION=5.4.6 4 | -------------------------------------------------------------------------------- /test/util/index.js: -------------------------------------------------------------------------------- 1 | const sleep = require('./sleep') 2 | module.exports = exports = { 3 | ...sleep 4 | } 5 | -------------------------------------------------------------------------------- /openssl-native.sha256: -------------------------------------------------------------------------------- 1 | DA3A142BD072B0FFEBA67FE0C178D152EF8276A6469D6F80D6FE497C905C48EC openssl-native.3.0.16.zip 2 | -------------------------------------------------------------------------------- /libyaml.ini: -------------------------------------------------------------------------------- 1 | 2 | # Version number of the dependencies package for C client (Windows only) 3 | LIBYAML_VERSION=0.2.5.12 4 | -------------------------------------------------------------------------------- /openssl-native.ini: -------------------------------------------------------------------------------- 1 | 2 | # Version number of the dependencies package for C client (Windows only) 3 | OPENSSL_VERSION=3.0.16 4 | -------------------------------------------------------------------------------- /ts-test/.npmignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | metrics-* 4 | metrics_sub_dir/metrics-* 5 | metrics_sub_dir/*/* 6 | features.conf -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npm test -- --invert --fgrep "#slow" --reporter progress 5 | -------------------------------------------------------------------------------- /test/util/sleep.js: -------------------------------------------------------------------------------- 1 | exports.sleep = function sleep (ms) { 2 | return new Promise((resolve) => setTimeout(resolve, ms)) 3 | } 4 | -------------------------------------------------------------------------------- /aerospike-client-c.sha256: -------------------------------------------------------------------------------- 1 | 4804B9B02688FEEE73C95ACAE87DCC839831155EE1E101B5126E7CD317644CFB aerospike-client-c-dependencies.1.0.3.zip 2 | -------------------------------------------------------------------------------- /ts-test/tests/util/sleep.ts: -------------------------------------------------------------------------------- 1 | export function sleep (ms: number) { 2 | return new Promise((resolve) => setTimeout(resolve, ms)) 3 | } 4 | -------------------------------------------------------------------------------- /aerospike-client-c.ini: -------------------------------------------------------------------------------- 1 | 2 | # Version number of the dependencies package for C client (Windows only) 3 | AEROSPIKE_C_DEPS_VERSION=1.0.3 4 | -------------------------------------------------------------------------------- /.github/workflows/config.conf.template: -------------------------------------------------------------------------------- 1 | [community-edition] 2 | hosts: 127.0.0.1:3000 3 | 4 | [enterprise-edition] 5 | hosts : 6 | user : 7 | password : 8 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "aerospike-client-c"] 2 | path = aerospike-client-c 3 | url = https://github.com/aerospike/aerospike-client-c.git 4 | branch = master 5 | -------------------------------------------------------------------------------- /ts-test/tests/util/index.ts: -------------------------------------------------------------------------------- 1 | export * from './options'; 2 | export * from './run_in_new_process'; 3 | export * from './sleep' 4 | export * from './statefulAsyncTest' -------------------------------------------------------------------------------- /.github/workflows/releasebundle-filespec.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | { 4 | "includeDeps": "false", 5 | "project": "clients" 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /ts-test/tests/dyn_config.yml: -------------------------------------------------------------------------------- 1 | metadata: 2 | app_name: configurationExample 3 | generation: 2 4 | version: 0.0.1 5 | 6 | dynamic: 7 | write: 8 | send_key: false -------------------------------------------------------------------------------- /ts-test/tests/dyn_config_edit.yml: -------------------------------------------------------------------------------- 1 | metadata: 2 | app_name: configurationExample 3 | generation: 2 4 | version: 0.0.1 5 | 6 | dynamic: 7 | write: 8 | send_key: true -------------------------------------------------------------------------------- /examples/lua/sample.lua: -------------------------------------------------------------------------------- 1 | function greet() 2 | return "Hello World!" 3 | end 4 | 5 | function greet_name(rec, name) 6 | return "Hello " .. tostring(name) .. "!" 7 | end 8 | -------------------------------------------------------------------------------- /ts-test/tests/dyn_config_send_key_true.yml: -------------------------------------------------------------------------------- 1 | metadata: 2 | app_name: configurationExample 3 | generation: 2 4 | version: 0.0.1 5 | 6 | dynamic: 7 | write: 8 | send_key: true -------------------------------------------------------------------------------- /examples/shared/streams.js: -------------------------------------------------------------------------------- 1 | exports.consume = function (stream) { 2 | return new Promise(function (resolve, reject) { 3 | stream.on('error', reject) 4 | stream.on('end', resolve) 5 | }) 6 | } 7 | -------------------------------------------------------------------------------- /.jfrog/projects/npm.yaml: -------------------------------------------------------------------------------- 1 | version: 1 2 | type: npm 3 | resolver: 4 | repo: clients-npm-dev-local 5 | serverId: Default-Server 6 | deployer: 7 | repo: clients-npm-dev-local 8 | serverId: Default-Server 9 | -------------------------------------------------------------------------------- /examples/lua/monte_carlo.lua: -------------------------------------------------------------------------------- 1 | local function one(rec) 2 | return 1 3 | end 4 | 5 | local function add(a, b) 6 | return a + b 7 | end 8 | 9 | function count(stream) 10 | return stream : map(one) : reduce(add) 11 | end 12 | -------------------------------------------------------------------------------- /examples/lua/scan.lua: -------------------------------------------------------------------------------- 1 | function increment(rec, bin, amount) 2 | bin = bin or 'i'; 3 | amount = amount or 1; 4 | trace("Incrementing bin '%s' by %i", bin, amount); 5 | rec[bin] = rec[bin] + amount; 6 | aerospike:update(rec); 7 | end 8 | -------------------------------------------------------------------------------- /ts-test/tests/dyn_config_metrics_disabled.yml: -------------------------------------------------------------------------------- 1 | metadata: 2 | app_name: configurationExample 3 | generation: 2 4 | version: 0.0.1 5 | dynamic: 6 | metrics: 7 | enable: false 8 | static: 9 | client: 10 | config_interval: 1000 -------------------------------------------------------------------------------- /ts-test/tests/dyn_config_permissions.yml: -------------------------------------------------------------------------------- 1 | metadata: 2 | app_name: configurationExample 3 | generation: 2 4 | version: 0.0.1 5 | 6 | static: 7 | client: 8 | config_interval: 2000 9 | dynamic: 10 | write: 11 | send_key: false -------------------------------------------------------------------------------- /.github/workflows/docker-build-context/roster.smd: -------------------------------------------------------------------------------- 1 | [ 2 | [ 3 | 97107025374203, 4 | 1 5 | ], 6 | { 7 | "key": "test", 8 | "value": "a1", 9 | "generation": 1, 10 | "timestamp": 465602976982 11 | } 12 | ] -------------------------------------------------------------------------------- /scripts/build_apidocs: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | BUILD_DIR=./build 3 | APIDOCS_DIR=$BUILD_DIR/apidocs 4 | APIDOCS_ARCHIVE=aerospike-client-nodejs-apidocs.zip 5 | 6 | rm -rf $APIDOCS_DIR $BUILD_DIR/$APIDOCS_ARCHIVE 7 | npm run apidocs 8 | (cd $APIDOCS_DIR; zip -r ../$APIDOCS_ARCHIVE .) 9 | -------------------------------------------------------------------------------- /examples/example_config/config.yml: -------------------------------------------------------------------------------- 1 | metadata: 2 | app_name: configurationExample 3 | generation: 2 4 | version: 0.0.1 5 | static: 6 | client: 7 | config_interval: 2 8 | dynamic: 9 | write: 10 | send_key: false 11 | static: 12 | client: 13 | config_interval: 1 -------------------------------------------------------------------------------- /scripts/watch_tests: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Watch for changes to tests and re-run then. 3 | if [ ! -x "$(command -v fswatch)" ]; then 4 | echo "Please install fswatch to use this script. On Mac OS, you can install it via Homebrew." 5 | exit -1 6 | fi 7 | echo "Watching test dir for changes..." 8 | fswatch test/*.js | xargs -n 1 mocha 9 | -------------------------------------------------------------------------------- /.github/workflows/master-bump-version.js: -------------------------------------------------------------------------------- 1 | const semver = require('semver') 2 | 3 | const currentVersion = process.argv[2] 4 | 5 | const version = semver.parse(currentVersion) 6 | 7 | if (!version) { 8 | console.error('Invalid version string') 9 | process.exit(1) 10 | } 11 | 12 | version.prerelease = []; 13 | console.log(version.format()) -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | charset = utf-8 6 | trim_trailing_whitespace = true 7 | 8 | [{lib,test,examples,benchmarks}/**.js] 9 | indent_style = space 10 | indent_size = 2 11 | 12 | [src/**.{h,cc}] 13 | indent_style = tab 14 | indent_size = tab 15 | 16 | [Makefile] 17 | indent_style = tab 18 | indent_size = tab -------------------------------------------------------------------------------- /ts-test/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "commonjs", 5 | "outDir": "./dist", 6 | "strict": true, 7 | "esModuleInterop": true, 8 | "skipLibCheck": true, 9 | "forceConsistentCasingInFileNames": true 10 | }, 11 | "include": ["tests/**/*.ts", "tests/*.ts", "tests/util/*.ts"] 12 | } -------------------------------------------------------------------------------- /scripts/check-install-script-results.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs' 2 | 3 | const folder = './lib/binding' 4 | 5 | const count = fs.readdirSync(folder, { withFileTypes: true }) 6 | .filter(dirent => dirent.isDirectory()).length 7 | 8 | if (count !== 3) { 9 | throw new Error(`Expected 3 subfolders, found ${count}`) 10 | } 11 | 12 | console.log('Exactly 3 subfolders found') 13 | -------------------------------------------------------------------------------- /docker/README.md: -------------------------------------------------------------------------------- 1 | # Docker Examples 2 | 3 | The docker files that were previously located in this directory have been moved to 4 | the [Nodejs-Client-Examples](https://github.com/aerospike-examples/nodejs-client-examples) directory. 5 | 6 | Files in this directory are not intended for production use, but rather to demonstrate the steps 7 | necessary to install and build the client on various systems. -------------------------------------------------------------------------------- /.github/actions/update-version/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Update version' 2 | description: 'Update version in repo without committing. Repo must already be checked out' 3 | inputs: 4 | new_version: 5 | description: Version string to set 6 | required: true 7 | 8 | runs: 9 | using: "composite" 10 | steps: 11 | - name: Update VERSION metadata 12 | run: npm version ${{ inputs.new_version }} --no-git-tag-version 13 | shell: bash 14 | -------------------------------------------------------------------------------- /examples/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aerospike-client-examples", 3 | "description": "Aerospike Client Library Examples", 4 | "license": "Apache-2.0", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/aerospike/aerospike-client-nodejs" 8 | }, 9 | "engines": { 10 | "node": ">=8" 11 | }, 12 | "main": "run.js", 13 | "dependencies": { 14 | "aerospike": "file:..", 15 | "yargs": "^18.0.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.github/actions/setup-docker-on-macos/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Install Docker on macOS runner' 2 | description: 'Install Docker using colima' 3 | 4 | runs: 5 | using: "composite" 6 | steps: 7 | - name: Install Docker Engine 8 | run: brew install colima 9 | shell: bash 10 | 11 | - name: Install Docker client 12 | run: brew install docker 13 | shell: bash 14 | 15 | - name: Start Docker Engine 16 | run: colima start 17 | shell: bash 18 | -------------------------------------------------------------------------------- /examples/shared/random.js: -------------------------------------------------------------------------------- 1 | const crypto = require('crypto') 2 | 3 | exports.identifier = function () { 4 | return crypto.randomBytes(10).toString('hex') 5 | } 6 | 7 | exports.int = function (min, max) { 8 | min = Math.ceil(min) 9 | max = Math.floor(max) + 1 // range inclusive maximum 10 | return min + Math.floor(Math.random() * (max - min)) 11 | } 12 | 13 | exports.float = function (min, max) { 14 | return min + Math.random() * (max - min) 15 | } 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .nyc_output/ 3 | .vscode/ 4 | lib/binding 5 | .idea/ 6 | build/ 7 | node_modules/ 8 | coverage/ 9 | npm-debug.log 10 | test.log 11 | aerospike-*.tgz 12 | scripts/build-c-client.sh-output.txt 13 | libuv* 14 | docs* 15 | ts-test/dist 16 | ts-test/metrics-* 17 | ts-test/metrics_sub_dir/metrics-* 18 | ts-test/node_modules/ 19 | ts-test/metrics_sub_dir/*/* 20 | ts-test/features.conf 21 | scripts/build-c-client.sh-cclient-output.log 22 | tsconfig.tsbuildinfo -------------------------------------------------------------------------------- /.github/workflows/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG image 2 | FROM $image 3 | RUN echo -e "security {\n\tenable-quotas true\n}\n" >> /etc/aerospike/aerospike.template.conf 4 | # security.smd was generated manually by 5 | # 1. Starting a new Aerospike EE server using Docker 6 | # 2. Creating the superuser user 7 | # 3. Copying /opt/aerospike/smd/security.smd from the container and committing it to this repo 8 | # This file should always work 9 | # TODO: generate this automatically, somehow 10 | COPY security.smd /opt/aerospike/smd/ 11 | -------------------------------------------------------------------------------- /scripts/build-package.sh-cclient-output.log: -------------------------------------------------------------------------------- 1 | project/modules.mk:16: *************************************************************** 2 | project/modules.mk:17: * 3 | project/modules.mk:18: * COMMON is '/home/dpelini/Documents/MRT/aerospike-client-nodejs/aerospike-client-c/modules/common' 4 | project/modules.mk:19: * COMMON doesn't contain 'Makefile'. 5 | project/modules.mk:20: * COMMON should be set to a valid path. 6 | project/modules.mk:21: * 7 | project/modules.mk:22: *************************************************************** 8 | project/modules.mk:23: *** . Stop. 9 | -------------------------------------------------------------------------------- /scripts/change-install-command.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | 3 | // Path to package.json 4 | const packageJsonPath = './package.json' 5 | 6 | // Read and parse package.json 7 | const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')) 8 | 9 | // Update the install script 10 | packageJson.scripts.install = 'npm-run-all removeExtraBinaries build' 11 | 12 | // Write the updated package.json back 13 | fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2), 'utf8') 14 | 15 | console.log('Updated the install script in package.json successfully.') 16 | -------------------------------------------------------------------------------- /.github/workflows/stage-bump-version.js: -------------------------------------------------------------------------------- 1 | const semver = require('semver') 2 | 3 | const rawVersion = process.argv[2] 4 | 5 | const rawDevVersion = process.argv[3] 6 | 7 | const version = semver.parse(rawVersion) 8 | 9 | const devVersion = semver.parse(rawDevVersion) 10 | 11 | 12 | if (!version || !devVersion) { 13 | console.error('Invalid version string') 14 | process.exit(1) 15 | } 16 | 17 | if (semver.gt(devVersion, version)) { 18 | devVersion.prerelease = ['rc', 1]; 19 | console.log(devVersion.format()) 20 | } 21 | else{ 22 | version.inc('prerelease', 'rc') 23 | console.log(version.format()) 24 | } -------------------------------------------------------------------------------- /examples/typescript.ts: -------------------------------------------------------------------------------- 1 | import * as Aerospike from 'aerospike'; 2 | 3 | (async function () { 4 | let client = null; 5 | try { 6 | client = await Aerospike.connect(); 7 | const key = new Aerospike.Key('test', 'test', 'abcd'); 8 | const bins = { 9 | name: 'Norma', 10 | age: 31 11 | }; 12 | 13 | await client.put(key, bins); 14 | const record = await client.get(key); 15 | console.info('Record:', record); 16 | await client.remove(key); 17 | } catch (error) { 18 | console.error('Error:', error); 19 | process.exit(1); 20 | } finally { 21 | if (client) client.close(); 22 | } 23 | })(); 24 | -------------------------------------------------------------------------------- /ts-test/scripts/three_node.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | set -x 5 | 6 | # Setup a cluster with RF=3 and 3 nodes in individual racks 7 | aerolab cluster create --count=3 --start=n -i=22.04 -f features.conf 8 | 9 | # Configure rack ids for each node 10 | aerolab conf rackid --nodes=1 --id=1 --no-restart 11 | aerolab conf rackid --nodes=2 --id=2 --no-restart 12 | aerolab conf rackid --nodes=3 --id=3 --no-restart 13 | 14 | # Set RF = 3 for all nodes 15 | aerolab attach shell -l all -- sed -i "s/replication-factor 2/replication-factor 3/" /etc/aerospike/aerospike.conf 16 | 17 | # restart 18 | aerolab aerospike restart 19 | 20 | # Get ip address of seed node 21 | echo SEED_IP=$(aerolab cluster list -j | jq ".[0].IpAddress" | tr -d \") 22 | -------------------------------------------------------------------------------- /benchmarks/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aerospike-benchmark", 3 | "version": "v0.1.0", 4 | "description": "Aerospike Client Benchmark", 5 | "keywords": [ 6 | "aerospike", 7 | "database", 8 | "nosql", 9 | "benchmark" 10 | ], 11 | "license": "Apache-2.0", 12 | "engines": { 13 | "node": ">=4" 14 | }, 15 | "os": [ 16 | "linux", 17 | "darwin" 18 | ], 19 | "cpu": [ 20 | "x64" 21 | ], 22 | "repository": { 23 | "type": "git", 24 | "url": "https://github.com/aerospike/aerospike-client-nodejs" 25 | }, 26 | "dependencies": { 27 | "aerospike": "file:..", 28 | "cli-table": "^0.3.11", 29 | "winston": "^3.5.1", 30 | "yargs": "^16.2.0" 31 | }, 32 | "main": "main.js" 33 | } 34 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. Please include the following: 21 | * The Aerospike client version 22 | * The Aerospike server version 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior. Please provide as much of the following as you can. 15 | 1. code that demonstrates the behavior 16 | 2. error messages and stacktrace if available 17 | 3. any relevant Aerospike log entries if available 18 | 19 | **Expected behavior** 20 | A clear and concise description of what you expected to happen. 21 | 22 | **Versions and Environment (please complete the following information):** 23 | - Client application OS 24 | - Aerospike Client Version 25 | - Aerospike Database Version 26 | 27 | **Additional context** 28 | Add any other context about the problem here. 29 | -------------------------------------------------------------------------------- /lib/features.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2019-2023 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | exports.CDT_MAP = 'cdt-map' 18 | exports.CDT_LIST = 'cdt-list' 19 | exports.BLOB_BITS = 'blob-bits' 20 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["typings/index.d.ts"], 3 | "compilerOptions": { 4 | /* Visit https://aka.ms/tsconfig.json to read more about this file */ 5 | "strict": true, 6 | "module": "commonjs", 7 | "moduleResolution": "node", 8 | "target": "es5", 9 | "lib": [ 10 | "es5", 11 | "dom" 12 | ], 13 | "allowJs": true, 14 | "declaration": true, 15 | "emitDeclarationOnly": true, 16 | "removeComments": true, 17 | "alwaysStrict": true, 18 | "pretty": false, 19 | "incremental": true, 20 | "noEmitHelpers": true, 21 | "importHelpers": true, 22 | "esModuleInterop": true, 23 | "experimentalDecorators": true, 24 | "emitDecoratorMetadata": true, 25 | "noImplicitAny": false, 26 | "resolveJsonModule": true, 27 | "isolatedModules": false, 28 | "skipLibCheck": true, 29 | "baseUrl": ".", 30 | "paths": { 31 | "*": ["typings/*"] 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ts-test/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ts-test", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "directories": { 6 | "test": "tests" 7 | }, 8 | "scripts": { 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "author": "", 12 | "license": "ISC", 13 | "description": "", 14 | "dependencies": { 15 | "@types/tmp": "^0.2.6", 16 | "aerospike": "file:..", 17 | "dockerode": "^4.0.9", 18 | "mocha": "^11.1.0", 19 | "p-throttle": "^8.1.0", 20 | "tmp": "^0.2.4", 21 | "typescript": "^5.9.3" 22 | }, 23 | "devDependencies": { 24 | "@types/chai": "^5.2.3", 25 | "@types/jest": "^30.0.0", 26 | "@types/mocha": "^10.0.10", 27 | "@types/semver": "^7.7.1", 28 | "@types/tmp": "^0.2.6", 29 | "@types/yargs": "^17.0.35", 30 | "mocha": "^10.7.3", 31 | "ts-node": "^10.9.2", 32 | "typedoc": "^0.28.15", 33 | "typescript": "^5.9.3" 34 | }, 35 | "overrides": { 36 | "@gerrit0/mini-shiki": "<=3.18.0", 37 | "glob": ">=11.1.0" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ts-test/tests/generators/metadata.ts: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2013-2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | // 20 | // Returns a static record. 21 | // 22 | export function constant (metadata: any): () => any { 23 | return function (): any { 24 | return metadata 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/txn_capacity.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the 'License') 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an 'AS IS' BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | const as = require('bindings')('aerospike.node') 20 | const capacity = as.txnCapacity 21 | 22 | module.exports = { 23 | READ_DEFAULT: capacity.READ_DEFAULT, 24 | WRITE_DEFAULT: capacity.WRITE_DEFAULT 25 | } 26 | -------------------------------------------------------------------------------- /test/generators/metadata.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2013-2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | // 20 | // Returns a static record. 21 | // 22 | function constant (metadata) { 23 | return function () { 24 | return metadata 25 | } 26 | } 27 | 28 | module.exports = { 29 | constant 30 | } 31 | -------------------------------------------------------------------------------- /lib/txn_state.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the 'License') 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an 'AS IS' BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | const as = require('bindings')('aerospike.node') 20 | const state = as.txnState 21 | 22 | module.exports = { 23 | OK: state.OPEN, 24 | VERIFIED: state.VERIFIED, 25 | COMMITTED: state.COMMITTED, 26 | ABORTED: state.ABORTED 27 | } 28 | -------------------------------------------------------------------------------- /src/include/expressions.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2021-2023 Aerospike, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | extern "C" { 22 | #include 23 | } 24 | 25 | v8::Local exp_opcode_values(); 26 | int compile_expression(v8::Local exp_ary, as_exp **filter_exp, 27 | const LogInfo *log); 28 | -------------------------------------------------------------------------------- /lib/commands/connect_command.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2013-2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | const Command = require('./command') 20 | 21 | module.exports = asCommand => class ConnectCommand extends Command(asCommand) { 22 | constructor (client, callback) { 23 | super(client, [], callback) 24 | this.ensureConnected = false 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/include/config.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013-2023 Aerospike, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include "log.h" 21 | #include "client.h" 22 | 23 | extern "C" { 24 | #include 25 | } 26 | 27 | int config_from_jsobject(as_config *config, v8::Local obj, AerospikeClient *client, 28 | const LogInfo *log); 29 | -------------------------------------------------------------------------------- /src/include/events.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright 2013-2023 Aerospike, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include "log.h" 22 | 23 | extern "C" { 24 | #include 25 | } 26 | 27 | void events_callback_init(as_config *config, v8::Local callback, 28 | LogInfo *log); 29 | void events_callback_close(as_config *config); 30 | -------------------------------------------------------------------------------- /src/main/enums/scanPriority.cc: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013-2023 Aerospike, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #include 18 | #include 19 | 20 | extern "C" { 21 | #include 22 | } 23 | 24 | using namespace v8; 25 | 26 | #define set(__obj, __name, __value) \ 27 | Nan::Set(__obj, Nan::New(__name).ToLocalChecked(), Nan::New(__value)) 28 | -------------------------------------------------------------------------------- /test/generators/util.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2013-2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | function range (end, start) { 20 | start = start || 0 21 | end = end || start + 1 22 | let i, j 23 | const a = Array(end - start + 1) 24 | for (i = 0, j = start; j < end; i++, j++) { 25 | a[i] = j 26 | } 27 | return a 28 | } 29 | 30 | module.exports = { 31 | range 32 | } 33 | -------------------------------------------------------------------------------- /lib/abort_status.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the 'License') 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an 'AS IS' BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | const as = require('bindings')('aerospike.node') 20 | const abortStatus = as.abortStatus 21 | 22 | module.exports = { 23 | OK: abortStatus.OK, 24 | ALREADY_ABORTED: abortStatus.ALREADY_ABORTED, 25 | ROLL_BACK_ABANDONED: abortStatus.ROLL_BACK_ABANDONED, 26 | CLOSE_ABANDONED: abortStatus.CLOSE_ABANDONED 27 | } 28 | -------------------------------------------------------------------------------- /benchmarks/logging.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2013-2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | const { createLogger, format, transports } = require('winston') 18 | 19 | exports.logger = createLogger({ 20 | format: format.combine( 21 | format.splat(), 22 | format.simple() 23 | ), 24 | transports: [ 25 | new transports.Console({ 26 | level: 'info', 27 | silent: false, 28 | colorize: true 29 | }) 30 | ] 31 | }) 32 | -------------------------------------------------------------------------------- /examples/shared/run.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2018-2023 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | const shared = require('./') 18 | 19 | module.exports = function (handler) { 20 | return async function (argv) { 21 | const client = shared.client(argv) 22 | try { 23 | await client.connect() 24 | await handler(client, argv) 25 | } catch (error) { 26 | console.error(error) 27 | } 28 | client.close() 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /lib/metrics_listeners.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2025 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | class MetricsListeners { 20 | constructor (options) { 21 | this.enableListener = options.enableListener 22 | this.snapshotListener = options.snapshotListener 23 | this.nodeCloseListener = options.nodeCloseListener 24 | this.disableListener = options.disableListener 25 | } 26 | } 27 | 28 | module.exports = MetricsListeners 29 | -------------------------------------------------------------------------------- /lib/privilege.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2023 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | /** 20 | * @class Privilege 21 | * 22 | * @summary User privileges including a permission code, namespace, and set. 23 | * 24 | */ 25 | function Privilege (code, options) { 26 | options = options || {} 27 | this.code = code 28 | this.namespace = options.namespace || '' 29 | this.set = options.set || '' 30 | } 31 | 32 | module.exports = Privilege 33 | -------------------------------------------------------------------------------- /lib/user.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2023 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | /** 20 | * @class User 21 | * 22 | * @summary Contains user roles and other user related information 23 | * 24 | */ 25 | function User (options) { 26 | this.connsInUse = options.connsInUse 27 | this.name = options.name 28 | this.readInfo = options.readInfo 29 | this.writeInfo = options.writeInfo 30 | this.roles = options.roles 31 | } 32 | 33 | module.exports = User 34 | -------------------------------------------------------------------------------- /lib/commands/write_record_command.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2013-2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | const Command = require('./command') 20 | 21 | module.exports = asCommand => class WriteRecordCommand extends Command(asCommand) { 22 | constructor (client, key, args, callback) { 23 | args = [key].concat(args) 24 | super(client, args, callback) 25 | this.key = key 26 | } 27 | 28 | convertResult () { 29 | return this.key 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /scripts/wait-for-node.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | ################################################################################ 3 | # Copyright 2013-2023 Aerospike, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | ################################################################################ 17 | 18 | LOG=$1 19 | if [ ! -f $LOG ]; then 20 | echo "A log file does not exist at $LOG" 21 | exit 1 22 | fi 23 | 24 | i=0 25 | while [ $i -le 12 ] 26 | do 27 | sleep 1 28 | grep -i "there will be cake" $LOG 29 | if [ $? == 0 ]; then 30 | exit 0 31 | else 32 | i=$(($i + 1)) 33 | echo -n "." 34 | fi 35 | done 36 | echo "the cake is a lie!" 37 | tail -n 1000 $LOG 38 | exit 2 -------------------------------------------------------------------------------- /lib/role.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2023 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | /** 20 | * @class Role 21 | * 22 | * @summary Contains user roles and other user related information 23 | * 24 | */ 25 | function Role (options) { 26 | this.name = options.name 27 | this.readQuota = options.readQuota 28 | this.writeQuota = options.writeQuota 29 | this.whitelist = options.whitelist 30 | this.privileges = options.privileges 31 | } 32 | 33 | module.exports = Role 34 | -------------------------------------------------------------------------------- /.github/workflows/docker-build-context/security.smd: -------------------------------------------------------------------------------- 1 | [ 2 | [ 3 | 162276881999406, 4 | 14 5 | ], 6 | { 7 | "key": "admin|P", 8 | "value": "$2a$10$7EqJtq98hPqEX7fNZaFWoO1mVO/4MLpGzsqojz6E9Gef6iXDjXdDa", 9 | "generation": 1, 10 | "timestamp": 0 11 | }, 12 | { 13 | "key": "admin|R|user-admin", 14 | "value": "", 15 | "generation": 1, 16 | "timestamp": 0 17 | }, 18 | { 19 | "key": "superuser|P", 20 | "value": "$2a$10$7EqJtq98hPqEX7fNZaFWoOZX0o4mZCBUwvzt/iecIcG4JaDOC41zK", 21 | "generation": 3, 22 | "timestamp": 458774922440 23 | }, 24 | { 25 | "key": "superuser|R|read-write-udf", 26 | "value": "", 27 | "generation": 3, 28 | "timestamp": 458774922441 29 | }, 30 | { 31 | "key": "superuser|R|sys-admin", 32 | "value": "", 33 | "generation": 3, 34 | "timestamp": 458774922442 35 | }, 36 | { 37 | "key": "superuser|R|user-admin", 38 | "value": "", 39 | "generation": 3, 40 | "timestamp": 458774922442 41 | }, 42 | { 43 | "key": "superuser|R|data-admin", 44 | "value": null, 45 | "generation": 2, 46 | "timestamp": 458774718056 47 | } 48 | ] 49 | -------------------------------------------------------------------------------- /benchmarks/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "host" : "bob-cluster-a", 3 | "port" : 3000, 4 | "timeout" : 0, 5 | "totalTimeout" : 0, 6 | "ttl" : 10000, 7 | "log" : "INFO", 8 | "namespace" : "test", 9 | "set" : "demo", 10 | "user" : "generic_client", 11 | "password" : "generic_client", 12 | "json" : false, 13 | "silent" : false, 14 | "longevity" : false, 15 | "alert" : "CONSOLE", 16 | "filename" : null, 17 | "operations" : 10, 18 | "iterations" : null, 19 | "processes" : 4, 20 | "time" : "1h", 21 | "reads" : 1, 22 | "writes" : 1, 23 | "keyRange" : { 24 | "min" : 0, 25 | "max" : 100000 26 | }, 27 | "binSpec" : [ 28 | { 29 | "name" : "bin1", 30 | "type" : "STRING", 31 | "size" : 1024 32 | }, 33 | { 34 | "name" : "bin2", 35 | "type" : "BYTES", 36 | "size" : 1024 37 | }, 38 | { 39 | "name" : "bin3", 40 | "type" : "INTEGER" 41 | } 42 | ], 43 | "promises" : true, 44 | "summary" : true 45 | } 46 | -------------------------------------------------------------------------------- /src/main/enums/udf_languages.cc: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013-2023 Aerospike, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #include 18 | #include 19 | 20 | using namespace v8; 21 | 22 | #define set(__obj, __name, __value) \ 23 | Nan::Set(__obj, Nan::New(__name).ToLocalChecked(), Nan::New(__value)) 24 | 25 | Local languages() 26 | { 27 | Nan::EscapableHandleScope scope; 28 | Local obj = Nan::New(); 29 | set(obj, "LUA", 0); 30 | return scope.Escape(obj); 31 | } 32 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # Set update schedule for GitHub Actions and npm dependencies 2 | 3 | version: 2 4 | updates: 5 | 6 | # GitHub Actions security updates 7 | - package-ecosystem: "github-actions" 8 | directory: "/" 9 | schedule: 10 | # Check for updates to GitHub Actions every weekday 11 | interval: "daily" 12 | cooldown: 13 | default-days: 2 14 | target-branch: "dev" 15 | 16 | # Main npm dependencies 17 | - package-ecosystem: "npm" 18 | directory: "/" 19 | schedule: 20 | interval: "weekly" 21 | target-branch: "dev" 22 | open-pull-requests-limit: 10 23 | 24 | # Examples npm dependencies 25 | - package-ecosystem: "npm" 26 | directory: "/examples" 27 | schedule: 28 | interval: "weekly" 29 | target-branch: "dev" 30 | open-pull-requests-limit: 5 31 | 32 | # Benchmarks npm dependencies 33 | - package-ecosystem: "npm" 34 | directory: "/benchmarks" 35 | schedule: 36 | interval: "weekly" 37 | target-branch: "dev" 38 | open-pull-requests-limit: 5 39 | 40 | # TypeScript test npm dependencies 41 | - package-ecosystem: "npm" 42 | directory: "/ts-test" 43 | schedule: 44 | interval: "weekly" 45 | target-branch: "dev" 46 | open-pull-requests-limit: 5 47 | -------------------------------------------------------------------------------- /examples/remove.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // ***************************************************************************** 3 | // Copyright 2013-2024 Aerospike, Inc. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License") 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ***************************************************************************** 17 | 18 | const Aerospike = require('aerospike') 19 | const shared = require('./shared') 20 | 21 | shared.runner() 22 | 23 | async function remove (client, argv) { 24 | const key = new Aerospike.Key(argv.namespace, argv.set, argv.key) 25 | await client.remove(key) 26 | console.info('Removed record:', key) 27 | } 28 | 29 | exports.command = 'remove ' 30 | exports.describe = 'Remove a record from the database' 31 | exports.handler = shared.run(remove) 32 | -------------------------------------------------------------------------------- /lib/commit_status.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the 'License') 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an 'AS IS' BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | const as = require('bindings')('aerospike.node') 20 | const commitStatus = as.commitStatus 21 | 22 | module.exports = { 23 | OK: commitStatus.OK, 24 | ALREADY_COMMITTED: commitStatus.ALREADY_COMMITTED, 25 | VERIFY_FAILED: commitStatus.VERIFY_FAILED, 26 | MARK_ROLL_FORWARD_ABANDONED: commitStatus.MARK_ROLL_FORWARD_ABANDONED, 27 | ROLL_FORWARD_ABANDONED: commitStatus.ROLL_FORWARD_ABANDONED, 28 | CLOSE_ABANDONED: commitStatus.CLOSE_ABANDONED 29 | } 30 | -------------------------------------------------------------------------------- /lib/commands/read_record_command.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2013-2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | const Command = require('./command') 20 | const Record = require('../record') 21 | 22 | module.exports = asCommand => class ReadRecordCommand extends Command(asCommand) { 23 | constructor (client, key, args, callback) { 24 | args = [key].concat(args) 25 | super(client, args, callback) 26 | this.key = key 27 | } 28 | 29 | convertResult (bins, metadata) { 30 | return new Record(this.key, bins, metadata) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lib/bigint.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2013-2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | // keep eslint happy 20 | const BigInt = global.BigInt || (() => {}) 21 | const MIN_INT64 = BigInt(-2) ** BigInt(63) 22 | const MAX_INT64 = BigInt(2) ** BigInt(63) - BigInt(1) 23 | 24 | exports.BigInt = global.BigInt || 25 | (() => { throw new Error('BigInt not supported on this version of Node.js') }) 26 | exports.bigIntSupported = !!global.BigInt 27 | 28 | exports.isInt64 = function (value) { 29 | return MIN_INT64 <= BigInt(value) && BigInt(value) <= MAX_INT64 30 | } 31 | -------------------------------------------------------------------------------- /ts-test/tests/bigint.ts: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2013-2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | /* eslint-env mocha */ 20 | /* global expect */ 21 | 22 | 23 | import * as helper from './test_helper'; 24 | 25 | import { expect } from 'chai'; 26 | 27 | describe('bigint', function () { 28 | context('BigInt supported - Node.js 10 and later', function () { 29 | describe('BigInt', function () { 30 | it('is an alias for the built-in BigInt', function () { 31 | expect(BigInt(42)).to.eq(global.BigInt(42)) 32 | }) 33 | }) 34 | }) 35 | }) 36 | -------------------------------------------------------------------------------- /scripts/validate-c-client.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ################################################################################ 3 | # Copyright 2013-2023 Aerospike, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | ################################################################################ 17 | 18 | 19 | ################################################################################ 20 | # 21 | # This script is used by bindings.gyp, to detect if libaerospike.a is 22 | # installed and exporting the proper environment variables. 23 | # 24 | ################################################################################ 25 | 26 | CWD=$(pwd) 27 | SCRIPT_DIR=$(dirname $0) 28 | BASE_DIR=$(cd "${SCRIPT_DIR}/.."; pwd) 29 | 30 | . ${SCRIPT_DIR}/build-commands.sh 31 | 32 | perform_check 33 | -------------------------------------------------------------------------------- /.github/actions/wait-for-as-server-to-start/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Wait for Aerospike server to start' 2 | description: Only tested on Linux and macOS 3 | inputs: 4 | container-name: 5 | required: true 6 | is-security-enabled: 7 | required: false 8 | default: 'false' 9 | is-strong-consistency-enabled: 10 | required: false 11 | default: 'false' 12 | 13 | runs: 14 | using: "composite" 15 | steps: 16 | - name: 'macOS: install timeout command' 17 | if: ${{ runner.os == 'macOS' }} 18 | run: brew install coreutils 19 | shell: bash 20 | 21 | # Composite actions doesn't support step-level timeout-minutes 22 | # Use timeout command and store polling logic in file to make it easier to read 23 | # Call bash shell explicitly since timeout uses "sh" shell by default, for some reason 24 | # Also, we don't want to fail if we timeout in case the server *did* finish starting up but the script couldn't detect it due to a bug 25 | # Effectively, this composite action is like calling "sleep" that is optimized to exit early when it detects an ok from the server 26 | - name: Wait for EE server to start 27 | run: timeout 30 bash ./.github/workflows/wait-for-as-server-to-start.bash ${{ inputs.container-name }} ${{ inputs.is-security-enabled }} ${{ inputs.is-strong-consistency-enabled }} || true 28 | shell: bash 29 | -------------------------------------------------------------------------------- /scripts/build-c-client.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ################################################################################ 3 | # Copyright 2013-2023 Aerospike, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | ################################################################################ 17 | 18 | 19 | ################################################################################ 20 | # 21 | # This script is used to build dependancy c-client sub-module. 22 | # 23 | ################################################################################ 24 | 25 | CWD=$(pwd) 26 | SCRIPT_DIR=$(dirname $0) 27 | BASE_DIR=$(cd "${SCRIPT_DIR}/.."; pwd) 28 | 29 | . ${SCRIPT_DIR}/build-commands.sh 30 | 31 | download_libuv 32 | rebuild_libuv 33 | 34 | rebuild_c_client 35 | 36 | perform_check 37 | 38 | cd ${CWD} 39 | -------------------------------------------------------------------------------- /test/generators/record.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2013-2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | // 20 | // Returns a static record. 21 | // 22 | function constant (bins) { 23 | return function () { 24 | return bins 25 | } 26 | } 27 | 28 | // 29 | // Returns a record from bins spec'd using generators record. 30 | // 31 | function record (bins) { 32 | return function () { 33 | const out = {} 34 | for (const bin in bins) { 35 | out[bin] = bins[bin]() 36 | } 37 | return out 38 | } 39 | } 40 | 41 | module.exports = { 42 | constant, 43 | record 44 | } 45 | -------------------------------------------------------------------------------- /lib/policies/metrics_policy.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2025 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | class MetricsPolicy { 20 | constructor (props) { 21 | props = props || {} 22 | 23 | this.metricsListeners = props.metricsListeners 24 | 25 | this.reportDir = props.reportDir 26 | 27 | this.reportSizeLimit = props.reportSizeLimit 28 | 29 | this.interval = props.interval 30 | 31 | this.latencyColumns = props.latencyColumns 32 | 33 | this.latencyShift = props.latencyShift 34 | 35 | this.labels = props.labels 36 | } 37 | } 38 | 39 | module.exports = MetricsPolicy 40 | -------------------------------------------------------------------------------- /examples/exists.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // ***************************************************************************** 3 | // Copyright 2013-2024 Aerospike, Inc. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License") 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ***************************************************************************** 17 | 18 | const Aerospike = require('aerospike') 19 | const shared = require('./shared') 20 | 21 | shared.runner() 22 | 23 | async function exists (client, argv) { 24 | const key = new Aerospike.Key(argv.namespace, argv.set, argv.key) 25 | const exists = await client.exists(key) 26 | console.info('Key: ', key) 27 | console.info('Record exists: ', exists) 28 | } 29 | 30 | exports.command = 'exists ' 31 | exports.describe = 'Test whether a record exists in the database' 32 | exports.handler = shared.run(exists) 33 | -------------------------------------------------------------------------------- /examples/add.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // ***************************************************************************** 3 | // Copyright 2013-2024 Aerospike, Inc. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License") 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ***************************************************************************** 17 | 18 | const Aerospike = require('aerospike') 19 | const shared = require('./shared') 20 | 21 | shared.runner() 22 | 23 | async function add (client, argv) { 24 | const key = new Aerospike.Key(argv.namespace, argv.set, argv.key) 25 | const bins = shared.cli.parseBins(argv.bins) 26 | await client.add(key, bins) 27 | console.info('Record updated successfully:', key) 28 | } 29 | 30 | exports.command = 'add ' 31 | exports.describe = 'Add one or more values to existing bin(s)' 32 | exports.handler = shared.run(add) 33 | -------------------------------------------------------------------------------- /test/udf.lua: -------------------------------------------------------------------------------- 1 | function withArguments(rec, value) 2 | return value 3 | end 4 | 5 | function withoutArguments(rec) 6 | return 1 7 | end 8 | 9 | function noop(rec) 10 | end 11 | 12 | 13 | function createRecord(rec, binName, binValue) 14 | rec[binName] = binValue 15 | if (aerospike:exists(rec)) then 16 | status = aerospike:update(rec) 17 | else 18 | status = aerospike:create(rec) 19 | end 20 | return status 21 | end 22 | 23 | function updateRecord(rec, binName, binValue) 24 | rec[binName] = binValue 25 | aerospike:update(rec) 26 | return rec 27 | end 28 | 29 | function count(stream) 30 | local function mapper(rec) 31 | return 1 32 | end 33 | local function reducer(v1, v2) 34 | return v1 + v2 35 | end 36 | return stream : map(mapper) : reduce(reducer) 37 | end 38 | 39 | function countGreaterThan(stream, binName, value) 40 | local function mapper(rec) 41 | if rec[binName] > value then 42 | return 1 43 | else 44 | return 0 45 | end 46 | end 47 | local function reducer(v1, v2) 48 | return v1 + v2 49 | end 50 | return stream : map(mapper) : reduce(reducer) 51 | end 52 | 53 | function even(stream, bin) 54 | local function filt(rec) 55 | return rec.value % 2 == 0 56 | end 57 | local function mapper(rec) 58 | return rec.value 59 | end 60 | return stream : filter(filt) : map(mapper) 61 | end 62 | -------------------------------------------------------------------------------- /.github/workflows/stage-tests.yml: -------------------------------------------------------------------------------- 1 | name: Stage Tests 2 | run-name: Stage tests (run_tests=${{ inputs.run_tests }}, use-server-rc=${{ inputs.use-server-rc }}, server-tag=${{ inputs.server-tag }}) 3 | 4 | on: 5 | workflow_call: 6 | inputs: 7 | run_tests: 8 | required: false 9 | type: boolean 10 | default: false 11 | version: 12 | type: string 13 | description: Build version 14 | required: true 15 | server-tag: 16 | type: string 17 | required: false 18 | default: '8.1.0.0-rc5' 19 | secrets: 20 | soup_hat: 21 | required: true 22 | cell_girl: 23 | required: true 24 | song_loss: 25 | required: true 26 | 27 | jobs: 28 | comprehensive-tests: 29 | strategy: 30 | matrix: 31 | platform-tag: [ 32 | "manylinux_x86_64", 33 | "manylinux_aarch64", 34 | "macosx_x86_64", 35 | #"macosx_x86_64_2", 36 | "macosx_arm64", 37 | #"macosx_arm64_2", 38 | "win_amd64" 39 | ] 40 | fail-fast: false 41 | uses: ./.github/workflows/stage-comprehensive-tests.yml 42 | with: 43 | platform-tag: ${{ matrix.platform-tag }} 44 | run_tests: ${{ inputs.run_tests }} 45 | server-tag: ${{ inputs.server-tag }} 46 | version: ${{ inputs.version }} 47 | secrets: inherit 48 | -------------------------------------------------------------------------------- /examples/append.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // ***************************************************************************** 3 | // Copyright 2013-2024 Aerospike, Inc. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License") 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ***************************************************************************** 17 | 18 | const Aerospike = require('aerospike') 19 | const shared = require('./shared') 20 | 21 | shared.runner() 22 | 23 | async function append (client, argv) { 24 | const key = new Aerospike.Key(argv.namespace, argv.set, argv.key) 25 | const bins = shared.cli.parseBins(argv.bins) 26 | await client.append(key, bins) 27 | console.info('Record updated successfully:', key) 28 | } 29 | 30 | exports.command = 'append ' 31 | exports.describe = 'Append one or more values to existing bin(s)' 32 | exports.handler = shared.run(append) 33 | -------------------------------------------------------------------------------- /scripts/verify-aerospike-npm-scripts.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | const { execSync } = require('child_process') 3 | 4 | const [pkg] = process.argv.slice(2) 5 | 6 | if (!pkg) { 7 | console.error('Usage: node check-npm-script.js ') 8 | process.exit(1) 9 | } 10 | 11 | let preInstallScript = null 12 | let installScript = null 13 | let postInstallScript = null 14 | 15 | try { 16 | preInstallScript = execSync(`npm view ${pkg} scripts.preinstall`, { encoding: 'utf8' }).trim() 17 | installScript = execSync(`npm view ${pkg} scripts.install`, { encoding: 'utf8' }).trim() 18 | postInstallScript = execSync(`npm view ${pkg} scripts.postinstall`, { encoding: 'utf8' }).trim() 19 | console.log(postInstallScript) 20 | } catch (err) { 21 | console.error(`Failed to fetch scripts for ${pkg}:`, err.message) 22 | process.exit(1) 23 | } 24 | 25 | if (preInstallScript !== 'npm install @mapbox/node-pre-gyp') { 26 | console.error('❌ preinstall script does not match expected value') 27 | process.exit(1) 28 | } 29 | 30 | if (installScript !== 'npm-run-all removeExtraBinaries build') { 31 | console.error('❌ install script does not match expected value') 32 | process.exit(1) 33 | } 34 | 35 | if (postInstallScript !== '') { 36 | console.error('❌ postinstall script does not match expected value') 37 | process.exit(1) 38 | } 39 | 40 | console.log('✅ install scripts match expected value') 41 | -------------------------------------------------------------------------------- /src/main/enums/predicates.cc: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013-2023 Aerospike, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #include 18 | #include 19 | 20 | extern "C" { 21 | #include 22 | } 23 | 24 | using namespace v8; 25 | 26 | #define set(__obj, __name, __value) \ 27 | Nan::Set(__obj, Nan::New(__name).ToLocalChecked(), Nan::New(__value)) 28 | 29 | Local predicates() 30 | { 31 | Nan::EscapableHandleScope scope; 32 | Local obj = Nan::New(); 33 | set(obj, "EQUAL", AS_PREDICATE_EQUAL); 34 | set(obj, "RANGE", AS_PREDICATE_RANGE); 35 | return scope.Escape(obj); 36 | } 37 | -------------------------------------------------------------------------------- /.github/workflows/dev-bump-version.js: -------------------------------------------------------------------------------- 1 | const semver = require('semver') 2 | 3 | const currentVersionString = process.argv[2] 4 | const currentJfrogVersion = process.argv[3] 5 | 6 | const version = semver.parse(currentVersionString) 7 | const jfrogVersion = semver.parse(currentJfrogVersion) 8 | 9 | if (!version || !jfrogVersion) { 10 | console.error('Invalid version string') 11 | process.exit(1) 12 | } 13 | 14 | if(version.major === jfrogVersion.major && 15 | version.minor === jfrogVersion.minor && 16 | version.patch === jfrogVersion.patch){ 17 | if(jfrogVersion.prerelease){ 18 | jfrogVersion.inc('prerelease', 'dev') 19 | console.log(jfrogVersion.format()) 20 | 21 | } 22 | else{ 23 | version.prerelease = ['dev', 1]; 24 | console.log(version.format()) 25 | } 26 | } 27 | else if(version.major > jfrogVersion.major || 28 | version.minor > jfrogVersion.minor || 29 | version.patch > jfrogVersion.patch){ 30 | //console.log("Current package version higher than current JFrog version.") 31 | version.prerelease = ['dev', 1]; 32 | console.log(version.format()) 33 | } 34 | else if(version.major < jfrogVersion.major || 35 | version.minor < jfrogVersion.minor || 36 | version.patch < jfrogVersion.patch){ 37 | //console.log("Current JFrog version higher than current package version.") 38 | jfrogVersion.inc('prerelease', 'dev') 39 | console.log(jfrogVersion.format()) 40 | 41 | } -------------------------------------------------------------------------------- /src/main/enums/exp_read_flags.cc: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2023 Aerospike, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #include 18 | #include 19 | 20 | extern "C" { 21 | #include 22 | } 23 | 24 | using namespace v8; 25 | 26 | #define set(__obj, __name, __value) \ 27 | Nan::Set(__obj, Nan::New(__name).ToLocalChecked(), Nan::New(__value)) 28 | 29 | Local expReadFlags() 30 | { 31 | Nan::EscapableHandleScope scope; 32 | Local obj = Nan::New(); 33 | set(obj, "DEFAULT", AS_EXP_READ_DEFAULT); 34 | set(obj, "EVAL_NO_FAIL", AS_EXP_READ_EVAL_NO_FAIL); 35 | 36 | return scope.Escape(obj); 37 | } -------------------------------------------------------------------------------- /test/README.md: -------------------------------------------------------------------------------- 1 | # Testing Aerospike Node.js Client 2 | 3 | ## Installation 4 | 5 | We also recommend installing Aerospike dependencies by running the following 6 | from the module's root directory: 7 | 8 | $ npm update 9 | 10 | This will install all required dependencies. 11 | 12 | ## Usage 13 | 14 | To run the test cases: 15 | 16 | $ npm test 17 | 18 | The tests are written and run using [`mocha`](http://visionmedia.github.io/mocha). 19 | You can choose to use `mocha` directly, but you must first install `mocha`: 20 | 21 | $ npm install -g mocha 22 | 23 | Note: some users may need to run this as sudo. 24 | 25 | Then to run the tests via mocha, you will want to run it from the modules' root 26 | directory: 27 | 28 | $ mocha -R spec 29 | 30 | ## Options 31 | 32 | You can modify the test with various options: 33 | 34 | --help Display this message. 35 | --host, -h Aerospike database address. [default: "127.0.0.1"] 36 | --port, -p Aerospike database port. [default: 3000] 37 | --timeout, -t Timeout in milliseconds. [default: 10] 38 | --log, -l Log level [0-5] [default: 2] 39 | --namespace, -n Namespace for the keys. [default: "test"] 40 | --set, -s Set for the keys. [default: "demo"] 41 | 42 | Options can be set via an environment variable `OPTIONS`: 43 | 44 | $ OPTIONS="--port 3010" npm test 45 | -------------------------------------------------------------------------------- /ts-test/tests/README.md: -------------------------------------------------------------------------------- 1 | # Testing Aerospike Node.js Client 2 | 3 | ## Installation 4 | 5 | We also recommend installing Aerospike dependencies by running the following 6 | from the module's root directory: 7 | 8 | $ npm update 9 | 10 | This will install all required dependencies. 11 | 12 | ## Usage 13 | 14 | To run the test cases: 15 | 16 | $ npm test 17 | 18 | The tests are written and run using [`mocha`](http://visionmedia.github.io/mocha). 19 | You can choose to use `mocha` directly, but you must first install `mocha`: 20 | 21 | $ npm install -g mocha 22 | 23 | Note: some users may need to run this as sudo. 24 | 25 | Then to run the tests via mocha, you will want to run it from the modules' root 26 | directory: 27 | 28 | $ mocha -R spec 29 | 30 | ## Options 31 | 32 | You can modify the test with various options: 33 | 34 | --help Display this message. 35 | --host, -h Aerospike database address. [default: "127.0.0.1"] 36 | --port, -p Aerospike database port. [default: 3000] 37 | --timeout, -t Timeout in milliseconds. [default: 10] 38 | --log, -l Log level [0-5] [default: 2] 39 | --namespace, -n Namespace for the keys. [default: "test"] 40 | --set, -s Set for the keys. [default: "demo"] 41 | 42 | Options can be set via an environment variable `OPTIONS`: 43 | 44 | $ OPTIONS="--port 3010" npm test 45 | -------------------------------------------------------------------------------- /src/main/enums/txn_capacity.cc: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2022-2023 Aerospike, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #include 18 | #include 19 | 20 | extern "C" { 21 | #include 22 | } 23 | 24 | using namespace v8; 25 | 26 | #define set(__obj, __name, __value) \ 27 | Nan::Set(__obj, Nan::New(__name).ToLocalChecked(), Nan::New(__value)) 28 | 29 | Local txnCapacity() 30 | { 31 | Nan::EscapableHandleScope scope; 32 | Local obj = Nan::New(); 33 | set(obj, "READ_DEFAULT", AS_TXN_READ_CAPACITY_DEFAULT); 34 | set(obj, "WRITE_DEFAULT", AS_TXN_WRITE_CAPACITY_DEFAULT); 35 | 36 | return scope.Escape(obj); 37 | } 38 | -------------------------------------------------------------------------------- /examples/shared/cli.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2018-2023 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | const util = require('util') 18 | 19 | function str2num (value) { 20 | return isNaN(value) ? value : +value 21 | } 22 | 23 | // @param { String[] } binStrs - list of "=" pairs 24 | exports.parseBins = function (binStrs) { 25 | return binStrs.reduce((bins, current) => { 26 | const [name, value] = current.toString().split('=') 27 | bins[name] = str2num(value) 28 | return bins 29 | }, {}) 30 | } 31 | 32 | exports.printRecord = function (record) { 33 | const key = record.key.key || record.key.digest.toString('hex') 34 | console.info('%s: %s', key, util.inspect(record.bins)) 35 | } 36 | -------------------------------------------------------------------------------- /src/main/enums/job_status.cc: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013-2023 Aerospike, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #include 18 | #include 19 | 20 | extern "C" { 21 | #include 22 | } 23 | 24 | using namespace v8; 25 | 26 | #define set(__obj, __name, __value) \ 27 | Nan::Set(__obj, Nan::New(__name).ToLocalChecked(), Nan::New(__value)) 28 | 29 | Local jobStatus() 30 | { 31 | Nan::EscapableHandleScope scope; 32 | Local obj = Nan::New(); 33 | set(obj, "UNDEF", AS_JOB_STATUS_UNDEF); 34 | set(obj, "INPROGRESS", AS_JOB_STATUS_INPROGRESS); 35 | set(obj, "COMPLETED", AS_JOB_STATUS_COMPLETED); 36 | return scope.Escape(obj); 37 | } 38 | -------------------------------------------------------------------------------- /ts-test/tests/generators/record.ts: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2013-2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | import Aerospike, {ConfigOptions, Host, AerospikeBins} from 'aerospike'; 19 | 20 | // 21 | // Returns a static record. 22 | // 23 | export function constant (bins: any): () => AerospikeBins { 24 | return function (): AerospikeBins { 25 | return bins 26 | } 27 | } 28 | 29 | // 30 | // Returns a record from bins spec'd using generators record. 31 | // 32 | export function record (bins: any): () => AerospikeBins { 33 | return function () { 34 | const out: AerospikeBins = {} 35 | for (const bin in bins) { 36 | out[bin] = bins[bin]() 37 | } 38 | return out 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/enums/query_duration.cc: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2023 Aerospike, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #include 18 | #include 19 | 20 | extern "C" { 21 | #include 22 | } 23 | 24 | using namespace v8; 25 | 26 | #define set(__obj, __name, __value) \ 27 | Nan::Set(__obj, Nan::New(__name).ToLocalChecked(), Nan::New(__value)) 28 | 29 | Local queryDuration() 30 | { 31 | Nan::EscapableHandleScope scope; 32 | Local obj = Nan::New(); 33 | set(obj, "LONG", AS_QUERY_DURATION_LONG); 34 | set(obj, "SHORT", AS_QUERY_DURATION_SHORT); 35 | set(obj, "LONG_RELAX_AP", AS_QUERY_DURATION_LONG_RELAX_AP); 36 | 37 | return scope.Escape(obj); 38 | } -------------------------------------------------------------------------------- /src/main/enums/ttl.cc: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013-2023 Aerospike, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #include 18 | #include 19 | 20 | #include "enums.h" 21 | 22 | using namespace v8; 23 | 24 | #define set(__obj, __name, __value) \ 25 | Nan::Set(__obj, Nan::New(__name).ToLocalChecked(), Nan::New(__value)) 26 | 27 | Local ttl_enum_values() 28 | { 29 | Nan::EscapableHandleScope scope; 30 | Local obj = Nan::New(); 31 | set(obj, "NAMESPACE_DEFAULT", TTL_NAMESPACE_DEFAULT); 32 | set(obj, "NEVER_EXPIRE", TTL_NEVER_EXPIRE); 33 | set(obj, "DONT_UPDATE", TTL_DONT_UPDATE); 34 | set(obj, "CLIENT_DEFAULT", TTL_CLIENT_DEFAULT); 35 | return scope.Escape(obj); 36 | } 37 | -------------------------------------------------------------------------------- /ts-test/tests/udf.lua: -------------------------------------------------------------------------------- 1 | function withArguments(rec, value) 2 | return value 3 | end 4 | 5 | function withoutArguments(rec) 6 | return 1 7 | end 8 | 9 | function noop(rec) 10 | end 11 | 12 | 13 | function createRecord(rec, binName, binValue) 14 | rec[binName] = binValue 15 | if (aerospike:exists(rec)) then 16 | status = aerospike:udpate(rec) 17 | else 18 | status = aerospike:create(rec) 19 | end 20 | return status 21 | end 22 | 23 | function updateRecord(rec, binName, binValue) 24 | rec[binName] = binValue 25 | aerospike:update(rec) 26 | return rec 27 | end 28 | 29 | function count(stream) 30 | local function mapper(rec) 31 | return 1 32 | end 33 | local function reducer(v1, v2) 34 | return v1 + v2 35 | end 36 | return stream : map(mapper) : reduce(reducer) 37 | end 38 | 39 | function countGreaterThan(stream, binName, value) 40 | local function mapper(rec) 41 | if rec[binName] > value then 42 | return 1 43 | else 44 | return 0 45 | end 46 | end 47 | local function reducer(v1, v2) 48 | return v1 + v2 49 | end 50 | return stream : map(mapper) : reduce(reducer) 51 | end 52 | 53 | function even(stream, bin) 54 | local function filt(rec) 55 | return rec.value % 2 == 0 56 | end 57 | local function mapper(rec) 58 | return rec.value 59 | end 60 | return stream : filter(filt) : map(mapper) 61 | end 62 | 63 | function deleteRecord(rec) 64 | aerospike:remove(rec) 65 | return 0 66 | end 67 | -------------------------------------------------------------------------------- /lib/commands/batch_command.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2013-2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | const Command = require('./command') 20 | const Record = require('../record') 21 | 22 | class BatchResult { 23 | constructor (status, record, inDoubt) { 24 | this.status = status 25 | this.record = record 26 | this.inDoubt = inDoubt 27 | } 28 | } 29 | 30 | module.exports = asCommand => class BatchCommand extends Command(asCommand) { 31 | convertResult (results) { 32 | if (!results) return [] 33 | 34 | return results.map(result => { 35 | const record = new Record(result.key, result.bins, result.meta) 36 | return new BatchResult(result.status, record, result.inDoubt) 37 | }) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/enums/txn_state.cc: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2022-2023 Aerospike, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #include 18 | #include 19 | 20 | extern "C" { 21 | #include 22 | } 23 | 24 | using namespace v8; 25 | 26 | #define set(__obj, __name, __value) \ 27 | Nan::Set(__obj, Nan::New(__name).ToLocalChecked(), Nan::New(__value)) 28 | 29 | Local txnState() 30 | { 31 | Nan::EscapableHandleScope scope; 32 | Local obj = Nan::New(); 33 | set(obj, "OPEN", AS_TXN_STATE_OPEN); 34 | set(obj, "VERIFIED", AS_TXN_STATE_VERIFIED); 35 | set(obj, "COMMITTED", AS_TXN_STATE_COMMITTED); 36 | set(obj, "ABORTED", AS_TXN_STATE_ABORTED); 37 | return scope.Escape(obj); 38 | } 39 | -------------------------------------------------------------------------------- /src/main/enums/batch_type.cc: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2022-2023 Aerospike, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #include 18 | #include 19 | 20 | extern "C" { 21 | #include 22 | } 23 | 24 | using namespace v8; 25 | 26 | #define set(__obj, __name, __value) \ 27 | Nan::Set(__obj, Nan::New(__name).ToLocalChecked(), Nan::New(__value)) 28 | 29 | Local batchTypes() 30 | { 31 | Nan::EscapableHandleScope scope; 32 | Local obj = Nan::New(); 33 | set(obj, "BATCH_READ", AS_BATCH_READ); 34 | set(obj, "BATCH_WRITE", AS_BATCH_WRITE); 35 | set(obj, "BATCH_APPLY", AS_BATCH_APPLY); 36 | set(obj, "BATCH_REMOVE", AS_BATCH_REMOVE); 37 | return scope.Escape(obj); 38 | } 39 | -------------------------------------------------------------------------------- /.github/workflows/fast-forward-merge.yml: -------------------------------------------------------------------------------- 1 | # As of this writing, there are no Github Actions in the marketplace 2 | # that allow fast forwarding using a personal access token 3 | # So we need to use this for now 4 | name: 'Fast forward merge' 5 | on: 6 | workflow_dispatch: 7 | inputs: 8 | ref_to_merge: 9 | type: string 10 | required: true 11 | base_branch: 12 | type: string 13 | required: true 14 | workflow_call: 15 | inputs: 16 | # If another branch, it must be origin/ 17 | ref_to_merge: 18 | type: string 19 | required: true 20 | base_branch: 21 | type: string 22 | required: true 23 | secrets: 24 | desk_mood: 25 | required: true 26 | 27 | jobs: 28 | merge: 29 | runs-on: ubuntu-22.04 30 | steps: 31 | 32 | - name: Harden the runner (Audit all outbound calls) 33 | uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0 34 | with: 35 | egress-policy: audit 36 | 37 | - name: Checkout 38 | uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 39 | with: 40 | # Fetch the whole history to prevent unrelated history errors 41 | fetch-depth: '0' 42 | token: ${{ secrets.desk_mood }} 43 | 44 | - name: Fast forward 45 | run: git merge --ff-only ${{ inputs.ref_to_merge }} 46 | 47 | - name: Upload changes to remote head branch 48 | run: git push 49 | -------------------------------------------------------------------------------- /examples/get.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // ***************************************************************************** 3 | // Copyright 2013-2024 Aerospike, Inc. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License") 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ***************************************************************************** 17 | // 18 | const Aerospike = require('aerospike') 19 | const shared = require('./shared') 20 | 21 | shared.runner() 22 | 23 | async function get (client, argv) { 24 | const key = new Aerospike.Key(argv.namespace, argv.set, argv.key) 25 | let record 26 | if (argv.bins) { 27 | record = await client.select(key, argv.bins) 28 | } else { 29 | record = await client.get(key) 30 | } 31 | console.info(record) 32 | } 33 | 34 | exports.command = 'get ' 35 | exports.describe = 'Fetch a record from the database' 36 | exports.handler = shared.run(get) 37 | exports.builder = { 38 | bins: { 39 | desc: 'Select specific bins to fetch', 40 | type: 'array' 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/policies/admin_policy.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2023 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | /** 20 | * A policy affecting the behavior of adminstraation operations. 21 | * 22 | * Please note that `AdminPolicy` does not derive from {@link BasePolicy}. 23 | * 24 | * @since v3.0.0 25 | */ 26 | class AdminPolicy { 27 | /** 28 | * Initializes a new AdminPolicy from the provided policy values. 29 | * 30 | * @param {Object} [props] - Policy values 31 | */ 32 | constructor (props) { 33 | props = props || {} 34 | 35 | /** 36 | * Maximum time in milliseconds to wait for the operation to complete. 37 | * 38 | * @type number 39 | */ 40 | this.timeout = props.timeout 41 | } 42 | } 43 | 44 | module.exports = AdminPolicy 45 | -------------------------------------------------------------------------------- /src/main/enums/abort_status.cc: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2024 Aerospike, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #include 18 | #include 19 | 20 | extern "C" { 21 | #include 22 | } 23 | 24 | using namespace v8; 25 | 26 | #define set(__obj, __name, __value) \ 27 | Nan::Set(__obj, Nan::New(__name).ToLocalChecked(), Nan::New(__value)) 28 | 29 | Local abortStatus() 30 | { 31 | Nan::EscapableHandleScope scope; 32 | Local obj = Nan::New(); 33 | set(obj, "OK", AS_ABORT_OK); 34 | set(obj, "ALREADY_ABORTED", AS_ABORT_ALREADY_ABORTED); 35 | set(obj, "ROLL_BACK_ABANDONED", AS_ABORT_ROLL_BACK_ABANDONED); 36 | set(obj, "CLOSE_ABANDONED", AS_ABORT_CLOSE_ABANDONED); 37 | return scope.Escape(obj); 38 | } 39 | -------------------------------------------------------------------------------- /src/include/scan.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013-2023 Aerospike, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | extern "C" { 18 | #include 19 | } 20 | 21 | #include 22 | 23 | #include "log.h" 24 | 25 | struct scan_udata { 26 | as_scan* scan; 27 | AsyncCommand * cmd; 28 | uint32_t count; 29 | uint32_t max_records; 30 | }; 31 | 32 | void setup_scan(as_scan *scan, v8::Local ns, 33 | v8::Local set, v8::Local maybe_options, 34 | LogInfo *log); 35 | 36 | void setup_options(as_scan *scan, v8::Local options, LogInfo *log); 37 | 38 | void setup_scan_pages(as_scan **scan, v8::Local ns, v8::Local set, 39 | v8::Local maybe_options, uint8_t* bytes, uint32_t bytes_size, LogInfo *log); -------------------------------------------------------------------------------- /ts-test/tests/types/generators.types.ts: -------------------------------------------------------------------------------- 1 | // types/arrayDefaults.ts 2 | 3 | export type StringDefaults = { 4 | random: boolean; 5 | length: { 6 | min: number; 7 | max: number; 8 | }; 9 | prefix: string; 10 | suffix: string; 11 | charset: string; 12 | }; 13 | 14 | export type BytesDefaults = { 15 | length: { 16 | min: number; 17 | max: number; 18 | }; 19 | byte: { 20 | min: number; 21 | max: number; 22 | }; 23 | }; 24 | 25 | export type IntegerDefaults = { 26 | random: boolean; 27 | min: number; 28 | max: number; 29 | }; 30 | 31 | export type DoubleDefaults = { 32 | random: boolean; 33 | min: number; 34 | max: number; 35 | step: number; 36 | }; 37 | 38 | export type GeneratorFunction = () => number | string | Uint8Array; 39 | 40 | export type ArrayDefaults = { 41 | values: GeneratorFunction[]; 42 | }; 43 | 44 | export interface Options { 45 | help: boolean; 46 | host: string | null; 47 | port: number | null; 48 | totalTimeout: number; 49 | log: number; 50 | log_file: number; 51 | namespace: string; 52 | set: string; 53 | user: string | null; 54 | password: string | null; 55 | clusterName?: string; 56 | cafile?: string; 57 | keyfile?: string; 58 | keyfilePassword?: string; 59 | certfile?: string; 60 | auth?: string; 61 | } 62 | 63 | export type Defaults = StringDefaults | BytesDefaults | IntegerDefaults | DoubleDefaults | ArrayDefaults; 64 | 65 | export interface TypeOptions { 66 | defaults: Defaults 67 | } 68 | 69 | export interface ExtendedOptions extends Options, TypeOptions {} 70 | 71 | -------------------------------------------------------------------------------- /examples/operate.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // ***************************************************************************** 3 | // Copyright 2013-2024 Aerospike, Inc. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License") 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ***************************************************************************** 17 | // 18 | const Aerospike = require('aerospike') 19 | const shared = require('./shared') 20 | const op = Aerospike.operations 21 | const lists = Aerospike.lists 22 | 23 | shared.runner() 24 | 25 | async function operate (client, argv) { 26 | const key = new Aerospike.Key(argv.namespace, argv.set, argv.key) 27 | const i = shared.random.int(1, 10) 28 | const ops = [ 29 | lists.append('values', i), 30 | op.read('values'), 31 | op.incr('sum', i), 32 | op.read('sum') 33 | ] 34 | const results = await client.operate(key, ops) 35 | console.info(results) 36 | } 37 | 38 | exports.command = 'operate ' 39 | exports.describe = 'Perform multiple operations on a single record' 40 | exports.handler = shared.run(operate) 41 | -------------------------------------------------------------------------------- /lib/policies/hll_policy.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2020-2023 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | /** 20 | * A policy affecting the behavior of {@link module:aerospike/hll|HLL} operations. 21 | * 22 | * @since v3.16.0 23 | */ 24 | class HLLPolicy { 25 | /** 26 | * Initializes a new HLLPolicy from the provided policy values. 27 | * 28 | * @param {Object} [props] - Policy values 29 | */ 30 | constructor (props) { 31 | props = props || {} 32 | 33 | /** 34 | * Specifies the behavior when writing byte values. 35 | * 36 | * @type number 37 | * @default Aerospike.hll.writeFlags.DEFAULT 38 | * @see {@link module:aerospike/hll.writeFlags} for supported policy values. 39 | */ 40 | this.writeFlags = props.writeFlags 41 | } 42 | } 43 | 44 | module.exports = HLLPolicy 45 | -------------------------------------------------------------------------------- /test/command.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2013-2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | /* eslint-env mocha */ 20 | /* global expect */ 21 | 22 | require('./test_helper') 23 | const Command = require('../lib/commands/command') 24 | 25 | describe('Command', function () { 26 | context('Extend Command', function () { 27 | class TestCommand extends Command('testCmd') { 28 | foo () { return 'bar' } 29 | } 30 | 31 | it('creates subclasses with informative constructor names', function () { 32 | const cmd = new TestCommand({}) 33 | expect(cmd.constructor.name).to.equal('TestCommand') 34 | }) 35 | 36 | it('keeps a reference to the client instance', function () { 37 | const client = {} 38 | const cmd = new TestCommand(client) 39 | expect(cmd.client).to.equal(client) 40 | }) 41 | }) 42 | }) 43 | -------------------------------------------------------------------------------- /lib/policies/bitwise_policy.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2019-2023 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | /** 20 | * A policy affecting the behavior of {@link module:aerospike/bitwise|bitwise} operations. 21 | * 22 | * @since v3.13.0 23 | */ 24 | class BitwisePolicy { 25 | /** 26 | * Initializes a new BitwisePolicy from the provided policy values. 27 | * 28 | * @param {Object} [props] - Policy values 29 | */ 30 | constructor (props) { 31 | props = props || {} 32 | 33 | /** 34 | * Specifies the behavior when writing byte values. 35 | * 36 | * @type number 37 | * @default Aerospike.bitwise.writeFlags.DEFAULT 38 | * @see {@link module:aerospike/bitwise.writeFlags} for supported policy values. 39 | */ 40 | this.writeFlags = props.writeFlags 41 | } 42 | } 43 | 44 | module.exports = BitwisePolicy 45 | -------------------------------------------------------------------------------- /ts-test/tests/command.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2013-2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | /* eslint-env mocha */ 20 | /* global expect */ 21 | 22 | require('./test_helper') 23 | const Command = require('../lib/commands/command') 24 | 25 | describe('Command', function () { 26 | context('Extend Command', function () { 27 | class TestCommand extends Command('testCmd') { 28 | foo () { return 'bar' } 29 | } 30 | 31 | it('creates subclasses with informative constructor names', function () { 32 | const cmd = new TestCommand({}) 33 | expect(cmd.constructor.name).to.equal('TestCommand') 34 | }) 35 | 36 | it('keeps a reference to the client instance', function () { 37 | const client = {} 38 | const cmd = new TestCommand(client) 39 | expect(cmd.client).to.equal(client) 40 | }) 41 | }) 42 | }) 43 | -------------------------------------------------------------------------------- /examples/apply.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // ***************************************************************************** 3 | // Copyright 2013-2024 Aerospike, Inc. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License") 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ***************************************************************************** 17 | // 18 | const Aerospike = require('aerospike') 19 | const shared = require('./shared') 20 | 21 | shared.runner() 22 | 23 | async function apply (client, argv) { 24 | const key = new Aerospike.Key(argv.namespace, argv.set, argv.key) 25 | 26 | const udfCall = { 27 | module: argv.module, 28 | funcname: argv.function, 29 | args: argv.args.map(arg => { 30 | try { 31 | return JSON.parse(arg) 32 | } catch (error) { 33 | return '' + arg 34 | } 35 | }) 36 | } 37 | 38 | const result = await client.apply(key, udfCall) 39 | console.info(result) 40 | } 41 | 42 | exports.command = 'apply [args...]' 43 | exports.describe = 'Apply a User-Defined Function (UDF) to a record' 44 | exports.handler = shared.run(apply) 45 | -------------------------------------------------------------------------------- /.github/actions/run-ee-server-for-ext-container/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Run EE server for another Docker container' 2 | description: 'Run EE server and configure tests to connect to it from another Docker container' 3 | inputs: 4 | # All inputs in composite actions are strings 5 | use-server-rc: 6 | required: true 7 | default: false 8 | server-tag: 9 | required: true 10 | default: '8.1.0.0-rc5' 11 | # Github Composite Actions can't access secrets 12 | # so we need to pass them in as inputs 13 | docker-hub-username: 14 | required: false 15 | docker-hub-password: 16 | required: false 17 | 18 | runs: 19 | using: "composite" 20 | steps: 21 | - name: Run EE server 22 | uses: ./.github/actions/run-ee-server 23 | with: 24 | use-server-rc: ${{ inputs.use-server-rc }} 25 | server-tag: ${{ inputs.server-tag }} 26 | docker-hub-username: ${{ inputs.docker-hub-username }} 27 | docker-hub-password: ${{ inputs.docker-hub-password }} 28 | 29 | - name: Get IP address of Docker container hosting server 30 | id: get-server-ip-address 31 | run: echo server-ip=$(docker container inspect -f '{{ .NetworkSettings.IPAddress }}' aerospike) >> $GITHUB_OUTPUT 32 | shell: bash 33 | 34 | 35 | - name: Configure tests to connect to that Docker container 36 | run: | 37 | pipx install crudini --pip-args "-c ${{ github.workspace }}/.github/workflows/requirements.txt"; 38 | crudini --existing=param --set config.conf enterprise-edition hosts ${{ steps.get-server-ip-address.outputs.server-ip }}:3000; 39 | cat config.conf 40 | working-directory: .github/workflows 41 | shell: bash 42 | -------------------------------------------------------------------------------- /src/main/enums/exp_write_flags.cc: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2023 Aerospike, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #include 18 | #include 19 | 20 | extern "C" { 21 | #include 22 | } 23 | 24 | using namespace v8; 25 | 26 | #define set(__obj, __name, __value) \ 27 | Nan::Set(__obj, Nan::New(__name).ToLocalChecked(), Nan::New(__value)) 28 | 29 | Local expWriteFlags() 30 | { 31 | Nan::EscapableHandleScope scope; 32 | Local obj = Nan::New(); 33 | set(obj, "DEFAULT", AS_EXP_WRITE_DEFAULT); 34 | set(obj, "CREATE_ONLY", AS_EXP_WRITE_CREATE_ONLY); 35 | set(obj, "UPDATE_ONLY", AS_EXP_WRITE_UPDATE_ONLY); 36 | set(obj, "ALLOW_DELETE", AS_EXP_WRITE_ALLOW_DELETE); 37 | set(obj, "POLICY_NO_FAIL", AS_EXP_WRITE_POLICY_NO_FAIL); 38 | set(obj, "EVAL_NO_FAIL", AS_EXP_WRITE_EVAL_NO_FAIL); 39 | 40 | return scope.Escape(obj); 41 | } -------------------------------------------------------------------------------- /lib/admin.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2023 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the 'License') 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an 'AS IS' BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | /** 20 | * @module aerospike/admin 21 | * 22 | * @description The admin module contains classes associated with RBAC (Role Based Access Control) security 23 | * methods defined in {@link Client} 24 | * 25 | */ 26 | 27 | /** 28 | * The {@link User} class holds role and database usage information for individual users. 29 | * 30 | * @summary User. 31 | */ 32 | exports.User = require('./user') 33 | 34 | /** 35 | * The {@link Privilege} class contains a {@link aerospike/privilegeCode | privilegeCode} as well as 36 | * an namespace and set. 37 | * 38 | * @summary Privilege 39 | */ 40 | exports.Privilege = require('./privilege') 41 | 42 | /** 43 | * The {@link Role} class holds quota, whitelist, and privilege information for an specified role. 44 | * 45 | * @summary Role 46 | */ 47 | exports.Role = require('./role') 48 | -------------------------------------------------------------------------------- /lib/commands/stream_command.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2013-2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | const Command = require('./command') 20 | const Key = require('../key') 21 | const Record = require('../record') 22 | 23 | module.exports = asCommand => class StreamCommand extends Command(asCommand) { 24 | constructor (stream, args) { 25 | super(stream.client, args) 26 | this.stream = stream 27 | } 28 | 29 | callback (error, record) { 30 | if (error) { 31 | this.stream.emit('error', error) 32 | } else if ('state' in record) { 33 | this.stream.emit('end', record.state) 34 | } else { 35 | this.stream.emit('data', record) 36 | } 37 | return !this.stream.aborted 38 | } 39 | 40 | convertResult (bins, meta, asKey) { 41 | if (!bins) return { state: meta } 42 | const key = Key.fromASKey(asKey) 43 | return new Record(key, bins, meta) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /jsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "source": { 3 | "include": [ 4 | "lib", 5 | "lib/policies", 6 | "lib/commands" 7 | ] 8 | }, 9 | "plugins": ["plugins/markdown"], 10 | "templates": { 11 | "cleverLinks": true, 12 | "monospaceLinks": false, 13 | "outputSourceFiles": true, 14 | "systemName": "Aerospike", 15 | "footer": "
High performance NoSQL database delivering speed at scale - Aerospike.com
", 16 | "copyright": "© 2013-2022 Aerospike, Inc.", 17 | "navType": "vertical", 18 | "theme": "simplex", 19 | "linenums": true, 20 | "collapseSymbols": false, 21 | "inverseNav": true, 22 | "analytics": { 23 | "ua": "UA-50452230-2", 24 | "domain": "aerospike.com" 25 | } 26 | }, 27 | "docdash": { 28 | "sectionOrder": [ 29 | "Modules", 30 | "Classes", 31 | "Events", 32 | "Tutorials", 33 | "Global" 34 | ],"meta": { 35 | "title": "Aerospike Node.js Client API Documentation", 36 | "description": "Explore the comprehensive documentation for the Aerospike Node.js Client API, covering usage, configuration, and examples. Learn how to integrate Aerospike with your Node.js applications efficiently.", 37 | "keyword": "Aerospike, Node.js, Client API, Documentation, Usage, Configuration, Examples, Integration" 38 | } 39 | }, 40 | "opts": { 41 | "destination": "./build/apidocs", 42 | "template": "./node_modules/docdash", 43 | "readme": "./docs/overview.md", 44 | "tutorials" : "./docs/tutorials", 45 | "recurse": true, 46 | "verbose": true 47 | } 48 | 49 | 50 | } -------------------------------------------------------------------------------- /examples/shared/index.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2018-2023 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | const path = require('path') 18 | 19 | exports.cli = require('./cli') 20 | exports.client = require('./client') 21 | exports.random = require('./random') 22 | exports.run = require('./run') 23 | exports.streams = require('./streams') 24 | 25 | // Check whether example has been executed directly or via the runner 26 | // (./run.js); if directly, invoke the runner instead and pass the command 27 | // line arguments. 28 | let started = false 29 | exports.runner = function () { 30 | if (started || require.main !== module.parent) { 31 | return 32 | } 33 | started = true 34 | 35 | const example = process.argv[1] 36 | const runner = path.join(example, '../run.js') 37 | const cmd = path.basename(example, '.js') 38 | 39 | process.argv.splice(1, 1, runner, cmd) 40 | delete require.cache[require.resolve(example)] 41 | 42 | require(runner) 43 | } 44 | -------------------------------------------------------------------------------- /src/main/enums/commit_status.cc: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2024 Aerospike, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #include 18 | #include 19 | 20 | extern "C" { 21 | #include 22 | } 23 | 24 | using namespace v8; 25 | 26 | #define set(__obj, __name, __value) \ 27 | Nan::Set(__obj, Nan::New(__name).ToLocalChecked(), Nan::New(__value)) 28 | 29 | Local commitStatus() 30 | { 31 | Nan::EscapableHandleScope scope; 32 | Local obj = Nan::New(); 33 | set(obj, "OK", AS_COMMIT_OK); 34 | set(obj, "ALREADY_COMMITTED", AS_COMMIT_ALREADY_COMMITTED); 35 | set(obj, "VERIFY_FAILED", AS_COMMIT_VERIFY_FAILED); 36 | set(obj, "MARK_ROLL_FORWARD_ABANDONED", AS_COMMIT_MARK_ROLL_FORWARD_ABANDONED); 37 | set(obj, "ROLL_FORWARD_ABANDONED", AS_COMMIT_ROLL_FORWARD_ABANDONED); 38 | set(obj, "CLOSE_ABANDONED", AS_COMMIT_CLOSE_ABANDONED); 39 | return scope.Escape(obj); 40 | } 41 | -------------------------------------------------------------------------------- /examples/connect.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // ***************************************************************************** 3 | // Copyright 2025 Aerospike, Inc. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License") 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ***************************************************************************** 17 | // 18 | const Aerospike = require('aerospike') 19 | const shared = require('./shared') 20 | 21 | shared.runner() 22 | 23 | async function connect (client, argv) { 24 | const config = { 25 | hosts: [ 26 | { addr: argv.hosts, port: argv.port } 27 | ] 28 | } 29 | if (argv.user) { 30 | config.user = argv.user 31 | } 32 | 33 | if (argv.password) { 34 | config.password = argv.password 35 | } 36 | let cli = null 37 | try { 38 | cli = await Aerospike.connect(config) 39 | console.log('Connected!') 40 | } catch (error) { 41 | console.log('Failed with: ' + error) 42 | } finally { 43 | if (client) { 44 | await cli.close() 45 | } 46 | } 47 | } 48 | 49 | exports.command = 'connect' 50 | exports.describe = 'Connect to the database' 51 | exports.handler = shared.run(connect) 52 | exports.builder = {} 53 | -------------------------------------------------------------------------------- /.github/workflows/dev-workflow.yml: -------------------------------------------------------------------------------- 1 | name: Dev workflow 2 | 3 | # 1. When a PR review is requested, run tests on that PR 4 | # 2. If all of the tests pass, allow the PR to be merged into `dev` 5 | # 3. Whenever a PR is merged to `dev`, bump version number in `dev` 6 | 7 | 8 | on: 9 | pull_request: 10 | branches: 11 | - 'disabled' 12 | 13 | # So we can test changes to the test-server-rc workflow 14 | workflow_dispatch: 15 | inputs: 16 | run_server_release_tests: 17 | description: 'DEBUG: Run server release tests in build-wheels workflow?' 18 | type: boolean 19 | default: false 20 | 21 | jobs: 22 | bump-dev-number: 23 | uses: ./.github/workflows/dev-bump-version.yml 24 | secrets: inherit 25 | 26 | #build-node-cpp-addons: 27 | # uses: ./.github/workflows/dev-build-node-cpp-addons.yml 28 | # needs: [ 29 | # bump-dev-number 30 | # ] 31 | # with: 32 | # version: ${{ needs.bump-dev-number.outputs.dev_version }} 33 | # run_tests: false 34 | # secrets: inherit 35 | 36 | upload-addons-to-jfrog: 37 | name: Upload artifacts to JFrog 38 | needs: [ 39 | bump-dev-number, 40 | #build-node-cpp-addons 41 | ] 42 | uses: ./.github/workflows/dev-upload-addons-to-jfrog.yml 43 | with: 44 | new_version: 6.5.1-dev.3 45 | secrets: inherit 46 | 47 | upload-npm-package-to-jfrog: 48 | name: upload package to JFrog NPM 49 | needs: [ 50 | bump-dev-number, 51 | #build-node-cpp-addons, 52 | upload-addons-to-jfrog, 53 | ] 54 | uses: ./.github/workflows/shared-upload-npm-package-to-jfrog.yml 55 | with: 56 | new_version: 6.5.1-dev.3 57 | pipeline-stage: 'dev' 58 | secrets: inherit 59 | -------------------------------------------------------------------------------- /.github/workflows/stage-workflow.yml: -------------------------------------------------------------------------------- 1 | name: Stage workflow 2 | 3 | on: 4 | push: 5 | branches: 6 | - 'dev' 7 | 8 | jobs: 9 | stage-get-jfrog-version: 10 | uses: ./.github/workflows/stage-get-jfrog-version.yml 11 | secrets: inherit 12 | 13 | #comprehensive-tests: 14 | # uses: ./.github/workflows/stage-tests.yml 15 | # with: 16 | # version: ${{ needs.stage-get-jfrog-version.outputs.dev_version }} 17 | # run_tests: true 18 | # needs: [ 19 | # stage-get-jfrog-version, 20 | # ] 21 | # secrets: inherit 22 | 23 | bump-stage-number: 24 | uses: ./.github/workflows/stage-bump-version.yml 25 | needs: [ 26 | stage-get-jfrog-version, 27 | #comprehensive-tests, 28 | ] 29 | secrets: inherit 30 | with: 31 | old_version: 6.5.1-dev.3 32 | 33 | stage-reupload-addons-to-jfrog: 34 | name: Upload artifacts to JFrog 35 | needs: [ 36 | stage-get-jfrog-version, 37 | #comprehensive-tests, 38 | bump-stage-number 39 | ] 40 | uses: ./.github/workflows/shared-reupload-addons-to-jfrog.yml 41 | with: 42 | old_version: 6.5.1-dev.3 43 | new_version: ${{ needs.bump-stage-number.outputs.new_stage_version }} 44 | pipeline-stage: 'stage' 45 | secrets: inherit 46 | 47 | upload-npm-package-to-jfrog: 48 | name: Upload artifacts to JFrog 49 | needs: [ 50 | stage-get-jfrog-version, 51 | #comprehensive-tests, 52 | bump-stage-number, 53 | stage-reupload-addons-to-jfrog 54 | ] 55 | uses: ./.github/workflows/shared-upload-npm-package-to-jfrog.yml 56 | with: 57 | new_version: ${{ needs.bump-stage-number.outputs.new_stage_version }} 58 | pipeline-stage: 'stage' 59 | secrets: inherit 60 | -------------------------------------------------------------------------------- /test/bigint.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2013-2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | /* eslint-env mocha */ 20 | /* global expect */ 21 | 22 | const helper = require('./test_helper') 23 | const bigint = require('../lib/bigint') 24 | 25 | describe('bigint', function () { 26 | context('BigInt supported - Node.js 10 and later', function () { 27 | helper.skipUnless(this, bigint.bigIntSupported) 28 | 29 | describe('BigInt', function () { 30 | it('is an alias for the built-in BigInt', function () { 31 | expect(bigint.BigInt(42)).to.eq(global.BigInt(42)) 32 | }) 33 | }) 34 | }) 35 | 36 | context('BigInt not supported - Node.js 8 and earlier', function () { 37 | helper.skipUnless(this, !bigint.bigIntSupported) 38 | 39 | describe('BigInt', function () { 40 | it('raises an exception if used', function () { 41 | expect(() => { bigint.BigInt(42) }).to.throw(Error, 'BigInt not supported') 42 | }) 43 | }) 44 | }) 45 | }) 46 | -------------------------------------------------------------------------------- /.github/workflows/stage-get-jfrog-version.yml: -------------------------------------------------------------------------------- 1 | name: Bump version 2 | 3 | permissions: 4 | id-token: write 5 | contents: read 6 | 7 | on: 8 | workflow_call: 9 | secrets: 10 | desk_mood: 11 | required: true 12 | outputs: 13 | dev_version: 14 | value: ${{ jobs.stage-get-jfrog-version.outputs.dev_version }} 15 | bump_sha: 16 | value: ${{ jobs.update-version-in-repo.outputs.bump_sha }} 17 | 18 | jobs: 19 | stage-get-jfrog-version: 20 | name: Get most recent JFrog version string 21 | runs-on: ubuntu-22.04 22 | outputs: 23 | dev_version: ${{ steps.stage-get-jfrog-version.outputs.dev_version }} 24 | steps: 25 | - name: Harden the runner (Audit all outbound calls) 26 | uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0 27 | with: 28 | egress-policy: audit 29 | 30 | - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 31 | with: 32 | token: ${{ secrets.desk_mood }} 33 | 34 | - name: Set up JFrog credentials 35 | uses: jfrog/setup-jfrog-cli@5b06f730cc5a6f55d78b30753f8583454b08c0aa # v4.8.1 36 | env: 37 | JF_URL: https://aerospike.jfrog.io 38 | with: 39 | oidc-provider-name: gh-aerospike-clients 40 | oidc-audience: aerospike/clients 41 | 42 | - name: Get jfrog version 43 | id: stage-get-jfrog-version 44 | run: | 45 | echo "dev_version=$(jfrog rt s "clients-npm-dev-local/aerospike/*" | jq -r '.[]?.path | capture("aerospike/(?[^/]+)") | .version' | grep -v '^-$' | grep -v '^lib$' | sort -V | grep -v 'rc' | tail -n1)" >> $GITHUB_OUTPUT 46 | 47 | - name: Print jfrog version 48 | run: echo "Jfrog version is ${{ steps.stage-get-jfrog-version.outputs.dev_version }}" 49 | -------------------------------------------------------------------------------- /lib/utils.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2013-2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | const HOST_RE = /^(\[[0-9a-f:]+]|(?:\d{1,3}\.){3}\d{1,3}|[a-z][a-z0-9\-.]+)(?::([a-z][a-z0-9\-.]+))?(?::(\d+))?$/i 20 | 21 | function parseHostString (hostString) { 22 | const parts = hostString.match(HOST_RE) 23 | if (!parts) { 24 | throw new Error('Invalid host address: ' + hostString) 25 | } 26 | 27 | const host = {} 28 | 29 | let addr = parts[1] 30 | if (addr.startsWith('[') && addr.endsWith(']')) { 31 | addr = addr.substr(1, addr.length - 2) 32 | } 33 | host.addr = addr 34 | 35 | const tlsName = parts[2] 36 | if (tlsName) { 37 | host.tlsname = tlsName 38 | } 39 | 40 | const port = parts[3] 41 | host.port = port ? Number.parseInt(port, 10) : 3000 42 | 43 | return host 44 | } 45 | 46 | function print (err, result) { 47 | if (err) { 48 | console.error('Error:', err.message) 49 | } else { 50 | console.info('Result:', result) 51 | } 52 | } 53 | 54 | module.exports = { 55 | parseHostString, 56 | print 57 | } 58 | -------------------------------------------------------------------------------- /lib/policies/list_policy.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2018-2023 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | /** 20 | * A policy affecting the behavior of list operations. 21 | * 22 | * @since v3.3.0 23 | */ 24 | class ListPolicy { 25 | /** 26 | * Initializes a new ListPolicy from the provided policy values. 27 | * 28 | * @param {Object} [props] - Policy values 29 | */ 30 | constructor (props) { 31 | props = props || {} 32 | 33 | /** 34 | * Sort order for the list. 35 | * 36 | * @type number 37 | * @default Aerospike.lists.order.UNORDERED 38 | * @see {@link module:aerospike/lists.order} for supported policy values. 39 | */ 40 | this.order = props.order 41 | 42 | /** 43 | * Specifies the behavior when replacing or inserting list items. 44 | * 45 | * @type number 46 | * @default Aerospike.lists.writeFlags.DEFAULT 47 | * @see {@link module:aerospike/lists.writeFlags} for supported policy values. 48 | */ 49 | this.writeFlags = props.writeFlags 50 | } 51 | } 52 | 53 | module.exports = ListPolicy 54 | -------------------------------------------------------------------------------- /src/main/enums/index.cc: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013-2023 Aerospike, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #include 18 | #include 19 | 20 | extern "C" { 21 | #include 22 | } 23 | 24 | using namespace v8; 25 | 26 | #define set(__obj, __name, __value) \ 27 | Nan::Set(__obj, Nan::New(__name).ToLocalChecked(), Nan::New(__value)) 28 | 29 | Local indexDataType() 30 | { 31 | Nan::EscapableHandleScope scope; 32 | Local obj = Nan::New(); 33 | set(obj, "STRING", AS_INDEX_STRING); 34 | set(obj, "NUMERIC", AS_INDEX_NUMERIC); 35 | set(obj, "GEO2DSPHERE", AS_INDEX_GEO2DSPHERE); 36 | set(obj, "BLOB", AS_INDEX_BLOB); 37 | return scope.Escape(obj); 38 | } 39 | 40 | Local indexType() 41 | { 42 | Nan::EscapableHandleScope scope; 43 | Local obj = Nan::New(); 44 | set(obj, "DEFAULT", AS_INDEX_TYPE_DEFAULT); 45 | set(obj, "LIST", AS_INDEX_TYPE_LIST); 46 | set(obj, "MAPKEYS", AS_INDEX_TYPE_MAPKEYS); 47 | set(obj, "MAPVALUES", AS_INDEX_TYPE_MAPVALUES); 48 | return scope.Escape(obj); 49 | } 50 | -------------------------------------------------------------------------------- /src/main/enums/privilege_code.cc: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2023 Aerospike, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #include 18 | #include 19 | 20 | extern "C" { 21 | #include 22 | } 23 | 24 | using namespace v8; 25 | 26 | #define set(__obj, __name, __value) \ 27 | Nan::Set(__obj, Nan::New(__name).ToLocalChecked(), Nan::New(__value)) 28 | 29 | Local privilegeCode() 30 | { 31 | Nan::EscapableHandleScope scope; 32 | Local obj = Nan::New(); 33 | set(obj, "USER_ADMIN", AS_PRIVILEGE_USER_ADMIN); 34 | set(obj, "SYS_ADMIN", AS_PRIVILEGE_SYS_ADMIN); 35 | set(obj, "DATA_ADMIN", AS_PRIVILEGE_DATA_ADMIN); 36 | set(obj, "UDF_ADMIN", AS_PRIVILEGE_UDF_ADMIN); 37 | set(obj, "SINDEX_ADMIN", AS_PRIVILEGE_SINDEX_ADMIN); 38 | set(obj, "READ", AS_PRIVILEGE_READ); 39 | set(obj, "READ_WRITE", AS_PRIVILEGE_READ_WRITE); 40 | set(obj, "READ_WRITE_UDF", AS_PRIVILEGE_READ_WRITE_UDF); 41 | set(obj, "WRITE", AS_PRIVILEGE_WRITE); 42 | set(obj, "TRUNCATE", AS_PRIVILEGE_TRUNCATE); 43 | return scope.Escape(obj); 44 | } -------------------------------------------------------------------------------- /src/include/query.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013-2023 Aerospike, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #pragma once 18 | 19 | extern "C" { 20 | #include 21 | } 22 | 23 | #include 24 | 25 | #include "log.h" 26 | 27 | 28 | struct query_udata { 29 | as_query* query; 30 | AsyncCommand* cmd; 31 | uint32_t count; 32 | uint32_t max_records; 33 | as_exp* exp; 34 | }; 35 | 36 | void setup_query(as_query *query, v8::Local ns, 37 | v8::Local set, v8::Local maybe_options, 38 | as_cdt_ctx* context, bool* with_context, as_exp **exp, LogInfo *log); 39 | void setup_options(as_query *query, v8::Local options, as_cdt_ctx* context, bool* with_context, as_exp **exp, LogInfo *log); 40 | void setup_query_pages(as_query ** query, v8::Local ns, v8::Local set, 41 | v8::Localmaybe_options, uint8_t* bytes, uint32_t bytes_size, 42 | as_cdt_ctx* context, bool* with_context, as_exp **exp, LogInfo *log); 43 | void free_query(as_query *query, as_policy_query *policy, as_exp *exp); 44 | -------------------------------------------------------------------------------- /lib/commands/exists_command.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2013-2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | const status = require('../status') 20 | const Command = require('./command') 21 | const Record = require('../record') 22 | 23 | module.exports = asCommand => class ExistsCommand extends Command(asCommand) { 24 | constructor (client, key, args, callback) { 25 | if (key) { 26 | args = [key].concat(args) 27 | } 28 | super(client, args, callback) 29 | this.key = key 30 | } 31 | 32 | convertResponse (error, bins, metadata) { 33 | error = this.convertError(error) 34 | if (error && error.code === status.ERR_RECORD_NOT_FOUND) { 35 | if (this.key) { 36 | return [null, this.convertResult({ ttl: null, gen: null })] 37 | } 38 | return [null, false] 39 | } else if (error) { 40 | return [error, null] 41 | } else { 42 | if (this.key) { 43 | return [null, this.convertResult(metadata)] 44 | } 45 | return [null, true] 46 | } 47 | } 48 | 49 | convertResult (metadata) { 50 | return new Record(this.key, null, metadata) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /test/remove_bin.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2013-2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | const { expect } = require('chai') 20 | /* global describe, context, it */ 21 | 22 | const Aerospike = require('../lib/aerospike') 23 | const helper = require('./test_helper') 24 | 25 | const keygen = helper.keygen 26 | 27 | const status = Aerospike.status 28 | const AerospikeError = Aerospike.AerospikeError 29 | 30 | describe('client.put(null bin)', function () { 31 | const client = helper.client 32 | 33 | context('with simple put null value', function () { 34 | it('delete bin using null put', function () { 35 | const key = keygen.string(helper.namespace, helper.set, { prefix: 'test/remove_bin/' })() 36 | 37 | return client.put(key, { str: 'abcde' }) 38 | .then(() => { 39 | client.put(key, { str: null }) 40 | .then(() => { 41 | client.get(key, function (err, bins, meta) { 42 | expect(err).to.be.instanceof(AerospikeError).with.property('code', status.ERR_RECORD_NOT_FOUND) 43 | }) 44 | }) 45 | }) 46 | }) 47 | }) 48 | }) 49 | -------------------------------------------------------------------------------- /src/main/commands/disable_metrics.cc: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013-2023 Aerospike, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | 18 | #include 19 | #include "client.h" 20 | #include "command.h" 21 | 22 | 23 | 24 | extern "C" { 25 | #include 26 | #include 27 | } 28 | 29 | using namespace v8; 30 | 31 | NAN_METHOD(AerospikeClient::DisableMetrics) 32 | { 33 | TYPE_CHECK_REQ(info[0], IsFunction, "Callback must be a function"); 34 | 35 | AerospikeClient *client = 36 | Nan::ObjectWrap::Unwrap(info.This()); 37 | AsyncCommand *cmd = 38 | new AsyncCommand("DisableMetrics", client, info[0].As()); 39 | 40 | LogInfo *log = cmd->log; 41 | 42 | aerospike_disable_metrics(client->as, &cmd->err); 43 | 44 | if (cmd->err.code == AEROSPIKE_METRICS_CONFLICT) { 45 | as_v8_warn(log, cmd->err.message); 46 | as_error_reset(&cmd->err); 47 | } 48 | 49 | if (cmd->err.code != AEROSPIKE_OK) { 50 | cmd->ErrorCallback(&cmd->err); 51 | goto Cleanup; 52 | } 53 | else{ 54 | Local argv[] = {Nan::Null(), Nan::Null()}; 55 | cmd->Callback(2, argv); 56 | } 57 | 58 | Cleanup: 59 | delete cmd; 60 | } -------------------------------------------------------------------------------- /examples/udf.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // ***************************************************************************** 3 | // Copyright 2013-2024 Aerospike, Inc. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License") 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ***************************************************************************** 17 | // 18 | const shared = require('./shared') 19 | const path = require('path') 20 | 21 | shared.runner() 22 | 23 | async function udfRegister (client, argv) { 24 | const module = argv.module 25 | const job = await client.udfRegister(module) 26 | await job.waitUntilDone() 27 | console.info('UDF module registered successfully') 28 | } 29 | 30 | async function udfRemove (client, argv) { 31 | const module = path.basename(argv.module) 32 | const job = await client.udfRemove(module) 33 | await job.waitUntilDone() 34 | console.info('UDF module removed successfully') 35 | } 36 | 37 | exports.command = 'udf ' 38 | exports.describe = 'Manage User-Defined Functions (UDF)' 39 | exports.builder = yargs => { 40 | return yargs 41 | .command({ 42 | command: 'register ', 43 | desc: 'Register a new UDF module with the cluster', 44 | handler: shared.run(udfRegister) 45 | }) 46 | .command({ 47 | command: 'remove ', 48 | desc: 'Remove a UDF module from the cluster', 49 | handler: shared.run(udfRemove) 50 | }) 51 | } 52 | -------------------------------------------------------------------------------- /examples/batch.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // ***************************************************************************** 3 | // Copyright 2013-2024 Aerospike, Inc. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License") 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ***************************************************************************** 17 | // 18 | const Aerospike = require('aerospike') 19 | const shared = require('./shared') 20 | 21 | shared.runner() 22 | 23 | async function batchRead (client, argv) { 24 | const batch = argv.keys.map(key => { 25 | const request = { 26 | key: new Aerospike.Key(argv.namespace, argv.set, key) 27 | } 28 | if (argv.bins) { 29 | request.bins = argv.bins 30 | } else { 31 | request.readAllBins = true 32 | } 33 | return request 34 | }) 35 | 36 | const batchResults = await client.batchRead(batch) 37 | 38 | for (const result of batchResults) { 39 | const record = result.record 40 | console.info(record.key.key, ':', 41 | result.status === Aerospike.status.OK ? record.bins : 'NOT FOUND' 42 | ) 43 | } 44 | } 45 | 46 | exports.command = 'batch ' 47 | exports.describe = 'Fetch multiple records from the database in a batch' 48 | exports.handler = shared.run(batchRead) 49 | exports.builder = { 50 | bins: { 51 | describe: 'List of bins to fetch for each record', 52 | type: 'array', 53 | group: 'Command:' 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /examples/shared/client.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2018-2023 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | const Aerospike = require('aerospike') 18 | const path = require('path') 19 | 20 | const UDF_USERDIR = path.normalize(path.join(__dirname, '..', 'lua')) 21 | 22 | module.exports = function (argv) { 23 | const config = defaultConfig(argv) 24 | Aerospike.setDefaultLogging(config.log) 25 | const client = Aerospike.client(config) 26 | client.captureStackTraces = argv.debugStacktraces 27 | return client 28 | } 29 | 30 | function defaultConfig (argv) { 31 | const defaultPolicy = { 32 | timeout: argv.totalTimeout, 33 | totalTimeout: argv.totalTimeout 34 | } 35 | return { 36 | hosts: argv.hosts, 37 | port: argv.port, 38 | policies: { 39 | apply: defaultPolicy, 40 | batch: defaultPolicy, 41 | info: defaultPolicy, 42 | operate: defaultPolicy, 43 | query: defaultPolicy, 44 | read: defaultPolicy, 45 | remove: defaultPolicy, 46 | scan: defaultPolicy, 47 | write: defaultPolicy 48 | }, 49 | modlua: { 50 | userPath: UDF_USERDIR 51 | }, 52 | log: { 53 | level: Aerospike.log.WARN + argv.verbose 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /test/double.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2013-2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | /* global expect, describe, it */ 20 | 21 | const Aerospike = require('../lib/aerospike') 22 | const Double = Aerospike.Double 23 | 24 | require('./test_helper.js') 25 | 26 | describe('Aerospike.Double #noserver', function () { 27 | describe('constructor', function () { 28 | it('returns a new Double value', function () { 29 | const subject = new Double(3.1415) 30 | 31 | expect(subject).to.be.instanceof(Double) 32 | expect(subject.Double).to.equal(3.1415) 33 | }) 34 | 35 | it('throws an error if not passed a number', function () { 36 | const fn = () => new Double('four point nine') 37 | expect(fn).to.throw(TypeError) 38 | }) 39 | 40 | it('throws an error if called without `new`', function () { 41 | const fn = () => Double(3.1415) 42 | expect(fn).to.throw('Invalid use of Double constructor') 43 | }) 44 | }) 45 | 46 | describe('#value()', function () { 47 | const subject = new Double(3.1415) 48 | 49 | it('returns the double value', function () { 50 | expect(subject.value()).to.equal(3.1415) 51 | }) 52 | }) 53 | }) 54 | -------------------------------------------------------------------------------- /lib/policies/info_policy.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2013-2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | /** 20 | * A policy affecting the behavior of info operations. 21 | * 22 | * Please note that `InfoPolicy` does not derive from {@link BasePolicy} and that 23 | * info commands do not support automatic retry. 24 | * 25 | * @since v3.0.0 26 | */ 27 | class InfoPolicy { 28 | /** 29 | * Initializes a new InfoPolicy from the provided policy values. 30 | * 31 | * @param {Object} [props] - Policy values 32 | */ 33 | constructor (props) { 34 | props = props || {} 35 | 36 | this.timeoutDelay = props.timeoutDelay 37 | /** 38 | * Maximum time in milliseconds to wait for the operation to complete. 39 | * 40 | * @type number 41 | */ 42 | this.timeout = props.timeout 43 | 44 | /** 45 | * Send request without any further processing. 46 | * 47 | * @type boolean 48 | */ 49 | this.sendAsIs = props.sendAsIs 50 | 51 | /** 52 | * Ensure the request is within allowable size limits. 53 | * 54 | * @type boolean 55 | */ 56 | this.checkBounds = props.checkBounds 57 | } 58 | } 59 | 60 | module.exports = InfoPolicy 61 | -------------------------------------------------------------------------------- /lib/commands/query_background_command.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2013-2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | const Job = require('../job') 20 | const Command = require('./command') 21 | 22 | function notEmpty (value) { 23 | return Array.isArray(value) && value.length > 0 24 | } 25 | 26 | function hasFilter (queryOrScan) { 27 | return notEmpty(queryOrScan.filters) 28 | } 29 | 30 | function moduleName (queryOrScan) { 31 | return hasFilter(queryOrScan) ? 'query' : 'scan' 32 | } 33 | 34 | // This command is used for both background queries and background scans, including 35 | // scans/queries that execute record UDFs, or one or more (write-only) operations. 36 | module.exports = asCommand => class QueryBackgroundBaseCommand extends Command(asCommand) { 37 | constructor (client, ns, set, queryObj, policy, queryID, callback) { 38 | queryID = queryID || Job.safeRandomJobID() 39 | const args = [ns, set, queryObj, policy, queryID] 40 | super(client, args, callback) 41 | 42 | this.client = client 43 | this.queryID = queryID 44 | this.queryObj = queryObj 45 | } 46 | 47 | convertResult () { 48 | return new Job(this.client, this.queryID, moduleName(this.queryObj)) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /test/generators/key.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2013-2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | const Key = require('../../lib/key') 20 | const valgen = require('./value') 21 | 22 | // 23 | // Returns a generator for bytes keys. 24 | // 25 | function bytes (namespace, set, options) { 26 | const bgen = valgen.bytes(options) 27 | return function () { 28 | return new Key(namespace, set, bgen()) 29 | } 30 | } 31 | 32 | // 33 | // Returns a generator for string keys. 34 | // 35 | function string (namespace, set, options) { 36 | const sgen = valgen.string(options) 37 | return function () { 38 | return new Key(namespace, set, sgen()) 39 | } 40 | } 41 | 42 | // 43 | // Returns a generator for integer keys. 44 | // 45 | function integer (namespace, set, options) { 46 | const igen = valgen.integer(options) 47 | return function () { 48 | return new Key(namespace, set, igen()) 49 | } 50 | } 51 | 52 | function range (keygen, end, start) { 53 | start = start || 0 54 | end = end || start + 1 55 | const a = [] 56 | for (let i = 0; i < end; i++) { 57 | a.push(keygen()) 58 | } 59 | return a 60 | } 61 | 62 | module.exports = { 63 | bytes, 64 | integer, 65 | string, 66 | range 67 | } 68 | -------------------------------------------------------------------------------- /ts-test/tests/remove_bin.ts: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2013-2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | /* global describe, context, it */ 19 | 20 | import Aerospike, { AerospikeError as ASError, status as statusModule, Client as Cli, Key } from 'aerospike'; 21 | 22 | import { expect } from 'chai'; 23 | import * as helper from './test_helper'; 24 | 25 | const keygen = helper.keygen 26 | 27 | const status: typeof statusModule = Aerospike.status 28 | const AerospikeError: typeof ASError = Aerospike.AerospikeError 29 | 30 | describe('client.put(null bin)', function () { 31 | const client: Cli = helper.client 32 | 33 | context('with simple put null value', function () { 34 | it('delete bin using null put', function () { 35 | const key: Key = keygen.string(helper.namespace, helper.set, { prefix: 'test/remove_bin/' })() 36 | 37 | return client.put(key, { str: 'abcde' }) 38 | .then(() => { 39 | client.put(key, { str: null }) 40 | .then(() => { 41 | client.get(key, function (err?: ASError) { 42 | expect(err!).to.be.instanceof(AerospikeError).with.property('code', status.ERR_RECORD_NOT_FOUND) 43 | }) 44 | }) 45 | }) 46 | }) 47 | }) 48 | }) 49 | -------------------------------------------------------------------------------- /.github/workflows/master-get-jfrog-version.yml: -------------------------------------------------------------------------------- 1 | # Takes in how to bump version as input 2 | # Commits changes to bump version and outputs the new version and commit hash as output 3 | name: Bump version 4 | 5 | permissions: 6 | # This is required for requesting the OIDC token 7 | id-token: write 8 | contents: read 9 | 10 | on: 11 | workflow_call: 12 | inputs: 13 | ref: 14 | required: false 15 | description: Commit to bump off of 16 | type: string 17 | outputs: 18 | stage_version: 19 | value: ${{ jobs.master-get-jfrog-version.outputs.stage_version }} 20 | 21 | jobs: 22 | master-get-jfrog-version: 23 | name: Get most recent JFrog version string 24 | runs-on: ubuntu-22.04 25 | outputs: 26 | stage_version: ${{ steps.master-get-jfrog-version.outputs.stage_version }} 27 | steps: 28 | 29 | - name: Harden the runner (Audit all outbound calls) 30 | uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0 31 | with: 32 | egress-policy: audit 33 | 34 | # Checkout the branch where we want to bump the new version 35 | - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 36 | 37 | - name: Set up JFrog credentials 38 | uses: jfrog/setup-jfrog-cli@5b06f730cc5a6f55d78b30753f8583454b08c0aa # v4.8.1 39 | env: 40 | JF_URL: https://aerospike.jfrog.io 41 | with: 42 | oidc-provider-name: gh-aerospike-clients 43 | oidc-audience: aerospike/clients 44 | 45 | - name: Get jfrog version 46 | id: master-get-jfrog-version 47 | run: | 48 | echo "stage_version=$(jfrog rt s "clients-npm-stage-local/aerospike/*" | jq -r '.[]?.path | capture("aerospike/(?[^/]+)") | .version' | grep -v '^-$' | grep -v '^lib$' | sort -V | grep -v 'dev' | tail -n1)" >> $GITHUB_OUTPUT 49 | 50 | - name: Print jfrog version 51 | run: echo "Jfrog version is ${{ steps.master-get-jfrog-version.outputs.stage_version }}" 52 | -------------------------------------------------------------------------------- /scripts/basic_test.js: -------------------------------------------------------------------------------- 1 | const Aerospike = require('aerospike') 2 | 3 | // INSERT HOSTNAME AND PORT NUMBER OF AEROSPIKE SERVER NODE HERE! 4 | const config = { 5 | hosts: '127.0.0.1 :3000' 6 | } 7 | 8 | const key = new Aerospike.Key('test', 'demo', 'demo') 9 | 10 | Aerospike.connect(config) 11 | .then(client => { 12 | const bins = { 13 | i: 123, 14 | s: 'hello', 15 | b: Buffer.from('world'), 16 | d: new Aerospike.Double(3.1415), 17 | g: Aerospike.GeoJSON.Point(103.913, 1.308), 18 | l: [1, 'a', { x: 'y' }], 19 | m: { foo: 4, bar: 7 } 20 | } 21 | const meta = { ttl: 10000 } 22 | const policy = new Aerospike.WritePolicy({ 23 | exists: Aerospike.policy.exists.CREATE_OR_REPLACE, 24 | // Timeouts disabled, latency dependent on server location. Configure as needed. 25 | socketTimeout: 0, 26 | totalTimeout: 0 27 | }) 28 | 29 | return client.put(key, bins, meta, policy) 30 | .then(() => { 31 | const ops = [ 32 | Aerospike.operations.incr('i', 1), 33 | Aerospike.operations.read('i'), 34 | Aerospike.lists.append('l', 'z'), 35 | Aerospike.maps.removeByKey('m', 'bar') 36 | ] 37 | 38 | return client.operate(key, ops) 39 | }) 40 | .then(result => { 41 | console.log(result.bins) // => { i: 124, l: 4, m: null } 42 | 43 | return client.get(key) 44 | }) 45 | .then(record => { 46 | console.log(record.bins) // => { i: 124, 47 | // s: 'hello', 48 | // b: , 49 | // d: 3.1415, 50 | // g: '{"type":"Point","coordinates":[103.913,1.308]}', 51 | // l: [ 1, 'a', { x: 'y' }, 'z' ], 52 | // m: { foo: 4 } } 53 | }) 54 | .then(() => client.close()) 55 | }) 56 | .catch(error => { 57 | console.error('Error: %s [%i]', error.message, error.code) 58 | if (error.client) { 59 | error.client.close() 60 | } 61 | }) 62 | -------------------------------------------------------------------------------- /ts-test/tests/double.ts: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2013-2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | /* global expect, describe, it */ 20 | 21 | import Aerospike, { Double as Doub } from 'aerospike'; 22 | 23 | import { expect } from 'chai'; 24 | 25 | const Double = Aerospike.Double 26 | 27 | describe('Aerospike.Double #noserver', function () { 28 | describe('constructor', function () { 29 | it('returns a new Double value', function () { 30 | const subject: Doub = new Double(3.1415) 31 | 32 | expect(subject).to.be.instanceof(Double) 33 | expect(subject.Double).to.equal(3.1415) 34 | }) 35 | /* 36 | it('throws an error if not passed a number', function () { 37 | const fn = () => new Double('four point nine') 38 | expect(fn).to.throw(TypeError) 39 | }) 40 | 41 | it('throws an error if called without `new`', function () { 42 | const fn = () => Double(3.1415) 43 | expect(fn).to.throw('Invalid use of Double constructor') 44 | }) 45 | */ 46 | }) 47 | 48 | describe('#value()', function () { 49 | const subject: Doub = new Double(3.1415) 50 | 51 | it('returns the double value', function () { 52 | expect(subject.value()).to.equal(3.1415) 53 | }) 54 | }) 55 | }) 56 | -------------------------------------------------------------------------------- /ts-test/tests/generators/key.ts: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2013-2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | import Aerospike from 'aerospike'; 19 | const Key = Aerospike.Key 20 | import * as valgen from './value'; 21 | 22 | // 23 | // Returns a generator for bytes keys. 24 | // 25 | export function bytes (namespace: any, set: any, options?: any) { 26 | const bgen = valgen.bytes(options) 27 | return function () { 28 | return new Key(namespace, set, bgen()) 29 | } 30 | } 31 | 32 | // 33 | // Returns a generator for string keys. 34 | // 35 | export function string (namespace: any, set: any, options?: any) { 36 | const sgen = valgen.string(options) 37 | return function () { 38 | return new Key(namespace, set, sgen()) 39 | } 40 | } 41 | 42 | // 43 | // Returns a generator for integer keys. 44 | // 45 | export function integer (namespace: any, set: any, options?: any) { 46 | const igen = valgen.integer(options) 47 | return function () { 48 | return new Key(namespace, set, igen()) 49 | } 50 | } 51 | 52 | export function range (keygen: any, end: number, start?: number) { 53 | start = start || 0 54 | end = end || start + 1 55 | const a = [] 56 | for (let i = 0; i < end; i++) { 57 | a.push(keygen()) 58 | } 59 | return a 60 | } -------------------------------------------------------------------------------- /.github/workflows/master-verify-npm-install.yml: -------------------------------------------------------------------------------- 1 | name: 'Donwload github artifacts' 2 | description: 'Download github artifacts for all supported versions' 3 | 4 | on: 5 | workflow_call: 6 | inputs: 7 | nodejs-tags: 8 | type: string 9 | required: false 10 | default: '[["v115", "20"], ["v127", "22"], ["v137", "24"], ["v141", "25"]]' 11 | new_version: 12 | type: string 13 | required: true 14 | jobs: 15 | run-npm-install-and-require-test: 16 | strategy: 17 | fail-fast: false 18 | matrix: 19 | os: [ubuntu-22.04, ubuntu-22.04-arm, macos-14-large, macos-15-large, SMA2, SMA3, windows-2022] 20 | nodejs-tag: ${{ fromJSON(inputs.nodejs-tags) }} 21 | runs-on: ${{ matrix.os }} 22 | steps: 23 | - name: Harden the runner (Audit all outbound calls) 24 | uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0 25 | with: 26 | egress-policy: audit 27 | 28 | - name: Delete workspace 29 | if: ${{ matrix.os != 'windows-2022' }} 30 | run: rm -rf ${{ github.workspace }}/* 31 | 32 | - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 33 | with: 34 | node-version: ${{ matrix.nodejs-tag[1] }} 35 | 36 | - name: verify runs and is aligned with expect functionality 37 | run: | 38 | npm install aerospike@${{ env.NEW_VERSION }} --omit=dev --ignore-scripts; 39 | node ./node_modules/aerospike/scripts/verify-aerospike-npm-scripts.js aerospike; 40 | npm --prefix ./node_modules/aerospike install @mapbox/node-pre-gyp --ignore-scripts 41 | npx --package aerospike npm run removeExtraBinaries --prefix ./node_modules/aerospike; 42 | npx --package aerospike npm run build --prefix ./node_modules/aerospike; 43 | node -e "const Aerospike = require('aerospike'); console.log(Aerospike.exp.unknown());" 44 | env: 45 | NEW_VERSION: ${{ inputs.new_version }} -------------------------------------------------------------------------------- /examples/dynamicConfig.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // ***************************************************************************** 3 | // Copyright 2025 Aerospike, Inc. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License") 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ***************************************************************************** 17 | // 18 | const Aerospike = require('aerospike') 19 | const shared = require('./shared') 20 | 21 | shared.runner() 22 | 23 | async function dynamicConfig (client, argv) { 24 | const config = { 25 | hosts: [ 26 | { addr: argv.hosts, port: argv.port } 27 | ], 28 | configProvider: { 29 | path: argv.dcp, 30 | interval: 1 31 | } 32 | } 33 | if (argv.user) { 34 | config.user = argv.user 35 | } 36 | 37 | if (argv.password) { 38 | config.password = argv.password 39 | } 40 | let cli = null 41 | try { 42 | console.log('Connecting...') 43 | cli = await Aerospike.connect(config) 44 | console.log('Connected!') 45 | } catch (error) { 46 | console.log('Failed with: ' + error) 47 | } finally { 48 | if (client) { 49 | await cli.close() 50 | } 51 | } 52 | } 53 | 54 | exports.command = 'dynamicConfig' 55 | exports.describe = 'Dynamic Config' 56 | exports.handler = shared.run(dynamicConfig) 57 | exports.builder = { 58 | dynamic_config_path: { 59 | alias: 'dcp', 60 | describe: 'Path of dynamic config', 61 | type: 'string', 62 | default: './example_config/config.yml' 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /scripts/build-package.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ################################################################################ 3 | # Copyright 2013-2023 Aerospike, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | ################################################################################ 17 | 18 | 19 | ################################################################################ 20 | # 21 | # This script is used to build various node versions packages. 22 | # 23 | ################################################################################ 24 | 25 | CWD=$(pwd) 26 | SCRIPT_DIR=$(dirname $0) 27 | BASE_DIR=$(cd "${SCRIPT_DIR}/.."; pwd) 28 | AS_HOST="bob-cluster-a" 29 | AS_USER="generic_client" 30 | AS_PWD="generic_client" 31 | AS_PORT="3000" 32 | AS_NAMESPACE="ssd-store" 33 | 34 | . ${SCRIPT_DIR}/build-commands.sh 35 | 36 | build_nodejs_client() { 37 | rm -rf ./node_modules 38 | rm -f package-lock.json 39 | nvm install $1 40 | nvm use $1 41 | npm install --unsafe-perm --build-from-source 42 | # node ${CWD}/node_modules/.bin/mocha --exit --U ${AS_USER} --P ${AS_PWD} --h ${AS_HOST} --port ${AS_PORT} --namespace ${AS_NAMESPACE} 43 | } 44 | 45 | configure_nvm 46 | 47 | download_libuv 48 | rebuild_libuv 49 | 50 | rebuild_c_client 51 | 52 | perform_check 53 | 54 | rm -rf ${AEROSPIKE_NODEJS_RELEASE_HOME}/node-*-${OS_FLAVOR}-* 55 | 56 | 57 | build_nodejs_client v18 58 | build_nodejs_client v20 59 | build_nodejs_client v22 60 | build_nodejs_client v23 61 | 62 | nvm use v22 63 | 64 | cd ${CWD} 65 | -------------------------------------------------------------------------------- /lib/batch_type.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2022-2023 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the 'License') 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an 'AS IS' BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | const as = require('bindings')('aerospike.node') 20 | const batchType = as.batchTypes 21 | 22 | /** 23 | * @module aerospike/batchType 24 | * 25 | * @description Identifies batch record type with designated enumerated type 26 | */ 27 | 28 | // ======================================================================== 29 | // Constants 30 | // ======================================================================== 31 | module.exports = { 32 | /** 33 | * Indicates that a {@link Record} instance is used in a batch for read operations. 34 | * @const {number} 35 | */ 36 | BATCH_READ: batchType.BATCH_READ, 37 | 38 | /** 39 | * Indicates that a {@link Record} instance is used in a batch for write operations. 40 | * @const {number} 41 | */ 42 | BATCH_WRITE: batchType.BATCH_WRITE, 43 | 44 | /** 45 | * Indicates that a {@link Record} instance is used in a batch for applying record. 46 | * @const {number} 47 | */ 48 | BATCH_APPLY: batchType.BATCH_APPLY, 49 | 50 | /** 51 | * Indicates that a {@link Record} instance is used in a batch for removal operations. 52 | * @const {number} 53 | */ 54 | BATCH_REMOVE: batchType.BATCH_REMOVE 55 | 56 | } 57 | -------------------------------------------------------------------------------- /.github/workflows/get-jfrog-stage-version.yml: -------------------------------------------------------------------------------- 1 | # Takes in how to bump version as input 2 | # Commits changes to bump version and outputs the new version and commit hash as output 3 | name: Bump version 4 | 5 | permissions: 6 | # This is required for requesting the OIDC token 7 | id-token: write 8 | contents: read 9 | 10 | on: 11 | workflow_call: 12 | secrets: 13 | desk_mood: 14 | required: true 15 | outputs: 16 | stage_version: 17 | value: ${{ jobs.get-jfrog-stage-version.outputs.stage_version }} 18 | bump_sha: 19 | value: ${{ jobs.update-version-in-repo.outputs.bump_sha }} 20 | 21 | jobs: 22 | get-jfrog-stage-version: 23 | name: Get most recent JFrog version string 24 | runs-on: ubuntu-22.04 25 | outputs: 26 | stage_version: ${{ steps.get-jfrog-stage-version.outputs.stage_version }} 27 | steps: 28 | - name: Harden the runner (Audit all outbound calls) 29 | uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0 30 | with: 31 | egress-policy: audit 32 | 33 | # Checkout the branch where we want to bump the new version 34 | - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 35 | with: 36 | token: ${{ secrets.desk_mood }} 37 | 38 | - name: Set up JFrog credentials 39 | uses: jfrog/setup-jfrog-cli@5b06f730cc5a6f55d78b30753f8583454b08c0aa # v4.8.1 40 | env: 41 | JF_URL: https://aerospike.jfrog.io 42 | with: 43 | oidc-provider-name: gh-aerospike-clients 44 | oidc-audience: aerospike/clients 45 | 46 | - name: Get jfrog version 47 | id: get-jfrog-stage-version 48 | run: | 49 | echo "stage_version=$(jfrog rt s "clients-npm-stage-local/aerospike/*" | jq -r '.[]?.path | capture("aerospike/(?[^/]+)") | .version' | grep -v '^-$' | grep -v '^lib$' | sort -V | grep -v 'dev' | tail -n1)" >> $GITHUB_OUTPUT 50 | 51 | - name: Print jfrog version 52 | run: echo "Jfrog version is ${{ steps.get-jfrog-stage-version.outputs.stage_version }}" -------------------------------------------------------------------------------- /src/main/enums/config_enum.cc: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013-2023 Aerospike, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #include 18 | #include 19 | 20 | extern "C" { 21 | #include 22 | #include 23 | } 24 | 25 | using namespace v8; 26 | 27 | #define set(__obj, __name, __value) \ 28 | Nan::Set(__obj, Nan::New(__name).ToLocalChecked(), Nan::New(__value)) 29 | 30 | Local log_enum_values() 31 | { 32 | Nan::EscapableHandleScope scope; 33 | Local obj = Nan::New(); 34 | set(obj, "OFF", -1); 35 | set(obj, "ERROR", AS_LOG_LEVEL_ERROR); 36 | set(obj, "WARN", AS_LOG_LEVEL_WARN); 37 | set(obj, "INFO", AS_LOG_LEVEL_INFO); 38 | set(obj, "DEBUG", AS_LOG_LEVEL_DEBUG); 39 | set(obj, "TRACE", AS_LOG_LEVEL_TRACE); 40 | set(obj, "DETAIL", 41 | AS_LOG_LEVEL_TRACE); // renamed in v3.4 - keep old name for backwards compatibility 42 | return scope.Escape(obj); 43 | } 44 | 45 | Local auth_mode_enum_values() 46 | { 47 | Nan::EscapableHandleScope scope; 48 | Local obj = Nan::New(); 49 | set(obj, "INTERNAL", AS_AUTH_INTERNAL); 50 | set(obj, "EXTERNAL", AS_AUTH_EXTERNAL); 51 | set(obj, "EXTERNAL_INSECURE", AS_AUTH_EXTERNAL_INSECURE); 52 | set(obj, "AUTH_PKI", AS_AUTH_PKI); 53 | return scope.Escape(obj); 54 | } 55 | -------------------------------------------------------------------------------- /ts-test/tests/config_pki.ts: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2013-2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | /* global expect, describe, it, context */ 20 | 21 | import Aerospike, { Client, AdminPolicy, admin, ConfigOptions } from 'aerospike'; 22 | import * as helper from './test_helper'; 23 | import { expect, assert } from 'chai'; 24 | 25 | function getRandomInt (max: number) { 26 | return Math.floor(Math.random() * max) 27 | } 28 | function randomString (num: number) { 29 | return getRandomInt(num) 30 | } 31 | 32 | function wait (ms: number) { 33 | return new Promise(resolve => setTimeout(resolve, ms)) 34 | } 35 | 36 | context('admin commands', async function () { 37 | 38 | 39 | 40 | it('Fails to connect when providing password alongside AUTH_PKI', async function () { 41 | const config: ConfigOptions = { 42 | hosts: helper.config.hosts, 43 | user: 'example', 44 | password: 'password350', 45 | authMode: Aerospike.auth.AUTH_PKI, 46 | } 47 | 48 | try{ 49 | let dummyClient = await Aerospike.client(config) 50 | 51 | } 52 | catch(error: any){ 53 | console.log(error) 54 | expect(error.message).to.eql("Password authentication is disabled for PKI-only users. Please authenticate using your certificate.") 55 | expect(error.code).to.eql(64) 56 | } 57 | 58 | 59 | }) 60 | 61 | }) -------------------------------------------------------------------------------- /examples/mrtAbort.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // ***************************************************************************** 3 | // Copyright 2013-2024 Aerospike, Inc. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License") 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ***************************************************************************** 17 | // 18 | const Aerospike = require('aerospike') 19 | const shared = require('./shared') 20 | 21 | shared.runner() 22 | 23 | async function mrtAbort (client, argv) { 24 | // sconst record1 = { abc: 123 } 25 | const record2 = { def: 456 } 26 | 27 | const mrt = new Aerospike.Transaction() 28 | 29 | const policy = { 30 | txn: mrt 31 | } 32 | const keyList = [] 33 | for (let i = 0; i < argv.keys.length; i++) { 34 | keyList.push(new Aerospike.Key(argv.namespace, argv.set, argv.keys[i])) 35 | } 36 | 37 | for (let i = 0; i < keyList.length; i++) { 38 | await client.put(keyList[i], record2, policy) 39 | await client.get(keyList[i], policy) 40 | } 41 | 42 | console.log(keyList) 43 | 44 | console.log('aborting multi-record transaction with %d operations.', keyList.length * 2) 45 | await client.abort(mrt) 46 | console.info('multi-record transaction has been aborted.') 47 | } 48 | 49 | exports.command = 'mrtAbort ' 50 | exports.describe = 'Abort a multi-record transaction' 51 | exports.handler = shared.run(mrtAbort) 52 | exports.builder = { 53 | keys: { 54 | desc: 'Provide keys for the records in the multi-record transaction', 55 | type: 'array', 56 | group: 'Command:' 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /examples/mrtCommit.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // ***************************************************************************** 3 | // Copyright 2013-2024 Aerospike, Inc. 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License") 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // ***************************************************************************** 17 | // 18 | const Aerospike = require('aerospike') 19 | const shared = require('./shared') 20 | 21 | shared.runner() 22 | 23 | async function mrtCommit (client, argv) { 24 | // const record1 = { abc: 123 } 25 | const record2 = { def: 456 } 26 | 27 | const mrt = new Aerospike.Transaction() 28 | 29 | const policy = { 30 | txn: mrt 31 | } 32 | const keyList = [] 33 | for (let i = 0; i < argv.keys.length; i++) { 34 | keyList.push(new Aerospike.Key(argv.namespace, argv.set, argv.keys[i])) 35 | } 36 | for (let i = 0; i < argv.keys.length; i++) { 37 | await client.put(keyList[i], record2, policy) 38 | await client.get(keyList[i], policy) 39 | } 40 | 41 | console.log(keyList) 42 | 43 | console.log('committing multi-record transaction with %d operations.', keyList.length * 2) 44 | await client.commit(mrt) 45 | console.info('multi-record transaction has been committed.') 46 | } 47 | 48 | exports.command = 'mrtCommit ' 49 | exports.describe = 'Commit a multi-record transaction' 50 | exports.handler = shared.run(mrtCommit) 51 | exports.builder = { 52 | keys: { 53 | desc: 'Provide keys for the records in the multi-record transaction', 54 | type: 'array', 55 | group: 'Command:' 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /.github/workflows/dev-build-node-cpp-addons.yml: -------------------------------------------------------------------------------- 1 | name: Build Node C++ Addons 2 | run-name: Build Node C++ Addons (run_tests=${{ inputs.run_tests }}, use-server-rc=${{ inputs.use-server-rc }}, server-tag=${{ inputs.server-tag }}) 3 | 4 | # Builds manylinux wheels and source distribution 5 | # Optionally run tests on manylinux wheels 6 | # Then upload artifacts to Github 7 | 8 | 9 | on: 10 | workflow_call: 11 | inputs: 12 | # The "dev" tests test the artifacts against a server 13 | # The dev-to-stage and stage-to-master workflow only need to build the artifacts, not test them 14 | run_tests: 15 | required: false 16 | type: boolean 17 | default: false 18 | version: 19 | type: string 20 | required: true 21 | # workflow_call hack 22 | is_workflow_call: 23 | type: boolean 24 | default: true 25 | required: false 26 | # This input is only used in workflow_call events 27 | use-server-rc: 28 | required: false 29 | default: false 30 | type: boolean 31 | server-tag: 32 | type: string 33 | required: false 34 | default: 'latest' 35 | secrets: 36 | soup_hat: 37 | required: true 38 | cell_girl: 39 | required: true 40 | song_loss: 41 | required: true 42 | 43 | jobs: 44 | build-node-cpp-bindings: 45 | strategy: 46 | matrix: 47 | platform-tag: [ 48 | "manylinux_x86_64", 49 | "manylinux_aarch64", 50 | "macosx_x86_64", 51 | "macosx_x86_64_2", 52 | "macosx_arm64", 53 | "macosx_arm64_2", 54 | "win_amd64" 55 | ] 56 | fail-fast: false 57 | uses: ./.github/workflows/dev-build-node-cpp-bindings.yml 58 | with: 59 | platform-tag: ${{ matrix.platform-tag }} 60 | # Can't use env context here, so just copy from build-sdist env var 61 | run_tests: false 62 | use-server-rc: ${{ inputs.use-server-rc }} 63 | server-tag: ${{ inputs.server-tag }} 64 | version: ${{ inputs.version }} 65 | secrets: inherit 66 | -------------------------------------------------------------------------------- /src/include/enums.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013-2023 Aerospike, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #define TTL_NAMESPACE_DEFAULT 0 22 | #define TTL_NEVER_EXPIRE -1 23 | #define TTL_DONT_UPDATE -2 24 | #define TTL_CLIENT_DEFAULT -3 25 | 26 | v8::Local auth_mode_enum_values(); 27 | v8::Local bitwise_enum_values(); 28 | v8::Local generation_policy_values(); 29 | v8::Local hll_enum_values(); 30 | v8::Local indexDataType(); 31 | v8::Local indexType(); 32 | v8::Local jobStatus(); 33 | v8::Local key_policy_values(); 34 | v8::Local languages(); 35 | v8::Local list_enum_values(); 36 | v8::Local log_enum_values(); 37 | v8::Local map_enum_values(); 38 | v8::Local policy(); 39 | v8::Local predicates(); 40 | v8::Local retry_policy_values(); 41 | v8::Local status(); 42 | v8::Local ttl_enum_values(); 43 | v8::Local batchTypes(); 44 | v8::Local queryDuration(); 45 | v8::Local privilegeCode(); 46 | v8::Local expReadFlags(); 47 | v8::Local expWriteFlags(); 48 | v8::Local abortStatus(); 49 | v8::Local commitStatus(); 50 | v8::Local txnState(); 51 | v8::Local txnCapacity(); 52 | -------------------------------------------------------------------------------- /src/include/transaction.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013-2024 Aerospike, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | #pragma once 17 | 18 | #include 19 | #include 20 | 21 | extern "C" { 22 | #include 23 | } 24 | 25 | #include "log.h" 26 | #include "command.h" 27 | 28 | class Transaction : public Nan::ObjectWrap { 29 | 30 | /*************************************************************************** 31 | * PUBLIC 32 | **************************************************************************/ 33 | public: 34 | static void Init(); 35 | static v8::Local NewInstance(v8::Local capacity_obj); 36 | 37 | Nan::Persistent persistent; 38 | as_txn *txn; 39 | 40 | Transaction(); 41 | ~Transaction(); 42 | 43 | /*************************************************************************** 44 | * PRIVATE 45 | **************************************************************************/ 46 | private: 47 | 48 | static inline Nan::Persistent &constructor() 49 | { 50 | static Nan::Persistent my_constructor; 51 | return my_constructor; 52 | } 53 | 54 | static NAN_METHOD(New); 55 | 56 | static NAN_METHOD(GetId); 57 | static NAN_METHOD(GetInDoubt); 58 | static NAN_METHOD(GetTimeout); 59 | static NAN_METHOD(GetState); 60 | 61 | static NAN_METHOD(SetTimeout); 62 | 63 | static NAN_METHOD(Close); 64 | 65 | }; 66 | -------------------------------------------------------------------------------- /test/aerospike.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2013-2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | /* global expect, describe, it */ 20 | 21 | const Aerospike = require('../lib/aerospike') 22 | const helper = require('./test_helper') 23 | 24 | describe('Aerospike', function () { 25 | describe('Aerospike.client() #noserver', function () { 26 | it('instantiates a new client instance', function (done) { 27 | const client = Aerospike.client(helper.config) 28 | expect(client).to.be.instanceof(Aerospike.Client) 29 | done() 30 | }) 31 | }) 32 | 33 | describe('Aerospike.connect()', function () { 34 | it('instantiates a new client instance and connects to the cluster', function (done) { 35 | Aerospike.connect(helper.config, (error, client) => { 36 | if (error) throw error 37 | expect(client).to.be.instanceof(Aerospike.Client) 38 | client.infoAny(error => { 39 | if (error) throw error 40 | client.close(false) 41 | done() 42 | }) 43 | }) 44 | }) 45 | 46 | it('returns a Promise that resolves to a client', function () { 47 | return Aerospike.connect(helper.config) 48 | .then(client => { 49 | expect(client).to.be.instanceof(Aerospike.Client) 50 | return client 51 | }) 52 | .then(client => client.close(false)) 53 | }) 54 | }) 55 | }) 56 | -------------------------------------------------------------------------------- /.github/workflows/dev-test-install-script.yaml: -------------------------------------------------------------------------------- 1 | name: Publish JFrog build to NPM 2 | 3 | permissions: 4 | # This is required for requesting the OIDC token 5 | id-token: write 6 | contents: read 7 | 8 | on: 9 | workflow_call: 10 | inputs: 11 | old_version: 12 | type: string 13 | required: false 14 | new_version: 15 | type: string 16 | required: false 17 | secrets: 18 | # Just make all the secrets required to make things simpler... 19 | NPMRC: 20 | required: true 21 | NPMRC_OFF: 22 | required: true 23 | NPM_TOKEN_OFF: 24 | required: true 25 | 26 | 27 | jobs: 28 | test-install-script: 29 | runs-on: ubuntu-22.04 30 | steps: 31 | 32 | - name: Harden the runner (Audit all outbound calls) 33 | uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0 34 | with: 35 | egress-policy: audit 36 | 37 | - name: Set up JFrog credentials 38 | uses: jfrog/setup-jfrog-cli@5b06f730cc5a6f55d78b30753f8583454b08c0aa # v4.8.1 39 | env: 40 | JF_URL: https://aerospike.jfrog.io 41 | with: 42 | oidc-provider-name: gh-aerospike-clients 43 | oidc-audience: aerospike/clients 44 | 45 | - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 46 | with: 47 | node-version: ${{ matrix.nodejs-tag[1] }} 48 | registry-url: 'https://registry.npmjs.org' 49 | 50 | - name: Download Artifacts from Jfrog 51 | run: jf rt dl "clients-npm-stage-local/aerospike/${{ env.OLD_VERSION }}/" "downloaded-artifacts/" 52 | env: 53 | OLD_VERSION: ${{ inputs.old_version }} 54 | PACKAGE_MANAGER: npm 55 | 56 | - name: Test install script for npm 57 | run: | 58 | tar --strip-components=1 -xvf aerospike-${{ env.OLD_VERSION }}.tgz; 59 | npm ci --ignore-scripts; 60 | npm-run-all removeExtraBinaries build; 61 | check-install-script-results.js; 62 | env: 63 | OLD_VERSION: ${{ inputs.old_version }} 64 | working-directory: downloaded-artifacts/aerospike/${{ inputs.old_version }} 65 | -------------------------------------------------------------------------------- /src/main/commands/transaction_abort.cc: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013-2023 Aerospike, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #include "client.h" 18 | #include "command.h" 19 | #include "conversions.h" 20 | #include "log.h" 21 | #include "async.h" 22 | #include "transaction.h" 23 | 24 | using namespace v8; 25 | 26 | NAN_METHOD(AerospikeClient::TransactionAbort) 27 | { 28 | // TYPE_CHECK_REQ(info[0], is_transaction_value, "Transaction must be an object"); 29 | TYPE_CHECK_REQ(info[1], IsFunction, "Callback must be a function"); 30 | 31 | AerospikeClient *client = 32 | Nan::ObjectWrap::Unwrap(info.This()); 33 | AsyncCommand *cmd = new AsyncCommand("Abort", client, info[1].As()); 34 | LogInfo *log = client->log; 35 | 36 | Transaction *transaction; 37 | as_status status; 38 | 39 | 40 | if (is_transaction_value(info[0])) { 41 | transaction = Nan::ObjectWrap::Unwrap(info[0].As()); 42 | } 43 | else { 44 | CmdErrorCallback(cmd, AEROSPIKE_ERR_PARAM, "Transaction object invalid"); 45 | goto Cleanup; 46 | } 47 | 48 | status = aerospike_abort_async(client->as, &cmd->err, transaction->txn, async_abort_listener, cmd, NULL); 49 | as_v8_debug(log, "Sending transaction abort command"); 50 | 51 | if (status == AEROSPIKE_OK) { 52 | cmd = NULL; // async callback responsible for deleting the command 53 | } 54 | else { 55 | cmd->ErrorCallback(); 56 | } 57 | 58 | Cleanup: 59 | delete cmd; 60 | } -------------------------------------------------------------------------------- /src/main/commands/transaction_commit.cc: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013-2023 Aerospike, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #include "client.h" 18 | #include "command.h" 19 | #include "conversions.h" 20 | #include "log.h" 21 | #include "async.h" 22 | #include "transaction.h" 23 | 24 | using namespace v8; 25 | 26 | 27 | NAN_METHOD(AerospikeClient::TransactionCommit) 28 | { 29 | //TYPE_CHECK_REQ(info[0], is_transaction_value, "Transaction must be an object"); 30 | TYPE_CHECK_REQ(info[1], IsFunction, "Callback must be a function"); 31 | 32 | AerospikeClient *client = 33 | Nan::ObjectWrap::Unwrap(info.This()); 34 | AsyncCommand *cmd = new AsyncCommand("Commit", client, info[1].As()); 35 | LogInfo *log = client->log; 36 | 37 | Transaction *transaction; 38 | as_status status; 39 | 40 | if (is_transaction_value(info[0])) { 41 | transaction = Nan::ObjectWrap::Unwrap(info[0].As()); 42 | } 43 | else { 44 | CmdErrorCallback(cmd, AEROSPIKE_ERR_PARAM, "Transaction object invalid"); 45 | goto Cleanup; 46 | } 47 | 48 | status = aerospike_commit_async(client->as, &cmd->err, transaction->txn , async_commit_listener, cmd, NULL); 49 | as_v8_debug(log, "Sending transaction commit command"); 50 | 51 | if (status == AEROSPIKE_OK) { 52 | cmd = NULL; // async callback responsible for deleting the command 53 | } 54 | else { 55 | cmd->ErrorCallback(); 56 | } 57 | 58 | Cleanup: 59 | delete cmd; 60 | 61 | } -------------------------------------------------------------------------------- /ts-test/tests/aerospike.ts: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2013-2024 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | /* global expect, describe, it */ 20 | 21 | import Aerospike, { Client } from 'aerospike'; 22 | 23 | import { expect } from 'chai'; 24 | import * as helper from './test_helper'; 25 | let client: Client 26 | describe('Aerospike', function () { 27 | describe('Aerospike.client() #noserver', function () { 28 | it('instantiates a new client instance', function (done) { 29 | client = Aerospike.client(helper.config) 30 | expect(client).to.be.instanceof(Aerospike.Client) 31 | done() 32 | }) 33 | }) 34 | 35 | describe('Aerospike.connect()', function () { 36 | it('instantiates a new client instance and connects to the cluster', function (done) { 37 | Aerospike.connect(helper.config, (error?: Error, client?) => { 38 | if (error) throw error 39 | expect(client).to.be.instanceof(Aerospike.Client) 40 | client?.infoAny((err?: Error) => { 41 | if (err) throw err 42 | client.close(false) 43 | done() 44 | }) 45 | }) 46 | }) 47 | 48 | it('returns a Promise that resolves to a client', function () { 49 | return Aerospike.connect(helper.config) 50 | .then(client => { 51 | expect(client).to.be.instanceof(Aerospike.Client) 52 | return client 53 | }) 54 | .then(client => client.close(false)) 55 | }) 56 | }) 57 | }) 58 | -------------------------------------------------------------------------------- /test/stats.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2018-2023 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | /* eslint-env mocha */ 20 | /* global expect */ 21 | /* eslint-disable no-unused-expressions */ 22 | 23 | const helper = require('./test_helper') 24 | const client = helper.client 25 | 26 | describe('Client#stats', function () { 27 | before(function (done) { 28 | // Send an async command to each node ensure we have at least 1 async 29 | // connection open. At least 1 sync connection has been opened to send some 30 | // info commands. 31 | client.scan(helper.namespace, 'noSuchSet').foreach().on('end', done) 32 | }) 33 | 34 | it('returns command queue stats', function () { 35 | const stats = client.stats() 36 | expect(stats.commands).to.not.be.empty 37 | expect(stats.commands.inFlight).to.be.at.least(0) 38 | expect(stats.commands.queued).to.be.at.least(0) 39 | }) 40 | 41 | it('returns cluster node stats', function () { 42 | const stats = client.stats() 43 | expect(stats.nodes).to.be.an('array').that.is.not.empty 44 | 45 | const node = stats.nodes.pop() 46 | expect(node.name).to.be.a('string').of.length(15) 47 | for (const connStats of [node.syncConnections, node.asyncConnections]) { 48 | expect(connStats.inPool).to.be.at.least(1) 49 | expect(connStats.inUse).to.be.at.least(0) 50 | expect(connStats.opened).to.be.at.least(1) 51 | expect(connStats.closed).to.be.at.least(0) 52 | } 53 | }) 54 | }) 55 | -------------------------------------------------------------------------------- /examples/put_test.js: -------------------------------------------------------------------------------- 1 | const Aerospike = require('aerospike') 2 | 3 | const config = { 4 | hosts: '172.17.0.3:3000', 5 | log: { 6 | level: Aerospike.log.DEBUG, 7 | file: process.stdout.fd 8 | } 9 | } 10 | const key = new Aerospike.Key('test', 'demo', 'demo') 11 | 12 | // process.on('uncaughtException', (err, origin) => { 13 | // fs.writeSync( 14 | // process.stderr.fd, 15 | // `Caught exception: ${err}\n` + 16 | // `Exception origin: ${origin}` 17 | // ); 18 | // }); 19 | 20 | console.log('Connect') 21 | Aerospike.connect(config) 22 | .then(client => { 23 | const bins = { 24 | i: 123, 25 | s: 'hello', 26 | b: Buffer.from('world'), 27 | d: new Aerospike.Double(3.1415), 28 | g: new Aerospike.GeoJSON({ type: 'Point', coordinates: [103.913, 1.308] }), 29 | l: [1, 'a', { x: 'y' }], 30 | m: { foo: 4, bar: 7 } 31 | } 32 | const meta = { ttl: 0 } 33 | const policy = new Aerospike.WritePolicy({ 34 | exists: Aerospike.policy.exists.CREATE_OR_REPLACE, 35 | timeout: 20000 36 | }) 37 | 38 | console.log('Put') 39 | return client.put(key, bins, meta, policy) 40 | .then(() => { 41 | const ops = [ 42 | Aerospike.operations.incr('i', 1), 43 | Aerospike.operations.read('i'), 44 | Aerospike.lists.append('l', 'z'), 45 | Aerospike.maps.removeByKey('m', 'bar') 46 | ] 47 | 48 | console.log('Operate') 49 | return client.operate(key, ops) 50 | }) 51 | .then(result => { 52 | console.log(result.bins) // => { c: 4, i: 124, m: null } 53 | 54 | return client.get(key) 55 | }) 56 | .then(record => { 57 | console.log(record.bins) // => { i: 124, 58 | // s: 'hello', 59 | // b: , 60 | // d: 3.1415, 61 | // g: '{"type":"Point","coordinates":[103.913,1.308]}', 62 | // l: [ 1, 'a', { x: 'y' }, 'z' ], 63 | // m: { foo: 4 } } 64 | }) 65 | .then(() => client.close()) 66 | .catch(error => { 67 | console.log('Error') 68 | client.close() 69 | return Promise.reject(error) 70 | }) 71 | }) 72 | .catch(error => console.log(error)) 73 | -------------------------------------------------------------------------------- /lib/bin.js: -------------------------------------------------------------------------------- 1 | // ***************************************************************************** 2 | // Copyright 2023 Aerospike, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License") 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ***************************************************************************** 16 | 17 | 'use strict' 18 | 19 | /** 20 | * @class Bin 21 | * @classdesc Aerospike Bin 22 | * 23 | * In the Aerospike database, each record (similar to a row in a relational database) stores 24 | * data using one or more bins (like columns in a relational database). The major difference 25 | * between bins and RDBMS columns is that you don't need to define a schema. Each record can 26 | * have multiple bins. Bins accept the data types listed {@link https://docs.aerospike.com/apidocs/nodejs/#toc4__anchor|here}. 27 | * 28 | * For information about these data types and how bins support them, see {@link https://docs.aerospike.com/server/guide/data-types/scalar-data-types|this}. 29 | * 30 | * Although the bin for a given record or object must be typed, bins in different rows do not 31 | * have to be the same type. There are some internal performance optimizations for single-bin namespaces. 32 | * 33 | * @summary Construct a new Aerospike Bin instance. 34 | * 35 | */ 36 | class Bin { 37 | /** @private */ 38 | constructor (name, value, mapOrder) { 39 | /** 40 | * Bin name. 41 | * 42 | * @member {String} Bin#name 43 | */ 44 | this.name = name 45 | 46 | /** 47 | * Bin value. 48 | * 49 | * @member {Any} Bin#value 50 | */ 51 | if (mapOrder === 1) { 52 | this.value = new Map(Object.entries(value)) 53 | } else { 54 | this.value = value 55 | } 56 | } 57 | } 58 | 59 | module.exports = Bin 60 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | 3 | VALGRIND_OPTS = --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes -v 4 | 5 | 6 | default: build 7 | 8 | .PHONY: build 9 | build: 10 | node-gyp build 11 | 12 | .PHONY: test 13 | test: build 14 | npm test 15 | 16 | .PHONY: empty-valgrind 17 | empty-valgrind: build 18 | mkdir -p valgrind 19 | valgrind $(VALGRIND_OPTS) node -e "" 1>valgrind/empty.out 2>valgrind/empty.valgrind 20 | 21 | .PHONY: test-valgrind 22 | test-valgrind: build 23 | mkdir -p valgrind 24 | valgrind $(VALGRIND_OPTS) npm test 1>valgrind/test.out 2>valgrind/test.valgrind 25 | 26 | .PHONY: benchmark-valgrind 27 | benchmark-valgrind: build 28 | mkdir -p valgrind 29 | valgrind $(VALGRIND_OPTS) node benchmarks/main.js -O 10000 -P 4 -R 0.5 1>valgrind/benchmark.out 2>valgrind/benchmark.valgrind 30 | 31 | .PHONY: put-valgrind 32 | put-valgrind: build 33 | mkdir -p valgrind 34 | valgrind $(VALGRIND_OPTS) node examples/put.js -q -I 100 foo 1>valgrind/put-100.out 2>valgrind/put-100.valgrind 35 | 36 | .PHONY: put 37 | put: build 38 | node examples/put.js -q -I 100 foo 39 | 40 | .PHONY: get-valgrind 41 | get-valgrind: build 42 | mkdir -p valgrind 43 | valgrind $(VALGRIND_OPTS) node examples/get.js -q -I 100 foo 1>valgrind/get-100.out 2>valgrind/get-100.valgrind 44 | 45 | .PHONY: get 46 | get: build 47 | node examples/get.js -q -I 100 foo 48 | 49 | .PHONY: query-valgrind 50 | query-valgrind: build 51 | mkdir -p valgrind 52 | node examples/index_create.js s idx_s string 53 | # valgrind $(VALGRIND_OPTS) node examples/query.js -I 1 1>valgrind/query-1.out 2>valgrind/query-1.valgrind 54 | valgrind $(VALGRIND_OPTS) node --expose-gc examples/query.js -q -I 100 1>valgrind/query-100.out 2>valgrind/query-100.valgrind 55 | # valgrind $(VALGRIND_OPTS) node examples/query.js -I 1000 1>valgrind/query-1000.out 2>valgrind/query-1000.valgrind 56 | # valgrind $(VALGRIND_OPTS) node examples/query.js -I 10000 1>valgrind/query-10000.out 2>valgrind/query-10000.valgrind 57 | 58 | .PHONY: query 59 | query: build 60 | node examples/index_create.js s idx_s string 61 | # node --expose-gc examples/query.js -I 1 62 | # node --expose-gc examples/query.js -I 100 63 | node --expose-gc examples/query.js -q -I 1000 64 | # node --expose-gc examples/query.js -I 10000 65 | 66 | 67 | 68 | --------------------------------------------------------------------------------