1package sqlite23import (4 "context"5 "database/sql"67 "git.lin.moe/go/mlisting/storage"8 _ "github.com/mattn/go-sqlite3"9)1011type Storage struct {12 *sql.DB13}1415func NewStorage(dsn string) (*Storage, error) {16 db, err := sql.Open("sqlite3", dsn)17 if err != nil {18 return nil, err19 }20 ctx, cancel := context.WithCancel(context.TODO())21 defer cancel()2223 if err := migrate(ctx, db); err != nil {24 return nil, err25 }2627 return &Storage{28 DB: db,29 }, nil30}3132func (s *Storage) GetList(ctx context.Context, address string) (storage.List, error) {33 const _sql = `select address, name, create_at, description, default_perm34 from list where address=?`35 list := new(List)36 list.db = s.DB3738 row := s.DB.QueryRowContext(ctx, _sql, address)39 if err := row.Scan(40 &list.address,41 &list.name,42 &list.create_at,43 &list.description,44 &list.default_perm); err != nil {45 return nil, err46 }47 return list, nil48}49func (s *Storage) Lists(ctx context.Context) ([]storage.List, error) {50 const _sql = `SELECT address, name, create_at, description, default_perm FROM list`51 rows, err := s.DB.QueryContext(ctx, _sql)52 if err != nil {53 return nil, err54 }55 defer rows.Close()5657 lists := []storage.List{}58 for rows.Next() {59 list := new(List)60 list.db = s.DB61 if err := rows.Scan(62 &list.address,63 &list.name,64 &list.create_at,65 &list.description,66 &list.default_perm); err != nil {67 return nil, err68 }69 lists = append(lists, list)70 }71 return lists, nil72}7374func (s *Storage) NewList(ctx context.Context, name, address, description string, perm uint8) (storage.List, error) {75 const _sql = `insert into76 list (name, address, description, default_perm)77 values (?, ?, ?, ?)78 returning name, address, create_at, description, default_perm`79 list := new(List)80 list.db = s.DB8182 row := s.DB.QueryRowContext(ctx, _sql, name, address, description, perm)8384 if err := row.Scan(85 &list.name,86 &list.address,87 &list.create_at,88 &list.description,89 &list.default_perm); err != nil {90 return nil, err91 }92 return list, nil93}9495func (s *Storage) UpdateList(ctx context.Context, address string, name, description string, defaultPerm uint8) (storage.List, error) {96 var i int97 if err := s.DB.QueryRowContext(ctx, "SELECT 1 from list where address=?", address).Scan(&i); err != nil {98 return nil, err99 }100 const _sql = "UPDATE list SET name=?, description=?, default_perm=? WHERE address=? RETURNING address, name, create_at, description, default_perm"101 var list = new(List)102 row := s.DB.QueryRowContext(ctx, _sql, name, description, defaultPerm, address)103 if err := row.Scan(&list.address, &list.name, &list.create_at, &list.description, &list.default_perm); err != nil {104 return nil, err105 }106 list.db = s.DB107 return list, nil108}109110func (s *Storage) DeleteList(ctx context.Context, address string) error {111 var err error112113 tx, err := s.DB.BeginTx(ctx, nil)114 if err != nil {115 return err116 }117118 _, err = tx.ExecContext(ctx, `DELETE FROM member WHERE list=?`, address)119 if err != nil {120 tx.Rollback()121 return err122 }123124 _, err = tx.ExecContext(ctx, `DELETE FROM list WHERE address=?`, address)125 if err != nil {126 tx.Rollback()127 return err128 }129 return tx.Commit()130}131132func (s *Storage) Shutdown(context.Context) error {133 return s.DB.Close()134}