Skip to content

Commit f39f917

Browse files
committed
Add postgres repo
1 parent a0f8247 commit f39f917

File tree

3 files changed

+178
-2
lines changed

3 files changed

+178
-2
lines changed

configs/postgres.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
port: 8787
2+
federates: []
3+
fqdn: localhost:8000
4+
admin_board: bf71bb0d73bc3b0edfd0bd750f9e191c476773b3660d9ba86d658b49083e0623
5+
sql_driver: postgres
6+
sql_connection_string: "user=springboard_test password=springboard_test dbname=springboard_test host=keyboard.local"

pkg/springboard/postgres_repo.go

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
package springboard
2+
3+
import (
4+
"database/sql"
5+
"log"
6+
"time"
7+
8+
_ "github.com/lib/pq"
9+
"github.com/pkg/errors"
10+
)
11+
12+
type PostgresRepo struct {
13+
db *sql.DB
14+
}
15+
16+
// BoardCount implements BoardRepo
17+
func (repo *PostgresRepo) BoardCount() (int, error) {
18+
query := `
19+
SELECT count(*)
20+
FROM boards
21+
`
22+
row := repo.db.QueryRow(query)
23+
24+
var count int
25+
err := row.Scan(&count)
26+
if err != nil {
27+
if err == sql.ErrNoRows {
28+
return 0, nil
29+
} else {
30+
return 0, err
31+
}
32+
}
33+
34+
return count, nil
35+
}
36+
37+
// DeleteBoardsBefore implements BoardRepo
38+
func (repo *PostgresRepo) DeleteBoardsBefore(expiry string) error {
39+
query := `
40+
SELECT COUNT(*)
41+
FROM boards
42+
WHERE modified < $1
43+
`
44+
row := repo.db.QueryRow(query, expiry)
45+
var count string
46+
err := row.Scan(&count)
47+
if err != nil {
48+
return errors.Wrap(err, "Error determining how many boards to delete")
49+
}
50+
log.Printf(" %s boards to delete", count)
51+
query = `
52+
DELETE FROM boards
53+
WHERE modified < $1
54+
`
55+
_, err = repo.db.Exec(query, expiry)
56+
if err != nil {
57+
return errors.Wrap(err, "Error running deletion query")
58+
}
59+
return nil
60+
}
61+
62+
// GetAllBoards implements BoardRepo
63+
func (repo *PostgresRepo) GetAllBoards() ([]Board, error) {
64+
query := `
65+
SELECT key, board, modified
66+
FROM boards
67+
ORDER BY modified DESC
68+
`
69+
rows, err := repo.db.Query(query)
70+
if err != nil {
71+
return nil, err
72+
}
73+
74+
boards := []Board{}
75+
for rows.Next() {
76+
var key, board, modified string
77+
78+
err = rows.Scan(&key, &board, &modified)
79+
if err != nil {
80+
return nil, err
81+
}
82+
83+
modifiedTime, err := time.Parse(time.RFC3339, modified)
84+
if err != nil {
85+
return nil, err
86+
}
87+
88+
boards = append(boards, Board{
89+
Key: key,
90+
Board: board,
91+
Modified: modifiedTime,
92+
})
93+
}
94+
95+
return boards, nil
96+
}
97+
98+
// GetBoard implements BoardRepo
99+
func (repo *PostgresRepo) GetBoard(key string) (*Board, error) {
100+
query := `
101+
SELECT key, board, modified, signature
102+
FROM boards
103+
WHERE key = $1
104+
`
105+
row := repo.db.QueryRow(query, key)
106+
107+
var dbkey, board, modified, signature string
108+
err := row.Scan(&dbkey, &board, &modified, &signature)
109+
if err != nil {
110+
if err != sql.ErrNoRows {
111+
return nil, err
112+
}
113+
return nil, nil
114+
}
115+
116+
modifiedTime, err := time.Parse(time.RFC3339, modified)
117+
if err != nil {
118+
return nil, err
119+
}
120+
121+
return &Board{
122+
Key: key,
123+
Board: board,
124+
Modified: modifiedTime,
125+
Signature: signature,
126+
}, nil
127+
}
128+
129+
// PublishBoard implements BoardRepo
130+
func (repo *PostgresRepo) PublishBoard(newBoard Board) error {
131+
_, err := repo.db.Exec(`
132+
INSERT INTO boards (key, board, modified, signature)
133+
values($1, $2, $3, $4)
134+
ON CONFLICT(key) DO UPDATE SET
135+
board=$2,
136+
modified=$3,
137+
signature=$4
138+
`, newBoard.Key, newBoard.Board, newBoard.ModifiedAtDBFormat(), newBoard.Signature)
139+
if err != nil {
140+
return errors.Wrap(err, "Could not save board")
141+
} else {
142+
return nil
143+
}
144+
}
145+
146+
func newPostgresRepo(dbName string) *PostgresRepo {
147+
// if the db doesn't exist, create it
148+
repo := PostgresRepo{}
149+
db, err := sql.Open("postgres", dbName)
150+
if err != nil {
151+
panic(err)
152+
}
153+
154+
initSQL := `
155+
CREATE TABLE IF NOT EXISTS boards (
156+
key VARCHAR(64) NOT NULL PRIMARY KEY,
157+
board VARCHAR(2217),
158+
modified TIMESTAMP,
159+
signature VARCHAR(128)
160+
);
161+
CREATE INDEX IF NOT EXISTS boards_modified ON boards(modified);
162+
`
163+
164+
_, err = db.Exec(initSQL)
165+
if err != nil {
166+
log.Fatalf("%q: %s\n", err, initSQL)
167+
}
168+
repo.db = db
169+
return &repo
170+
}

pkg/springboard/server.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ import (
1818
"text/template"
1919
"time"
2020

21-
_ "github.com/glebarez/go-sqlite"
22-
_ "github.com/lib/pq"
2321
)
2422

2523
const max_sig = (1 << 256) - 1
@@ -49,6 +47,8 @@ type BoardRepo interface {
4947
func initDB(driver, connectionString string) BoardRepo {
5048
if driver == "sqlite" {
5149
return newSqliteRepo(connectionString)
50+
} else if driver == "postgres" {
51+
return newPostgresRepo(connectionString)
5252
} else {
5353
panic("Unsupported driver " + driver)
5454
}

0 commit comments

Comments
 (0)