package henwen import ( "context" "os" "time" "crawshaw.io/sqlite/sqlitex" ) type GenString func() (string, error) type Store struct { pool *sqlitex.Pool genString GenString } const InMemory = ":memory:" func NewStore(filename string, genString GenString) (*Store, error) { var needCreate bool if filename == InMemory { filename = "file::memory:?mode=memory" needCreate = true } else if _, err := os.Stat(filename); os.IsNotExist(err) { needCreate = true } // If the file exists, then assume it was created properly. pool, err := sqlitex.Open(filename, 0, 10) if err != nil { return nil, err } store := &Store{ pool: pool, genString: genString, } if needCreate { err = store.createSchema() if err != nil { defer pool.Close() return nil, err } } return store, nil } func (s *Store) Close() error { return s.pool.Close() } const schema = ` CREATE TABLE event ( id INTEGER PRIMARY KEY, alpha_id TEXT NOT NULL, admin_alpha_id TEXT NOT NULL, name TEXT NOT NULL, earliest_date DATE NOT NULL, latest_date DATE NOT NULL, duration INTEGER NOT NULL, UNIQUE (alpha_id) ); CREATE TABLE response ( id INTEGER PRIMARY KEY, alpha_id TEXT NOT NULL, event_id INTEGER NOT NULL, UNIQUE (alpha_id), FOREIGN KEY (event_id) REFERENCES event(id) ); CREATE TABLE response_time ( response_id INTEGER PRIMARY KEY, time INTEGER NOT NULL, CHECK (0 <= time < 24) );` func (s *Store) createSchema() error { conn := s.pool.Get(context.Background()) defer s.pool.Put(conn) return sqlitex.ExecScript(conn, schema) } type CreateEventCommand struct { Name string EarliestDate, LatestDate time.Time Duration int } type CreateEventResult struct { AlphaID, AdminAlphaID string } func (s *Store) CreateEvent(ctx context.Context, cmd CreateEventCommand) (result CreateEventResult, err error) { conn := s.pool.Get(ctx) defer s.pool.Put(conn) alphaID, err := s.genString() if err != nil { return } adminAlphaID, err := s.genString() if err != nil { return } const dateFmt = "2006-01-02" const query = ` INSERT INTO event(alpha_id, admin_alpha_id, name, earliest_date, latest_date, duration) VALUES (?, ?, ?, ?, ?, ?);` err = sqlitex.Exec(conn, query, nil, alphaID, adminAlphaID, cmd.Name, cmd.EarliestDate.Format(dateFmt), cmd.LatestDate.Format(dateFmt), cmd.Duration, ) if err != nil { return } result.AdminAlphaID = adminAlphaID result.AlphaID = alphaID return }