diff --git a/pkg/package/database.go b/pkg/package/database.go index af94dac2..bd046bd5 100644 --- a/pkg/package/database.go +++ b/pkg/package/database.go @@ -17,4 +17,13 @@ package pkg // Database is a merely simple in-memory db. // FIXME: Use a proper structure or delegate to third-party -var Database map[string]string = map[string]string{} +type PackageDatabase interface { + Get(s string) (string, error) + Set(k, v string) error + + Create([]byte) (string, error) + Retrieve(ID string) ([]byte, error) + + GetPackage(ID string) (Package, error) + CreatePackage(p Package) (string, error) +} diff --git a/pkg/package/database_mem.go b/pkg/package/database_mem.go new file mode 100644 index 00000000..f954f84a --- /dev/null +++ b/pkg/package/database_mem.go @@ -0,0 +1,110 @@ +// Copyright © 2019 Ettore Di Giacinto +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, see . + +package pkg + +import ( + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "hash/crc32" +) + +var DBInMemoryInstance PackageDatabase + +type InMemoryDatabase struct { + Database map[string]string +} + +func NewInMemoryDatabase() PackageDatabase { + // In memoryDB is a singleton + if DBInMemoryInstance == nil { + DBInMemoryInstance = &InMemoryDatabase{Database: map[string]string{}} + } + return DBInMemoryInstance +} + +func (db *InMemoryDatabase) Get(s string) (string, error) { + + pa, ok := db.Database[s] + if !ok { + return "", errors.New("No key found with that id") + } + return pa, nil +} + +func (db *InMemoryDatabase) Set(k, v string) error { + db.Database[k] = v + + return nil +} + +func (db *InMemoryDatabase) Create(v []byte) (string, error) { + enc := base64.StdEncoding.EncodeToString(v) + crc32q := crc32.MakeTable(0xD5828281) + ID := fmt.Sprintf("%08x\n", crc32.Checksum([]byte(enc), crc32q)) + + return ID, db.Set(ID, enc) +} + +func (db *InMemoryDatabase) Retrieve(ID string) ([]byte, error) { + pa, err := db.Get(ID) + if err != nil { + return nil, err + } + + enc, err := base64.StdEncoding.DecodeString(pa) + if err != nil { + return nil, err + } + return enc, nil +} + +func (db *InMemoryDatabase) GetPackage(ID string) (Package, error) { + + enc, err := db.Retrieve(ID) + if err != nil { + return nil, err + } + + p := &DefaultPackage{} + + if err := json.Unmarshal(enc, &p); err != nil { + return nil, err + } + return p, nil +} + +// Encode encodes the package to string. +// It returns an ID which can be used to retrieve the package later on. +func (db *InMemoryDatabase) CreatePackage(p Package) (string, error) { + + pd, ok := p.(*DefaultPackage) + if !ok { + return "", errors.New("InMemoryDatabase suports only DefaultPackage") + } + + res, err := json.Marshal(pd) + if err != nil { + return "", err + } + + ID, err := db.Create(res) + if err != nil { + return "", err + } + return ID, nil +} diff --git a/pkg/package/package.go b/pkg/package/package.go index 06831f08..697b90dd 100644 --- a/pkg/package/package.go +++ b/pkg/package/package.go @@ -16,12 +16,6 @@ package pkg import ( - "encoding/base64" - "encoding/json" - "errors" - "fmt" - "hash/crc32" - "github.com/crillab/gophersat/bf" version "github.com/hashicorp/go-version" @@ -98,16 +92,7 @@ func (p *DefaultPackage) RemoveUse(use string) { // Encode encodes the package to string. // It returns an ID which can be used to retrieve the package later on. func (p *DefaultPackage) Encode() (string, error) { - res, err := json.Marshal(p) - if err != nil { - return "", err - } - - enc := base64.StdEncoding.EncodeToString(res) - crc32q := crc32.MakeTable(0xD5828281) - ID := fmt.Sprintf("%08x\n", crc32.Checksum([]byte(enc), crc32q)) - Database[ID] = base64.StdEncoding.EncodeToString(res) - return ID, nil + return NewInMemoryDatabase().CreatePackage(p) } func (p *DefaultPackage) WithState(state State) Package { @@ -175,22 +160,7 @@ func (p *DefaultPackage) Expand(world []Package) ([]Package, error) { } func DecodePackage(ID string) (Package, error) { - - pa, ok := Database[ID] - if !ok { - return nil, errors.New("No package found with that id") - } - - enc, err := base64.StdEncoding.DecodeString(pa) - if err != nil { - return nil, err - } - p := &DefaultPackage{} - - if err := json.Unmarshal(enc, &p); err != nil { - return nil, err - } - return p, nil + return NewInMemoryDatabase().GetPackage(ID) } func NormalizeFlagged(p Package) {