-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.go
98 lines (87 loc) · 2.38 KB
/
server.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
// Server implementation
//
// DB Structure:
//
// root+
// catalog1+
// |
// + BYNAME Name -> Id
// + BYID Id -> { Database }
// + DB +
// |
// +<id1>
// BYNAME Name -> Id
// BYID ID -> { Table }
// TBLS
// + <id1>
// DATA
// PARTS
// + <id2>
// DATA
// PARTS
// |
// + <id2>
// DATA
// TBLS
//
package main
import (
"strings"
"fmt"
pb "github.com/akolb1/hmsv2api/gometastore/protobuf"
"github.com/boltdb/bolt"
"github.com/imdario/go-ulid"
)
const (
bynameHdr = "BYNAME"
byIDHdr = "BYID"
dbHdr = "DB"
tblsHdr = "TBLS"
)
type metastoreServer struct {
db *bolt.DB
}
func newServer(db *bolt.DB) *metastoreServer {
return &metastoreServer{db: db}
}
// Table ops
// getULID returns a unique ID.
func getULID() string {
return strings.TrimRight(ulid.New().String(), "\u0000")
}
// getDatabaseBucket returns Database bucket for the database specified by ID.
//
// tx - Bolt transaction
// catalog - catalog name, must be non-empty
// db - Database ID, must be non-empty and either name or Id should be specified
func getDatabaseBucket(tx *bolt.Tx, catalog string, db *pb.Id) (bucket *bolt.Bucket, err error) {
catBucket := tx.Bucket([]byte(catalog))
if catBucket == nil {
return nil, fmt.Errorf("missing catalog %s", catalog)
}
idMap := catBucket.Bucket([]byte(byIDHdr))
if idMap == nil {
return nil, fmt.Errorf("corrupted catalog %s: missing ID map", catalog)
}
idBytesDb := []byte(db.Id)
if db.Id == "" {
// Locate DB ID by name
nameIDBucket := catBucket.Bucket([]byte(bynameHdr))
if nameIDBucket == nil {
return nil, fmt.Errorf("corrupt catalog - missing NAME map")
}
idBytesDb = nameIDBucket.Get([]byte(db.Name))
if idBytesDb == nil {
return nil, fmt.Errorf("database %s doesn't exist", db.Name)
}
}
dbInfoBucket := catBucket.Bucket([]byte(dbHdr))
if dbInfoBucket == nil {
return nil, fmt.Errorf("corrupt catalog %s: no DB info", catalog)
}
dbBucket := dbInfoBucket.Bucket(idBytesDb)
if dbBucket == nil {
return nil, fmt.Errorf("corrupt catalog %s/%s: no DB info", catalog, db.Name)
}
return dbBucket, nil
}