package storage import ( "database/sql" "status/model" "strconv" "strings" ) type statusQueryBuilder struct { where string limit string offset string } func (p statusQueryBuilder) build() string { query := []string{`SELECT id, author, content, created_at from statuses`} if p.where != "" { query = append(query, `WHERE`, p.where) } query = append(query, `ORDER BY created_at desc`) if p.limit != "" { query = append(query, `LIMIT`, p.limit) } if p.offset != "" { query = append(query, `OFFSET`, p.offset) } return strings.Join(query, " ") } func (s *Storage) populateStatus(rows *sql.Rows) (model.Status, error) { var status model.Status err := rows.Scan(&status.Id, &status.User, &status.Content, &status.CreatedAt) if err != nil { return status, err } return status, nil } func (s *Storage) CreatePost(status model.Status) (int64, error) { var lid int64 err := s.db.QueryRow(`INSERT INTO statuses (author, content) VALUES ($1, $2) RETURNING id`, status.User, status.Content).Scan(&lid) return lid, err } func (s *Storage) StatusById(id int64) (model.Status, error) { var status model.Status err := s.db.QueryRow( `SELECT id, author, content from statuses WHERE id=$1`, id).Scan( &status.Id, &status.User, &status.Content, ) return status, err } func (s *Storage) StatusByUsername(user string, perPage int, page int64) ([]model.Status, bool, error) { rows, err := s.db.Query(statusQueryBuilder{ where: `author = $1`, limit: strconv.Itoa(perPage + 1), offset: `$2`, }.build(), user, page*int64(perPage)) if err != nil { return nil, false, err } var statuses []model.Status for rows.Next() { post, err := s.populateStatus(rows) if err != nil { return statuses, false, err } statuses = append(statuses, post) } if len(statuses) > perPage { return statuses[0:perPage], true, err } return statuses, false, err } func (s *Storage) Statuses(page int64, perPage int) ([]model.Status, bool, error) { rows, err := s.db.Query(statusQueryBuilder{ limit: strconv.Itoa(perPage + 1), offset: `$1`, }.build(), page*int64(perPage)) if err != nil { return nil, false, err } var statuses []model.Status for rows.Next() { post, err := s.populateStatus(rows) if err != nil { return statuses, false, err } statuses = append(statuses, post) } if len(statuses) > perPage { return statuses[0:perPage], true, err } return statuses, false, err } func (s *Storage) UpdateStatus(status model.Status) error { stmt, err := s.db.Prepare(`UPDATE statuses SET content = $1 WHERE id = $2 and author = $3;`) if err != nil { return err } _, err = stmt.Exec(status.Content, status.Id, status.User) return err } func (s *Storage) DeleteStatus(id int64, author string) error { stmt, err := s.db.Prepare(`DELETE from statuses WHERE id = $1 and author = $2;`) if err != nil { return err } _, err = stmt.Exec(id, author) return err }