/
schema_adapter_postgresql.go
80 lines (65 loc) · 2.23 KB
/
schema_adapter_postgresql.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
package sql
import (
"database/sql"
"fmt"
"strings"
"github.com/ThreeDotsLabs/watermill/message"
)
// DefaultPostgreSQLSchema is a default implementation of SchemaAdapter based on PostgreSQL.
type DefaultPostgreSQLSchema struct {
// GenerateMessagesTableName may be used to override how the messages table name is generated.
GenerateMessagesTableName func(topic string) string
}
func (s DefaultPostgreSQLSchema) SchemaInitializingQueries(topic string) []string {
createMessagesTable := strings.Join([]string{
`CREATE TABLE IF NOT EXISTS ` + s.MessagesTable(topic) + ` (`,
`"offset" SERIAL,`,
`"uuid" VARCHAR(36) NOT NULL,`,
`"created_at" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,`,
`"payload" JSON DEFAULT NULL,`,
`"metadata" JSON DEFAULT NULL`,
`);`,
}, "\n")
return []string{createMessagesTable}
}
func (s DefaultPostgreSQLSchema) InsertQuery(topic string, msgs message.Messages) (string, []interface{}, error) {
insertQuery := fmt.Sprintf(
`INSERT INTO %s (uuid, payload, metadata) VALUES %s`,
s.MessagesTable(topic),
defaultInsertMarkers(len(msgs)),
)
args, err := defaultInsertArgs(msgs)
if err != nil {
return "", nil, err
}
return insertQuery, args, nil
}
func defaultInsertMarkers(count int) string {
result := strings.Builder{}
index := 1
for i := 0; i < count; i++ {
result.WriteString(fmt.Sprintf("($%d,$%d,$%d),", index, index+1, index+2))
index += 3
}
return strings.TrimRight(result.String(), ",")
}
func (s DefaultPostgreSQLSchema) SelectQuery(topic string, consumerGroup string, offsetsAdapter OffsetsAdapter) (string, []interface{}) {
nextOffsetQuery, nextOffsetArgs := offsetsAdapter.NextOffsetQuery(topic, consumerGroup)
selectQuery := `
SELECT "offset", uuid, payload, metadata FROM ` + s.MessagesTable(topic) + `
WHERE
"offset" > (` + nextOffsetQuery + `)
ORDER BY
"offset" ASC
LIMIT 1`
return selectQuery, nextOffsetArgs
}
func (s DefaultPostgreSQLSchema) UnmarshalMessage(row *sql.Row) (offset int, msg *message.Message, err error) {
return unmarshalDefaultMessage(row)
}
func (s DefaultPostgreSQLSchema) MessagesTable(topic string) string {
if s.GenerateMessagesTableName != nil {
return s.GenerateMessagesTableName(topic)
}
return fmt.Sprintf(`"watermill_%s"`, topic)
}