github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/pkg/names/write.go (about)

     1  package names
     2  
     3  import (
     4  	"path/filepath"
     5  	"sort"
     6  
     7  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/base"
     8  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/config"
     9  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/file"
    10  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/types"
    11  )
    12  
    13  func CustomWriteNames(chain string, dryRun bool) (err error) {
    14  	database := DatabaseCustom
    15  	if dryRun {
    16  		database = DatabaseDryRun
    17  	}
    18  
    19  	customNamesMutex.Lock()
    20  	defer customNamesMutex.Unlock()
    21  
    22  	return writeDatabase(
    23  		chain,
    24  		database,
    25  		customNames,
    26  	)
    27  }
    28  
    29  func RegularWriteNames(chain string, dryRun bool) (err error) {
    30  	database := DatabaseRegular
    31  	if dryRun {
    32  		database = DatabaseDryRun
    33  	}
    34  
    35  	regularNamesMutex.Lock()
    36  	defer regularNamesMutex.Unlock()
    37  
    38  	return writeDatabase(
    39  		chain,
    40  		database,
    41  		regularNames,
    42  	)
    43  }
    44  
    45  func writeDatabase(chain string, database DatabaseType, names map[base.Address]types.Name) error {
    46  	namesPath := getDatabasePath(chain, database)
    47  	tmpPath := filepath.Join(config.PathToCache(chain), "tmp")
    48  
    49  	// openDatabaseForEdit truncates the file when it opens. We make
    50  	// a backup so we can restore it on an error if we need to.
    51  	backup, err := file.MakeBackup(tmpPath, namesPath)
    52  	if err != nil {
    53  		return err
    54  	}
    55  
    56  	db, err := openDatabaseForEdit(chain, database)
    57  	if err != nil {
    58  		// The backup will replace the now truncated file.
    59  		return err
    60  	}
    61  
    62  	if database != DatabaseDryRun {
    63  		if err = file.Lock(db); err != nil {
    64  			return err
    65  		}
    66  		defer func() {
    67  			_ = file.Unlock(db)
    68  		}()
    69  	}
    70  
    71  	defer func() {
    72  		_ = db.Close()
    73  		// If the backup exists, it will replace the now truncated file.
    74  		backup.Restore()
    75  	}()
    76  
    77  	sorted := make([]types.Name, 0, len(names))
    78  	for _, name := range names {
    79  		sorted = append(sorted, name)
    80  	}
    81  	sort.SliceStable(sorted, func(i, j int) bool {
    82  		return sorted[i].Address.Hex() < sorted[j].Address.Hex()
    83  	})
    84  
    85  	writer := NewNameWriter(db)
    86  	for _, name := range sorted {
    87  		if err = writer.Write(&name); err != nil {
    88  			return err
    89  		}
    90  	}
    91  	writer.Flush()
    92  
    93  	err = writer.Error()
    94  	if err == nil {
    95  		// Everything went okay, so we can remove the backup.
    96  		backup.Clear()
    97  	}
    98  	return err
    99  }