/*- * Copyright (c) 2018, 2026 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Universal Permissive License v 1.0 as shown at * https://oss.oracle.com/licenses/upl/ */ import type { EventEmitter } from "events"; import type { Config } from "./config"; import type { TableDDLOpt, ModifyTableOpt, CompletionOpt, GetTableOpt, TableUsageOpt, GetIndexOpt, GetIndexesOpt, ListTablesOpt, GetOpt, PutOpt, PutIfOpt, DeleteOpt, DeleteIfOpt, MultiDeleteOpt, WriteMultipleOpt, PutManyOpt, DeleteManyOpt, PrepareOpt, QueryOpt, AdminDDLOpt, AdminStatusOpt, AdminListOpt, AddReplicaOpt, ReplicaStatsOpt } from "./opt"; import type { TableLimits, TableETag, DefinedTags, FreeFormTags, WriteOperation, RowVersion, Operation } from "./param"; import type { TableResult, TableUsageResult, IndexInfo, ListTablesResult, GetResult, PutResult, DeleteResult, MultiDeleteResult, WriteMultipleResult, QueryResult, AdminResult, UserInfo, ReplicaStats, ReplicaStatsResult } from "./result"; import type { ServiceType, TableState, AdminState } from "./constants"; import type { RowKey, AnyRow, AnyKey } from "./data"; import type { PreparedStatement } from "./stmt"; import type { AuthorizationProvider } from "./auth/config"; import type { IAMConfig } from "./auth/iam/types"; import type { KVStoreAuthConfig } from "./auth/kvstore/types"; import type { NoSQLError } from "./error"; import type { NoSQLClientEvents } from "./events"; import type { Region } from "./region"; import type { StatsControl } from "./stats_control"; /** * Defines NoSQLClient, which is the point of access to the * Oracle NoSQL Database Cloud service. */ /** * NoSQLClient class provides access to Oracle NoSQL Database * tables. Methods of this class are used to create and manage tables and * indexes, and to read and write data. All operations are performed * asynchronously. *
* Each method returns a Promise object that will resolve to the * result of the operation if successful, or reject with an error upon * failure. To handle results and errors, you may use promise chains * with .then.catch or async functions with await. The result of * operation is a JavaScript object with properties specific to each * operation and is documented for each method below. If any error * has occurred, the promise will reject with {@link NoSQLError} or * one of its subclasses. *
* You instantiate NoSQLClient by providing connection and credential * information, either in the form of a configuration object of type * {@link Config} or a path to a file that holds {@link Config} information. * Some parameters, such as the service endpoint or region, are required. * Other parameters are optional and need not be specified in the * {@link Config}. Default values are used for optional parameters. *
* Note that it is possible to create {@link NoSQLClient} instance without * providing configuration if all of the following are true: *
* Each method of NoSQLClient also takes an optional opt * parameter which contains options specific to a particular * operation. Some of these options may be the same as those * specified by {@link Config} and will override the {@link Config} * values for this operation. The method description describes which * options are pertinent for that operation. If an options is not * specified in the opt parameter and is also not present in * {@link Config}, the driver will use default values. *
* In general, same methods and options are applicable to both Oracle * NoSQL Database Cloud Service and On-Premise Oracle NoSQL Database. * However, some methods, options and result types may be specific to * particular {@link ServiceType}, which is specified in their documentation. *
* For cloud service only: for each method you may provide * opt.compartment which specifies the compartment of the given table * (or compartment used to perform given operation). If not set in options or * initial config (see {@link Config#compartment}), the root * compartment of the tenancy is assumed. The compartment is a string that * may be either the id (OCID) of the compartment or a compartment name. Both * are acceptable. If a name is used it can be either the name of a top-level * compartment, or for nested compartments, it should be a compartment path * to the nested compartment that does not include the root compartment name * (tenant), e.g. compartmentA.compartmentB.compartmentC *
* Alternatively, instead of setting opt.compartment * you may prefix the table name with its compartment name (for top-level * compartments) or compartment path (for nested compartments), e.g. * compartmentA.compartmentB.compartmentC:myTable. * Note that the table name cannot be * prefixed with compartment id. Prefixing the table with compartment * name/path takes precendence over other methods of specifying the * compartment. *
* For events emitted by {@link NoSQLClient}, see {@link NoSQLClientEvents}.
*
* @see {@page connect-cloud.md}
* @see {@page connect-on-prem.md}
* @see {@page tables.md}
*
* @example
* Using {@link NoSQLClient} with async-await.
* ```ts
* const NoSQLClient = require('oracle-nosqldb').NoSQLClient;
*
* async function test() {
* let client;
* try {
* client = new NoSQLClient('config.json');
* let res = await client.tableDDL(
* 'CREATE TABLE foo(id INTEGER, name STRING, PRIMARY KEY(id))',
* {
* tableLimits: {
* readUnits: 100,
* writeUnits: 100,
* storageGB: 50
* }
* }
* );
* console.log('Table: %s, state: %s', res.tableName,
* res.tableState);
* await client.forCompletion(res);
* res = await client.put('foo', { id: 1, name: 'test' });
* res = await client.get('foo', { id: 1 });
* console.log(res.row);
* //..........
* } catch(err) {
* //handle errors
* } finally {
* if (client) {
* client.close();
* }
* }
* }
* ```
*/
export class NoSQLClient extends EventEmitter {
/**
* Constructs an instance of NoSQLClient. This function is synchronous.
* @param {string|Config|null} [config] Configuration for NoSQL client.
* May be either a string indicating the file path to a configuration
* file, or a {@link Config} object. If a file path is supplied,
* the path can be absolute or relative to the current directory
* of the application. The file should contain the {@link Config} object
* and can be either JSON or JavaScript (in the latter case its
* module.exports should be set to the {@link Config} object).
* Note that you may pass null or omit this parameter (use
* no-argument constructor) if using the cloud service with the default OCI
* configuration file that contains credentials and region identifier, as
* described above
* @throws {NoSQLArgumentError} if the configuration is
* missing required properties or contains invalid property values
* @see {@link Config}
*/
constructor(config?: string | Config | null);
/**
* The version of the driver.
*/
static readonly version: string;
/**
* Returns the service type used by this {@link NoSQLClient} instance.
* @returns {ServiceType} Service type
*/
readonly serviceType: ServiceType;
/**
* Returns the {@link StatsControl} object for this client. It may be used
* to inspect or change the collection profile, register an interval
* handler, control pretty printing, and start or stop collection.
*
* Statistics are grouped by operation name, such as Get, Put, Query and
* Table. The REGULAR profile reports request and error counts, retries and
* retry delays, rate-limit delay, request latency, request size, result
* size, and active connections. MORE also reports 95th and 99th percentile
* latency. ALL additionally reports per-query statistics, including the
* query text, logical and HTTP request counts, preparation information,
* whether the query is simple or performs writes, and its query plan when
* available.
*
* Statistics are collected for the configured interval. At the end of
* each interval, the SDK generates a JSON snapshot that applications can
* filter and parse. The snapshot is logged when `statsEnableLog` is `true`
* and delivered to `statsHandler` when a handler is configured. After the
* snapshot is generated, the interval counters are cleared and collection
* continues with fresh counters.
*
* Collection intervals are aligned relative to the top of the hour. The
* first snapshot may therefore cover less than the complete configured
* interval. For example, if a client using a 10-minute interval starts at
* 10:07, its first snapshot is generated at 10:10.
*
* A non-NONE profile configured on the client starts collection
* automatically. To write snapshots to a specific file, configure a
* `statsHandler` that writes the serialized snapshot to that file and set
* `statsEnableLog` to `false` to avoid duplicate console output.
*
* @example
* ```ts
* const client = new NoSQLClient({
* endpoint: "localhost:8080",
* statsProfile: StatsControl.Profile.ALL,
* statsInterval: 60,
* statsHandler: stats => {
* console.log(stats);
* }
* });
*
* const statsControl = client.getStatsControl();
* statsControl.setPrettyPrint(true);
* statsControl.start();
*
* // Run application requests while statistics collection is active.
* await client.get("Users", { id: 1 });
* await client.put("Users", { id: 1, name: "Mayank" });
*
* statsControl.stop();
*
* // Example handler output (metric values vary by workload):
* {
* clientId: "a1b2c3d4",
* startTime: "2026-07-21T10:00:00Z",
* endTime: "2026-07-21T10:01:00Z",
* connections: { min: 1, max: 2, avg: 1.5 },
* requests: [{
* name: "Get",
* httpRequestCount: 1,
* errors: 0,
* retry: {
* count: 0,
* delayMs: 0,
* authCount: 0,
* throttleCount: 0
* },
* rateLimitDelayMs: 0,
* httpRequestLatencyMs: {
* min: 2, max: 2, avg: 2, "95th": 2, "99th": 2
* },
* requestSize: { min: 93, max: 93, avg: 93 },
* resultSize: { min: 150, max: 150, avg: 150 }
* }]
* }
* ```
*
* @example Writing statistics snapshots to a file
* ```ts
* import { createWriteStream } from "node:fs";
*
* const statsFile = createWriteStream("./client-stats.log", {
* flags: "a"
* });
*
* const client = new NoSQLClient({
* endpoint: "localhost:8080",
* statsProfile: StatsControl.Profile.ALL,
* statsEnableLog: false,
* statsHandler: stats => {
* statsFile.write(`Client stats|${JSON.stringify(stats)}\n`);
* }
* });
* ```
*
* @see {@link StatsControl}
* @see {@link StatsProfile}
* @see {@link StatsSnapshot}
*/
getStatsControl(): StatsControl;
/**
* Releases resources associated with NoSQLClient. This method must be
* called after NoSQLClient is no longer needed.
* @returns {Promise} Promise, which may be resolved if closing
* the client did not require asynchronous operations. The resolved
* value is ignored. Currently, the close may need to perform
* asynchronous operation only when using {@link ServiceType.KVSTORE},
* otherwise resolved Promise is returned. The Promise should not reject
* (rather log the error if any), so you only need to await for
* it if you need to perform an action upon its completion.
* @see {@link ServiceType}
*/
close(): Promise
* Built-in authorization providers use with this SDK obtain authorization
* information such as authorization signature or token and cache it for
* some time. In some instances, obtaining this information make take
* some time, especially in cases when a network request to authorization
* server is required, e.g. when using Cloud Service with Instance
* Principal (see {@link IAMConfig}). By default, this information is
* obtained on demand when database operation is issued and this may cause
* timeout errors if the default timeout for database operations is not
* sufficient to obtain this information. You may call this method to
* obtain and pre-cache authorization information, so that when database
* operations are issued, they do not need to spend any extra time on
* obtaining authorization.
* A current use case for this method is when using Cloud Service
* with Instance Principal, because a network request is required to
* obtain authorization token (as well additional requests to obtain
* instance region, instance certificates, instance private key, etc).
* An alternative solution is to increase operation timeouts to allot
* enough time to obtain authorzation token when required. However,
* calling {@link NoSQLClient#precacheAuth} will provide better
* performance when starting multiple concurrent database operations.
*
* Call this method after creating {@link NoSQLClient} instance before
* performing database operations. Note that after the authorization
* expires, it will need to be obtained again which make take some time in
* some cases as described above. However, build-in authoirzation
* providers used with this SDK are configured to refresh the
* authorization in background ahead of its expiration so that database
* operations may use existing authorization while the new one is obtained
* in the background.
*
* Calling this method is equivalient to calling
* {@link AuthorizationProvider#getAuthorization} method of authorization
* provider which will pre-cache the authorzation in the process, so if
* using custom {@link AuthorizationProvider} that does not cache
* authorzation, this method will have no effect.
*
* This method does not take explicit timeout, but uses timeouts specified
* for authorization network requests for given built-in authorization
* provider. See properties {@link IAMConfig#timeout} and
* {@link KVStoreAuthConfig#timeout}.
* @example
* Using precacheAuth on new NoSQLClient instance.
* ```ts
* let client;
* try {
* client = await new NoSQLClient(config).precacheAuth();
* .....
* } finally {
* client?.close();
* }
* ```
* @async
* @returns {Promise} Promise of {@link NoSQLClient} of this instance
* @see {@link IAMConfig}
* @see {@link KVStoreAuthConfig}
* @see {@link AuthorizationProvider}
*/
precacheAuth(): Promise
* Operations using table DDL statements infer the table name from the
* statement itself, e.g. "CREATE TABLE mytable(...)". Table
* creation requires a valid {@link TableLimits} object to define
* the throughput and storage desired for the table. It is an
* error for TableLimits to be specified with a statement other
* than create or alter table.
*
* Note that these are potentially long-running operations, so the
* result returned by this API does not imply operation completion
* and the table may be in an intermediate state. (see {@link
* TableState}). The caller should use the {@link NoSQLClient#getTable}
* method to check the status of the operation or
* {@link NoSQLClient#forCompletion} to asynchronously wait for the
* operation completion.
*
* Alternatively, if {@link TableDDLOpt#complete} is set to true, this API
* will complete (i.e. the returned Promise will resolve) only
* when the operation is completed and the table reaches state
* {@link TableState.ACTIVE} or {@link TableState.DROPPED} (if the
* operation was "DROP TABLE"). This is equivalent to sequentially
* executing {@link NoSQLClient#tableDDL} and
* {@link NoSQLClient#forCompletion}. In this case,
* {@link TableDDLOpt#timeout} covers the whole time interval until
* operation completion.
* If not specified, separate default timeouts are used for issuing the
* DDL operation and waiting for its completion, with values of
* {@link Config#ddlTimeout} and {@link Config#tablePollTimeout}
* correspondingly (the latter defaults to no timeout if
* {@link Config#tablePollTimeout} is not set). You may also use
* {@link TableDDLOpt#delay} to specify polling delay (see
* {@link NoSQLClient#forCompletion}).
* @async
* @param {string} stmt SQL statement
* @param {TableDDLOpt} [opt] Options object, see {@link TableDDLOpt}
* @returns {Promise} Promise of {@link TableResult}
* @see {@link TableResult}
* @see {@link forCompletion}
*/
tableDDL(stmt: string, opt?: TableDDLOpt): Promise
* Sets new limits of throughput and storage for existing table.
*
* Same considerations as described in {@link NoSQLClient#tableDDL} about
* long-running operations, using {@link NoSQLClient#forCompletion} and
* options {@link ModifyTableOpt#complete} and
* {@link ModifyTableOpt#delay} apply to this API.
* See {@link NoSQLClient#tableDDL}.
* @async
* @param {string} tableName Table name
* @param {TableLimits} tableLimits New table limits for the table
* @param {ModifyTableOpt} [opt] Options object, see
* {@link ModifyTableOpt}
* @returns {Promise} Promise of {@link TableResult}
* @see {@link TableResult}
* @see {@link NoSQLClient#tableDDL}
*/
setTableLimits(tableName: string, tableLimits: TableLimits,
opt?: ModifyTableOpt): Promise
* Sets defined and free-form tags on existing table.
* See {@link DefinedTags} and {@link FreeFormTags} for more
* information on tagging.
*
* Same considerations as described in {@link NoSQLClient#tableDDL} about
* long-running operations, using {@link NoSQLClient#forCompletion} and
* options {@link ModifyTableOpt#complete} and
* {@link ModifyTableOpt#delay} apply to this API.
* See {@link NoSQLClient#tableDDL}.
* @async
* @param {string} tableName Table name
* @param {DefinedTags} definedTags Cloud Service only. Defined tags
* to use for the operation. See {@link DefinedTags}. Pass
* undefined if you wish to set only free-form tags
* @param {FreeFormTags} [freeFormTags] Cloud Service only. Free-form
* tags to use for the operation. See {@link FreeFormTags}. Pass
* undefined (or omit if not using opt parameter) if you
* wish to set only defined tags.
* @param {ModifyTableOpt} [opt] Options object, see
* {@link ModifyTableOpt}
* @returns {Promise} Promise of {@link TableResult}
* @see {@link DefinedTags}
* @see {@link FreeFormTags}
* @see {@link TableResult}
* @see {@link NoSQLClient.tableDDL}
*/
setTableTags(tableName: string, definedTags: DefinedTags|undefined,
freeFormTags?: FreeFormTags, opt?: ModifyTableOpt):
Promise
* Table DDL operations are operations initiated by {@link tableDDL}.
* These are potentially long-running operations and {@link TableResult}
* returned by {@link tableDDL} does not imply operation completion.
* {@link forCompletion} takes {@link TableResult} as an argument and
* completes (i.e. the returned {@link !Promise | Promise} resolves) when
* the corresponding operation is completed by the service. This is
* accomplished by polling the operation state at specified intervals
* using {@link getTable} until the table state becomes
* {@link TableState.ACTIVE} for all operations except "DROP TABLE", in
* the latter case polling until the table state becomes
* {@link TableState.DROPPED}.
*
* The result of this method is {@link TableResult} representing the state
* of the operation at the last poll. If the operation fails, this method
* will result in error (i.e. the returned {@link !Promise | Promise} will
* reject with an error) contaning information about the operation
* failure.
*
* Note that on operation completion, the passed {@link TableResult} is
* modified in place (to reflect operation completion) in addition to
* being returned.
*
* As a more convenient way to perform table DDL operations to completion,
* you may pass {@link TableDDLOpt#complete} to {@link tableDDL}. In this
* case, after table DDL operation is initiated, {@link tableDDL} will use
* {@link forCompletion} to await operation completion.
* @example
* Using forCompletion with table DDL operation.
* ```ts
* try {
* let res = await client.tableDDL('DROP TABLE.....');
* await client.forCompletion(res);
* } catch(err) {
* // May be caused by client.forCompletion() if long running table
* // DDL operation was unsuccessful.
* }
* ```
* @async
* @param {TableResult} res Result of {@link NoSQLClient#tableDDL}. This
* result is modified by this method on operation completion
* @param {CompletionOpt} [opt] Options object, see {@link CompletionOpt}
* @returns {Promise} Promise of {@link TableResult}, which is the object
* passed as first argument and modified to reflect operation completion
* @see {@link NoSQLClient#tableDDL}
* @see {@link NoSQLClient#getTable}
* @see {@link TableResult}
*/
forCompletion(res: TableResult, opt?: CompletionOpt):
Promise
* Admin DDL operations are operations initiated by {@link adminDDL}.
* These are potentially long-running operations and {@link AdminResult}
* returned by {@link adminDDL} does not imply operation completion.
* {@link forCompletion} takes {@link AdminResult} as an argument
* and completes (i.e. the returned {@link !Promise | Promise} resolves)
* when the corresponding operation is completed by the service. This is
* accomplished by polling the operation state at specified intervals
* using {@link adminStatus} until the state of operation becomes
* {@link AdminState.COMPLETE}.
*
* The result of this method is {@link AdminResult} representing the state
* of the operation at the last poll. If the operation fails, this method
* will result in error (i.e. the returned {@link !Promise | Promise} will
* reject with an error) contaning information about the operation
* failure.
*
* Note that on operation completion, the passed {@link AdminResult} is
* modified in place (to reflect operation completion) in addition to
* being returned.
*
* As a more convenient way to perform admin DDL operations to completion,
* you may pass {@link AdminDDLOpt#complete} to {@link adminDDL}. In this
* case, after DDL operation is initiated, {@link adminDDL} will use
* {@link forCompletion} to await operation completion.
* @example
* Using forCompletion with admin DDL operation.
* ```ts
* try {
* res = await client.adminDDL('CREATE NAMESPACE.....');
* await client.forCompletion(res);
* } catch(err) {
* // May be caused by client.forCompletion() if long running admin
* // DDL operation was unsuccessful.
* }
* ```
* @async
* @param {AdminResult} res Result of {@link NoSQLClient#adminDDL}. This
* result is modified by this method on operation completion
* @param {CompletionOpt} [opt] Options object, see {@link CompletionOpt}
* @returns {Promise} Promise of {@link AdminResult}, which is the object
* passed as first argument and modified to reflect operation completion
* @see {@link NoSQLClient#adminDDL}
* @see {@link NoSQLClient#adminStatus}
* @see {@link AdminResult}
*/
forCompletion(res: AdminResult, opt?: CompletionOpt):
Promise
* This API is used to ensure that the table is ready for data
* operations after it has been created or altered. It should only be used
* if the table DDL operation has been performed outside of the current
* flow of control (e.g. by another application) such that the
* {@link TableResult} of the DDL operation is not available. To wait for
* completion of the table DDL operation that you issued, use
* {@link NoSQLClient#forCompletion}. This API waits until
* the table has transitioned from an intermediate state like
* {@link TableState.CREATING} or {@link TableState.UPDATING} to a
* stable state like {@link TableState.ACTIVE}, at which point it
* can be used.
*
* The result of this operation, if successful, is a {@link TableResult}
* that shows the table state from the last poll. The
* state of {@link TableState.DROPPED} is treated specially in
* that it will be returned as success, even if the table does not
* exist. Other states will throw an exception if the table is not
* found.
* @async
* @param {string} tableName Table name
* @param {TableState} tableState Desired table state
* @param {CompletionOpt} [opt] Options object, see {@link CompletionOpt}
* @returns {Promise} Promise of {@link TableResult} representing
* result of the last poll
* @see {@link NoSQLClient#getTable}
* @see {@link NoSQLClient#tableDDL}
* @see {@link NoSQLClient#forCompletion}
*/
forTableState(tableName: string, tableState: TableState,
opt?: CompletionOpt): Promise
* Retrieves dynamic information associated with a table, as returned in
* {@link TableUsageResult}. This information includes a time series of
* usage snapshots, each indicating data such as read and write
* throughput, throttling events, etc, as found in {@link TableUsage}.
*
* Usage information is collected in time slices and returned in
* individual usage records. It is possible to return a range of usage
* records within a given time period. Unless the time period is
* specified, only the most recent usage record is returned. Usage records
* are created on a regular basis and maintained for a period of time.
* Only records for time periods that have completed are returned so that
* a user never sees changing data for a specific range.
*
* Because the number of table usage records can be very large, you may
* page the results over multiple calls to
* {@link NoSQLClient#getTableUsage} using
* {@link TableUsageOpt#startIndex} and {@link TableUsageOpt#limit}
* parameters as shown in the example. However, the
* recommended way is to call {@link NoSQLClient#tableUsageIterable} and
* iterate over its result.
* @example
* Paging over table usage records.
*
* We iterate until the number of returned table usage records becomes
* less than the limit (and possibly 0), which means that the last
* partial result has been received.
*
* Retrieves dynamic information associated with a table, as returned in
* {@link TableUsageResult}.
*
* Use this API when you need to retrieve a
* large number of table usage records and you wish to page the results
* rather than returning the whole list at once. The iteration is done
* by using for-await-of loop. The iteration is asynchronous and
* each step of the iteration returns a Promise of
* {@link TableUsageResult}. Using this API is equivalent to paging table
* usage records as shown in the example of
* {@link NoSQLClient#getTableUsage}.
*
* Note that you must specify a time range (at least one of
* {@link TableUsageOpt#startTime} and {@link TableUsageOpt#endTime} for
* which to return table usage records, otherwise only one (the most
* recent) table usage record will be returned.
*
* You may optionally specify a limit on the number of table usage records
* returned in each partial result using {@link TableUsageOpt#limit}. If
* not specified, a default system limit will be used.
* @example
* Paging table usage records.
* ```ts
* const now = Date.now();
*
* const opt = {
* startTime: now - 3600 * 1000, // last 1 hour
* endTime: now,
* limit: 100
* };
*
* for await(const res of client.tableUsageIterable('MyTable', opt)) {
* for(const rec of res.usageRecords) {
* console.log(rec);
* }
* }
* ```
* @param {string} tableName Table name
* @param {TableUsageOpt} [opt] Options object, see {@link TableUsageOpt}
* @returns {AsyncIterable} Async iterable of {@link TableUsageResult}
* @see {@link #getTableUsage}
* @since 5.4
*/
tableUsageIterable(tableName: string, opt?: TableUsageOpt):
AsyncIterable
* It is not possible to put part of a row. Any fields that are not
* provided will be defaulted, overwriting any existing value. Fields that
* are not nullable or defaulted must be provided or the operation will
* fail.
*
* By default a put operation is unconditional, but put operations can be
* conditional based on existence, or not, of a previous value as well as
* conditional on the {@link RowVersion} of the existing value:
*
* It is also possible to return information about the existing row.
* The row, including its {@link RowVersion} and modification time can be
* optionally returned as part of {@link PutResult} via properties
* {@link PutResult#existingRow}, {@link PutResult#existingVersion} and
* {@link PutResult#existingModificationTime}.
* The existing row information will only be returned if
* {@link PutOpt#returnExisting} is true and one of the following occurs:
*
* The information about the result of the put operation is returned as
* {@link PutResult}. Note that the failure cases discussed above that
* resulted from inability to satisfy {@link PutOpt#ifAbsent},
* {@link PutOpt#ifPresent} or {@link PutOpt#matchVersion} options are
* still considered successful as API calls, i.e. they result in
* {@link PutResult} and not {@link NoSQLError}. See
* {@link PutResult#success}. However if put fails for other reasons,
* this API call will result in error instead.
*
* @async
* @typeParam TRow Type of table row instance. Must include primary key
* fields. Defaults to {@link AnyRow}.
* @param {string} tableName Table name
* @param {TRow} row Table row
* @param {PutOpt} [opt] Options object, see {@link PutOpt}
* @returns {Promise} Promise of {@link PutResult}
* @see {@link AnyRow}
* @see {@link RowVersion}
* @see {@link TimeToLive}
* @see {@link PutResult}
*/
put
* By default a delete operation is unconditional and will succeed if the
* specified row exists. Delete operations can be made conditional based
* on whether the {@link RowVersion} of an existing row matches that
* supplied {@link DeleteOpt#matchVersion}.
*
* It is also possible to return information about the existing row. The
* row, its version and modification time can be optionally returned as
* part of {@link DeleteResult} via properties
* {@link DeleteResult#existingRow}, {@link DeleteResult#existingVersion}
* and {@link DeleteResult#existingModificationTime}. The existing row
* information will only be returned if {@link DeleteOpt#returnExisting}
* is true and one of the following occurs:
*
* The information about the result of the delete operation is returned as
* {@link DeleteResult}. Note that the failures to delete if the row
* doesn't exist or if {@link DeleteOpt#matchVersion} is set and the
* version did not match are still considered successful as API calls,
* i.e. they result in {@link DeleteResult} and not {@link NoSQLError},
* see {@link DeleteResult#success}. However if delete fails for other
* reasons, this API call will result in error instead.
* @async
* @typeParam TRow Type of table row instance. Must include primary key
* fields. Defaults to {@link AnyRow}.
* @param {string} tableName Table name
* @param {RowKey
* The information about the result of this operation will be returned as
* {@link MultiDeleteResult}.
*
* Because this operation can exceed the maximum amount of data modified
* in a single operation it is possible that it will delete only part of
* the range of rows and a continuation key will be set in
* {@link MultiDeleteResult} that can be used to continue the operation.
* @async
* @typeParam TRow Type of table row instance. Must include primary key
* fields. Defaults to {@link AnyRow}.
* @param {string} tableName Table name
* @param {Key} key Partial primary key
* @param {MultiDeleteOpt} [opt] Options object, {@link MultiDeleteOpt}
* @returns {Promise} Promise of {@link MultiDeleteResult}
* @see {@link AnyKey}
* @see {@link FieldRange}
* @see {@link MultiDeleteResult}
*/
deleteRange
* There are some size-based limitations on this operation:
*
* Note that in addition to {@link WriteMultipleOpt} passed to this API,
* each sub operation can pass its own put or delete options in
* {@link WriteOperation} Each option explicitly set in
* {@link WriteOperation} will take precedence over its value in
* {@link WriteMultipleOpt}, otherwise {@link WriteMultipleOpt} can be
* used to specify options that should be the same for all sub operations.
*
* It is possible to issue operations for multiple tables as long as
* these tables have the same shard key. This means that these tables
* must be part of the same parent/child table hierarchy that has a single
* ancestor table specifying the shard key (you may include operations for
* this ancestor table and/or any of its descendants). To issue
* operations for multiple tables, use the overload of this API without
* the tableName and specify table per operation as
* {@link WriteOperation#tableName}.
* @overload
* @async
* @typeParam TRow Type of table row instance. Must include primary key
* fields. Defaults to {@link AnyRow}.
* @param {string} tableName Table name, if all operations are for a
* single table. If issuing operations for multiple tables, use the
* overload without tableName parameter. Specifying
* tableName parameter together with
* {@link WriteOperation#tableName} for any operation will result in error
* @param {WriteOperation[]} operations Array of
* {@link WriteOperation} objects each representing single put or delete
* operation, see {@link WriteOperation}
* @param {WriteMultipleOpt} [opt] Options object, see
* {@link WriteMultipleOpt}
* @returns {Promise} Promise of {@link WriteMultipleResult}
*/
writeMany
* The result of this operation is {@link PreparedStatement}. It supports
* bind variables in queries which can be used to more easily reuse a
* query by parameterization, see {@link PreparedStatement} for details.
* @async
* @param {string} stmt Query SQL statement
* @param {PrepareOpt} [opt] Options object, see {@link PrepareOpt}.
* @returns {Promise} Promise of {@link PreparedStatement}
*/
prepare(stmt: string, opt?: PrepareOpt): Promise
* Queries that include a full shard key will execute much more
* efficiently than more distributed queries that must go to multiple
* shards.
*
* DDL-style queries such as "CREATE TABLE ..." or "DROP TABLE .." are not
* supported by this API. Those operations must be performed using
* {@link NoSQLClient#tableDDL}.
*
* For performance reasons prepared queries are preferred for queries that
* may be reused. Prepared queries bypass compilation of the query. They
* also allow for parameterized queries using bind variables, see
* {@link NoSQLClient#prepare}.
*
* The result of this operation is returned as {@link QueryResult}. It
* contains array of result records and may contain continuation key as
* {@link QueryResult#continuationKey}.
*
* The amount of data read by a single query request is limited by a
* system default and can be further limited by setting
* {@link QueryOpt#maxReadKB}. This limits the amount of data
* read and not the amount of data returned, which means
* that a query can return zero results but still have more data to read.
* This situation is detected by checking if the {@link QueryResult} has a
* continuation key. In addition, number of results returned by the query
* may be explicitly limited by setting {@link QueryOpt#limit}. For this
* reason queries should always operate in a loop, acquiring more results,
* until the continuation key is null, indicating that the query is done.
* Inside the loop the continuation key is applied to
* {@link NoSQLClient#query} by setting {@link QueryOpt#continuationKey}.
*
* The easier way to iterate over query results is by using
* {@link NoSQLClient#queryIterable}, in which case you do not need to
* deal with continuaton key.
*
* @async
* @typeParam TRow Type that represent the shape of query result record.
* This may be different from the shape of table row. Defaults to
* {@link AnyRow}
* @param {string|PreparedStatement} stmt Query statement, can be either
* SQL query string or a prepared query represented as
* {@link PreparedStatement}, see {@link NoSQLClient#prepare}
* @param {QueryOpt} [opt] Options object, see {@link QueryOpt}
* @returns {Promise} Promise of {@link QueryResult}
* @see {@link NoSQLClient#queryIterable}
*/
query
* Note that calling this API by itself does not start
* the query, the query is started when starting the iteration via
* for-await-of loop.
*
* The returned iterable cannot be reused for multiple queries.
* To execute another query, call {@link NoSQLClient#queryIterable} again
* to create a new iterable.
*
* All other considerations described in {@link NoSQLClient#query} apply
* when using this API.
* @example
* Using {@link queryIterable}.
* ```ts
* try {
* const stmt = 'SELECT * from orders';
* for await(const res of client.queryIterable(stmt)) {
* console.log(`Retrieved ${res.rows.length} rows`);
* // Do something with res.rows
* }
* } catch(err) {
* // handle errors
* }
* ```
* @typeParam TRow Type that represent the shape of query result record.
* This may be different from the shape of table row. Defaults to
* {@link AnyRow}
* @param {string|PreparedStatement} stmt Query statement, same as for
* {@link NoSQLClient#query}
* @param {QueryOpt} [opt] Options object, see <@link QueryOpt>
* @returns {AsyncIterable} Async iterable of {@link QueryResult}
* @see {@link NoSQLClient#query}
*/
queryIterable
* Performs an administrative operation on the system. The operations
* allowed are defined by Data Definition Language (DDL) portion of the
* query language that do not affect a specific table. For table-specific
* DLL operations use {@link NoSQLClient#tableDDL}.
*
* Examples of statements passed to this method include:
*
*
* Note that these are potentially long-running operations, so the
* result returned by this API does not imply operation completion. The
* caller should use the {@link NoSQLClient#adminStatus} method to check
* the status of the operation or {@link NoSQLClient#forCompletion} to
* asynchronously wait for the operation completion.
*
* Alternatively, if {@link AdminDDLOpt#complete} is set to true, this API
* will complete (i.e. the returned {@link !Promise | Promise} will
* resolve) only when the operation is completed. This is equivalent to
* sequentially executing {@link NoSQLClient#adminDDL} and
* {@link NoSQLClient#forCompletion}. In this case,
* {@link AdminDDLOpt#timeout} covers the whole time interval until
* operation completion. If not specified, separate default timeouts are
* used for issuing the DDL operation and waiting for its completion, with
* values of {@link Config#ddlTimeout} and {@link Config#adminPollTimeout}
* correspondingly (the latter defaults to no timeout if
* {@link Config#adminPollTimeout} is not set). You may also use
* {@link AdminDDLOpt#delay} to specify polling delay (see
* {@link NoSQLClient#forCompletion}).
*
* Note that some of the statements used by admin DDL may contain
* passwords in which case it is advisable to pass the statement as
* {@link !Buffer | Buffer} so that the memory can be subsequently cleared
* by the application. The {@link !Buffer | Buffer} should contain the
* statement as UTF-8 encoded string.
*
* @async
* @param {Buffer|string} stmt Statement for the operation as string or
* Buffer containing UTF-8 encoded string
* @param {AdminDDLOpt} [opt] Options object, see {@link AdminDDLOpt}
* @returns {Promise} Promise of {@link AdminResult}
* @see {@link AdminResult}
* @see {@link NoSQLClient#forCompletion}
*/
adminDDL(stmt: Buffer | string, opt?: AdminDDLOpt): Promise
* Check the status of the operation performed by
* {@link NoSQLClient#adminDDL}. Returns the status of the operation
* as {@link AdminResult}, that includes operation state and operation
* output if any.
* @async
* @param {AdminResult} adminResult Result returned by
* {@link NoSQLClient#adminDDL}
* @param {AdminStatusOpt} [opt] Options object, {@link AdminStatusOpt}
* @returns {Promise} Promise of {@link AdminResult}
* @see {@link NoSQLClient#adminDDL}
* @see {@link AdminResult}
*/
adminStatus(adminResult: AdminResult, opt?: AdminStatusOpt):
Promise
* Returns the namespaces in the store as an array of strings. If no
* namespaces are found, empty array is returned.
*
* This operation entails executing admin DDL and waiting for the
* operation completion.
* @async
* @param {AdminListOpt} [opt] Options object, {@link AdminListOpt}
* @returns {Promise} Promise of string[] of namespace names
* @see {@link NoSQLClient#adminDDL}
*/
listNamespaces(opt?: AdminListOpt): Promise
* Returns the users in the store as an array of {@link UserInfo}. If no
* users are found, empty array is returned.
*
* This operation entails executing admin DDL and waiting for the
* operation completion.
* @async
* @param {AdminListOpt} [opt] Options object, {@link AdminListOpt}
* @returns {Promise} Promise of {@link UserInfo}[] of objects containing
* information about each user
* @see {@link UserInfo}
* @see {@link NoSQLClient#adminDDL}
*/
listUsers(opt?: AdminListOpt): Promise
* Returns the roles in the store as an array of strings. If no
* roles are found, empty array is returned.
*
* This operation entails executing admin DDL and waiting for the
* operation completion.
* @async
* @param {AdminListOpt} [opt] Options object, {@link AdminListOpt}
* @returns {Promise} Promise of string[] of role names
* @see {@link NoSQLClient#adminDDL}
*/
listRoles(opt?: AdminListOpt): Promise
* Adds replica to a table.
*
* This operation adds replica to a Global Active table. If performed on
* a regular table (singleton), it will be converted to Global Active
* table, provided that the sigleton table schema conforms to certain
* restrictions. For more information, see
* {@link https://docs.oracle.com/en/cloud/paas/nosql-cloud/gasnd | Global Active Tables in NDCS}.
*
* Note that {@link TableLimits} for the replica table will default to
* the table limits for the existing table, however you can override
* the values of {@link TableLimits#readUnits} and
* {@link TableLimits#writeUnits} for the replica by using
* {@link AddReplicaOpt#readUnits} and {@link AddReplicaOpt#writeUnits}.
* The storage capacity of the replica will always be the same as that of
* the existing table.
*
* As with {@link tableDDL}, the result returned from this API does not
* imply operation completion. Same considerations as described in
* {@link tableDDL} about long-running operations apply here, including
* using {@link forCompletion} and options
* {@link ModifyTableOpt#complete} and {@link ModifyTableOpt#delay}. See
* {@link NoSQLClient#tableDDL}.
*
* Note that even after this operation is completed (as described above),
* the replica table in the receiver region may still be in the process of
* being initialized with the data from the sender region, during which
* time the data operations on the replica table will fail with
* {@link ErrorCode.TABLE_NOT_READY}.
* @async
* @param tableName Table name
* @param region Region where to add the replica
* @param opt Options object, see {@link AddReplicaOpt}
* @returns {Promise} Promise of {@link TableResult}
* @see {@link AddReplicaOpt}
* @see {@link TableResult}
*/
addReplica(tableName: string, region: Region|string,
opt?: AddReplicaOpt) : Promise
* Drops replica from a table.
*
* This operation drops replica from a Global Active table. For more
* information, see
* {@link https://docs.oracle.com/en/cloud/paas/nosql-cloud/gasnd | Global Active Tables in NDCS}.
*
* As with {@link tableDDL}, the result returned from this API does not
* imply operation completion. Same considerations as described in
* {@link tableDDL} about long-running operations apply here, including
* using {@link forCompletion} and options
* {@link ModifyTableOpt#complete} and {@link ModifyTableOpt#delay}. See
* {@link NoSQLClient#tableDDL}.
* @async
* @param tableName Table name
* @param region Region from where to drop the replica
* @param opt Options object, see {@link ModifyTableOpt}
* @returns {Promise} Promise of {@link TableResult}
* @see {@link ModifyTableOpt}
* @see {@link TableResult}
*/
dropReplica(tableName: string, region: Region|string,
opt?: ModifyTableOpt) : Promise
* This method waits asynchronously for local table replica to complete
* its initialization.
*
* After table replica is created, it needs to be initialized by copying
* the data (if any) from the sender region. During this initialization
* process, even though the table state of the replica table is
* {@link TableState.ACTIVE}, data operations cannot be performed on the
* replica table.
*
* This method is used to ensure that the replica table is ready for data
* operations by asynchronously waiting for the initialization process to
* complete. It works similar to {@link forCompletion} by polling the
* table state at regular intervals until
* {@link TableResult#isLocalReplicaInitialized} is true.
*
* Note that this operation must be performed in the receiver region
* where the table replica resides (not in the sender region from where
* the replica was created), meaning that this {@link NoSQLClient}
* instance must be configured with the receiver region (see
* {@link Config#region}).
* @async
* @param tableName Table name
* @param opt Options object, see {@link CompletionOpt}
* @returns {Promise} Promise of {@link TableResult}
* @see {@link https://docs.oracle.com/en/cloud/paas/nosql-cloud/gasnd | Global Active Tables in NDCS}.
* @see {@link addReplica}
* @see {@link TableResult#isLocalReplicaInitialized}
* @see {@link forCompletion}
* @see {@link forTableState}
*/
forLocalReplicaInit(tableName: string, opt?: CompletionOpt):
Promise
* Gets replica statistics information.
*
* This operation retrieves stats information for the replicas of a Global
* Active table. This information includes a time series of replica stats,
* as found in {@link ReplicaStats}. For more information on Global Active
* tables, see
* {@link https://docs.oracle.com/en/cloud/paas/nosql-cloud/gasnd | Global Active Tables in NDCS}.
*
* It is possible to return a range of stats records or, by default, only
* the most recent stats records (up to the limit) for each replica if
* {@link ReplicaStatsOpt#startTime} is not specified. Replica stats
* records are created on a regular basis and maintained for a period of
* time. Only records for time periods that have completed are returned
* so that a user never sees changing data for a specific range.
*
* By default, this operation returns stats for all replicas as an object
* keyed by region id of each replica and values being an array of
* {@link ReplicaStats} per replica (see
* {@link ReplicaStatsResult#statsRecords}). You may limit the result to
* the stats of only one replica by providing its
* {@link ReplicaStatsOpt#region}.
*
* Because the number of replica stats records can be very large, each
* call to {@link getReplicaStats} returns a limited number of records
* (the default limit is 1000). You can customize this limit via
* {@link ReplicaStatsOpt#limit} option. You can retrive large number of
* replica stats records over multiple calls to {@link getReplicaStats} by
* setting {@link ReplicaStatsOpt#startTime} on each subsequent call to
* the value of {@link ReplicaStatsResult#nextStartTime} returned by a
* previous call.
* @async
* @param tableName Table name
* @param opt Options object, see {@link ReplicaStatsOpt}.
* @returns {Promise} Promise of {@link ReplicaStatsResult}
* @see {@link ReplicaStatsOpt}
* @see {@link ReplicaStatsResult}
*/
getReplicaStats(tableName: string, opt?: ReplicaStatsOpt) :
Promise
*
* Note that only one of {@link PutOpt#ifAbsent}, {@link PutOpt#ifPresent}
* or {@link PutOpt#matchVersion} options may be specified for given put
* operation.
*
*
* Use of {@link PutOpt#returnExisting} may result in additional consumed
* read capacity.
*
*
* Use of {@link DeleteOpt#returnExisting} may result in additional
* consumed read capacity.
*
*
* The result of this operation is returned as
* {@link WriteMultipleResult}. On successful completion, it will store
* array of the execution results of all sub operations. If this
* operation was aborted because of failure of a sub operation which has
* {@link WriteOperation#abortOnFail} set to true, or if
* {@link WriteMultipleOpt#abortOnFail} is true, then the index and
* execution result of the failed sub operation will be stored in
* {@link WriteMultipleResult} (thus the API call in this case is still
* successful and no error results).
*
*
* This API may be more convenient to use than
* {@link NoSQLClient#writeMany} when applicable.
* @async
* @typeParam TRow Type of table row instance. Must include primary key
* fields. Defaults to {@link AnyRow}.
* @param {string} tableName
* @param {TRow[]} rows Array of rows to put
* @param {PutManyOpt} [opt] Options object, see {@link PutManyOpt}
* @returns {Promise} Promise of {@link WriteMultipleResult}
* @see {@link writeMany}
*/
putMany
*
* This API may be more more convenient to use than
* {@link NoSQLClient#writeMany} when applicable.
* @async
* @typeParam TRow Type of table row instance. Must include primary key
* fields. Defaults to {@link AnyRow}.
* @param {string} tableName
* @param {TKey[]} keys Array of primary keys to delete
* @param {DeleteManyOpt} [opt] Options object, see {@link DeleteManyOpt}
* @returns {Promise} Promise of {@link WriteMultipleResult}
* @see {@link writeMany}
*/
deleteMany
*
*