95 lines
2.7 KiB
Go
95 lines
2.7 KiB
Go
package storage
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
)
|
|
|
|
type AdminDocument struct {
|
|
ID int64 `json:"id"`
|
|
Kind string `json:"kind"`
|
|
Title string `json:"title"`
|
|
Body string `json:"body"`
|
|
FileID *int64 `json:"file_id"`
|
|
File string `json:"file,omitempty"`
|
|
FileMime string `json:"file_mime,omitempty"`
|
|
PreviewID *int64 `json:"preview_id"`
|
|
Preview string `json:"preview,omitempty"`
|
|
IssuedAt *time.Time `json:"issued_at"`
|
|
Sort int `json:"sort"`
|
|
Published bool `json:"published"`
|
|
}
|
|
|
|
func (s *Storage) AdminDocuments(ctx context.Context) ([]AdminDocument, error) {
|
|
rows, err := s.pool.Query(ctx, `
|
|
SELECT d.id, d.kind, d.title, d.body, d.file_id, COALESCE(f.path, ''), COALESCE(f.mime, ''),
|
|
d.preview_id, COALESCE(p.path, ''), d.issued_at, d.sort, d.published
|
|
FROM documents d
|
|
LEFT JOIN media f ON f.id = d.file_id
|
|
LEFT JOIN media p ON p.id = d.preview_id
|
|
ORDER BY d.kind, d.sort, d.id`)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
var out []AdminDocument
|
|
for rows.Next() {
|
|
var d AdminDocument
|
|
if err := rows.Scan(&d.ID, &d.Kind, &d.Title, &d.Body, &d.FileID, &d.File, &d.FileMime,
|
|
&d.PreviewID, &d.Preview, &d.IssuedAt, &d.Sort, &d.Published); err != nil {
|
|
return nil, err
|
|
}
|
|
out = append(out, d)
|
|
}
|
|
return out, rows.Err()
|
|
}
|
|
|
|
type DocumentInput struct {
|
|
Kind string
|
|
Title string
|
|
Body string
|
|
FileID *int64
|
|
PreviewID *int64
|
|
IssuedAt *time.Time
|
|
Sort int
|
|
Published bool
|
|
}
|
|
|
|
func (s *Storage) AdminCreateDocument(ctx context.Context, in DocumentInput) (int64, error) {
|
|
var id int64
|
|
err := s.pool.QueryRow(ctx, `
|
|
INSERT INTO documents (kind, title, body, file_id, preview_id, issued_at, sort, published)
|
|
VALUES ($1,$2,$3,$4,$5,$6,$7,$8)
|
|
RETURNING id`,
|
|
in.Kind, in.Title, in.Body, in.FileID, in.PreviewID, in.IssuedAt, in.Sort, in.Published).Scan(&id)
|
|
return id, wrapConflict(err)
|
|
}
|
|
|
|
func (s *Storage) AdminUpdateDocument(ctx context.Context, id int64, in DocumentInput) error {
|
|
tag, err := s.pool.Exec(ctx, `
|
|
UPDATE documents SET kind=$2, title=$3, body=$4, file_id=$5, preview_id=$6, issued_at=$7,
|
|
sort=$8, published=$9
|
|
WHERE id=$1`,
|
|
id, in.Kind, in.Title, in.Body, in.FileID, in.PreviewID, in.IssuedAt, in.Sort, in.Published)
|
|
if err != nil {
|
|
return wrapConflict(err)
|
|
}
|
|
if tag.RowsAffected() == 0 {
|
|
return ErrNotFound
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// AdminDeleteDocument удаляет запись; файлы остаются в медиатеке.
|
|
func (s *Storage) AdminDeleteDocument(ctx context.Context, id int64) error {
|
|
tag, err := s.pool.Exec(ctx, `DELETE FROM documents WHERE id=$1`, id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if tag.RowsAffected() == 0 {
|
|
return ErrNotFound
|
|
}
|
|
return nil
|
|
}
|