forked from hswaw/hscloud
118 lines
2.3 KiB
Go
118 lines
2.3 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"fmt"
|
|
"time"
|
|
|
|
_ "github.com/lib/pq"
|
|
)
|
|
|
|
// app is the model of the oodviewer app.
|
|
// The data modeled is a K/V map from string ('Term') to list of entries.
|
|
type app struct {
|
|
db *sql.DB
|
|
}
|
|
|
|
// term represents a key in the K/V map of the model.
|
|
type term struct {
|
|
// Name of the term, the 'K' of the K/V map.
|
|
Name string
|
|
// Count of entries (len(V) of the K/V map).
|
|
Entries uint64
|
|
}
|
|
|
|
// entry is an element contained under a term. A list of entries ([]entry) is
|
|
// the 'V' of the K/V map.
|
|
type entry struct {
|
|
Entry string `json:"entry"`
|
|
Added int64 `json:"added"`
|
|
Author string `json:"author"`
|
|
}
|
|
|
|
// newApp returns an instantiated app given a lib/pq postgres connection
|
|
// string.
|
|
func newApp(postgres string) (*app, error) {
|
|
db, err := sql.Open("postgres", flagPostgres)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("Open: %v", err)
|
|
}
|
|
|
|
return &app{
|
|
db: db,
|
|
}, nil
|
|
}
|
|
|
|
// getTerms returns all terms stored in the database.
|
|
func (a *app) getTerms(ctx context.Context) ([]term, error) {
|
|
rows, err := a.db.QueryContext(ctx, `
|
|
SELECT
|
|
_term._name,
|
|
count(_entry._text)
|
|
FROM
|
|
_term
|
|
LEFT JOIN _entry
|
|
ON
|
|
_entry._term_oid = _term._oid
|
|
GROUP BY _term._oid
|
|
ORDER BY _term._name
|
|
`)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var res []term
|
|
for rows.Next() {
|
|
var name string
|
|
var count uint64
|
|
if err := rows.Scan(&name, &count); err != nil {
|
|
return nil, err
|
|
}
|
|
res = append(res, term{
|
|
Name: name,
|
|
Entries: count,
|
|
})
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return res, err
|
|
}
|
|
|
|
// getEntries returns all entries of a given term stored in the database.
|
|
func (a *app) getEntries(ctx context.Context, name string) ([]entry, error) {
|
|
rows, err := a.db.QueryContext(ctx, `
|
|
SELECT
|
|
_entry._text,
|
|
_entry._added_at,
|
|
_entry._added_by
|
|
FROM
|
|
_term
|
|
LEFT JOIN _entry
|
|
ON _entry._term_oid = _term._oid
|
|
WHERE lower(_term._name) = lower($1)
|
|
ORDER BY _entry._added_at
|
|
`, name)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var res []entry
|
|
for rows.Next() {
|
|
var text string
|
|
var added time.Time
|
|
var author string
|
|
if err := rows.Scan(&text, &added, &author); err != nil {
|
|
return nil, err
|
|
}
|
|
res = append(res, entry{
|
|
Entry: text,
|
|
Added: added.Unix(),
|
|
Author: author,
|
|
})
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return res, err
|
|
}
|