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 }