|
|
package explorer |
|
|
|
|
|
|
|
|
|
|
|
import ( |
|
|
"encoding/json" |
|
|
"os" |
|
|
"sort" |
|
|
"sync" |
|
|
|
|
|
"github.com/gofrs/flock" |
|
|
) |
|
|
|
|
|
|
|
|
type Database struct { |
|
|
path string |
|
|
data map[string]TokenData |
|
|
flock *flock.Flock |
|
|
sync.Mutex |
|
|
} |
|
|
|
|
|
|
|
|
type TokenData struct { |
|
|
Name string `json:"name"` |
|
|
Description string `json:"description"` |
|
|
Clusters []ClusterData |
|
|
Failures int |
|
|
} |
|
|
|
|
|
type ClusterData struct { |
|
|
Workers []string |
|
|
Type string |
|
|
NetworkID string |
|
|
} |
|
|
|
|
|
|
|
|
func NewDatabase(path string) (*Database, error) { |
|
|
fileLock := flock.New(path + ".lock") |
|
|
db := &Database{ |
|
|
data: make(map[string]TokenData), |
|
|
path: path, |
|
|
flock: fileLock, |
|
|
} |
|
|
return db, db.load() |
|
|
} |
|
|
|
|
|
|
|
|
func (db *Database) Get(token string) (TokenData, bool) { |
|
|
db.flock.Lock() |
|
|
defer db.flock.Unlock() |
|
|
db.Lock() |
|
|
defer db.Unlock() |
|
|
db.load() |
|
|
t, ok := db.data[token] |
|
|
return t, ok |
|
|
} |
|
|
|
|
|
|
|
|
func (db *Database) Set(token string, t TokenData) error { |
|
|
db.flock.Lock() |
|
|
defer db.flock.Unlock() |
|
|
db.Lock() |
|
|
defer db.Unlock() |
|
|
db.load() |
|
|
db.data[token] = t |
|
|
|
|
|
return db.save() |
|
|
} |
|
|
|
|
|
|
|
|
func (db *Database) Delete(token string) error { |
|
|
db.flock.Lock() |
|
|
defer db.flock.Unlock() |
|
|
db.Lock() |
|
|
defer db.Unlock() |
|
|
db.load() |
|
|
delete(db.data, token) |
|
|
return db.save() |
|
|
} |
|
|
|
|
|
func (db *Database) TokenList() []string { |
|
|
db.flock.Lock() |
|
|
defer db.flock.Unlock() |
|
|
db.Lock() |
|
|
defer db.Unlock() |
|
|
db.load() |
|
|
tokens := []string{} |
|
|
for k := range db.data { |
|
|
tokens = append(tokens, k) |
|
|
} |
|
|
|
|
|
sort.Slice(tokens, func(i, j int) bool { |
|
|
|
|
|
return tokens[i] < tokens[j] |
|
|
}) |
|
|
|
|
|
return tokens |
|
|
} |
|
|
|
|
|
|
|
|
func (db *Database) load() error { |
|
|
if _, err := os.Stat(db.path); os.IsNotExist(err) { |
|
|
return nil |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
f, err := os.ReadFile(db.path) |
|
|
if err != nil { |
|
|
return err |
|
|
} |
|
|
return json.Unmarshal(f, &db.data) |
|
|
} |
|
|
|
|
|
|
|
|
func (db *Database) save() error { |
|
|
|
|
|
|
|
|
f, err := os.Create(db.path) |
|
|
if err != nil { |
|
|
return err |
|
|
} |
|
|
defer f.Close() |
|
|
return json.NewEncoder(f).Encode(db.data) |
|
|
} |
|
|
|