-
Notifications
You must be signed in to change notification settings - Fork 15
/
postgres.go
128 lines (106 loc) · 3.15 KB
/
postgres.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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package postgres
import (
"database/sql"
"fmt"
sqlds "github.com/ipfs/go-ds-sql"
_ "github.com/lib/pq" //postgres driver
)
// Options are the postgres datastore options, reexported here for convenience.
type Options struct {
Host string
Port string
User string
Password string
Database string
Table string
}
// Queries are the postgres queries for a given table.
type Queries struct {
deleteQuery string
existsQuery string
getQuery string
putQuery string
queryQuery string
prefixQuery string
limitQuery string
offsetQuery string
getSizeQuery string
}
// NewQueries creates a new PostgreSQL set of queries for the passed table
func NewQueries(tbl string) Queries {
return Queries{
deleteQuery: fmt.Sprintf("DELETE FROM %s WHERE key = $1", tbl),
existsQuery: fmt.Sprintf("SELECT exists(SELECT 1 FROM %s WHERE key=$1)", tbl),
getQuery: fmt.Sprintf("SELECT data FROM %s WHERE key = $1", tbl),
putQuery: fmt.Sprintf("INSERT INTO %s (key, data) VALUES ($1, $2) ON CONFLICT (key) DO UPDATE SET data = $2", tbl),
queryQuery: fmt.Sprintf("SELECT key, data FROM %s", tbl),
prefixQuery: ` WHERE key LIKE '%s%%' ORDER BY key`,
limitQuery: ` LIMIT %d`,
offsetQuery: ` OFFSET %d`,
getSizeQuery: fmt.Sprintf("SELECT octet_length(data) FROM %s WHERE key = $1", tbl),
}
}
// Delete returns the postgres query for deleting a row.
func (q Queries) Delete() string {
return q.deleteQuery
}
// Exists returns the postgres query for determining if a row exists.
func (q Queries) Exists() string {
return q.existsQuery
}
// Get returns the postgres query for getting a row.
func (q Queries) Get() string {
return q.getQuery
}
// Put returns the postgres query for putting a row.
func (q Queries) Put() string {
return q.putQuery
}
// Query returns the postgres query for getting multiple rows.
func (q Queries) Query() string {
return q.queryQuery
}
// Prefix returns the postgres query fragment for getting a rows with a key prefix.
func (q Queries) Prefix() string {
return q.prefixQuery
}
// Limit returns the postgres query fragment for limiting results.
func (q Queries) Limit() string {
return q.limitQuery
}
// Offset returns the postgres query fragment for returning rows from a given offset.
func (q Queries) Offset() string {
return q.offsetQuery
}
// GetSize returns the postgres query for determining the size of a value.
func (q Queries) GetSize() string {
return q.getSizeQuery
}
// Create returns a datastore connected to postgres
func (opts *Options) Create() (*sqlds.Datastore, error) {
opts.setDefaults()
fmtstr := "postgresql:///%s?host=%s&port=%s&user=%s&password=%s&sslmode=disable"
constr := fmt.Sprintf(fmtstr, opts.Database, opts.Host, opts.Port, opts.User, opts.Password)
db, err := sql.Open("postgres", constr)
if err != nil {
return nil, err
}
return sqlds.NewDatastore(db, NewQueries(opts.Table)), nil
}
func (opts *Options) setDefaults() {
if opts.Host == "" {
opts.Host = "127.0.0.1"
}
if opts.Port == "" {
opts.Port = "5432"
}
if opts.User == "" {
opts.User = "postgres"
}
if opts.Database == "" {
opts.Database = "datastore"
}
if opts.Table == "" {
opts.Table = "blocks"
}
}