github.com/koko1123/flow-go-1@v0.29.6/storage/badger/collections.go (about)

     1  package badger
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  
     7  	"github.com/dgraph-io/badger/v3"
     8  
     9  	"github.com/koko1123/flow-go-1/model/flow"
    10  	"github.com/koko1123/flow-go-1/storage"
    11  	"github.com/koko1123/flow-go-1/storage/badger/operation"
    12  	"github.com/koko1123/flow-go-1/storage/badger/transaction"
    13  )
    14  
    15  type Collections struct {
    16  	db           *badger.DB
    17  	transactions *Transactions
    18  }
    19  
    20  func NewCollections(db *badger.DB, transactions *Transactions) *Collections {
    21  	c := &Collections{
    22  		db:           db,
    23  		transactions: transactions,
    24  	}
    25  	return c
    26  }
    27  
    28  func (c *Collections) StoreLight(collection *flow.LightCollection) error {
    29  	err := operation.RetryOnConflict(c.db.Update, operation.InsertCollection(collection))
    30  	if err != nil {
    31  		return fmt.Errorf("could not insert collection: %w", err)
    32  	}
    33  
    34  	return nil
    35  }
    36  
    37  func (c *Collections) Store(collection *flow.Collection) error {
    38  	return operation.RetryOnConflictTx(c.db, transaction.Update, func(ttx *transaction.Tx) error {
    39  		light := collection.Light()
    40  		err := transaction.WithTx(operation.SkipDuplicates(operation.InsertCollection(&light)))(ttx)
    41  		if err != nil {
    42  			return fmt.Errorf("could not insert collection: %w", err)
    43  		}
    44  
    45  		for _, tx := range collection.Transactions {
    46  			err = c.transactions.storeTx(tx)(ttx)
    47  			if err != nil {
    48  				return fmt.Errorf("could not insert transaction: %w", err)
    49  			}
    50  		}
    51  
    52  		return nil
    53  	})
    54  }
    55  
    56  func (c *Collections) ByID(colID flow.Identifier) (*flow.Collection, error) {
    57  	var (
    58  		light      flow.LightCollection
    59  		collection flow.Collection
    60  	)
    61  
    62  	err := c.db.View(func(btx *badger.Txn) error {
    63  		err := operation.RetrieveCollection(colID, &light)(btx)
    64  		if err != nil {
    65  			return fmt.Errorf("could not retrieve collection: %w", err)
    66  		}
    67  
    68  		for _, txID := range light.Transactions {
    69  			tx, err := c.transactions.ByID(txID)
    70  			if err != nil {
    71  				return fmt.Errorf("could not retrieve transaction: %w", err)
    72  			}
    73  
    74  			collection.Transactions = append(collection.Transactions, tx)
    75  		}
    76  
    77  		return nil
    78  	})
    79  	if err != nil {
    80  		return nil, err
    81  	}
    82  
    83  	return &collection, nil
    84  }
    85  
    86  func (c *Collections) LightByID(colID flow.Identifier) (*flow.LightCollection, error) {
    87  	var collection flow.LightCollection
    88  
    89  	err := c.db.View(func(tx *badger.Txn) error {
    90  		err := operation.RetrieveCollection(colID, &collection)(tx)
    91  		if err != nil {
    92  			return fmt.Errorf("could not retrieve collection: %w", err)
    93  		}
    94  
    95  		return nil
    96  	})
    97  	if err != nil {
    98  		return nil, err
    99  	}
   100  
   101  	return &collection, nil
   102  }
   103  
   104  func (c *Collections) Remove(colID flow.Identifier) error {
   105  	return operation.RetryOnConflict(c.db.Update, func(btx *badger.Txn) error {
   106  		err := operation.RemoveCollection(colID)(btx)
   107  		if err != nil {
   108  			return fmt.Errorf("could not remove collection: %w", err)
   109  		}
   110  		return nil
   111  	})
   112  }
   113  
   114  func (c *Collections) StoreLightAndIndexByTransaction(collection *flow.LightCollection) error {
   115  	return operation.RetryOnConflict(c.db.Update, func(tx *badger.Txn) error {
   116  		err := operation.InsertCollection(collection)(tx)
   117  		if err != nil {
   118  			return fmt.Errorf("could not insert collection: %w", err)
   119  		}
   120  
   121  		for _, txID := range collection.Transactions {
   122  			err = operation.IndexCollectionByTransaction(txID, collection.ID())(tx)
   123  			if errors.Is(err, storage.ErrAlreadyExists) {
   124  				continue
   125  			}
   126  			if err != nil {
   127  				return fmt.Errorf("could not insert transaction ID: %w", err)
   128  			}
   129  		}
   130  
   131  		return nil
   132  	})
   133  }
   134  
   135  func (c *Collections) LightByTransactionID(txID flow.Identifier) (*flow.LightCollection, error) {
   136  	var collection flow.LightCollection
   137  	err := c.db.View(func(tx *badger.Txn) error {
   138  		collID := &flow.Identifier{}
   139  		err := operation.RetrieveCollectionID(txID, collID)(tx)
   140  		if err != nil {
   141  			return fmt.Errorf("could not retrieve collection id: %w", err)
   142  		}
   143  
   144  		err = operation.RetrieveCollection(*collID, &collection)(tx)
   145  		if err != nil {
   146  			return fmt.Errorf("could not retrieve collection: %w", err)
   147  		}
   148  
   149  		return nil
   150  	})
   151  	if err != nil {
   152  		return nil, err
   153  	}
   154  
   155  	return &collection, nil
   156  }