source: code/trunk/db.go@ 757

Last change on this file since 757 was 712, checked in by contact, 4 years ago

Add Prometheus instrumentation for the database

File size: 3.7 KB
RevLine 
[98]1package soju
[77]2
3import (
[652]4 "context"
[148]5 "fmt"
[457]6 "net/url"
[263]7 "strings"
[434]8 "time"
[712]9
10 "github.com/prometheus/client_golang/prometheus"
[77]11)
12
[531]13type Database interface {
14 Close() error
[652]15 Stats(ctx context.Context) (*DatabaseStats, error)
[531]16
[652]17 ListUsers(ctx context.Context) ([]User, error)
18 GetUser(ctx context.Context, username string) (*User, error)
19 StoreUser(ctx context.Context, user *User) error
20 DeleteUser(ctx context.Context, id int64) error
[531]21
[652]22 ListNetworks(ctx context.Context, userID int64) ([]Network, error)
23 StoreNetwork(ctx context.Context, userID int64, network *Network) error
24 DeleteNetwork(ctx context.Context, id int64) error
25 ListChannels(ctx context.Context, networkID int64) ([]Channel, error)
26 StoreChannel(ctx context.Context, networKID int64, ch *Channel) error
27 DeleteChannel(ctx context.Context, id int64) error
[531]28
[652]29 ListDeliveryReceipts(ctx context.Context, networkID int64) ([]DeliveryReceipt, error)
30 StoreClientDeliveryReceipts(ctx context.Context, networkID int64, client string, receipts []DeliveryReceipt) error
[531]31}
32
[712]33type MetricsCollectorDatabase interface {
34 Database
35 MetricsCollector() prometheus.Collector
36}
37
[620]38func OpenDB(driver, source string) (Database, error) {
39 switch driver {
40 case "sqlite3":
41 return OpenSqliteDB(source)
42 case "postgres":
43 return OpenPostgresDB(source)
44 default:
45 return nil, fmt.Errorf("unsupported database driver: %q", driver)
46 }
47}
48
[607]49type DatabaseStats struct {
50 Users int64
51 Networks int64
52 Channels int64
53}
54
[77]55type User struct {
[382]56 ID int64
[77]57 Username string
[85]58 Password string // hashed
[568]59 Realname string
[327]60 Admin bool
[77]61}
62
[95]63type SASL struct {
64 Mechanism string
65
66 Plain struct {
67 Username string
68 Password string
69 }
[307]70
71 // TLS client certificate authentication.
72 External struct {
73 // X.509 certificate in DER form.
74 CertBlob []byte
75 // PKCS#8 private key in DER form.
76 PrivKeyBlob []byte
77 }
[95]78}
79
[77]80type Network struct {
[263]81 ID int64
82 Name string
83 Addr string
84 Nick string
85 Username string
86 Realname string
87 Pass string
88 ConnectCommands []string
89 SASL SASL
[542]90 Enabled bool
[77]91}
92
[149]93func (net *Network) GetName() string {
94 if net.Name != "" {
95 return net.Name
96 }
97 return net.Addr
98}
99
[457]100func (net *Network) URL() (*url.URL, error) {
101 s := net.Addr
102 if !strings.Contains(s, "://") {
103 // This is a raw domain name, make it an URL with the default scheme
104 s = "ircs://" + s
105 }
106
107 u, err := url.Parse(s)
108 if err != nil {
109 return nil, fmt.Errorf("failed to parse upstream server URL: %v", err)
110 }
111
112 return u, nil
113}
114
[664]115func GetNick(user *User, net *Network) string {
116 if net.Nick != "" {
117 return net.Nick
118 }
119 return user.Username
120}
121
[674]122func GetUsername(user *User, net *Network) string {
123 if net.Username != "" {
124 return net.Username
125 }
126 return GetNick(user, net)
127}
128
[568]129func GetRealname(user *User, net *Network) string {
[457]130 if net.Realname != "" {
131 return net.Realname
132 }
[568]133 if user.Realname != "" {
134 return user.Realname
135 }
[664]136 return GetNick(user, net)
[457]137}
138
[434]139type MessageFilter int
140
141const (
142 // TODO: use customizable user defaults for FilterDefault
143 FilterDefault MessageFilter = iota
144 FilterNone
145 FilterHighlight
146 FilterMessage
147)
148
149func parseFilter(filter string) (MessageFilter, error) {
150 switch filter {
151 case "default":
152 return FilterDefault, nil
153 case "none":
154 return FilterNone, nil
155 case "highlight":
156 return FilterHighlight, nil
157 case "message":
158 return FilterMessage, nil
159 }
160 return 0, fmt.Errorf("unknown filter: %q", filter)
161}
162
[77]163type Channel struct {
[497]164 ID int64
165 Name string
166 Key string
[434]167
[497]168 Detached bool
169 DetachedInternalMsgID string
170
[434]171 RelayDetached MessageFilter
172 ReattachOn MessageFilter
173 DetachAfter time.Duration
174 DetachOn MessageFilter
[77]175}
176
[489]177type DeliveryReceipt struct {
178 ID int64
179 Target string // channel or nick
180 Client string
181 InternalMsgID string
182}
Note: See TracBrowser for help on using the repository browser.