2022-12-04 22:27:41 +00:00
|
|
|
package mmkv
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
"path"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
DefaultVaultID = "mmkv.default"
|
|
|
|
)
|
|
|
|
|
|
|
|
type manager struct {
|
|
|
|
dir string
|
|
|
|
vaults map[string]Vault
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewManager creates a new MMKV Manager.
|
|
|
|
func NewManager(dir string) (Manager, error) {
|
|
|
|
// check dir exists
|
|
|
|
info, err := os.Stat(dir)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to stat dir: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if !info.IsDir() {
|
|
|
|
return nil, fmt.Errorf("not a directory")
|
|
|
|
}
|
|
|
|
|
|
|
|
return &manager{
|
|
|
|
dir: dir,
|
|
|
|
vaults: make(map[string]Vault),
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *manager) OpenVault(id string) (Vault, error) {
|
|
|
|
if id == "" {
|
|
|
|
id = DefaultVaultID
|
|
|
|
}
|
|
|
|
|
|
|
|
if v, ok := m.vaults[id]; ok {
|
|
|
|
return v, nil
|
|
|
|
}
|
|
|
|
|
2024-02-04 16:47:24 +00:00
|
|
|
vault, err := m.openVault(id, "")
|
2022-12-04 22:27:41 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to open vault: %w", err)
|
|
|
|
}
|
|
|
|
m.vaults[id] = vault
|
|
|
|
|
|
|
|
return vault, nil
|
|
|
|
}
|
|
|
|
|
2024-02-04 16:47:24 +00:00
|
|
|
func (m *manager) OpenVaultCrypto(id string, cryptoKey string) (Vault, error) {
|
|
|
|
if id == "" {
|
|
|
|
id = DefaultVaultID
|
|
|
|
}
|
|
|
|
|
|
|
|
if v, ok := m.vaults[id]; ok {
|
|
|
|
return v, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
vault, err := m.openVault(id, cryptoKey)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to open vault: %w", err)
|
|
|
|
}
|
|
|
|
m.vaults[id] = vault
|
|
|
|
|
|
|
|
return vault, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *manager) openVault(id string, cryptoKey string) (Vault, error) {
|
2022-12-04 22:27:41 +00:00
|
|
|
metaFile, err := os.Open(path.Join(m.dir, id+".crc"))
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to open metadata file: %w", err)
|
|
|
|
}
|
|
|
|
defer metaFile.Close()
|
|
|
|
|
|
|
|
vaultFile, err := os.Open(path.Join(m.dir, id))
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to open vault file: %w", err)
|
|
|
|
}
|
|
|
|
defer vaultFile.Close()
|
|
|
|
|
|
|
|
meta, err := loadMetadata(metaFile)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to load metadata: %w", err)
|
|
|
|
}
|
|
|
|
|
2024-02-04 16:47:24 +00:00
|
|
|
v, err := loadVault(vaultFile, meta, cryptoKey)
|
2022-12-04 22:27:41 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to load vault: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return v, nil
|
|
|
|
}
|