-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstore.go
90 lines (79 loc) · 1.96 KB
/
store.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
package nidhi
import (
"context"
"database/sql"
_ "embed"
"fmt"
)
const (
schemaTemplate = `
CREATE SCHEMA IF NOT EXISTS %s
`
tableTemplate = `
CREATE TABLE IF NOT EXISTS %s.%s (
id TEXT NOT NULL PRIMARY KEY,
revision BIGINT NOT NULL,
document JSONB NOT NULL,
deleted BOOLEAN NOT NULL DEFAULT FALSE,
metadata JSONB NOT NULL DEFAULT '{}'
)
`
ColId = "id"
ColDoc = "document"
ColRev = `"revision"`
ColMeta = "metadata"
ColDel = "deleted"
notDeleted = ColDel + " = false "
)
type (
// IdFn should return the unique id of a document.
IdFn[T any] func(*T) string
// SetIdFn should set the unique id of a document.
SetIdFn[T any] func(*T, string)
)
// StoreOptions are options for a Store.
type StoreOptions struct {
// MetadataRegistry is the registry of metadata parts.
MetadataRegistry map[string]func() MetadataPart
// Hooks for the store operations.
Hooks []Hooks
}
// Store is the collection of documents
type Store[T any] struct {
db *sql.DB
table string
fields []string
idFn IdFn[T]
setIdFn SetIdFn[T]
mdr map[string]func() MetadataPart
hooks []Hooks
}
// NewStore returns a new store.
//
// Typically this is never directly called. It is called via a more concrete generated function.
// See protoc-gen-nidhi.
func NewStore[T any](
ctx context.Context,
db *sql.DB,
schema, table string,
fields []string,
idFn IdFn[T],
setIdFn SetIdFn[T],
opts StoreOptions,
) (*Store[T], error) {
if _, err := db.ExecContext(ctx, fmt.Sprintf(schemaTemplate, schema)); err != nil {
return nil, fmt.Errorf("nidhi: failed to create schema: %q, err: %w", schema, err)
}
if _, err := db.ExecContext(ctx, fmt.Sprintf(tableTemplate, schema, table)); err != nil {
return nil, fmt.Errorf("nidhi: failed to create table: \"%s.%s\", err: %w", schema, table, err)
}
return &Store[T]{
db: db,
table: schema + "." + table,
fields: fields,
idFn: idFn,
setIdFn: setIdFn,
mdr: opts.MetadataRegistry,
hooks: opts.Hooks,
}, nil
}