2024-08-10 21:55:58 -07:00
|
|
|
package gcsql
|
|
|
|
|
2024-08-10 22:21:05 -07:00
|
|
|
import (
|
|
|
|
"database/sql"
|
|
|
|
"errors"
|
|
|
|
)
|
|
|
|
|
2024-08-11 00:40:45 -07:00
|
|
|
const (
|
|
|
|
AllFilters ShowFilters = iota
|
|
|
|
OnlyActiveFilters
|
|
|
|
OnlyInactiveFilters
|
|
|
|
)
|
|
|
|
|
2024-08-11 00:08:57 -07:00
|
|
|
var (
|
|
|
|
ErrInvalidConditionField = errors.New("unrecognized conditional field")
|
|
|
|
ErrInvalidMatchAction = errors.New("unrecognized filter action")
|
2024-08-11 00:40:45 -07:00
|
|
|
ErrInvalidFilter = errors.New("unrecognized filter id")
|
2024-08-11 00:08:57 -07:00
|
|
|
)
|
|
|
|
|
2024-08-11 00:40:45 -07:00
|
|
|
type ShowFilters int
|
|
|
|
|
2024-08-11 01:00:05 -07:00
|
|
|
// GetFilterByID returns the filter with the given ID, and an error if one occured
|
2024-08-11 00:08:57 -07:00
|
|
|
func GetFilterByID(id int) (*Filter, error) {
|
|
|
|
var filter Filter
|
|
|
|
err := QueryRowTimeoutSQL(nil,
|
|
|
|
`SELECT id, staff_id, staff_note, issued_at, match_action, match_detail, is_active FROM DBPREFIXfilters WHERE id = ?`,
|
|
|
|
[]any{id}, []any{&filter.ID, &filter.StaffID, &filter.StaffNote, &filter.IssuedAt, &filter.MatchAction, &filter.MatchDetail, &filter.IsActive},
|
|
|
|
)
|
2024-08-11 00:40:45 -07:00
|
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
|
|
return nil, ErrInvalidFilter
|
|
|
|
} else if err != nil {
|
2024-08-11 00:08:57 -07:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return &filter, nil
|
|
|
|
}
|
|
|
|
|
2024-08-11 00:40:45 -07:00
|
|
|
// GetAllFilters returns an array of all post filters, and an error if one occured. It can optionally return only the active or
|
|
|
|
// only the inactive filters (or return all)
|
|
|
|
func GetAllFilters(show ShowFilters) ([]Filter, error) {
|
2024-08-11 00:08:57 -07:00
|
|
|
query := `SELECT id, staff_id, staff_note, issued_at, match_action, match_detail, is_active FROM DBPREFIXfilters`
|
2024-08-11 00:40:45 -07:00
|
|
|
if show == OnlyActiveFilters {
|
|
|
|
query += " WHERE is_active = TRUE"
|
|
|
|
} else if show == OnlyInactiveFilters {
|
|
|
|
query += " WHERE is_active = FALSE"
|
|
|
|
}
|
2024-08-11 00:08:57 -07:00
|
|
|
rows, cancel, err := QueryTimeoutSQL(nil, query)
|
|
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
|
|
return nil, nil
|
|
|
|
} else if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer func() {
|
|
|
|
cancel()
|
|
|
|
rows.Close()
|
|
|
|
}()
|
|
|
|
var filters []Filter
|
|
|
|
for rows.Next() {
|
|
|
|
var filter Filter
|
|
|
|
if err = rows.Scan(
|
|
|
|
&filter.ID, &filter.StaffID, &filter.StaffNote, &filter.IssuedAt, &filter.MatchAction, &filter.MatchDetail, &filter.IsActive,
|
|
|
|
); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
filters = append(filters, filter)
|
|
|
|
}
|
|
|
|
return filters, rows.Close()
|
2024-08-10 22:21:05 -07:00
|
|
|
}
|
|
|
|
|
2024-08-11 01:00:05 -07:00
|
|
|
// GetFiltersByBoardDir returns the filters associated with the given board dir, optionally including filters
|
|
|
|
// not associated with a specific board. It can optionally return only the active or only the inactive filters
|
|
|
|
// (or return all)
|
|
|
|
func GetFiltersByBoardDir(dir string, includeAllBoards bool, show ShowFilters) ([]Filter, error) {
|
|
|
|
query := `SELECT DBPREFIXfilters.id, staff_id, staff_note, issued_at, match_action, match_detail, is_active
|
|
|
|
FROM DBPREFIXfilters
|
|
|
|
LEFT JOIN DBPREFIXfilter_boards ON filter_id = DBPREFIXfilters.id
|
|
|
|
LEFT JOIN DBPREFIXboards ON DBPREFIXboards.id = board_id`
|
|
|
|
|
|
|
|
if dir == "" {
|
|
|
|
if show == OnlyActiveFilters {
|
|
|
|
query += " WHERE is_active = TRUE"
|
|
|
|
} else if show == OnlyInactiveFilters {
|
|
|
|
query += " WHERE is_active = FALSE"
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
query += ` WHERE dir = ?`
|
|
|
|
if includeAllBoards {
|
|
|
|
query += " OR board_id IS NULL"
|
|
|
|
}
|
|
|
|
if show == OnlyActiveFilters {
|
|
|
|
query += " AND is_active = TRUE"
|
|
|
|
} else if show == OnlyInactiveFilters {
|
|
|
|
query += " AND is_active = FALSE"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
rows, cancel, err := QueryTimeoutSQL(nil, query, dir)
|
|
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
|
|
return nil, nil
|
|
|
|
} else if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer func() {
|
|
|
|
cancel()
|
|
|
|
rows.Close()
|
|
|
|
}()
|
|
|
|
var filters []Filter
|
|
|
|
for rows.Next() {
|
|
|
|
var filter Filter
|
|
|
|
if err = rows.Scan(
|
|
|
|
&filter.ID, &filter.StaffID, &filter.StaffNote, &filter.IssuedAt, &filter.MatchAction, &filter.MatchDetail, &filter.IsActive,
|
|
|
|
); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
filters = append(filters, filter)
|
|
|
|
}
|
|
|
|
return filters, rows.Close()
|
|
|
|
}
|
|
|
|
|
2024-08-10 21:55:58 -07:00
|
|
|
// GetFiltersByBoardID returns an array of post filters associated to the given board ID, including
|
2024-08-11 01:00:05 -07:00
|
|
|
// filters set to "All boards" if includeAllBoards is true. It can optionally return only the active or
|
|
|
|
// only the inactive filters (or return all)
|
|
|
|
func GetFiltersByBoardID(boardID int, includeAllBoards bool, show ShowFilters) ([]Filter, error) {
|
2024-08-11 00:08:57 -07:00
|
|
|
query := `SELECT DBPREFIXfilters.id, staff_id, staff_note, issued_at, match_action, match_detail, is_active
|
2024-08-10 21:55:58 -07:00
|
|
|
FROM DBPREFIXfilters LEFT JOIN DBPREFIXfilter_boards ON filter_id = DBPREFIXfilters.id
|
|
|
|
WHERE board_id = ?`
|
|
|
|
if includeAllBoards {
|
|
|
|
query += " OR board_id IS NULL"
|
|
|
|
}
|
2024-08-11 01:00:05 -07:00
|
|
|
if show == OnlyActiveFilters {
|
|
|
|
query += " AND is_active = TRUE"
|
|
|
|
} else if show == OnlyInactiveFilters {
|
|
|
|
query += " AND is_active = FALSE"
|
|
|
|
}
|
|
|
|
|
2024-08-10 21:55:58 -07:00
|
|
|
rows, cancel, err := QueryTimeoutSQL(nil, query, boardID)
|
2024-08-11 00:08:57 -07:00
|
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
|
|
return nil, nil
|
|
|
|
} else if err != nil {
|
2024-08-10 21:55:58 -07:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer func() {
|
|
|
|
cancel()
|
|
|
|
rows.Close()
|
|
|
|
}()
|
|
|
|
var filters []Filter
|
|
|
|
for rows.Next() {
|
|
|
|
var filter Filter
|
|
|
|
if err = rows.Scan(
|
2024-08-11 00:08:57 -07:00
|
|
|
&filter.ID, &filter.StaffID, &filter.StaffNote, &filter.IssuedAt, &filter.MatchAction, &filter.MatchDetail, &filter.IsActive,
|
2024-08-10 21:55:58 -07:00
|
|
|
); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2024-08-11 00:08:57 -07:00
|
|
|
filters = append(filters, filter)
|
2024-08-10 21:55:58 -07:00
|
|
|
}
|
|
|
|
return filters, rows.Close()
|
|
|
|
}
|
|
|
|
|
|
|
|
// Conditions returns an array of filter conditions associated with the filter
|
|
|
|
func (f *Filter) Conditions() ([]FilterCondition, error) {
|
|
|
|
if len(f.conditions) > 0 {
|
|
|
|
return f.conditions, nil
|
|
|
|
}
|
2024-08-11 00:08:57 -07:00
|
|
|
rows, cancel, err := QueryTimeoutSQL(nil, `SELECT id, filter_id, is_regex, search, field FROM DBPREFIXfilter_conditions WHERE filter_id = ?`, f.ID)
|
2024-08-10 21:55:58 -07:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer func() {
|
|
|
|
cancel()
|
|
|
|
rows.Close()
|
|
|
|
}()
|
|
|
|
for rows.Next() {
|
|
|
|
var condition FilterCondition
|
|
|
|
if err = rows.Scan(&condition.ID, &condition.FilterID, &condition.IsRegex, &condition.Search, &condition.Field); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
f.conditions = append(f.conditions, condition)
|
|
|
|
}
|
|
|
|
return f.conditions, rows.Close()
|
|
|
|
}
|
|
|
|
|
|
|
|
// BoardDirs returns an array of board directories associated with this filter
|
|
|
|
func (f *Filter) BoardDirs() ([]string, error) {
|
2024-08-10 22:21:05 -07:00
|
|
|
rows, cancel, err := QueryTimeoutSQL(nil, `SELECT dir FROM DBPREFIXfilter_boards
|
|
|
|
LEFT JOIN DBPREFIXboards ON DBPREFIXboards.id = board_id WHERE filter_id = ?`, f.ID)
|
|
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
|
|
cancel()
|
|
|
|
return nil, nil
|
|
|
|
} else if err != nil {
|
2024-08-10 21:55:58 -07:00
|
|
|
cancel()
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer func() {
|
|
|
|
cancel()
|
|
|
|
rows.Close()
|
|
|
|
}()
|
|
|
|
var dirs []string
|
|
|
|
for rows.Next() {
|
|
|
|
var dir *string
|
|
|
|
if err = rows.Scan(&dir); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if dir != nil {
|
|
|
|
dirs = append(dirs, *dir)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return dirs, rows.Close()
|
|
|
|
}
|
2024-08-10 22:21:05 -07:00
|
|
|
|
|
|
|
func (f *Filter) BoardIDs() ([]int, error) {
|
|
|
|
rows, cancel, err := QueryTimeoutSQL(nil, `SELECT board_id FROM DBPREFIXfilter_boards WHERE filter_id = ?`, f.ID)
|
2024-08-11 00:40:45 -07:00
|
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
|
|
return nil, nil
|
|
|
|
} else if err != nil {
|
2024-08-10 22:21:05 -07:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer func() {
|
|
|
|
cancel()
|
|
|
|
rows.Close()
|
|
|
|
}()
|
|
|
|
var ids []int
|
|
|
|
for rows.Next() {
|
|
|
|
var id int
|
|
|
|
if err = rows.Scan(&id); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
ids = append(ids, id)
|
|
|
|
}
|
|
|
|
return ids, nil
|
|
|
|
}
|
2024-08-11 00:40:45 -07:00
|
|
|
|
|
|
|
// SetFilterActive updates the filter with the given id, setting its active status and returning an error if one occured
|
|
|
|
func SetFilterActive(id int, active bool) error {
|
|
|
|
_, err := ExecTimeoutSQL(nil, `UPDATE DBPREFIXfilters SET is_active = ? WHERE id = ?`, active, id)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2024-08-11 01:00:05 -07:00
|
|
|
// DeleteFilter deletes the filter row from the database
|
2024-08-11 00:40:45 -07:00
|
|
|
func DeleteFilter(id int) error {
|
|
|
|
_, err := ExecTimeoutSQL(nil, `DELETE FROM DBPREFIXfilters WHERE id = ?`, id)
|
|
|
|
return err
|
|
|
|
}
|