Skip to main content

Database Agent - JS/TS

Read and write an external database server.

Logic TypeAvailable
Generic logic
Aggregator logic

Database Agent Configuration

See: Agent Configuration

A Database Agent Configuration defines an external database server that will be allowed to be accessed from LOC runtime.

The Database Agent requires a configuration reference name so that it can access data on the database server. The reference name can be added to a logic while creating or editing a data process.

Import and Usage

import {
DatabaseAgent,
} from "@fstnetwork/loc-logic-sdk";

export async function run(ctx) {
const dbClient = await DatabaseAgent.acquire("db-config-ref");
const result = await dbClient?.query("SELECT * FROM table1;", []);
}

export async function handleError(ctx, error) {
// ... same
}

Class Reference

Type

  • DatabaseAgent

Method: Acquire Database Client

async acquire(configurationName: string): Promise<DatabaseClient>
ParameterDescription
configurationNameDatabase Agent Configuration reference name

Acquire a Database client using a configuration reference name. Throws an error if the configuration cannot be found.

Database Client

Type

  • DatabaseClient

Importable from @fstnetwork/loc-logic-sdk

Method: Select Query

async query(rawSql: string, params: any[]): Promise<Database.QueryResults>
ParameterTypeDescription
rawSqlstringSQL prepared statement
paramsany[]Values to be inserted into the prepared statement

Execute a select query and returns a QueryResults object.

Always Use Prepared Statements

It is strongly recommended to query a database using prepared statements. For example, the following code works but is vulnerable to SQL injection attack:

// bad practice
const result = await dbClient.query(
`SELECT * FROM table1 WHERE col_1 = ${value1} AND col_2 = ${value2};`,
[],
);

Instead, seperate parameters into the params array:

const result = await dbClient.query(
"SELECT * FROM table1 WHERE col_1 = ? AND col_2 = ?;",
[value1, value2],
);
Prepared Statement Placeholders
Supported DatabasePlaceholder
MySQL/Oracle?
Microsoft SQL Server@P1, @P2...
PostgreSQL$1, $2...

QueryResults

Results from select query.

PropertyTypeDescription
columnsDatabase.QueryResultColumn[]Column descriptions
rowsArray<{ [key: string]: any }>Columns names and row values

If a column in the result has the name of ColName, the value can be accessed as rows[index].ColName or rows[index]["ColName"].

info

PostgreSQL returns lowered-case column names, which makes it rows[index].colname.

Database.QueryResultColumn

PropertyTypeDescription
namestringColumn name
typestringColumn data type

Method: Action Query

async execute(rawSql: string, params: any[]): Promise<any>
ParameterTypeDescription
rawSqlstringSQL prepared statement
paramsany[]Values to be inserted into the prepared statement

Execute an action query (insert, update, delete, etc.). Returns the number of affected rows.

Method: Begin Transaction

async beginTransaction(): Promise<DatabaseClient>

Begin a transaction. All action queries will only take effect when commitTransaction() is called.

Modify Transaction Isolation Level

Advanced users can modify the transaction isolation level with the following SQL statement:

--MySQL, MS SQL Server
SET TRANSACTION ISOLATION LEVEL <LEVEL>

--PostgreSQL, Oracle
SET TRANSACTION <LEVEL>

The default level setting is READ COMMITTED.

Method: Commit Transaction

async commitTransaction(): Promise<void>

Commit a transaction.

Method: Rollback Transaction

async rollbackTransaction(): Promise<void>

Rollback a transaction. The database may throw an error if commitTransaction() is already called.

Method: Release Connection

async release(): Promise<void>

The LOC runtime will also try to close unreleased connection when the task completes execution.

Examples

Query From Table

const dbClient = await DatabaseAgent.acquire("db-config-ref");

const value1 = "value1";
const value2 = "value2";

const result = await dbClient?.query(
"SELECT * FROM table1 WHERE col_1 = ? AND col_2 = ?;",
[value1, value2],
);

const rows = result?.rows;

// iterate through rows
rows.forEach((row) => {
const value1 = row.col_1;
const value2 = row.col_2;
// ...
});

await dbClient?.release();

Insert Data Into Table

const dbClient = await DatabaseAgent.acquire("db-config-ref");

const value1 = "value1";
const value2 = "value2";

await dbClient?.execute("INSERT INTO table1 (col_1, col_2) VALUES (?, ?);", [
value1,
value2,
]);

Error Handling with Transaction

const dbClient = await DatabaseAgent.acquire("db-config-ref");

try {
await dbClient?.beginTransaction();

// a series of SQL action queries to be completed

await dbClient?.commitTransaction();
} catch (e) {
try {
await dbClient?.rollbackTransaction();
} catch (e) {
// error occurred after commit
}
} finally {
await dbClient?.release();
}