Paso 5: Modificación de documentos de un libro mayor - Amazon Quantum Ledger Database (Amazon QLDB)

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Paso 5: Modificación de documentos de un libro mayor

Ahora que tiene datos con los que trabajar, puede empezar a realizar cambios en los documentos en elvehicle-registrationlibro mayor en Amazon QLDB. En este paso, los siguientes ejemplos de código muestran cómo ejecutar instrucciones de lenguaje de manipulación de datos (DML). Estas declaraciones actualizan al propietario principal de un vehículo y añaden un propietario secundario a otro vehículo.

Para modificar documentos

  1. Utilice el siguiente programa (TransferVehicleOwnership.ts) para actualizar el propietario principal del vehículo con VIN1N4AL11D75C109151en su libro mayor.

    /* * 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 { PERSON, VEHICLE } from "./model/SampleData"; import { PERSON_TABLE_NAME } from "./qldb/Constants"; import { error, log } from "./qldb/LogUtil"; import { getDocumentId } from "./qldb/Util"; /** * Query a driver's information using the given ID. * @param txn The {@linkcode TransactionExecutor} for lambda execute. * @param documentId The unique ID of a document in the Person table. * @returns Promise which fulfills with an Ion value containing the person. */ export async function findPersonFromDocumentId(txn: TransactionExecutor, documentId: string): Promise<dom.Value> { const query: string = "SELECT p.* FROM Person AS p BY pid WHERE pid = ?"; let personId: dom.Value; await txn.execute(query, documentId).then((result: Result) => { const resultList: dom.Value[] = result.getResultList(); if (resultList.length === 0) { throw new Error(`Unable to find person with ID: ${documentId}.`); } personId = resultList[0]; }); return personId; } /** * Find the primary owner for the given VIN. * @param txn The {@linkcode TransactionExecutor} for lambda execute. * @param vin The VIN to find primary owner for. * @returns Promise which fulfills with an Ion value containing the primary owner. */ export async function findPrimaryOwnerForVehicle(txn: TransactionExecutor, vin: string): Promise<dom.Value> { log(`Finding primary owner for vehicle with VIN: ${vin}`); const query: string = "SELECT Owners.PrimaryOwner.PersonId FROM VehicleRegistration AS v WHERE v.VIN = ?"; let documentId: string = undefined; await txn.execute(query, vin).then((result: Result) => { const resultList: dom.Value[] = result.getResultList(); if (resultList.length === 0) { throw new Error(`Unable to retrieve document ID using ${vin}.`); } const PersonIdValue: dom.Value = resultList[0].get("PersonId"); if (PersonIdValue === null) { throw new Error(`Expected field name PersonId not found.`); } documentId = PersonIdValue.stringValue(); }); return findPersonFromDocumentId(txn, documentId); } /** * Update the primary owner for a vehicle using the given VIN. * @param txn The {@linkcode TransactionExecutor} for lambda execute. * @param vin The VIN for the vehicle to operate on. * @param documentId New PersonId for the primary owner. * @returns Promise which fulfills with void. */ async function updateVehicleRegistration(txn: TransactionExecutor, vin: string, documentId: string): Promise<void> { const statement: string = "UPDATE VehicleRegistration AS r SET r.Owners.PrimaryOwner.PersonId = ? WHERE r.VIN = ?"; log(`Updating the primary owner for vehicle with VIN: ${vin}...`); await txn.execute(statement, documentId, vin).then((result: Result) => { const resultList: dom.Value[] = result.getResultList(); if (resultList.length === 0) { throw new Error("Unable to transfer vehicle, could not find registration."); } log(`Successfully transferred vehicle with VIN ${vin} to new owner.`); }); } /** * Validate the current owner of the given vehicle and transfer its ownership to a new owner in a single transaction. * @param txn The {@linkcode TransactionExecutor} for lambda execute. * @param vin The VIN of the vehicle to transfer ownership of. * @param currentOwner The GovId of the current owner of the vehicle. * @param newOwner The GovId of the new owner of the vehicle. */ export async function validateAndUpdateRegistration( txn: TransactionExecutor, vin: string, currentOwner: string, newOwner: string ): Promise<void> { const primaryOwner: dom.Value = await findPrimaryOwnerForVehicle(txn, vin); const govIdValue: dom.Value = primaryOwner.get("GovId"); if (govIdValue !== null && govIdValue.stringValue() !== currentOwner) { log("Incorrect primary owner identified for vehicle, unable to transfer."); } else { const documentId: string = await getDocumentId(txn, PERSON_TABLE_NAME, "GovId", newOwner); await updateVehicleRegistration(txn, vin, documentId); log("Successfully transferred vehicle ownership!"); } } /** * Find primary owner for a particular vehicle's VIN. * Transfer to another primary owner for a particular vehicle's VIN. * @returns Promise which fulfills with void. */ const main = async function(): Promise<void> { try { const qldbDriver: QldbDriver = getQldbDriver(); const vin: string = VEHICLE[0].VIN; const previousOwnerGovId: string = PERSON[0].GovId; const newPrimaryOwnerGovId: string = PERSON[1].GovId; await qldbDriver.executeLambda(async (txn: TransactionExecutor) => { await validateAndUpdateRegistration(txn, vin, previousOwnerGovId, newPrimaryOwnerGovId); }); } catch (e) { error(`Unable to connect and run queries: ${e}`); } } if (require.main === module) { main(); }
  2. Para ejecutar el programa transpired, introduzca el siguiente comando.

    node dist/TransferVehicleOwnership.js
  3. Utilice el siguiente programa (AddSecondaryOwner.ts) para añadir un propietario secundario al vehículo con VINKM8SRDHF6EU074761en su libro mayor.

    /* * 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 { PERSON, VEHICLE_REGISTRATION } from "./model/SampleData"; import { PERSON_TABLE_NAME } from "./qldb/Constants"; import { error, log } from "./qldb/LogUtil"; import { getDocumentId } from "./qldb/Util"; import { prettyPrintResultList } from "./ScanTable"; /** * Add a secondary owner into 'VehicleRegistration' table for a particular VIN. * @param txn The {@linkcode TransactionExecutor} for lambda execute. * @param vin VIN of the vehicle to query. * @param secondaryOwnerId The secondary owner's person ID. * @returns Promise which fulfills with void. */ export async function addSecondaryOwner( txn: TransactionExecutor, vin: string, secondaryOwnerId: string ): Promise<void> { log(`Inserting secondary owner for vehicle with VIN: ${vin}`); const query: string = `FROM VehicleRegistration AS v WHERE v.VIN = ? INSERT INTO v.Owners.SecondaryOwners VALUE ?`; const personToInsert = {PersonId: secondaryOwnerId}; await txn.execute(query, vin, personToInsert).then(async (result: Result) => { const resultList: dom.Value[] = result.getResultList(); log("VehicleRegistration Document IDs which had secondary owners added: "); prettyPrintResultList(resultList); }); } /** * Query for a document ID with a government ID. * @param txn The {@linkcode TransactionExecutor} for lambda execute. * @param governmentId The government ID to query with. * @returns Promise which fulfills with the document ID as a string. */ export async function getDocumentIdByGovId(txn: TransactionExecutor, governmentId: string): Promise<string> { const documentId: string = await getDocumentId(txn, PERSON_TABLE_NAME, "GovId", governmentId); return documentId; } /** * Check whether a driver has already been registered for the given VIN. * @param txn The {@linkcode TransactionExecutor} for lambda execute. * @param vin VIN of the vehicle to query. * @param secondaryOwnerId The secondary owner's person ID. * @returns Promise which fulfills with a boolean. */ export async function isSecondaryOwnerForVehicle( txn: TransactionExecutor, vin: string, secondaryOwnerId: string ): Promise<boolean> { log(`Finding secondary owners for vehicle with VIN: ${vin}`); const query: string = "SELECT Owners.SecondaryOwners FROM VehicleRegistration AS v WHERE v.VIN = ?"; let doesExist: boolean = false; await txn.execute(query, vin).then((result: Result) => { const resultList: dom.Value[] = result.getResultList(); resultList.forEach((value: dom.Value) => { const secondaryOwnersList: dom.Value[] = value.get("SecondaryOwners").elements(); secondaryOwnersList.forEach((secondaryOwner) => { const personId: dom.Value = secondaryOwner.get("PersonId"); if (personId !== null && personId.stringValue() === secondaryOwnerId) { doesExist = true; } }); }); }); return doesExist; } /** * Finds and adds secondary owners for a vehicle. * @returns Promise which fulfills with void. */ const main = async function(): Promise<void> { try { const qldbDriver: QldbDriver = getQldbDriver(); const vin: string = VEHICLE_REGISTRATION[1].VIN; const govId: string = PERSON[0].GovId; await qldbDriver.executeLambda(async (txn: TransactionExecutor) => { const documentId: string = await getDocumentIdByGovId(txn, govId); if (await isSecondaryOwnerForVehicle(txn, vin, documentId)) { log(`Person with ID ${documentId} has already been added as a secondary owner of this vehicle.`); } else { await addSecondaryOwner(txn, vin, documentId); } }); log("Secondary owners successfully updated."); } catch (e) { error(`Unable to add secondary owner: ${e}`); } } if (require.main === module) { main(); }
  4. Para ejecutar el programa transpired, introduzca el siguiente comando.

    node dist/AddSecondaryOwner.js

Para revisar estos cambios en elvehicle-registrationcontabilidad, consultePaso 6: Ver el historial de revisiones de un documento.