Skip to content

Commit b31e4fe

Browse files
committed
Introducing metadata storage interface for isolation and warm fuzzies
1 parent 97272f3 commit b31e4fe

9 files changed

+107
-37
lines changed

metadata/database.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,10 @@ func NewDatabase(url string, log *logrus.Logger) (*Database, error) {
110110
}
111111

112112
// Save saves some metadata
113-
func (db *Database) Save(m *Metadata) (sql.Result, error) {
113+
func (db *Database) Save(m *Metadata) error {
114114
statement := db.st.InsertMetadata.St
115115
if statement == nil {
116-
return nil, errNoStatement
116+
return errNoStatement
117117
}
118118

119119
res, err := statement.Exec(m.JobID, m.Size, m.Path, m.ContentType)
@@ -131,7 +131,7 @@ func (db *Database) Save(m *Metadata) (sql.Result, error) {
131131
db.log.WithFields(logFields).Info("saving metadata")
132132
}
133133

134-
return res, err
134+
return err
135135
}
136136

137137
// Lookup looks up some metadata

metadata/lookup_saver.go

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package metadata
2+
3+
// LookupSaver is the interface needed for reads and writes of metadata
4+
type LookupSaver interface {
5+
Save(*Metadata) error
6+
Lookup(string, string) (*Metadata, error)
7+
LookupAll(string) ([]*Metadata, error)
8+
}

metadata/null_lookup_saver.go

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package metadata
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
"sync"
7+
)
8+
9+
type NullLookupSaver struct {
10+
mdMap map[string]*Metadata
11+
12+
l *sync.Mutex
13+
}
14+
15+
func NewNullLookupSaver() *NullLookupSaver {
16+
return &NullLookupSaver{
17+
mdMap: map[string]*Metadata{},
18+
19+
l: &sync.Mutex{},
20+
}
21+
}
22+
23+
func (nls *NullLookupSaver) Save(m *Metadata) error {
24+
nls.l.Lock()
25+
defer nls.l.Unlock()
26+
nls.mdMap[fmt.Sprintf("%s-%s", m.JobID, m.Path)] = m
27+
return nil
28+
}
29+
30+
func (nls *NullLookupSaver) Lookup(jobID, path string) (*Metadata, error) {
31+
nls.l.Lock()
32+
defer nls.l.Unlock()
33+
m, ok := nls.mdMap[fmt.Sprintf("%s-%s", jobID, path)]
34+
if ok {
35+
return m, nil
36+
}
37+
return nil, errNoMetadata
38+
}
39+
40+
func (nls *NullLookupSaver) LookupAll(jobID string) ([]*Metadata, error) {
41+
nls.l.Lock()
42+
defer nls.l.Unlock()
43+
mds := []*Metadata{}
44+
45+
for key, m := range nls.mdMap {
46+
keyParts := strings.SplitN(key, "-", 1)
47+
if len(keyParts) < 2 {
48+
return nil, errNoMetadata
49+
}
50+
51+
if keyParts[0] == jobID {
52+
mds = append(mds, m)
53+
}
54+
}
55+
56+
return mds, nil
57+
}

server/server.go

+19-13
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ type Server struct {
2727
log *logrus.Logger
2828
store store.Storer
2929
auth auth.Auther
30-
md *metadata.Database
30+
md metadata.LookupSaver
3131
}
3232

3333
// Main is the top of the pile. Start here.
@@ -41,7 +41,7 @@ func Main(log *logrus.Logger) {
4141
opts.FileStorePrefix = "tmp"
4242
}
4343

44-
server, err := NewServer(opts, log)
44+
server, err := NewServer(opts, log, nil)
4545
if err != nil {
4646
log.Fatal(err)
4747
}
@@ -60,7 +60,7 @@ func Main(log *logrus.Logger) {
6060
}
6161

