blob: afe6bc85130953a5125315bb9ed7efa0193e4881 [file] [log] [blame]
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
}