GetTransaction retrieves a transaction by its ID from the database. It logs the transaction retrieval using OpenTelemetry tracing. Parameters: - ctx: Context for managing the request and tracing. - id: The unique transaction ID. Returns: - The retrieved transaction if successful, or an error if retr
(ctx context.Context, id string)
| 381 | // Returns: |
| 382 | // - The retrieved transaction if successful, or an error if retrieval fails. |
| 383 | func (d Datasource) GetTransaction(ctx context.Context, id string) (*model.Transaction, error) { |
| 384 | // Start a new tracing span for the database operation |
| 385 | ctx, span := otel.Tracer("transaction.database").Start(ctx, "GetTransaction") |
| 386 | defer span.End() |
| 387 | |
| 388 | // Execute the SQL query to retrieve the transaction by its ID |
| 389 | row := d.Conn.QueryRowContext(ctx, ` |
| 390 | SELECT transaction_id, source, reference, amount, precise_amount, precision, currency, destination, description, status, created_at, meta_data, parent_transaction, hash |
| 391 | FROM ledgerforge.transactions |
| 392 | WHERE transaction_id = $1 |
| 393 | `, id) |
| 394 | |
| 395 | // Initialize a Transaction model and scan the result into it |
| 396 | txn := &model.Transaction{} |
| 397 | var metaDataJSON []byte |
| 398 | var preciseAmountStr string |
| 399 | err := row.Scan(&txn.TransactionID, &txn.Source, &txn.Reference, &txn.Amount, &preciseAmountStr, &txn.Precision, &txn.Currency, &txn.Destination, &txn.Description, &txn.Status, &txn.CreatedAt, &metaDataJSON, &txn.ParentTransaction, &txn.Hash) |
| 400 | // Handle errors, including no rows found |
| 401 | if err != nil { |
| 402 | if err == sql.ErrNoRows { |
| 403 | span.RecordError(err) |
| 404 | return nil, apierror.NewAPIError(apierror.ErrNotFound, fmt.Sprintf("Transaction with ID '%s' not found", id), err) |
| 405 | } |
| 406 | span.RecordError(err) |
| 407 | return nil, apierror.NewAPIError(apierror.ErrInternalServer, "Failed to retrieve transaction", err) |
| 408 | } |
| 409 | |
| 410 | // Unmarshal the metadata JSON into the transaction's MetaData field |
| 411 | err = json.Unmarshal(metaDataJSON, &txn.MetaData) |
| 412 | if err != nil { |
| 413 | span.RecordError(err) |
| 414 | return nil, apierror.NewAPIError(apierror.ErrInternalServer, "Failed to unmarshal metadata", err) |
| 415 | } |
| 416 | |
| 417 | txn.PreciseAmount, err = parseBigInt(preciseAmountStr) |
| 418 | if err != nil { |
| 419 | span.RecordError(err) |
| 420 | return nil, fmt.Errorf("failed to parse precise_amount: %w", err) |
| 421 | } |
| 422 | |
| 423 | // Log the successful transaction retrieval as an event in the tracing span |
| 424 | span.AddEvent("Transaction retrieved", trace.WithAttributes( |
| 425 | attribute.String("transaction.id", txn.TransactionID), |
| 426 | attribute.String("transaction.reference", txn.Reference), |
| 427 | )) |
| 428 | |
| 429 | return txn, nil |
| 430 | } |
| 431 | |
| 432 | // IsParentTransactionVoid checks if a parent transaction has a status of 'VOID'. |
| 433 | // It uses OpenTelemetry to trace the operation and returns a boolean indicating |