town/models/models.go

191 lines
3.0 KiB
Go
Raw Normal View History

2023-02-23 00:04:26 +00:00
// shared database related code
package models
import (
"database/sql"
"time"
_ "github.com/mattn/go-sqlite3"
)
2023-02-23 00:14:38 +00:00
type SignupNote struct {
2023-02-23 06:20:00 +00:00
ID int64
Created time.Time
Author string
Content string
SignupID int64
2023-02-23 00:14:38 +00:00
}
func (n *SignupNote) Insert(db *sql.DB) error {
2023-02-23 06:20:00 +00:00
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
2023-02-23 00:14:38 +00:00
return nil
2023-02-23 00:04:26 +00:00
}
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
2023-02-23 00:14:38 +00:00
Notes []SignupNote
2023-02-23 00:04:26 +00:00
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
}
2023-02-23 07:19:30 +00:00
func (s *TownSignup) RefreshNotes(db *sql.DB) error {
stmt, err := db.Prepare(`
SELECT created, author, content
FROM notes
WHERE signupid = ?`)
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
}
2023-02-23 00:04:26 +00:00
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
2023-02-23 06:20:00 +00:00
FROM signups WHERE decision IS NULL`)
2023-02-23 00:04:26 +00:00
if err != nil {
return nil, err
}
defer rows.Close()
out := []*TownSignup{}
for rows.Next() {
su := &TownSignup{}
2023-02-23 06:20:00 +00:00
var timestamp int64
2023-02-23 00:04:26 +00:00
if err = rows.Scan(
&su.ID,
2023-02-23 06:20:00 +00:00
&timestamp,
2023-02-23 00:04:26 +00:00
&su.Email,
&su.How,
&su.Why,
&su.Links,
); err != nil {
return nil, err
}
2023-02-23 06:20:00 +00:00
su.Created = time.Unix(timestamp, 0)
2023-02-23 07:19:30 +00:00
/* TODO do i need this? refreshing on render
if err = su.RefreshNotes(db); err != nil {
return nil, err
}
*/
2023-02-23 00:04:26 +00:00
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
2023-02-23 06:20:00 +00:00
//Notes []AdminNote
State UserState
Admin bool
2023-02-23 00:04:26 +00:00
}