Step 3: Create tables, indexes, and sample data - Amazon Quantum Ledger Database (Amazon QLDB)

Step 3: Create tables, indexes, and sample data

Important

End of support notice: Existing customers will be able to use Amazon QLDB until end of support on 07/31/2025. For more details, see Migrate an Amazon QLDB Ledger to Amazon Aurora PostgreSQL.

When your Amazon QLDB ledger is active and accepts connections, you can start creating tables for data about vehicles, their owners, and their registration information. After creating the tables and indexes, you can load them with data.

In this step, you create four tables in the vehicle-registration ledger:

  • VehicleRegistration

  • Vehicle

  • Person

  • DriversLicense

You also create the following indexes.

Table name Field
VehicleRegistration VIN
VehicleRegistration LicensePlateNumber
Vehicle VIN
Person GovId
DriversLicense LicenseNumber
DriversLicense PersonId

When inserting sample data, you first insert documents into the Person table. Then, you use the system-assigned id from each Person document to populate the corresponding fields in the appropriate VehicleRegistration and DriversLicense documents.

Tip

As a best practice, use a document's system-assigned id as a foreign key. While you can define fields that are intended to be unique identifiers (for example, a vehicle's VIN), the true unique identifier of a document is its id. This field is included in the document's metadata, which you can query in the committed view (the system-defined view of a table).

For more information about views in QLDB, see Core concepts. To learn more about metadata, see Querying document metadata.

To create tables and indexes
  1. Use the following program (CreateTable.ts) to create the previously mentioned tables.

    /* * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: MIT-0 * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * software and associated documentation files (the "Software"), to deal in the Software * without restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ import { QldbDriver, Result, TransactionExecutor } from "amazon-qldb-driver-nodejs"; import { getQldbDriver } from "./ConnectToLedger"; import { DRIVERS_LICENSE_TABLE_NAME, PERSON_TABLE_NAME, VEHICLE_REGISTRATION_TABLE_NAME, VEHICLE_TABLE_NAME } from "./qldb/Constants"; import { error, log } from "./qldb/LogUtil"; /** * Create multiple tables in a single transaction. * @param txn The {@linkcode TransactionExecutor} for lambda execute. * @param tableName Name of the table to create. * @returns Promise which fulfills with the number of changes to the database. */ export async function createTable(txn: TransactionExecutor, tableName: string): Promise<number> { const statement: string = `CREATE TABLE ${tableName}`; return await txn.execute(statement).then((result: Result) => { log(`Successfully created table ${tableName}.`); return result.getResultList().length; }); } /** * Create tables in a QLDB ledger. * @returns Promise which fulfills with void. */ const main = async function(): Promise<void> { try { const qldbDriver: QldbDriver = getQldbDriver(); await qldbDriver.executeLambda(async (txn: TransactionExecutor) => { Promise.all([ createTable(txn, VEHICLE_REGISTRATION_TABLE_NAME), createTable(txn, VEHICLE_TABLE_NAME), createTable(txn, PERSON_TABLE_NAME), createTable(txn, DRIVERS_LICENSE_TABLE_NAME) ]); }); } catch (e) { error(`Unable to create tables: ${e}`); } } if (require.main === module) { main(); }
    Note

    This program demonstrates how to use the executeLambda function in a QLDB driver instance. In this example, you run multiple CREATE TABLE PartiQL statements with a single lambda expression.

    This execute function implicitly starts a transaction, runs all of the statements in the lambda, and then auto-commits the transaction.

  2. To run the transpiled program, enter the following command.

    node dist/CreateTable.js
  3. Use the following program (CreateIndex.ts) to create indexes on the tables, as previously described.

    /* * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: MIT-0 * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * software and associated documentation files (the "Software"), to deal in the Software * without restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ import { QldbDriver, TransactionExecutor } from "amazon-qldb-driver-nodejs"; import { getQldbDriver } from "./ConnectToLedger"; import { DRIVERS_LICENSE_TABLE_NAME, GOV_ID_INDEX_NAME, LICENSE_NUMBER_INDEX_NAME, LICENSE_PLATE_NUMBER_INDEX_NAME, PERSON_ID_INDEX_NAME, PERSON_TABLE_NAME, VEHICLE_REGISTRATION_TABLE_NAME, VEHICLE_TABLE_NAME, VIN_INDEX_NAME } from "./qldb/Constants"; import { error, log } from "./qldb/LogUtil"; /** * Create an index for a particular table. * @param txn The {@linkcode TransactionExecutor} for lambda execute. * @param tableName Name of the table to add indexes for. * @param indexAttribute Index to create on a single attribute. * @returns Promise which fulfills with the number of changes to the database. */ export async function createIndex( txn: TransactionExecutor, tableName: string, indexAttribute: string ): Promise<number> { const statement: string = `CREATE INDEX on ${tableName} (${indexAttribute})`; return await txn.execute(statement).then((result) => { log(`Successfully created index ${indexAttribute} on table ${tableName}.`); return result.getResultList().length; }); } /** * Create indexes on tables in a particular ledger. * @returns Promise which fulfills with void. */ const main = async function(): Promise<void> { try { const qldbDriver: QldbDriver = getQldbDriver(); await qldbDriver.executeLambda(async (txn: TransactionExecutor) => { Promise.all([ createIndex(txn, PERSON_TABLE_NAME, GOV_ID_INDEX_NAME), createIndex(txn, VEHICLE_TABLE_NAME, VIN_INDEX_NAME), createIndex(txn, VEHICLE_REGISTRATION_TABLE_NAME, VIN_INDEX_NAME), createIndex(txn, VEHICLE_REGISTRATION_TABLE_NAME, LICENSE_PLATE_NUMBER_INDEX_NAME), createIndex(txn, DRIVERS_LICENSE_TABLE_NAME, PERSON_ID_INDEX_NAME), createIndex(txn, DRIVERS_LICENSE_TABLE_NAME, LICENSE_NUMBER_INDEX_NAME) ]); }); } catch (e) { error(`Unable to create indexes: ${e}`); } } if (require.main === module) { main(); }
  4. To run the transpiled program, enter the following command.

    node dist/CreateIndex.js
