191 lines
3.0 KiB
Go
191 lines
3.0 KiB
Go
// shared database related code
|
|
package models
|
|
|
|
import (
|
|
"database/sql"
|
|
"time"
|
|
|
|
_ "github.com/mattn/go-sqlite3"
|
|
)
|
|
|
|
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 = ?`)
|
|
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(
|
|
×tamp,
|
|
¬e.Author,
|
|
¬e.Content,
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
note.Created = time.Unix(timestamp, 0)
|
|
s.Notes = append(s.Notes, *note)
|
|
}
|
|
|
|
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,
|
|
×tamp,
|
|
&su.Email,
|
|
&su.How,
|
|
&su.Why,
|
|
&su.Links,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
su.Created = time.Unix(timestamp, 0)
|
|
|
|
/* TODO do i need this? refreshing on render
|
|
if err = su.RefreshNotes(db); err != nil {
|
|
return nil, err
|
|
}
|
|
*/
|
|
|
|
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
|
|
}
|