domino-db Reference
This page describes each domino-db class and function in detail. To navigate between sections, use the table of contents on the right.
DominoDB class
The DominoDB class is the single export of this module. You use DominoDB to obtain references to other classes.
useServer
A factory function for instantiating a Server instance.
NOTE: This function does not make any requests to Domino for verification of the configuration.
Parameters
configuration
{Object
}: The configuration passed for binding
hostName
{string
}: The host name of the Domino server (ex: "demo.host.com")connection
{Object
}: The connection properties used for requests sent to the Domino server
port
{string
}: The Proton portsecure
{boolean
}:true
if TLS is enabled on the above portcredentials
{Object
}: The credentials used for secure requests.
rootCertificate
{Buffer
}: Required if TLS is enabled.clientCertificate
{Buffer
}: Required if TLS is enabled.clientKey
{Buffer
}: Required if TLS is enabled.idFilePassword
{string
}: Required only if you intend to use this server instance to encrypt and decrypt documents. This feature assumes the target server has access to an ID vault and the identity specified byclientCertificate
has an ID file in the vault. See Item encryption and decryption for details.
Return Value
{
Promise
<Server
>}
A promise resolved with a deeply frozen Server class reference. If the configuration parameters are invalid, the promise will be rejected with an error message.
Example
const { useServer } = require('@domino/domino-db');
const config = {
hostName: 'www.demo.domain.com',
};
useServer(config)
.then(server => {
// server is available for use. See "Server" docs for class members
})
.catch(error => {
// server configuration is malformed
console.log(error);
});
Server class
You obtain an instance of Server
by calling DominoDB::useServer.
You use Server::useDatabase to obtain a reference to a Database
.
See below for a description of additional Server
functions.
useDatabase
A factory function for instantiating a Database instance that is bound to a specific database.
NOTE: This function does not make any requests to Domino for verification of the configuration.
Parameters
configuration
{Object
} The configuration passed for binding
filePath
{string
} The path to the database, relative to the Domino data directory
Return Value
{
Promise
<Database
>} A promise resolved with an instance of the Database class, bound with the configuration information.
Example
const { useServer } = require('@domino/domino-db');
const config = require('./server-config.js');
useServer(config)
.then(async server => {
const database = await server.useDatabase({
filePath: '/example/directory/demo.nsf',
});
// database is available for use. See "Database" docs for class members
})
.catch(error => {
// Either "config" is malformed OR databaseConfig is malformed.
console.log(error);
});
getHostName
A getter function which returns the Domino server host name.
Return Value
{
Promise
<string
>} A promise resolved with the Domino server host name.
Example
const { useServer } = require('@domino/domino-db');
const config = require('./server-config.js'); // { ... "hostName": "foo.bar" }
useServer(config).then(async server => {
const hostName = await server.getHostName();
console.log(hostName); // foo.bar
});
getConnection
A getter function which returns the connection properties used to access the Domino server.
Return Value
{
Promise
<Object
>} A promise resolved with the value of the connection object.
Example
const { useServer } = require('@domino/domino-db');
// { ... "connection": {
// "port": "3003",
// }
const config = require('./server-config.js');
useServer(config).then(async server => {
const connection = await server.getConnection();
console.log(connection.port); // 3003
});
Database class
You obtain an instance of Database
by calling Server::useDatabase.
You use Database::useDocument to obtain an instance of a Document
.
See below for a description of other Database
functions.
useDocument
A factory function for instantiating a Document instance that is bound to a specific document.
NOTE: This function does not make any requests to Domino for verification of the configuration.
Parameters
configuration
{Object
}
unid
{string
} The unid of the document.
Return Value
{
Promise
<Document
>} A promise resolved with an instance of the Document class, bound with the unid provided.
Example
const { useServer } = require('@domino/domino-db');
const serverConfig = require('./server-config.js');
const databaseConfig = require('./database-config.js');
useServer(serverConfig).then(async server => {
const database = await server.useDatabase(databaseConfig);
const document = await database.useDocument({
unid: '12345678901234567890123456789012',
});
// document is available for use. See "Document" docs for class members
});
createDocument
Creates a document.
Parameters
options
{Object
}
document
{Object
} REQUIRED - The new document contents. See domino-db document schema for information about representing a document as a JavaScript object.
Return Value
{
Promise
<string
>} A promise resolved with the UNID of the new document
Example
const { useServer } = require('@domino/domino-db');
const serverConfig = require('./server-config.js');
const databaseConfig = require('./database-config.js');
useServer(serverConfig).then(async server => {
const database = await server.useDatabase(databaseConfig);
const unid = await database.createDocument({
document: {
Form: 'Contact',
FirstName: 'Aaron',
LastName: 'Aardman',
City: 'Arlington',
State: 'MA',
},
});
// unid is the unique identifier of the new document
});
bulkCreateDocuments
Creates multiple documents. To create a single document, see Database::createDocument.
Parameters
options
{Object
}
documents
{Array
<Object
>} REQUIRED - An array of new documentsonErrorOptions
{string
} A optional string specifying what to do when an error occurs. Must be either"ON_ERROR_CONTINUE"
or"ON_ERROR_ABORT_REMAINING"
.
Return Value
{
Promise
<Object
>} A promise resolved with a BulkResponse object.
Example
const { useServer } = require('@domino/domino-db');
const serverConfig = require('./server-config.js');
const databaseConfig = require('./database-config.js');
useServer(serverConfig).then(async server => {
const database = await server.useDatabase(databaseConfig);
const response = await database.bulkCreateDocuments({
documents: [
{
Form: 'Contact',
FirstName: 'Aaron',
LastName: 'Aardman',
City: 'Arlington',
State: 'MA',
},
{
Form: 'Contact',
FirstName: 'Brian',
LastName: 'Aardman',
City: 'Andover',
State: 'MA',
},
],
});
// response.documents is an array of objects. Map to an
// array of UNIDs.
const unids = response.documents.map(doc => doc['@unid']);
});
bulkReadDocuments
Reads all documents matching a query string. For the query syntax, see Domino Query Langauge.
Parameters
options
{Object
}
query
{string
} REQUIRED - A query string.queryArgs
{Array
<Object
>} An optional array of values to substitute in the query string. See Query arguments for details.queryLimits
{Object
} An optional set of limits on the query.
maxViewEntriesScanned
{number
} The maximum number of view entries to scan.maxDocumentsScanned
{number
} The maximum number of documents to scan.maxMilliSeconds
{number
} The maximum number of milliseconds to spend executing the query.itemNames
{Array
<string
>} An optional array of item names. Use this option to read selected items. The default is to read no document items.start
{number
} An optional zero-based start index. Use this to page through a large set of matching documents.count
{number
} An optional count of the maximum number of documents to read.onErrorOptions
{string
} A optional string specifying what to do when an error occurs. Must be either"ON_ERROR_CONTINUE"
or"ON_ERROR_ABORT_REMAINING"
.
Return Value
{
Promise
<Object
>} A promise resolved with a BulkResponse object.
Example
const { useServer } = require('@domino/domino-db');
const serverConfig = require('./server-config.js');
const databaseConfig = require('./database-config.js');
useServer(serverConfig).then(async server => {
const database = await server.useDatabase(databaseConfig);
const documents = await database.bulkReadDocuments({
query: "Form = 'Contact' and LastName = 'Aardman'",
});
// documents is an array of documents -- one for each
// document that matches the query
});
bulkReadDocumentsByUnid
Reads multiple documents by UNID. To read a single document, see Document::read.
Parameters
options
{Object
}
unids
{Array
<string
>} REQUIRED - An array of UNIDs.itemNames
{Array
<string
>} An optional array of item names. Use this option to read selected items. The default is to read no document items.onErrorOptions
{string
} A optional string specifying what to do when an error occurs. Must be either"ON_ERROR_CONTINUE"
or"ON_ERROR_ABORT_REMAINING"
.
Return Value
{
Promise
<Object
>} A promise resolved with a BulkResponse object.
Example
const { useServer } = require('@domino/domino-db');
const serverConfig = require('./server-config.js');
const databaseConfig = require('./database-config.js');
useServer(serverConfig).then(async server => {
const database = await server.useDatabase(databaseConfig);
const documents = await database.bulkReadDocumentsByUnid({
unids: [
'28438659F50E2637852582C600038599',
'5B5544335FA7D893852582C60003859A',
],
});
// documents is an array of documents -- one for each
// UNID in the unids array
});
bulkDeleteDocuments
Deletes all documents matching a query string.
Parameters
options
{Object
}
query
{string
} REQUIRED - A query string.queryArgs
{Array
<Object
>} An optional array of values to substitute in the query string. See Query arguments for details.queryLimits
{Object
} An optional set of limits on the query. See bulkReadDocuments for details.start
{number
} An optional zero-based document start index.count
{number
} An optional count of the maximum number of documents to delete.onErrorOptions
{string
} A optional string specifying what to do when an error occurs. Must be either"ON_ERROR_CONTINUE"
or"ON_ERROR_ABORT_REMAINING"
.
Return Value
{
Promise
<Object
>} A promise resolved with a BulkResponse object.
Example
const { useServer } = require('@domino/domino-db');
const serverConfig = require('./server-config.js');
const databaseConfig = require('./database-config.js');
useServer(serverConfig).then(async server => {
const database = await server.useDatabase(databaseConfig);
const response = await database.bulkDeleteDocuments({
query: "Form = 'Contact' and LastName = 'Aardman'",
});
// response.documents is an array of objects -- one for each
// document matching the query.
});
bulkDeleteDocumentsByUnid
Deletes multiple documents by UNID. To delete a single document, see Document::delete.
Parameters
options
{Object
}
unids
{Array
<string
>} REQUIRED - An array of UNIDs.onErrorOptions
{string
} A optional string specifying what to do when an error occurs. Must be either"ON_ERROR_CONTINUE"
or"ON_ERROR_ABORT_REMAINING"
.
Return Value
{
Promise
<Object
>} A promise resolved with a BulkResponse object.
Example
const { useServer } = require('@domino/domino-db');
const serverConfig = require('./server-config.js');
const databaseConfig = require('./database-config.js');
useServer(serverConfig).then(async server => {
const database = await server.useDatabase(databaseConfig);
const response = await database.bulkDeleteDocumentsByUnid({
unids: [
'28438659F50E2637852582C600038599',
'5B5544335FA7D893852582C60003859A',
],
});
// response.documents is an array of objects -- one for each
// UNID in the unids array.
});
bulkDeleteItems
Deletes selected items in all documents matching a query string.
Parameters
options
{Object
}
query
{string
} REQUIRED -- A query string.queryArgs
{Array
<Object
>} An optional array of values to substitute in the query string. See Query arguments for details.queryLimits
{Object
} An optional set of limits on the query. See bulkReadDocuments for details.itemNames
{Array
<string
>} REQUIRED - An array of item namesstart
{number
} An optional zero-based document start index.count
{number
} An optional count of the maximum number of documents to process.onErrorOptions
{string
} A optional string specifying what to do when an error occurs. Must be either"ON_ERROR_CONTINUE"
or"ON_ERROR_ABORT_REMAINING"
.
Return Value
{
Promise
<Object
>} A promise resolved with a BulkResponse object.
Example
const { useServer } = require('@domino/domino-db');
const serverConfig = require('./server-config.js');
const databaseConfig = require('./database-config.js');
useServer(serverConfig).then(async server => {
const database = await server.useDatabase(databaseConfig);
// Delete the EMail and Phone items for each document
// matching the query
const response = await database.bulkDeleteItems({
query: "Form = 'Contact' and LastName = 'Aardman'",
itemNames: ['EMail', 'Phone'],
});
// response.documents is an array of objects -- one for each
// document matching the query.
});
bulkDeleteItemsByUnid
Deletes selected items in multiple documents.
Parameters
options
{Object
}
unids
{Array
<string
>} REQUIRED - An array of UNIDs.itemNames
{Array
<string
>} REQUIRED - An array of item namesonErrorOptions
{string
} A optional string specifying what to do when an error occurs. Must be either"ON_ERROR_CONTINUE"
or"ON_ERROR_ABORT_REMAINING"
.
Return Value
{
Promise
<Object
>} A promise resolved with a BulkResponse object.
Example
const { useServer } = require('@domino/domino-db');
const serverConfig = require('./server-config.js');
const databaseConfig = require('./database-config.js');
useServer(serverConfig).then(async server => {
const database = await server.useDatabase(databaseConfig);
// Delete the EMail and Phone items for each document
// in the unids array
const response = await database.bulkDeleteItemsByUnid({
unids: [
'28438659F50E2637852582C600038599',
'5B5544335FA7D893852582C60003859A',
],
itemNames: ['EMail', 'Phone'],
});
// response.documents is an array of objects -- one for each
// UNID in the unids array.
});
bulkReplaceItems
Replaces selected items in all documents matching a query.
Parameters
options
{Object
}
query
{string
} REQUIRED - A query string.queryArgs
{Array
<Object
>} An optional array of values to substitute in the query string. See Query arguments for details.queryLimits
{Object
} An optional set of limits on the query. See bulkReadDocuments for details.replaceItems
{Object
} REQUIRED - An object containing items to replace in all matching documents.start
{number
} An optional zero-based document start index.count
{number
} An optional count of the maximum number of documents to process.onErrorOptions
{string
} A optional string specifying what to do when an error occurs. Must be either"ON_ERROR_CONTINUE"
or"ON_ERROR_ABORT_REMAINING"
.
Return Value
{
Promise
<Object
>} A promise resolved with a BulkResponse object.
Example
const { useServer } = require('@domino/domino-db');
const serverConfig = require('./server-config.js');
const databaseConfig = require('./database-config.js');
useServer(serverConfig).then(async server => {
const database = await server.useDatabase(databaseConfig);
// Replace City and State with same values for all
// matching documents.
const response = await database.bulkReplaceItems({
query: "Form = 'Contact' and LastName = 'Aardman'",
replaceItems: {
City: 'Chelmsford',
State: 'MA',
},
});
// response.documents is an array of objects -- one for each
// document matching the query.
});
bulkReplaceItemsByUnid
Replaces selected items in multiple documents by UNID.
Parameters
options
{Object
}
replaceItemsByUnid
{Array
<string
>} REQUIRED - An array of document objects. Each document object must include at least an@unid
property.replaceItems
{Object
} An optional object containing items to replace in all matching documents.onErrorOptions
{string
} A optional string specifying what to do when an error occurs. Must be either"ON_ERROR_CONTINUE"
or"ON_ERROR_ABORT_REMAINING"
.
Return Value
{
Promise
<Object
>} A promise resolved with a BulkResponse object.
Example
const { useServer } = require('@domino/domino-db');
const serverConfig = require('./server-config.js');
const databaseConfig = require('./database-config.js');
useServer(serverConfig).then(async server => {
const database = await server.useDatabase(databaseConfig);
// Replace FirstName and LastName with different values
// per document. Replace City and State with same values
// for all documents.
const response = await database.bulkReplaceItemsByUnid({
replaceItemsByUnid: [
{
'@unid': 'F0C617C4AF746BED852582B9006819F9',
FirstName: 'Aaron',
LastName: 'Aardman',
},
{
'@unid': '3EB633978241DD02852582B9006819FE',
FirstName: 'Brian',
LastName: 'Zelnick',
},
],
replaceItems: {
City: 'Chelmsford',
State: 'MA',
},
});
// response.documents is an array of objects -- one for each document
// in the replaceItemsByUnid array.
});
bulkReplaceDocumentsByUnid
Replaces multiple documents.
Parameters
options
{Object
}
documents
{Array
<Object
>} REQUIRED - An array of documents to update. Each document object must include an@unid
property.onErrorOptions
{string
} A optional string specifying what to do when an error occurs. Must be either"ON_ERROR_CONTINUE"
or"ON_ERROR_ABORT_REMAINING"
.
Return Value
{
Promise
<Object
>} A promise resolved with a BulkResponse object.
Example
const { useServer } = require('@domino/domino-db');
const serverConfig = require('./server-config.js');
const databaseConfig = require('./database-config.js');
useServer(serverConfig).then(async server => {
const database = await server.useDatabase(databaseConfig);
const response = await database.bulkReplaceDocumentsByUnid({
documents: [
{
'@unid': 'F0C617C4AF746BED852582B9006819F9',
Form: 'Contact',
FirstName: 'Aaron',
LastName: 'Aardman',
City: 'Arlington',
State: 'MA',
},
{
'@unid': '3EB633978241DD02852582B9006819FE',
Form: 'Contact',
FirstName: 'Brian',
LastName: 'Aardman',
City: 'Andover',
State: 'MA',
},
],
});
// response.documents is an array of objects -- one for each
// document in the documents array.
});
explainQuery
Explains how a query string is processed.
Parameters
options
{Object
}
query
{string
} REQUIRED - A query string.queryArgs
{Array
<Object
>} An optional array of values to substitute in the query string. See Query arguments for details.queryLimits
{Object
} An optional set of limits on the query. See bulkReadDocuments for details.
Return Value
{
Promise
<string
>} A promise resolved with explanation string
Example
const { useServer } = require('@domino/domino-db');
const serverConfig = require('./server-config.js');
const databaseConfig = require('./database-config.js');
useServer(serverConfig).then(async server => {
const database = await server.useDatabase(databaseConfig);
const explain = await database.explainQuery({
query: "Form = 'Contact' and LastName = 'Aardman'",
});
// explain is a string explaining how the query was
// processed on the server
});
getServer
A getter function which returns a reference to the Server
instance
this Database
is bound to.
Return Value
{
Promise
<Server
>} A promise resolved with the Server class instance
Example
const { useServer } = require('@domino/domino-db');
const serverConfig = require('./server-config.js');
const databaseConfig = require('./database-config.js');
useServer(serverConfig).then(async server => {
const database = await server.useDatabase(databaseConfig);
const databaseServer = await database.getServer();
console.log(databaseServer === server); // true
});
getFilePath
A getter function which returns the database's path, relative to the data directory. This is a getter function for the value passed to Server::useDatabase when creating this Database class.
Return Value
{
Promise
<string
>} A promise resolved with the path of the database
Example
const { useServer } = require('@domino/domino-db');
const serverConfig = require('./server-config.js');
// { filePath: 'projects/foo/test.nsf' }
const databaseConfig = require('./database-config.js');
useServer(serverConfig).then(async server => {
const database = await server.useDatabase(databaseConfig);
const path = await database.getFilePath();
console.log(path); // projects/foo/test.nsf
});
Document class
You obtain an instance of Document
by calling Database::useDocument.
See below for a description of each Document
function.
getDatabase
A getter function which returns a reference to the Database class instance that this Document is bound to
Return Value
{
Promise
<Server
>} A promise resolved with the Database class instance
Example
const { useServer } = require('@domino/domino-db');
const serverConfig = require('./server-config.js');
const databaseConfig = require('./database-config.js');
useServer(serverConfig).then(async server => {
const database = await server.useDatabase(databaseConfig);
const document = await database.useDocument({
unid: '28438659F50E2637852582C600038599',
});
const myDatabase = await document.getDatabase();
console.log(myDatabase === database); // true
});
getUnid
A getter function which returns the unid of the document. This is a getter function for the value passed to Database::useDocument when creating this Database class.
Return Value
{
Promise
<string
>} A promise resolved with the unid of this document
Example
const { useServer } = require('@domino/domino-db');
const serverConfig = require('./server-config.js');
const databaseConfig = require('./database-config.js');
useServer(serverConfig).then(async server => {
const database = await server.useDatabase(databaseConfig);
const document = await database.useDocument({
unid: '5B5544335FA7D893852582C60003859A',
});
const documentUnid = await document.getUnid();
console.log(documentUnid); // 5B5544335FA7D893852582C60003859A
});
read
Reads the specific document
Parameters
options
{Object
}
itemNames
{Array
<string
>} - Specifies the list of items expected in the response. For example,{ itemNames: ['FirstName', 'LastName'] }
requests items matching those item names. If the document includes items namedPhoto
, they are not included in the response.
Return Value
{
Promise
<Object
>} A promise resolved with the JSON document retrieved from the Domino server.
Example
const { useServer } = require('@domino/domino-db');
const serverConfig = require('./server-config.js');
const databaseConfig = require('./database-config.js');
useServer(serverConfig).then(async server => {
const database = await server.useDatabase(databaseConfig);
const document = await database.useDocument({
unid: '28438659F50E2637852582C600038599',
});
try {
const myDocument = await document.read();
/* myDocument:
{
@created string
The date the document was created.
@modified string
The last modification date of the document.
@unid string
The universal ID of the document.
< * >: {...}
}
*/
} catch (e) {
// network Error or Domino Error
}
});
replaceItems
Updates selected items in a document
Parameters
options
{Object
}
replaceItems
{Object
} REQUIRED - A partial document object, the portion of the document to update
Return Value
{
Promise
<undefined
>} A promise resolved withundefined
Example
const { useServer } = require('@domino/domino-db');
const serverConfig = require('./server-config.js');
const databaseConfig = require('./database-config.js');
useServer(serverConfig).then(async server => {
const database = await server.useDatabase(databaseConfig);
const document = await database.useDocument({
unid: '28438659F50E2637852582C600038599',
});
await document.replaceItems({
replaceItems: { demoMessage: 'This is a demo message' },
});
});
replace
Replaces all items in a document.
Parameters
options
{Object
}
document
{Object
} REQUIRED - The new document contents
Return Value
{
Promise
<undefined
>} A promise resolved withundefined
Example
const { useServer } = require('@domino/domino-db');
const serverConfig = require('./server-config.js');
const databaseConfig = require('./database-config.js');
useServer(serverConfig).then(async server => {
const database = await server.useDatabase(databaseConfig);
const document = await database.useDocument({
unid: '28438659F50E2637852582C600038599',
});
await document.replace({
document: { demoMessage: 'This is a demo message' },
});
});
delete
Deletes a document
Return Value
{
Promise
<undefined
>} A promise resolved withundefined
Example
const { useServer } = require('@domino/domino-db');
const serverConfig = require('./server-config.js');
const databaseConfig = require('./database-config.js');
useServer(serverConfig).then(async server => {
const database = await server.useDatabase(databaseConfig);
const document = await database.useDocument({
unid: '28438659F50E2637852582C600038599',
});
await document.delete();
});
deleteItems
Deletes selected items from the document
Parameters
options
{Object
}
itemNames
{Array
<string
>} REQUIRED - Specifies the list of items to delete. For example,{ itemNames: ['FirstName', 'LastName'] }
deletes items matching those item names. If the document includes items namedPhoto
, they are not deleted.
Return Value
{
Promise
<undefined
>} A promise resolved withundefined
Example
const { useServer } = require('@domino/domino-db');
const serverConfig = require('./server-config.js');
const databaseConfig = require('./database-config.js');
useServer(serverConfig).then(async server => {
const database = await server.useDatabase(databaseConfig);
const document = await database.useDocument({
unid: '28438659F50E2637852582C600038599',
});
document.deleteItems({
itemNames: ['FirstName', 'LastName'],
});
});
BulkResponse class
Many functions return a promise that is resolved with a BulkResponse
object.
For example, bulkCreateDocuments,
bulkReadDocuments, and
bulkDeleteDocuments each return such a promise.
BulkResponse Properties
The format of the BulkResponse
object is basically the same regardless of the
operation:
documents
{Array
<Object
>} An array of objects representing the documents affected by the operation. The contents of each object depends on the operation.documentRange
{Object
} An object describing the range of documents affected by the operation. This property isundefined
for abulkCreateDocuments
response.
start
{number
} The start index relative to the entire set.count
{number
} The number of items in thedocuments
array.total
{number
} The total number of documents in the set. For example, for abulkReadDocuments
response, this is the total number of documents matching the given query. The value ofcount
might be less thantotal
.errors
{number
} The number of errors in thedocuments
array.
Of course, the exact content of the object depends on the operation. See below for some sample responses.
BulkResponse Examples
Here's an example of a bulkCreateDocuments
response (in JSON format). The
response contains the UNIDs of the new documents and no errors:
{
"documents": [
{
"@unid": "D586D2E2EE19F1F685258301006EEDFD"
},
{
"@unid": "2569C7A4AD97F90785258301006EEDFE"
}
],
"errors": 0
}
Here's an example of a bulkReadDocuments
response. Each object in the
documents
array contains metadata (@unid
, @created
, @modified
) and
document items (FirstName
, LastName
). There are no errors in the response:
{
"documents": [
{
"@unid": "D586D2E2EE19F1F685258301006EEDFD",
"@created": {
"type": "datetime",
"data": "2018-09-07T20:11:38.85Z"
},
"@modified": {
"type": "datetime",
"data": "2018-09-07T20:11:38.86Z"
},
"FirstName": "Sally",
"LastName": "Smith"
},
{
"@unid": "2569C7A4AD97F90785258301006EEDFE",
"@created": {
"type": "datetime",
"data": "2018-09-07T20:11:38.86Z"
},
"@modified": {
"type": "datetime",
"data": "2018-09-07T20:11:38.88Z"
},
"FirstName": "Bob",
"LastName": "Smith"
}
],
"documentRange": {
"total": 2,
"start": 0,
"count": 2
},
"errors": 0
}
Here's an example of a bulkReadDocumentsByUnid
response. The first object in
the documents
array contains metadata and document items. The second object
indicates there was an error reading the document. In this case, the request
included an invalid UNID:
{
"documents": [
{
"@unid": "2569C7A4AD97F90785258301006EEDFE",
"@created": {
"type": "datetime",
"data": "2018-09-07T20:11:38.86Z"
},
"@modified": {
"type": "datetime",
"data": "2018-09-07T20:11:38.88Z"
},
"FirstName": "Bob",
"LastName": "Smith"
},
{
"@error": {
"message": "Proton (65541): Bad note UNID",
"code": "ERR_BAD_REQUEST",
"cause": {
"name": "ProtonError",
"code": 65541
}
}
}
],
"documentRange": {
"total": 2,
"start": 0,
"count": 2
},
"errors": 1
}
It's important to understand, when errors > 0
, the documents
array contains
at least one error. The error is represented by an @error
property whose value
is a DominoDbError object. The following sample code
shows one way to filter the errors from the documents
array.
const { errors, documents } = response;
if (errors) {
documents.filter(document => document['@error']).forEach(error => {
// Handle error
});
}
DominoDbError class
When a domino-db function fails, it throws an instance of DominoDbError
. You
use following properties to determine the cause of the failure.
DominoDbError Properties
name
{string
} Always equals'DominoDbError'
.code
{string
} A general error code. This string is never translated. Therefore your application can compare error code values in any locale. See Error codes for a complete list of codes.message
{string
} A description of the error. This string may be translated to the locale of the remote Domino server. Therefore your application should avoid displaying this string to an end user.cause
{Object
} The root cause of the error orundefined
. When this property is defined, the value is usually a sub-class ofError
. Examples includeProtonError
andGrpcError
. These objects can help determine the cause of a failure in a particular environment, but they should not be considered a fixed part of the domino-db interface. For any given error condition, a newer version of the domino-db module may expose a differentcause
object.stack
{string
} A backtrace of functions on the stack at the time thisDominoDbError
object was created.
Error codes
'ERR_BAD_REQUEST'
- The request was malformed. For example, when reading view entries,options.count === 'foo'
produces this error code becausecount
is the wrong type.'ERR_FORBIDDEN'
- The server denied access to the requested resource.'ERR_INTERNAL_ERROR'
- An internal error occurred. This should happen relatively rarely.'ERR_NOT_AUTHORIZED'
- The request was not authenticated or the authenticated identity does not have access to the requested resource.'ERR_NOT_CONNECTED'
- The domino-db module could not connect to the target server.'ERR_NOT_FOUND'
- The requested resource could not be found.'ERR_NOT_MODIFIED'
- When conditionally reading a resource (e.g.options.ifModifiedSince
), the resource has not been modified. Therefore there is nothing to read.'ERR_PRECONDITION_FAILED'
- When conditionally modifying a resource (e.g.options.ifUnmodifiedSince
), the precondition failed. Therefore the operation failed.
Query Arguments
When you construct a query to use with domino-db it often makes sense to define
the query exactly. For example, the following query finds all contact documents
where LastName
is Aardman:
Form = 'Contact' and LastName = 'Aardman'
On the other hand, you sometimes want to construct a query with variables and
then substitute those variables at run time. For example, the following query
defines a single variable (ln
), the value of which is unknown until run time:
Form = 'Contact' and LastName = ?ln
And the following sample shows how you might use such a query string in a call
to bulkReadDocuments
:
const { useServer } = require('@domino/domino-db');
const serverConfig = require('./server-config.js');
const databaseConfig = require('./database-config.js');
useServer(serverConfig).then(async server => {
const database = await server.useDatabase(databaseConfig);
const documents = await database.bulkReadDocuments({
query: "Form = 'Contact' and LastName = ?ln",
queryArgs: [
{
name: 'ln',
value: lastNameValue,
},
],
});
// documents is an array of documents -- one for each
// document that matches the query
});
NOTE: Argument substitution is a core feature of the Domino Query Language (DQL). It's important to understand the substitution happens on the Domino server while Proton is processing your request.
Query arguments can be either named, as in the previous example, or unnamed.
When unnamed, you substitute variables by ordinal position in the query. The
following call to bulkReadDocuments
is essentially equivalent to the previous
one:
const documents = await database.bulkReadDocuments({
query: "Form = 'Contact' and LastName = ?",
queryArgs: [
{
ordinal: 1,
value: lastNameValue,
},
],
});
You can specify a queryArgs
array when calling bulkReadDocuments
or any
other function that requires a query
string. Each element of the array must be
either a value or an object with the following properties:
ordinal
{number
} Required if noname
is specified. The value ofordinal
is the one-based position of the corresponding unnamed variable in the query string.name
{string
} Required if noordinal
is specified. The value ofname
must match one of the named variables in the query string. For example, to match variable?ln
, specifyln
.value
{string
|number
|Object
} Required. This is the value to substitute for the matching variable.
The following example defines a query
string and a queryArgs
array with
three elements:
query: 'LastName = ? and Number = ? and Date = ?',
queryArgs: [
{
ordinal: 1,
value: stringValue,
},
{
ordinal: 2,
value: numberValue,
},
{
ordinal: 3,
value: {
type: 'datetime',
data: datetimeValue,
}
},
],
Even more simply, you can imply the ordinal position of each argument like this:
query: 'LastName = ? and Number = ? and Date = ?',
queryArgs: [
stringValue,
numberValue,
{
type: 'datetime',
data: datetimeValue,
},
],
Let's assume you use the above query
and queryArgs
properties in a call to
bulkReadDocuments
. Before executing the query on the server, DQL should
substitute the arguments as follows:
- Assuming
stringValue
is a string, DQL substitutes query variable 1 with the TYPE_TEXT value. - Assuming
numberValue
is a number, DQL substitutes variable 2 with the TYPE_NUMBER value. - Assuming
datetimeValue
is a valid ISO8601 date string, DQL substitutes variable 3 with a TYPE_TIME value.
If you specify a query argument value of a different type (e.g. boolean
or
undefined
), you should expect the operation to fail.
Item encryption and decryption
The domino-db module and Proton support item-level encryption and decryption of documents. These features require your application to authenticate as an identity that has an ID file in a Domino ID vault. Furthermore, the current implementation requires your application to specify the ID file password. This section describes how to encrypt and decrypt items with domino-db.
ID file password
When Proton is configured to accept secure requests (SSL/TLS), you specify your
application's credentials when you call useServer
. See
Secure network requests for
general information about client credentials. If your application needs to encrypt
and/or decrypt document items, your credentials
object must also include an
idFilePassword
property as shown below:
const serverConfig = {
hostName: 'your.server.com', // Host name of your server
connection: {
port: '3002', // Proton port on your server
secure: true,
},
credentials: {
rootCertificate,
clientCertificate,
clientKey,
idFilePassword: 'your-password',
},
};
useServer(serverConfig).then(server => {
// server is available for use. Proton verifies the ID file
// password for all requests from this Server instance.
});
When you specify idFilePassword
in your server configuration, Proton verifies
the password for all subsequent requests. This is true whether or not a specific
request involves encryption or decryption. There is a small performance penalty
associated with password verification, but this approach makes Proton responses
more predictable. If you specify idFilePassword
Proton must be able to both
locate your application's ID file in a vault and use the password to unlock the
ID file. If your application doesn't need to encrypt or decrypt items, you
should omit the idFilePassword
property.
Encryption
When you create or update a document with domino-db, you specify one or more
document items. To encrypt an item you must use the canonical format as
described in domino-db document schema and you must
include a boolean encrypt
property as show below:
Description: {
type: 'text',
data: 'Some very very secret string',
encrypt: true
}
That's all there is to it. As long as your server configuration includes the
correct ID file password (as previously mentioned), the Description
item is
encrypted on disk. By default, the item is encrypted so only your application
can decrypt it, but there are two ways to change the audience.
To encrypt items for another identity, you add a PublicEncryptionKeys
item to
the document. For example, the following encrypts the Description
item so only
Joe User can decrypt it:
Description: {
type: 'text',
data: 'Some very very secret string',
encrypt: true
},
PublicEncryptionKeys: 'Joe User/Your Org'
The PublicEncryptionKeys
can be either a string or an array of strings.
However each string must be a valid name. Proton must be able to find each name
in a directory and each name must have an associated public encryption key. If
these conditions are not met, your create (or update) request will fail.
It's also important to understand that PublicEncryptionKeys
literally lists
the entire target audience for the encrypted items. By default, this does not
include your application. To encrypt a document for both Joe User and your
application, you must specify something like this:
Description: {
type: 'text',
data: 'Some very very secret string',
encrypt: true
},
PublicEncryptionKeys: ['Joe User/Your Org', 'Your Application/Your Org']
As an alternative, you can use SecretEncryptionKeys
to encrypt a document for
a group of identities that share a secret key.
Description: {
type: 'text',
data: 'Some very very secret string',
encrypt: true
},
SecretEncryptionKeys: 'Top Secret Key'
This works only if Proton is able to load Top Secret Key from your application's
ID file. If your create (or update) operation succeeds, a user will not be able
to decrypt the Description
item unless the user's ID file also includes Top
Secret Key.
Decryption
Unlike encryption, decryption is mostly a passive act. When you use domino-db to read a document, the response includes a decrypted item only if the conditions allow it. Otherwise, the read request succeeds, but the response doesn't include the decrypted item.
As an example, consider this code:
useServer(serverConfig).then(async server => {
const database = await server.useDatabase(databaseConfig);
const document = await database.useDocument({
unid: '28438659F50E2637852582C600038599',
});
try {
const myDocument = await document.read({ itemNames: ['Description'] });
// myDocument is ready to use
} catch (e) {
// handle error
}
});
This code attempts to read an item named Description
from a single document.
If the Description item exists and it is decrypted you can expect the
following excerpt in the response:
Description: {
type: 'text',
data: 'Some very very secret string',
encrypt: true
}
However, this only happens if:
- Your server configuration included
idFilePassword
as described above. - Proton is able to load and unlock your application's ID file from the vault.
- The Description item is encrypted for your application.
If your server configuration does not include idFilePassword
or the item is
not encrypted for your application, the read request succeeds, but Description
is omitted from the response.