github.com/safing/portbase@v0.19.5/database/main.go (about) 1 package database 2 3 import ( 4 "errors" 5 "fmt" 6 "path/filepath" 7 8 "github.com/tevino/abool" 9 10 "github.com/safing/portbase/utils" 11 ) 12 13 const ( 14 databasesSubDir = "databases" 15 ) 16 17 var ( 18 initialized = abool.NewBool(false) 19 20 shuttingDown = abool.NewBool(false) 21 shutdownSignal = make(chan struct{}) 22 23 rootStructure *utils.DirStructure 24 databasesStructure *utils.DirStructure 25 ) 26 27 // InitializeWithPath initializes the database at the specified location using a path. 28 func InitializeWithPath(dirPath string) error { 29 return Initialize(utils.NewDirStructure(dirPath, 0o0755)) 30 } 31 32 // Initialize initializes the database at the specified location using a dir structure. 33 func Initialize(dirStructureRoot *utils.DirStructure) error { 34 if initialized.SetToIf(false, true) { 35 rootStructure = dirStructureRoot 36 37 // ensure root and databases dirs 38 databasesStructure = rootStructure.ChildDir(databasesSubDir, 0o0700) 39 err := databasesStructure.Ensure() 40 if err != nil { 41 return fmt.Errorf("could not create/open database directory (%s): %w", rootStructure.Path, err) 42 } 43 44 if registryPersistence.IsSet() { 45 err = loadRegistry() 46 if err != nil { 47 return fmt.Errorf("could not load database registry (%s): %w", filepath.Join(rootStructure.Path, registryFileName), err) 48 } 49 } 50 51 return nil 52 } 53 return errors.New("database already initialized") 54 } 55 56 // Shutdown shuts down the whole database system. 57 func Shutdown() (err error) { 58 if shuttingDown.SetToIf(false, true) { 59 close(shutdownSignal) 60 } else { 61 return 62 } 63 64 controllersLock.RLock() 65 defer controllersLock.RUnlock() 66 67 for _, c := range controllers { 68 err = c.Shutdown() 69 if err != nil { 70 return 71 } 72 } 73 return 74 } 75 76 // getLocation returns the storage location for the given name and type. 77 func getLocation(name, storageType string) (string, error) { 78 location := databasesStructure.ChildDir(name, 0o0700).ChildDir(storageType, 0o0700) 79 // check location 80 err := location.Ensure() 81 if err != nil { 82 return "", fmt.Errorf(`failed to create/check database dir "%s": %w`, location.Path, err) 83 } 84 return location.Path, nil 85 }