town/models/models.go

215 lines
3.4 KiB
Go

// shared database related code
package models
import (
"database/sql"
"time"
_ "github.com/mattn/go-sqlite3"
)
// TODO consider splitting this stuff out into packages
type SignupNote struct {
ID int64
Created time.Time
Author string
Content string
SignupID int64
}
func (n *SignupNote) Insert(db *sql.DB) error {
n.Created = time.Now()
stmt, err := db.Prepare(`
INSERT INTO notes (created, author, content, signupid)
VALUES (
?, ?, ?, ?
)`)
if err != nil {
return err
}
result, err := stmt.Exec(
n.Created.Unix(),
n.Author,
n.Content,
n.SignupID)
if err != nil {
return err
}
defer stmt.Close()
liid, err := result.LastInsertId()
if err != nil {
return err
}
n.ID = liid
return nil
}
type SignupDecision string
const (
SignupAccepted SignupDecision = "accepted"
SignupRejected SignupDecision = "rejected"
)
type TownSignup struct {
ID int64
Created time.Time
Email string
How string
Why string
Links string
Notes []SignupNote
Decision SignupDecision
DecisionTime time.Time
DecidedBy string
CleanEmail string
}
func (s *TownSignup) Insert(db *sql.DB) error {
stmt, err := db.Prepare(`
INSERT INTO signups (created, email, how, why, links) VALUES(
?, ?, ?, ?, ?
) RETURNING id
`)
if err != nil {
return err
}
result, err := stmt.Exec(s.Created.Unix(), s.Email, s.How, s.Why, s.Links)
if err != nil {
return err
}
defer stmt.Close()
liid, err := result.LastInsertId()
if err != nil {
return err
}
s.ID = liid
return nil
}
func (s *TownSignup) RefreshNotes(db *sql.DB) error {
stmt, err := db.Prepare(`
SELECT created, author, content
FROM notes
WHERE signupid = ?
ORDER BY created ASC`)
if err != nil {
return err
}
rows, err := stmt.Query(s.ID)
if err != nil {
return err
}
defer stmt.Close()
s.Notes = []SignupNote{}
for rows.Next() {
note := &SignupNote{}
var timestamp int64
err = rows.Scan(
&timestamp,
&note.Author,
&note.Content,
)
if err != nil {
return err
}
note.Created = time.Unix(timestamp, 0)
s.Notes = append(s.Notes, *note)
}
return nil
}
func (s *TownSignup) Review(db *sql.DB) error {
stmt, err := db.Prepare(`
UPDATE signups SET
decision = ?,
decision_time = ?,
decided_by = ?,
clean_email = ?
WHERE id = ?`)
if err != nil {
return err
}
_, err = stmt.Exec(
s.Decision,
s.DecisionTime.Unix(),
s.DecidedBy,
s.CleanEmail,
s.ID)
if err != nil {
return err
}
stmt.Close()
return nil
}
func (s *TownSignup) All(db *sql.DB) ([]*TownSignup, error) {
// TODO notes; circle back once can author them
rows, err := db.Query(`
SELECT
id, created, email, how, why, links
FROM signups WHERE decision IS NULL`)
if err != nil {
return nil, err
}
defer rows.Close()
out := []*TownSignup{}
for rows.Next() {
su := &TownSignup{}
var timestamp int64
if err = rows.Scan(
&su.ID,
&timestamp,
&su.Email,
&su.How,
&su.Why,
&su.Links,
); err != nil {
return nil, err
}
su.Created = time.Unix(timestamp, 0)
out = append(out, su)
}
return out, nil
}
// below is all TODO and unused rn
type UserState string
const (
StateActive = "active"
StateTempBan = "temp_banned"
StateBan = "banned"
)
type TownAccount struct {
ID int64
Emails []string
Username string
Signup int
//Notes []AdminNote
State UserState
Admin bool
}