Skip to content
This repository was archived by the owner on Sep 2, 2024. It is now read-only.

Commit 9bd62e5

Browse files
committed
first function runtime implementation close #10
1 parent fb2e75b commit 9bd62e5

File tree

10 files changed

+492
-61
lines changed

10 files changed

+492
-61
lines changed

db/base.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@ func (b *Base) Add(auth internal.Auth, db *mongo.Database, col string, doc map[s
4040
}
4141

4242
type PagedResult struct {
43-
Page int64 `json:"page"`
44-
Size int64 `json:"size"`
45-
Total int64 `json:"total"`
46-
Results []interface{} `json:"results"`
43+
Page int64 `json:"page"`
44+
Size int64 `json:"size"`
45+
Total int64 `json:"total"`
46+
Results []bson.M `json:"results"`
4747
}
4848

4949
type ListParams struct {
@@ -100,7 +100,7 @@ func (b *Base) List(auth internal.Auth, db *mongo.Database, col string, params L
100100
}
101101
defer cur.Close(ctx)
102102

103-
var results []interface{}
103+
var results []bson.M
104104

105105
for cur.Next(ctx) {
106106
var v bson.M
@@ -120,7 +120,7 @@ func (b *Base) List(auth internal.Auth, db *mongo.Database, col string, params L
120120
}
121121

122122
if len(results) == 0 {
123-
results = make([]interface{}, 1)
123+
results = make([]bson.M, 1)
124124
}
125125

126126
result.Results = results
@@ -155,7 +155,7 @@ func (b *Base) Query(auth internal.Auth, db *mongo.Database, col string, filter
155155
result.Total = count
156156

157157
if count == 0 {
158-
result.Results = make([]interface{}, 0)
158+
result.Results = make([]bson.M, 0)
159159
return result, nil
160160
}
161161

@@ -180,7 +180,7 @@ func (b *Base) Query(auth internal.Auth, db *mongo.Database, col string, filter
180180
}
181181
defer cur.Close(ctx)
182182

183-
var results []interface{}
183+
var results []bson.M
184184

185185
for cur.Next(ctx) {
186186
var v bson.M
@@ -200,7 +200,7 @@ func (b *Base) Query(auth internal.Auth, db *mongo.Database, col string, filter
200200
}
201201

202202
if len(results) == 0 {
203-
results = make([]interface{}, 1)
203+
results = make([]bson.M, 1)
204204
}
205205

206206
result.Results = results

db_test.go

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,16 @@ import (
1313
"time"
1414
)
1515

16-
func dbPost(t *testing.T, hf func(http.ResponseWriter, *http.Request), repo string, v interface{}) *http.Response {
16+
// dbPost post on behalf of adminToken by default (use params[0] true for root)
17+
func dbPost(t *testing.T, hf func(http.ResponseWriter, *http.Request), repo string, v interface{}, params ...bool) *http.Response {
18+
if params == nil {
19+
params = make([]bool, 0)
20+
}
21+
22+
if len(params) == 0 {
23+
params = append(params, false)
24+
}
25+
1726
b, err := json.Marshal(v)
1827
if err != nil {
1928
t.Fatal("error marshaling post data:", err)
@@ -23,12 +32,23 @@ func dbPost(t *testing.T, hf func(http.ResponseWriter, *http.Request), repo stri
2332
w := httptest.NewRecorder()
2433

2534
req.Header.Set("SB-PUBLIC-KEY", pubKey)
26-
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", adminToken))
35+
36+
tok := adminToken
37+
if params[0] {
38+
tok = rootToken
39+
}
40+
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", tok))
2741

2842
stdAuth := []middleware.Middleware{
2943
middleware.WithDB(database.client),
3044
middleware.RequireAuth(database.client),
3145
}
46+
if params[0] {
47+
stdAuth = []middleware.Middleware{
48+
middleware.WithDB(client),
49+
middleware.RequireRoot(client),
50+
}
51+
}
3252
h := middleware.Chain(http.HandlerFunc(hf), stdAuth...)
3353

3454
h.ServeHTTP(w, req)

function/management.go

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
package function
2+
3+
import (
4+
"context"
5+
"staticbackend/internal"
6+
"time"
7+
8+
"go.mongodb.org/mongo-driver/bson"
9+
"go.mongodb.org/mongo-driver/bson/primitive"
10+
"go.mongodb.org/mongo-driver/mongo"
11+
"go.mongodb.org/mongo-driver/mongo/options"
12+
)
13+
14+
// ExecData represents a server-side function with its name, code and execution
15+
// history
16+
type ExecData struct {
17+
ID primitive.ObjectID `bson:"_id" json:"id"`
18+
FunctionName string `bson:"name" json:"name"`
19+
TriggerTopic string `bson:"tr" json:"trigger"`
20+
Code string `bson:"code" json:"code"`
21+
Version int `bson:"v" json:"version"`
22+
LastUpdated time.Time `bson:"lu" json:"lastUpdated"`
23+
History []ExecHistory `bson:"h" json:"history"`
24+
}
25+
26+
// ExecHistory represents a function run ending result
27+
type ExecHistory struct {
28+
Version int `bson:"v" json:"version"`
29+
Started time.Time `bson:"s" json:"started"`
30+
Completed time.Time `bson:"c" json:"completed"`
31+
Success bool `bson:"ok" json:"success"`
32+
Output []string `bson:"out" json:"output"`
33+
}
34+
35+
func Add(db *mongo.Database, data ExecData) (string, error) {
36+
data.ID = primitive.NewObjectID()
37+
data.Version = 1
38+
data.LastUpdated = time.Now()
39+
40+
ctx := context.Background()
41+
if _, err := db.Collection("sb_functions").InsertOne(ctx, data); err != nil {
42+
return "", err
43+
}
44+
45+
return data.ID.Hex(), nil
46+
}
47+
48+
func Update(db *mongo.Database, id, code, trigger string) error {
49+
oid, err := primitive.ObjectIDFromHex(id)
50+
if err != nil {
51+
return err
52+
}
53+
54+
update := bson.M{
55+
"$set": bson.M{"code": code, "lu": time.Now(), "tr": trigger},
56+
"$inc": bson.M{"v": 1},
57+
}
58+
filter := bson.M{internal.FieldID: oid}
59+
60+
ctx := context.Background()
61+
res := db.Collection("sb_functions").FindOneAndUpdate(ctx, filter, update)
62+
if err := res.Err(); err != nil {
63+
return err
64+
}
65+
66+
return nil
67+
}
68+
69+
func GetForExecution(db *mongo.Database, name string) (ExecData, error) {
70+
var result ExecData
71+
72+
filter := bson.M{"name": name}
73+
74+
ctx := context.Background()
75+
opt := &options.FindOneOptions{}
76+
opt.SetProjection(bson.M{"h": -1})
77+
78+
sr := db.Collection("sb_functions").FindOne(ctx, filter, opt)
79+
if err := sr.Decode(&result); err != nil {
80+
return result, err
81+
} else if err := sr.Err(); err != nil {
82+
return result, err
83+
}
84+
85+
return result, nil
86+
}
87+
88+
func GetByID(db *mongo.Database, id string) (ExecData, error) {
89+
var result ExecData
90+
91+
oid, err := primitive.ObjectIDFromHex(id)
92+
if err != nil {
93+
return result, err
94+
}
95+
96+
filter := bson.M{internal.FieldID: oid}
97+
98+
ctx := context.Background()
99+
sr := db.Collection("sb_functions").FindOne(ctx, filter)
100+
if err := sr.Decode(&result); err != nil {
101+
return result, err
102+
} else if err := sr.Err(); err != nil {
103+
return result, err
104+
}
105+
106+
return result, nil
107+
}
108+
109+
func List(db *mongo.Database) ([]ExecData, error) {
110+
opt := &options.FindOptions{}
111+
opt.SetProjection(bson.M{"h": -1})
112+
113+
ctx := context.Background()
114+
cur, err := db.Collection("sb_functions").Find(ctx, bson.M{}, opt)
115+
if err != nil {
116+
return nil, err
117+
}
118+
defer cur.Close(ctx)
119+
120+
var results []ExecData
121+
for cur.Next(ctx) {
122+
var ed ExecData
123+
err := cur.Decode(&ed)
124+
if err != nil {
125+
return nil, err
126+
}
127+
128+
results = append(results, ed)
129+
}
130+
131+
return results, nil
132+
}
133+
134+
func Delete(db *mongo.Database, name string) error {
135+
filter := bson.M{"name": name}
136+
137+
ctx := context.Background()
138+
if _, err := db.Collection("sb_functions").DeleteOne(ctx, filter); err != nil {
139+
return err
140+
}
141+
142+
return nil
143+
}

0 commit comments

Comments
 (0)