To load data into the tables
  1. Review the following .ts files.

    1. SampleData.ts – Contains the sample data that you insert into the vehicle-registration tables.

      /* * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: MIT-0 * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * software and associated documentation files (the "Software"), to deal in the Software * without restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ import { Decimal } from "ion-js"; const EMPTY_SECONDARY_OWNERS: object[] = []; export const DRIVERS_LICENSE = [ { PersonId: "", LicenseNumber: "LEWISR261LL", LicenseType: "Learner", ValidFromDate: new Date("2016-12-20"), ValidToDate: new Date("2020-11-15") }, { PersonId: "", LicenseNumber : "LOGANB486CG", LicenseType: "Probationary", ValidFromDate : new Date("2016-04-06"), ValidToDate : new Date("2020-11-15") }, { PersonId: "", LicenseNumber : "744 849 301", LicenseType: "Full", ValidFromDate : new Date("2017-12-06"), ValidToDate : new Date("2022-10-15") }, { PersonId: "", LicenseNumber : "P626-168-229-765", LicenseType: "Learner", ValidFromDate : new Date("2017-08-16"), ValidToDate : new Date("2021-11-15") }, { PersonId: "", LicenseNumber : "S152-780-97-415-0", LicenseType: "Probationary", ValidFromDate : new Date("2015-08-15"), ValidToDate : new Date("2021-08-21") } ]; export const PERSON = [ { FirstName : "Raul", LastName : "Lewis", DOB : new Date("1963-08-19"), Address : "1719 University Street, Seattle, WA, 98109", GovId : "LEWISR261LL", GovIdType : "Driver License" }, { FirstName : "Brent", LastName : "Logan", DOB : new Date("1967-07-03"), Address : "43 Stockert Hollow Road, Everett, WA, 98203", GovId : "LOGANB486CG", GovIdType : "Driver License" }, { FirstName : "Alexis", LastName : "Pena", DOB : new Date("1974-02-10"), Address : "4058 Melrose Street, Spokane Valley, WA, 99206", GovId : "744 849 301", GovIdType : "SSN" }, { FirstName : "Melvin", LastName : "Parker", DOB : new Date("1976-05-22"), Address : "4362 Ryder Avenue, Seattle, WA, 98101", GovId : "P626-168-229-765", GovIdType : "Passport" }, { FirstName : "Salvatore", LastName : "Spencer", DOB : new Date("1997-11-15"), Address : "4450 Honeysuckle Lane, Seattle, WA, 98101", GovId : "S152-780-97-415-0", GovIdType : "Passport" } ]; export const VEHICLE = [ { VIN : "1N4AL11D75C109151", Type : "Sedan", Year : 2011, Make : "Audi", Model : "A5", Color : "Silver" }, { VIN : "KM8SRDHF6EU074761", Type : "Sedan", Year : 2015, Make : "Tesla", Model : "Model S", Color : "Blue" }, { VIN : "3HGGK5G53FM761765", Type : "Motorcycle", Year : 2011, Make : "Ducati", Model : "Monster 1200", Color : "Yellow" }, { VIN : "1HVBBAANXWH544237", Type : "Semi", Year : 2009, Make : "Ford", Model : "F 150", Color : "Black" }, { VIN : "1C4RJFAG0FC625797", Type : "Sedan", Year : 2019, Make : "Mercedes", Model : "CLK 350", Color : "White" } ]; export const VEHICLE_REGISTRATION = [ { VIN : "1N4AL11D75C109151", LicensePlateNumber : "LEWISR261LL", State : "WA", City : "Seattle", ValidFromDate : new Date("2017-08-21"), ValidToDate : new Date("2020-05-11"), PendingPenaltyTicketAmount : new Decimal(9025, -2), Owners : { PrimaryOwner : { PersonId : "" }, SecondaryOwners : EMPTY_SECONDARY_OWNERS } }, { VIN : "KM8SRDHF6EU074761", LicensePlateNumber : "CA762X", State : "WA", City : "Kent", PendingPenaltyTicketAmount : new Decimal(13075, -2), ValidFromDate : new Date("2017-09-14"), ValidToDate : new Date("2020-06-25"), Owners : { PrimaryOwner : { PersonId : "" }, SecondaryOwners : EMPTY_SECONDARY_OWNERS } }, { VIN : "3HGGK5G53FM761765", LicensePlateNumber : "CD820Z", State : "WA", City : "Everett", PendingPenaltyTicketAmount : new Decimal(44230, -2), ValidFromDate : new Date("2011-03-17"), ValidToDate : new Date("2021-03-24"), Owners : { PrimaryOwner : { PersonId : "" }, SecondaryOwners : EMPTY_SECONDARY_OWNERS } }, { VIN : "1HVBBAANXWH544237", LicensePlateNumber : "LS477D", State : "WA", City : "Tacoma", PendingPenaltyTicketAmount : new Decimal(4220, -2), ValidFromDate : new Date("2011-10-26"), ValidToDate : new Date("2023-09-25"), Owners : { PrimaryOwner : { PersonId : "" }, SecondaryOwners : EMPTY_SECONDARY_OWNERS } }, { VIN : "1C4RJFAG0FC625797", LicensePlateNumber : "TH393F", State : "WA", City : "Olympia", PendingPenaltyTicketAmount : new Decimal(3045, -2), ValidFromDate : new Date("2013-09-02"), ValidToDate : new Date("2024-03-19"), Owners : { PrimaryOwner : { PersonId : "" }, SecondaryOwners : EMPTY_SECONDARY_OWNERS } } ];
    2. Util.ts – A utility module that imports from the ion-js package to provide helper functions that convert, parse, and print Amazon Ion data.

      /* * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: MIT-0 * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * software and associated documentation files (the "Software"), to deal in the Software * without restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ import { Result, TransactionExecutor } from "amazon-qldb-driver-nodejs"; import { GetBlockResponse, GetDigestResponse, ValueHolder } from "aws-sdk/clients/qldb"; import { Decimal, decodeUtf8, dom, IonTypes, makePrettyWriter, makeReader, Reader, Timestamp, toBase64, Writer } from "ion-js"; import { error } from "./LogUtil"; /** * TODO: Replace this with json.stringify * Returns the string representation of a given BlockResponse. * @param blockResponse The BlockResponse to convert to string. * @returns The string representation of the supplied BlockResponse. */ export function blockResponseToString(blockResponse: GetBlockResponse): string { let stringBuilder: string = ""; if (blockResponse.Block.IonText) { stringBuilder = stringBuilder + "Block: " + blockResponse.Block.IonText + ", "; } if (blockResponse.Proof.IonText) { stringBuilder = stringBuilder + "Proof: " + blockResponse.Proof.IonText; } stringBuilder = "{" + stringBuilder + "}"; const writer: Writer = makePrettyWriter(); const reader: Reader = makeReader(stringBuilder); writer.writeValues(reader); return decodeUtf8(writer.getBytes()); } /** * TODO: Replace this with json.stringify * Returns the string representation of a given GetDigestResponse. * @param digestResponse The GetDigestResponse to convert to string. * @returns The string representation of the supplied GetDigestResponse. */ export function digestResponseToString(digestResponse: GetDigestResponse): string { let stringBuilder: string = ""; if (digestResponse.Digest) { stringBuilder += "Digest: " + JSON.stringify(toBase64(<Uint8Array> digestResponse.Digest)) + ", "; } if (digestResponse.DigestTipAddress.IonText) { stringBuilder += "DigestTipAddress: " + digestResponse.DigestTipAddress.IonText; } stringBuilder = "{" + stringBuilder + "}"; const writer: Writer = makePrettyWriter(); const reader: Reader = makeReader(stringBuilder); writer.writeValues(reader); return decodeUtf8(writer.getBytes()); } /** * Get the document IDs from the given table. * @param txn The {@linkcode TransactionExecutor} for lambda execute. * @param tableName The table name to query. * @param field A field to query. * @param value The key of the given field. * @returns Promise which fulfills with the document ID as a string. */ export async function getDocumentId( txn: TransactionExecutor, tableName: string, field: string, value: string ): Promise<string> { const query: string = `SELECT id FROM ${tableName} AS t BY id WHERE t.${field} = ?`; let documentId: string = undefined; await txn.execute(query, value).then((result: Result) => { const resultList: dom.Value[] = result.getResultList(); if (resultList.length === 0) { throw new Error(`Unable to retrieve document ID using ${value}.`); } documentId = resultList[0].get("id").stringValue(); }).catch((err: any) => { error(`Error getting documentId: ${err}`); }); return documentId; } /** * Sleep for the specified amount of time. * @param ms The amount of time to sleep in milliseconds. * @returns Promise which fulfills with void. */ export function sleep(ms: number): Promise<void> { return new Promise(resolve => setTimeout(resolve, ms)); } /** * Find the value of a given path in an Ion value. The path should contain a blob value. * @param value The Ion value that contains the journal block attributes. * @param path The path to a certain attribute. * @returns Uint8Array value of the blob, or null if the attribute cannot be found in the Ion value * or is not of type Blob */ export function getBlobValue(value: dom.Value, path: string): Uint8Array | null { const attribute: dom.Value = value.get(path); if (attribute !== null && attribute.getType() === IonTypes.BLOB) { return attribute.uInt8ArrayValue(); } return null; } /** * TODO: Replace this with json.stringify * Returns the string representation of a given ValueHolder. * @param valueHolder The ValueHolder to convert to string. * @returns The string representation of the supplied ValueHolder. */ export function valueHolderToString(valueHolder: ValueHolder): string { const stringBuilder: string = `{ IonText: ${valueHolder.IonText}}`; const writer: Writer = makePrettyWriter(); const reader: Reader = makeReader(stringBuilder); writer.writeValues(reader); return decodeUtf8(writer.getBytes()); } /** * Converts a given value to Ion using the provided writer. * @param value The value to convert to Ion. * @param ionWriter The Writer to pass the value into. * @throws Error: If the given value cannot be converted to Ion. */ export function writeValueAsIon(value: any, ionWriter: Writer): void { switch (typeof value) { case "string": ionWriter.writeString(value); break; case "boolean": ionWriter.writeBoolean(value); break; case "number": ionWriter.writeInt(value); break; case "object": if (Array.isArray(value)) { // Object is an array. ionWriter.stepIn(IonTypes.LIST); for (const element of value) { writeValueAsIon(element, ionWriter); } ionWriter.stepOut(); } else if (value instanceof Date) { // Object is a Date. ionWriter.writeTimestamp(Timestamp.parse(value.toISOString())); } else if (value instanceof Decimal) { // Object is a Decimal. ionWriter.writeDecimal(value); } else if (value === null) { ionWriter.writeNull(IonTypes.NULL); } else { // Object is a struct. ionWriter.stepIn(IonTypes.STRUCT); for (const key of Object.keys(value)) { ionWriter.writeFieldName(key); writeValueAsIon(value[key], ionWriter); } ionWriter.stepOut(); } break; default: throw new Error(`Cannot convert to Ion for type: ${(typeof value)}.`); } }
      Note

      The getDocumentId function runs a query that returns system-assigned document IDs from a table. To learn more, see Using the BY clause to query document ID.

  2. Use the following program (InsertDocument.ts) to insert the sample data into your tables.

    /* * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: MIT-0 * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * software and associated documentation files (the "Software"), to deal in the Software * without restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ import { QldbDriver, Result, TransactionExecutor } from "amazon-qldb-driver-nodejs"; import { dom } from "ion-js"; import { getQldbDriver } from "./ConnectToLedger"; import { DRIVERS_LICENSE, PERSON, VEHICLE, VEHICLE_REGISTRATION } from "./model/SampleData"; import { DRIVERS_LICENSE_TABLE_NAME, PERSON_TABLE_NAME, VEHICLE_REGISTRATION_TABLE_NAME, VEHICLE_TABLE_NAME } from "./qldb/Constants"; import { error, log } from "./qldb/LogUtil"; /** * Insert the given list of documents into a table in a single transaction. * @param txn The {@linkcode TransactionExecutor} for lambda execute. * @param tableName Name of the table to insert documents into. * @param documents List of documents to insert. * @returns Promise which fulfills with a {@linkcode Result} object. */ export async function insertDocument( txn: TransactionExecutor, tableName: string, documents: object[] ): Promise<Result> { const statement: string = `INSERT INTO ${tableName} ?`; const result: Result = await txn.execute(statement, documents); return result; } /** * Handle the insertion of documents and updating PersonIds all in a single transaction. * @param txn The {@linkcode TransactionExecutor} for lambda execute. * @returns Promise which fulfills with void. */ async function updateAndInsertDocuments(txn: TransactionExecutor): Promise<void> { log("Inserting multiple documents into the 'Person' table..."); const documentIds: Result = await insertDocument(txn, PERSON_TABLE_NAME, PERSON); const listOfDocumentIds: dom.Value[] = documentIds.getResultList(); log("Updating PersonIds for 'DriversLicense' and PrimaryOwner for 'VehicleRegistration'..."); updatePersonId(listOfDocumentIds); log("Inserting multiple documents into the remaining tables..."); await Promise.all([ insertDocument(txn, DRIVERS_LICENSE_TABLE_NAME, DRIVERS_LICENSE), insertDocument(txn, VEHICLE_REGISTRATION_TABLE_NAME, VEHICLE_REGISTRATION), insertDocument(txn, VEHICLE_TABLE_NAME, VEHICLE) ]); } /** * Update the PersonId value for DriversLicense records and the PrimaryOwner value for VehicleRegistration records. * @param documentIds List of document IDs. */ export function updatePersonId(documentIds: dom.Value[]): void { documentIds.forEach((value: dom.Value, i: number) => { const documentId: string = value.get("documentId").stringValue(); DRIVERS_LICENSE[i].PersonId = documentId; VEHICLE_REGISTRATION[i].Owners.PrimaryOwner.PersonId = documentId; }); } /** * Insert documents into a table in a QLDB ledger. * @returns Promise which fulfills with void. */ const main = async function(): Promise<void> { try { const qldbDriver: QldbDriver = getQldbDriver(); await qldbDriver.executeLambda(async (txn: TransactionExecutor) => { await updateAndInsertDocuments(txn); }); } catch (e) { error(`Unable to insert documents: ${e}`); } } if (require.main === module) { main(); }
    Note
    • This program demonstrates how to call the execute function with parameterized values. You can pass data parameters in addition to the PartiQL statement that you want to run. Use a question mark (?) as a variable placeholder in your statement string.

    • If an INSERT statement succeeds, it returns the id of each inserted document.

  3. To run the transpiled program, enter the following command.

    node dist/InsertDocument.js

Next, you can use SELECT statements to read data from the tables in the vehicle-registration ledger. Proceed to Step 4: Query the tables in a ledger.