// 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 }