Skip to content

Refactor AddFeatureAnnotation to use latest arangomanager transaction API #413

@cybersiddhu

Description

@cybersiddhu

Background

The current implementation of AddFeatureAnnotation doesn't leverage the latest transactional capabilities of the arangomanager package. With recent publication handling improvements, we should update our transaction management approach.

Proposed Changes

  1. Replace sequential database operations with a single atomic transaction using the correct arangomanager API

  2. Update transaction structure:

    func (r *FeatureAnnotationRepo) AddFeatureAnnotation(fa *model.FeatureAnnotation) error {
        txOptions := &arangomanager.TransactionOptions{
            WriteCollections: []string{
                r.featCollection,
                r.pubCollection,
                r.featPubEdgeCollection,
            },
        }
        
        // Begin transaction with context
        tx, err := r.database.BeginTransaction(context.Background(), txOptions)
        if err != nil {
            return fmt.Errorf("error beginning transaction: %w", err)
        }
        
        // Store feature annotation using AQL with transaction
        faDoc, err := r.storeFeatureAnnotationTx(tx, fa)
        if err != nil {
            tx.Abort() // Abort transaction on error
            return err
        }
        
        // Handle publications atomically if present
        if len(fa.Publications) > 0 {
            pubIDs, err := r.upsertPublicationsTx(tx, fa.Publications)
            if err != nil {
                tx.Abort() // Abort transaction on error
                return err
            }
            
            // Create feature-publication edges within same transaction
            if err := r.createPublicationEdgesTx(tx, faDoc.Key, pubIDs); err != nil {
                tx.Abort() // Abort transaction on error
                return err
            }
        }
        
        // Commit the transaction
        if err := tx.Commit(); err != nil {
            return fmt.Errorf("error committing transaction: %w", err)
        }
        
        return nil
    }
  3. Update or create transaction-specific helper methods:

    // Example of a transaction-aware helper method
    func (r *FeatureAnnotationRepo) storeFeatureAnnotationTx(tx arangomanager.TransactionHandler, fa *model.FeatureAnnotation) (FeatureAnnotationDoc, error) {
        // Prepare AQL query and bind vars
        query := fmt.Sprintf("INSERT @doc INTO %s RETURN NEW", r.featCollection)
        bindVars := map[string]interface{}{
            "doc": prepareFeatureDoc(fa),
        }
        
        // Execute within transaction context
        result, err := tx.DoRun(query, bindVars)
        if err != nil {
            return FeatureAnnotationDoc{}, err
        }
        
        // Process result
        var faDoc FeatureAnnotationDoc
        if err := result.Read(&faDoc); err != nil {
            return FeatureAnnotationDoc{}, err
        }
        
        return faDoc, nil
    }

Benefits

  • Atomic operations ensure data consistency
  • Explicit transaction control with proper error handling
  • Uses the correct BeginTransaction/Commit/Abort pattern from arangomanager
  • Properly manages transaction lifecycle

Implementation Notes

  • Need to create transaction-aware versions of existing database operations
  • Update imports to include context package
  • Consider refactoring existing code to follow similar transactional pattern

Related Work

Builds on recent publication handling improvements (commits 5bfe6e9, 2a852b0)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions