import { CommitTransactionResult , ExecuteStatementResult , ValueHolder } from "aws-sdk/clients/qldbsession" ; import { dumpBinary , toBase64 } from "ion-js" ; import { Lock } from "semaphore-async-await" ; import { Communicator } from "./Communicator" ; import { ClientError } from "./errors/Errors" ; import { QldbHash } from "./QldbHash" ; import { Result } from "./Result" ; import { ResultReadable } from "./ResultReadable" ; internal export class Transaction { private _communicator : Communicator ; private _txnId : string ; private _txnHash : QldbHash ; private _hashLock : Lock ; param communicator param txnId constructor ( communicator , txnId ) { this . _communicator = communicator ; this . _txnId = txnId ; this . _txnHash = QldbHash . toQldbHash ( txnId ) ; this . _hashLock = new Lock ( ) ; } returns throws async commit ( ) { await this . _hashLock . acquire ( ) ; try { const commitTxnResult = await this . _communicator . commit ( this . _txnId , this . _txnHash . getQldbHash ( ) ) ; if ( toBase64 ( this . _txnHash . getQldbHash ( ) ) !== toBase64 ( < Uint8Array > ( commitTxnResult . CommitDigest ) ) ) { throw new ClientError ( `Transaction's commit digest did not match returned value from QLDB.
                    Please retry with a new transaction. Transaction ID: ${ this . _txnId }.` ) ; } } finally { this . _hashLock . release ( ) ; } } param statement param parameters returns throws async execute ( statement , ... parameters ) { const result = await this . _sendExecute ( statement , parameters ) ; return Result . create ( this . _txnId , result , this . _communicator ) ; } param statement param parameters returns throws throws async executeAndStreamResults ( statement , ... parameters ) { const result = await this . _sendExecute ( statement , parameters ) ; return new ResultReadable ( this . _txnId , result , this . _communicator ) ; } returns getTransactionId ( ) { return this . _txnId ; } param statement param parameters returns private async _sendExecute ( statement , parameters ) { await this . _hashLock . acquire ( ) ; try { let statementHash = QldbHash . toQldbHash ( statement ) ; const valueHolderList = parameters . map ( ( param ) => { let ionBinary ; try { ionBinary = dumpBinary ( param ) ; } catch ( e ) { e . message = `Failed to convert parameter ${ String ( param ) } to Ion Binary: ${ e . message }` ; throw e ; } statementHash = statementHash . dot ( QldbHash . toQldbHash ( ionBinary ) ) ; const valueHolder = { IonBinary : ionBinary } ; return valueHolder ; } ) ; this . _txnHash = this . _txnHash . dot ( statementHash ) ; const result = await this . _communicator . executeStatement ( this . _txnId , statement , valueHolderList ) ; return result ; } finally { this . _hashLock . release ( ) ; } } }