c74bab3033
Motivation: 当数据库查询无结果时,Go 的 `var slice []Type` 声明会使 JSON 序列化输出 `null`,而非 `[]`。这在 API 响应中造成不一致,也增加了客户端的空值处理负担。改为 `make([]Type, 0)` 后空结果统一输出为 `[]`,提升 API 规范性。 Changes: * 统一 store 层所有 List 方法使用 `make([]Type, 0)` 初始化切片,覆盖 Sources、Channels、Templates、Rules、MessageLogs 及 RuleChannels 查询 * 新增完整的 cURL 示例文档,覆盖全部 API 端点(通知、Source、Template、Channel、Rule、消息记录) * 新增 Postman Collection JSON 文件,可直接导入 HTTPie 使用,包含环境变量配置
82 lines
2.5 KiB
Go
82 lines
2.5 KiB
Go
package store
|
|
|
|
import (
|
|
"context"
|
|
"crypto/rand"
|
|
"encoding/hex"
|
|
"fmt"
|
|
|
|
"aiaa-notification-service/internal/model"
|
|
)
|
|
|
|
func generateAPIKey() string {
|
|
b := make([]byte, 32)
|
|
rand.Read(b)
|
|
return "sk-" + hex.EncodeToString(b)
|
|
}
|
|
|
|
func (s *Store) CreateSource(ctx context.Context, src *model.Source) error {
|
|
src.APIKey = generateAPIKey()
|
|
query := `INSERT INTO notification_source (name, api_key, parse_mode, parse_pattern, status) VALUES (?, ?, ?, ?, ?)`
|
|
result, err := s.DB.ExecContext(ctx, query, src.Name, src.APIKey, src.ParseMode, src.ParsePattern, src.Status)
|
|
if err != nil {
|
|
return fmt.Errorf("create source: %w", err)
|
|
}
|
|
id, _ := result.LastInsertId()
|
|
src.ID = int(id)
|
|
return nil
|
|
}
|
|
|
|
func (s *Store) GetSource(ctx context.Context, id int) (*model.Source, error) {
|
|
var src model.Source
|
|
err := s.DB.GetContext(ctx, &src, `SELECT * FROM notification_source WHERE id = ?`, id)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("get source %d: %w", id, err)
|
|
}
|
|
return &src, nil
|
|
}
|
|
|
|
func (s *Store) GetSourceByAPIKey(ctx context.Context, apiKey string) (*model.Source, error) {
|
|
var src model.Source
|
|
err := s.DB.GetContext(ctx, &src, `SELECT * FROM notification_source WHERE api_key = ? AND status = 1`, apiKey)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("get source by api_key: %w", err)
|
|
}
|
|
return &src, nil
|
|
}
|
|
|
|
func (s *Store) GetSourceByName(ctx context.Context, name string) (*model.Source, error) {
|
|
var src model.Source
|
|
err := s.DB.GetContext(ctx, &src, `SELECT * FROM notification_source WHERE name = ?`, name)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("get source by name %s: %w", name, err)
|
|
}
|
|
return &src, nil
|
|
}
|
|
|
|
func (s *Store) ListSources(ctx context.Context) ([]model.Source, error) {
|
|
sources := make([]model.Source, 0)
|
|
err := s.DB.SelectContext(ctx, &sources, `SELECT * FROM notification_source ORDER BY id`)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("list sources: %w", err)
|
|
}
|
|
return sources, nil
|
|
}
|
|
|
|
func (s *Store) UpdateSource(ctx context.Context, id int, src *model.Source) error {
|
|
query := `UPDATE notification_source SET name=?, parse_mode=?, parse_pattern=?, status=? WHERE id=?`
|
|
_, err := s.DB.ExecContext(ctx, query, src.Name, src.ParseMode, src.ParsePattern, src.Status, id)
|
|
if err != nil {
|
|
return fmt.Errorf("update source %d: %w", id, err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *Store) DeleteSource(ctx context.Context, id int) error {
|
|
_, err := s.DB.ExecContext(ctx, `DELETE FROM notification_source WHERE id = ?`, id)
|
|
if err != nil {
|
|
return fmt.Errorf("delete source %d: %w", id, err)
|
|
}
|
|
return nil
|
|
}
|