You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
270 lines
6.3 KiB
270 lines
6.3 KiB
package dao |
|
|
|
import ( |
|
"context" |
|
"fmt" |
|
"strings" |
|
"time" |
|
|
|
"go-common/app/service/main/antispam/util" |
|
|
|
"go-common/library/database/sql" |
|
"go-common/library/log" |
|
) |
|
|
|
const ( |
|
columnsRegexp = `id, admin_id, area, name, operation, content, state, ctime, mtime` |
|
|
|
selectRegexpCountsSQL = `SELECT COUNT(1) FROM regexps %s` |
|
selectRegexpsByCondSQL = `SELECT ` + columnsRegexp + ` FROM regexps %s` |
|
selectRegexpByIDsSQL = `SELECT ` + columnsRegexp + ` FROM regexps WHERE id IN(%s)` |
|
selectRegexpByContentsSQL = `SELECT ` + columnsRegexp + ` FROM regexps WHERE content IN(%s)` |
|
selectRegexpByAreaAndContentSQL = `SELECT ` + columnsRegexp + ` FROM regexps WHERE area = %s AND content IN(%s)` |
|
|
|
insertRegexpSQL = `INSERT INTO regexps(id, admin_id, area, name, operation, content, state) VALUES(?, ?, ?, ?, ?, ?, ?)` |
|
updateRegexpSQL = `UPDATE regexps SET admin_id = ?, name = ?, content = ?, operation = ?, state = ?, mtime = ? WHERE id = ?` |
|
) |
|
|
|
const ( |
|
// OperationLimit . |
|
OperationLimit int = iota |
|
// OperationPutToWhiteList . |
|
OperationPutToWhiteList |
|
// OperationRestrictLimit . |
|
OperationRestrictLimit |
|
// OperationIgnore . |
|
OperationIgnore |
|
) |
|
|
|
// RegexpDaoImpl . |
|
type RegexpDaoImpl struct{} |
|
|
|
// Regexp . |
|
type Regexp struct { |
|
ID int64 `db:"id"` |
|
Area int `db:"area"` |
|
Name string `db:"name"` |
|
AdminID int64 `db:"admin_id"` |
|
Operation int `db:"operation"` |
|
Content string `db:"content"` |
|
State int `db:"state"` |
|
CTime time.Time `db:"ctime"` |
|
MTime time.Time `db:"mtime"` |
|
} |
|
|
|
// NewRegexpDao . |
|
func NewRegexpDao() *RegexpDaoImpl { |
|
return &RegexpDaoImpl{} |
|
} |
|
|
|
// GetByCond . |
|
func (*RegexpDaoImpl) GetByCond(ctx context.Context, |
|
cond *Condition) (regexps []*Regexp, totalCounts int64, err error) { |
|
sqlConds := make([]string, 0) |
|
if cond.Area != "" { |
|
sqlConds = append(sqlConds, fmt.Sprintf("area = %s", cond.Area)) |
|
} |
|
if cond.State != "" { |
|
sqlConds = append(sqlConds, fmt.Sprintf("state = %s", cond.State)) |
|
} |
|
var optionSQL string |
|
if len(sqlConds) > 0 { |
|
optionSQL = fmt.Sprintf("WHERE %s", strings.Join(sqlConds, " AND ")) |
|
} |
|
|
|
var limitSQL string |
|
if cond.Pagination != nil { |
|
queryCountsSQL := fmt.Sprintf(selectRegexpCountsSQL, optionSQL) |
|
totalCounts, err = GetTotalCounts(ctx, db, queryCountsSQL) |
|
if err != nil { |
|
return nil, 0, err |
|
} |
|
offset, limit := cond.OffsetLimit(totalCounts) |
|
if limit == 0 { |
|
return nil, 0, ErrResourceNotExist |
|
} |
|
limitSQL = fmt.Sprintf("LIMIT %d, %d", offset, limit) |
|
} |
|
if cond.OrderBy != "" { |
|
optionSQL = fmt.Sprintf("%s ORDER BY %s %s", optionSQL, cond.OrderBy, cond.Order) |
|
} |
|
if limitSQL != "" { |
|
optionSQL = fmt.Sprintf("%s %s", optionSQL, limitSQL) |
|
} |
|
querySQL := fmt.Sprintf(selectRegexpsByCondSQL, optionSQL) |
|
log.Info("OptionSQL(%s), GetByCondSQL(%s)", optionSQL, querySQL) |
|
regexps, err = queryRegexps(ctx, db, querySQL) |
|
if err != nil { |
|
return nil, totalCounts, err |
|
} |
|
return regexps, totalCounts, nil |
|
} |
|
|
|
// Update . |
|
func (rdi *RegexpDaoImpl) Update(ctx context.Context, r *Regexp) (*Regexp, error) { |
|
err := updateRegexp(ctx, db, r) |
|
if err != nil { |
|
return nil, err |
|
} |
|
return rdi.GetByID(ctx, r.ID) |
|
} |
|
|
|
// Insert . |
|
func (rdi *RegexpDaoImpl) Insert(ctx context.Context, r *Regexp) (*Regexp, error) { |
|
err := insertRegexp(ctx, db, r) |
|
if err != nil { |
|
return nil, err |
|
} |
|
return rdi.GetByID(ctx, r.ID) |
|
} |
|
|
|
// GetByID . |
|
func (rdi *RegexpDaoImpl) GetByID(ctx context.Context, id int64) (*Regexp, error) { |
|
rs, err := rdi.GetByIDs(ctx, []int64{id}) |
|
if err != nil { |
|
return nil, err |
|
} |
|
if rs[0] == nil { |
|
return nil, ErrResourceNotExist |
|
} |
|
return rs[0], nil |
|
} |
|
|
|
// GetByIDs . |
|
func (*RegexpDaoImpl) GetByIDs(ctx context.Context, ids []int64) ([]*Regexp, error) { |
|
rs, err := queryRegexps(ctx, db, fmt.Sprintf(selectRegexpByIDsSQL, util.IntSliToSQLVarchars(ids))) |
|
if err != nil { |
|
return nil, err |
|
} |
|
res := make([]*Regexp, len(ids)) |
|
for i, id := range ids { |
|
for _, r := range rs { |
|
if r.ID == id { |
|
res[i] = r |
|
} |
|
} |
|
} |
|
return res, nil |
|
} |
|
|
|
// GetByContents . |
|
func (*RegexpDaoImpl) GetByContents(ctx context.Context, contents []string) ([]*Regexp, error) { |
|
if len(contents) == 0 { |
|
log.Error("%v", ErrParams) |
|
return nil, ErrParams |
|
} |
|
rs, err := queryRegexps(ctx, db, fmt.Sprintf(selectRegexpByContentsSQL, util.StrSliToSQLVarchars(contents))) |
|
if err != nil { |
|
return nil, err |
|
} |
|
res := make([]*Regexp, len(contents)) |
|
for i, c := range contents { |
|
for _, r := range rs { |
|
if strings.EqualFold(r.Content, c) { |
|
res[i] = r |
|
} |
|
} |
|
} |
|
return res, nil |
|
} |
|
|
|
// GetByAreaAndContent . |
|
func (*RegexpDaoImpl) GetByAreaAndContent(ctx context.Context, cond *Condition) (*Regexp, error) { |
|
rs, err := queryRegexps(ctx, db, fmt.Sprintf(selectRegexpByAreaAndContentSQL, |
|
cond.Area, util.StrSliToSQLVarchars(cond.Contents))) |
|
if err != nil { |
|
return nil, err |
|
} |
|
return rs[0], nil |
|
} |
|
|
|
func insertRegexp(ctx context.Context, executer Executer, r *Regexp) error { |
|
res, err := executer.Exec(ctx, insertRegexpSQL, |
|
r.ID, |
|
r.AdminID, |
|
r.Area, |
|
r.Name, |
|
r.Operation, |
|
r.Content, |
|
r.State, |
|
) |
|
if err != nil { |
|
log.Error("%v", err) |
|
return err |
|
} |
|
lastID, err := res.LastInsertId() |
|
if err != nil { |
|
log.Error("%v", err) |
|
return err |
|
} |
|
r.ID = lastID |
|
return nil |
|
} |
|
|
|
func updateRegexp(ctx context.Context, executer Executer, r *Regexp) error { |
|
_, err := executer.Exec(ctx, updateRegexpSQL, |
|
r.AdminID, |
|
r.Name, |
|
r.Content, |
|
r.Operation, |
|
r.State, |
|
time.Now(), |
|
|
|
r.ID, |
|
) |
|
if err != nil { |
|
log.Error("%v", err) |
|
return err |
|
} |
|
return nil |
|
} |
|
|
|
func queryRegexps(ctx context.Context, q Querier, rawSQL string) ([]*Regexp, error) { |
|
rows, err := q.Query(ctx, rawSQL) |
|
if err == sql.ErrNoRows { |
|
err = ErrResourceNotExist |
|
} |
|
if err != nil { |
|
log.Error("Error: %v, sql: %s", err, rawSQL) |
|
return nil, err |
|
} |
|
defer rows.Close() |
|
|
|
rs, err := mapRowToRegexps(rows) |
|
if err != nil { |
|
return nil, err |
|
} |
|
if len(rs) == 0 { |
|
log.Error("Error: %v, sql: %s", ErrResourceNotExist, rawSQL) |
|
return nil, ErrResourceNotExist |
|
} |
|
return rs, nil |
|
} |
|
|
|
func mapRowToRegexps(rows *sql.Rows) (rs []*Regexp, err error) { |
|
rs = make([]*Regexp, 0) |
|
for rows.Next() { |
|
r := Regexp{} |
|
err = rows.Scan( |
|
&r.ID, |
|
&r.AdminID, |
|
&r.Area, |
|
&r.Name, |
|
&r.Operation, |
|
&r.Content, |
|
&r.State, |
|
&r.CTime, |
|
&r.MTime, |
|
) |
|
if err != nil { |
|
log.Error("%v", err) |
|
return nil, err |
|
} |
|
rs = append(rs, &r) |
|
} |
|
if err = rows.Err(); err != nil { |
|
log.Error("%v", err) |
|
return nil, err |
|
} |
|
return rs, nil |
|
}
|
|
|