6262
// NewServer creates a new *Server with a router and its routes registered
63-
func NewServer(opts *Options, log *logrus.Logger) (*Server, error) {
63+
func NewServer(opts *Options, log *logrus.Logger, md metadata.LookupSaver) (*Server, error) {
6464
var err error
6565

6666
log.Debug("creating new server")
@@ -72,7 +72,7 @@ func NewServer(opts *Options, log *logrus.Logger) (*Server, error) {
7272
srv.setupRouter()
7373
srv.setupNegroni()
7474

75-
err = srv.getDB()
75+
err = srv.getMd(md)
7676
if err != nil {
7777
return nil, err
7878
}
@@ -188,19 +188,25 @@ func (srv *Server) setupAuther() error {
188188
panic("fell through to a bad place ¯\\_(ツ)_/¯")
189189
}
190190

191-
func (srv *Server) getDB() error {
191+
func (srv *Server) getMd(md metadata.LookupSaver) error {
192192
srv.log.Debug("getting database handle")
193-
db, err := metadata.NewDatabase(srv.opts.DatabaseURL, srv.log)
194-
if err != nil {
195-
return err
196-
}
197193

198-
err = db.Init()
199-
if err != nil {
200-
return err
194+
if md == nil {
195+
mddb, err := metadata.NewDatabase(srv.opts.DatabaseURL, srv.log)
196+
197+
if err != nil {
198+
return err
199+
}
200+
201+
err = mddb.Init()
202+
if err != nil {
203+
return err
204+
}
205+
206+
md = mddb
201207
}
202208

203-
srv.md = db
209+
srv.md = md
204210
return nil
205211
}
206212

server/server_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"testing"
77

88
"github.com/Sirupsen/logrus"
9+
"github.com/hamfist/artifacts-service/metadata"
910
)
1011

1112
var (
@@ -29,13 +30,12 @@ func TestServerDefaults(t *testing.T) {
2930
opts := NewOptions()
3031
log := getPanicLogger()
3132

32-
srv, err := NewServer(opts, log)
33+
srv, err := NewServer(opts, log, metadata.NewNullLookupSaver())
3334
if err != nil {
3435
t.Fatalf("%v", err)
3536
}
3637

3738
if !reflect.DeepEqual(srv.opts, opts) {
3839
t.Fatalf("opts %v != %v", srv.opts, opts)
3940
}
40-
4141
}

store/file_store.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@ import (
1818
type FileStore struct {
1919
Prefix string
2020
log *logrus.Logger
21-
db *metadata.Database
21+
md metadata.LookupSaver
2222
}
2323

2424
// NewFileStore returns a *FileStore. AMAZE.
25-
func NewFileStore(prefix string, log *logrus.Logger, db *metadata.Database) *FileStore {
25+
func NewFileStore(prefix string, log *logrus.Logger, md metadata.LookupSaver) *FileStore {
2626
return &FileStore{
2727
Prefix: prefix,
2828
log: log,
29-
db: db,
29+
md: md,
3030
}
3131
}
3232

store/s3_store.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ type S3Store struct {
2121
secret string
2222
bucket string
2323
log *logrus.Logger
24-
db *metadata.Database
24+
md metadata.LookupSaver
2525
b *s3.Bucket
2626
}
2727

2828
// NewS3Store initializes an *S3Store. Wow!
2929
func NewS3Store(key, secret, bucket, regionName string,
30-
log *logrus.Logger, db *metadata.Database) (*S3Store, error) {
30+
log *logrus.Logger, md metadata.LookupSaver) (*S3Store, error) {
3131

3232
log.Debug("getting aws auth")
3333
auth, err := aws.GetAuth(key, secret)
@@ -62,7 +62,7 @@ func NewS3Store(key, secret, bucket, regionName string,
6262
bucket: bucket,
6363

6464
log: log,
65-
db: db,
65+
md: md,
6666
b: b,
6767
}, nil
6868
}
@@ -89,7 +89,7 @@ func (s3s *S3Store) Store(a *artifact.Artifact) error {
8989
}
9090

9191
md := artifactToMetadata(a)
92-
_, err = s3s.db.Save(md)
92+
err = s3s.md.Save(md)
9393
if err != nil {
9494
return err
9595
}

store/s3_store_test.go

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
package store
22

3-
import "testing"
3+
import (
4+
"testing"
5+
6+
"github.com/hamfist/artifacts-service/metadata"
7+
)
48

59
func TestNewS3StoreDefaults(t *testing.T) {
610
log := getPanicLogger()
7-
db := getTestDB()
8-
s3s, err := NewS3Store("key", "secret", "bucket", "us-west-2", log, db)
11+
md := metadata.NewNullLookupSaver()
12+
s3s, err := NewS3Store("key", "secret", "bucket", "us-west-2", log, md)
913
if err != nil {
1014
t.Fatalf("%v", err)
1115
}

store/store_test.go

+4-9
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ var (
1212
dbURL = os.Getenv("DATABASE_URL")
1313
)
1414

15+
type testSaver struct {
16+
mds map[string]*metadata.Metadata
17+
}
18+
1519
func init() {
1620
os.Clearenv()
1721
os.Setenv("DATABASE_URL", dbURL)
@@ -25,15 +29,6 @@ func getPanicLogger() *logrus.Logger {
2529
return log
2630
}
2731

28-
func getTestDB() *metadata.Database {
29-
db, err := metadata.NewDatabase(dbURL, getPanicLogger())
30-
if err != nil {
31-
panic(err)
32-
}
33-
34-
return db
35-
}
36-
3732
func TestStuff(t *testing.T) {
3833
if false {
3934
t.Fail()

0 commit comments

Comments
 (0)