source: code/trunk/db.go@ 756

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

Add Prometheus instrumentation for the database

File size: 3.7 KB
Line 
1package soju
2
3import (
4 "context"
5 "fmt"
6 "net/url"
7 "strings"
8 "time"
9
10 "github.com/prometheus/client_golang/prometheus"
11)
12
13type Database interface {
14 Close() error
15 Stats(ctx context.Context) (*DatabaseStats, error)
16
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
21
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
28
29 ListDeliveryReceipts(ctx context.Context, networkID int64) ([]DeliveryReceipt, error)
30 StoreClientDeliveryReceipts(ctx context.Context, networkID int64, client string, receipts []DeliveryReceipt) error
31}
32
33type MetricsCollectorDatabase interface {
34 Database
35 MetricsCollector() prometheus.Collector
36}
37
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
49type DatabaseStats struct {
50 Users int64
51 Networks int64
52 Channels int64
53}
54
55type User struct {
56 ID int64
57 Username string
58 Password string // hashed
59 Realname string
60 Admin bool
61}
62
63type SASL struct {
64 Mechanism string
65
66 Plain struct {
67 Username string
68 Password string
69 }
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 }
78}
79
80type Network struct {
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
90 Enabled bool
91}
92
93func (net *Network) GetName() string {
94 if net.Name != "" {
95 return net.Name
96 }
97 return net.Addr
98}
99
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
115func GetNick(user *User, net *Network) string {
116 if net.Nick != "" {
117 return net.Nick
118 }
119 return user.Username
120}
121
122func GetUsername(user *User, net *Network) string {
123 if net.Username != "" {
124 return net.Username
125 }
126 return GetNick(user, net)
127}
128
129func GetRealname(user *User, net *Network) string {
130 if net.Realname != "" {
131 return net.Realname
132 }
133 if user.Realname != "" {
134 return user.Realname
135 }
136 return GetNick(user, net)
137}
138
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
163type Channel struct {
164 ID int64
165 Name string
166 Key string
167
168 Detached bool
169 DetachedInternalMsgID string
170
171 RelayDetached MessageFilter
172 ReattachOn MessageFilter
173 DetachAfter time.Duration
174 DetachOn MessageFilter
175}
176
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.