-
Notifications
You must be signed in to change notification settings - Fork 5
/
datastore.go
128 lines (112 loc) · 3.35 KB
/
datastore.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package database
import (
"context"
"errors"
"cloud.google.com/go/datastore"
)
const (
entityKind string = "Jobs"
entityNamespace string = "captions-jobs"
)
// DatastoreClient is a datastore interface with operations used by the captions API
type DatastoreClient interface {
Put(context.Context, *datastore.Key, interface{}) (*datastore.Key, error)
Get(context.Context, *datastore.Key, interface{}) error
Delete(context.Context, *datastore.Key) error
GetAll(context.Context, *datastore.Query, interface{}) ([]*datastore.Key, error)
}
// DatastoreDatabase is a datastore client that implements DB interface
type DatastoreDatabase struct {
client DatastoreClient
kind string
namespace string
}
// NewDatastoreDatabase returns a DatastoreDatabase
func NewDatastoreDatabase(projectID string) (*DatastoreDatabase, error) {
ctx := context.Background()
client, err := datastore.NewClient(ctx, projectID)
if err != nil {
return nil, err
}
return &DatastoreDatabase{
client,
entityKind,
entityNamespace,
}, nil
}
// StoreJob stores a job
func (d *DatastoreDatabase) StoreJob(job *Job) (string, error) {
if _, err := d.GetJob(job.ID); err == nil {
return "", errors.New("job already exists")
}
ctx := context.Background()
key := newNameKeyWithNamespace(d.kind, job.ID, d.namespace)
_, err := d.client.Put(ctx, key, job)
if err != nil {
return "", err
}
return job.ID, nil
}
// GetJob retrieves a job from database
func (d *DatastoreDatabase) GetJob(id string) (*Job, error) {
result := &Job{}
ctx := context.Background()
key := newNameKeyWithNamespace(d.kind, id, d.namespace)
err := d.client.Get(ctx, key, result)
if err == datastore.ErrNoSuchEntity {
return nil, ErrJobNotFound
}
if err != nil {
return nil, errors.New("unknown error from Datastore")
}
return result, nil
}
// GetJobs retrieves all jobs in database
func (d *DatastoreDatabase) GetJobs(parentID string) ([]Job, error) {
var jobs []Job
ctx := context.Background()
query := datastore.NewQuery(d.kind).Namespace(d.namespace).Filter("ParentID =", parentID)
_, err := d.client.GetAll(ctx, query, &jobs)
if err != nil {
return nil, errors.New("unknown error from Datastore")
}
if len(jobs) == 0 {
return nil, ErrNoJobs
}
return jobs, nil
}
// UpdateJob updates a job
func (d *DatastoreDatabase) UpdateJob(id string, job *Job) error {
_, err := d.GetJob(id)
if err != nil {
return err
}
ctx := context.Background()
key := newNameKeyWithNamespace(d.kind, id, d.namespace)
_, err = d.client.Put(ctx, key, job)
return err
}
// DeleteJob deletes a job from database
func (d *DatastoreDatabase) DeleteJob(id string) error {
ctx := context.Background()
key := newNameKeyWithNamespace(d.kind, id, d.namespace)
return d.client.Delete(ctx, key)
}
// GetJobByProviderID returns a job associated with a given provider ID
func (d *DatastoreDatabase) GetJobByProviderID(providerID string) (*Job, error) {
ctx := context.Background()
query := datastore.NewQuery(d.kind).Namespace(d.namespace).Filter("ProviderParams.ProviderID =", providerID).Limit(1)
var jobs []Job
if _, err := d.client.GetAll(ctx, query, &jobs); err != nil {
return nil, err
}
if len(jobs) == 0 {
return nil, ErrNoJobs
}
return &jobs[0], nil
}
func newNameKeyWithNamespace(kind, name, namespace string) *datastore.Key {
key := datastore.NameKey(kind, name, nil)
key.Namespace = namespace
return key
}