2021-06-28 00:42:39 +08:00
package models
import (
"strings"
"github.com/didi/nightingale/v5/pkg/istr"
"github.com/toolkits/pkg/logger"
"github.com/toolkits/pkg/str"
)
type Resource struct {
Id int64 ` json:"id" `
Ident string ` json:"ident" `
Alias string ` json:"alias" `
Tags string ` json:"tags" `
Note string ` json:"note" `
MuteBtime int64 ` json:"mute_btime" `
MuteEtime int64 ` json:"mute_etime" `
ClasspathIds [ ] int64 ` xorm:"-" json:"classpath_ids" `
}
func ( r * Resource ) Del ( ) error {
session := DB . NewSession ( )
defer session . Close ( )
if err := session . Begin ( ) ; err != nil {
return err
}
if _ , err := session . Exec ( "DELETE FROM classpath_resource WHERE res_ident=?" , r . Ident ) ; err != nil {
return err
}
if _ , err := session . Exec ( "DELETE FROM resource WHERE id=?" , r . Id ) ; err != nil {
return err
}
return session . Commit ( )
}
func ResourceTotalByClasspathId ( classpathIds [ ] int64 , query string ) ( int64 , error ) {
if len ( classpathIds ) == 0 {
return 0 , nil
}
q := "%" + query + "%"
2021-07-20 14:40:50 +08:00
num , err := DB . Where ( "ident in (select res_ident from classpath_resource where classpath_id in (" + str . IdsString ( classpathIds ) + ")) and (ident like ? or alias like ? or tags like ? or note like ?)" , q , q , q , q ) . Count ( new ( Resource ) )
2021-06-28 00:42:39 +08:00
if err != nil {
logger . Errorf ( "mysql.error count resource in classpath(id=%v) query=%s fail: %v" , classpathIds , query , err )
return 0 , internalServerError
}
return num , nil
}
func ResourceGetsByClasspathId ( classpathIds [ ] int64 , query string , limit , offset int ) ( [ ] Resource , error ) {
if len ( classpathIds ) == 0 {
return [ ] Resource { } , nil
}
q := "%" + query + "%"
var objs [ ] Resource
2021-07-20 14:40:50 +08:00
err := DB . Where ( "ident in (select res_ident from classpath_resource where classpath_id in (" + str . IdsString ( classpathIds ) + ")) and (ident like ? or alias like ? or tags like ? or note like ?)" , q , q , q , q ) . OrderBy ( "ident" ) . Limit ( limit , offset ) . Find ( & objs )
2021-06-28 00:42:39 +08:00
if err != nil {
logger . Errorf ( "mysql.error query resource in classpath(id=%d) query=%s fail: %v" , classpathIds , query , err )
return nil , internalServerError
}
if len ( objs ) == 0 {
return [ ] Resource { } , nil
}
return objs , nil
}
// 这个sql写法很简单, 只是不知道性能是否会是问题
func ResourceTotalByClasspathQuery ( qpaths [ ] int64 , qres string ) ( int64 , error ) {
if len ( qpaths ) == 0 {
return ResourceTotal ( qres )
}
num , err := DB . Where ( "ident in (select res_ident from classpath_resource where classpath_id in (" + str . IdsString ( qpaths ) + ")) and (ident like ? or alias like ?)" , "%" + qres + "%" , "%" + qres + "%" ) . Count ( new ( Resource ) )
if err != nil {
logger . Errorf ( "mysql.error ResourceTotalByClasspathQuery fail: %v" , err )
return 0 , internalServerError
}
return num , nil
}
func ResourceGetsByClasspathQuery ( qpaths [ ] int64 , qres string , limit , offset int ) ( [ ] Resource , error ) {
if len ( qpaths ) == 0 {
return ResourceGets ( qres , limit , offset )
}
var objs [ ] Resource
err := DB . Where ( "ident in (select res_ident from classpath_resource where classpath_id in (" + str . IdsString ( qpaths ) + ")) and (ident like ? or alias like ?)" , "%" + qres + "%" , "%" + qres + "%" ) . OrderBy ( "ident" ) . Limit ( limit , offset ) . Find ( & objs )
if err != nil {
logger . Errorf ( "mysql.error ResourceGetsByClasspathQuery fail: %v" , err )
return nil , internalServerError
}
if len ( objs ) == 0 {
return [ ] Resource { } , nil
}
return objs , nil
}
// ResourceTotal query resource only
func ResourceTotal ( query string ) ( int64 , error ) {
num , err := DB . Where ( "ident like ? or alias like ?" , "%" + query + "%" , "%" + query + "%" ) . Count ( new ( Resource ) )
if err != nil {
logger . Errorf ( "mysql.error query(%s) resource fail: %v" , query , err )
return 0 , internalServerError
}
return num , nil
}
// ResourceGets query resource only
func ResourceGets ( query string , limit , offset int ) ( [ ] Resource , error ) {
var objs [ ] Resource
err := DB . Where ( "ident like ? or alias like ?" , "%" + query + "%" , "%" + query + "%" ) . OrderBy ( "ident" ) . Limit ( limit , offset ) . Find ( & objs )
if err != nil {
logger . Errorf ( "mysql.error query resource fail: %v" , err )
return nil , internalServerError
}
if len ( objs ) == 0 {
return [ ] Resource { } , nil
}
return objs , nil
}
func ResourceGetAll ( ) ( [ ] Resource , error ) {
var objs [ ] Resource
err := DB . Find ( & objs )
if err != nil {
logger . Errorf ( "mysql.error query resource fail: %v" , err )
return nil , internalServerError
}
if len ( objs ) == 0 {
return [ ] Resource { } , nil
}
return objs , nil
}
func ResourceCleanExpire ( ) error {
_ , err := DB . Exec ( "UPDATE resource SET mute_btime = 0, mute_etime = 0 WHERE mute_etime < unix_timestamp(now())" )
if err != nil {
logger . Errorf ( "mysql.error: ResourceCleanExpire fail: %v" , err )
}
return err
}
// ResourceAliasMapper 返回map, key是ident, value是alias
func ResourceAliasMapper ( ) ( map [ string ] string , error ) {
var objs [ ] Resource
err := DB . Cols ( "ident" , "alias" ) . Find ( & objs )
if err != nil {
logger . Errorf ( "mysql.error: ResourceAliasMapper fail: %v" , err )
return nil , err
}
count := len ( objs )
if count == 0 {
return map [ string ] string { } , nil
}
mapper := make ( map [ string ] string , count )
for i := 0 ; i < count ; i ++ {
mapper [ objs [ i ] . Ident ] = objs [ i ] . Alias
}
return mapper , nil
}
func ResourceGet ( where string , args ... interface { } ) ( * Resource , error ) {
var obj Resource
has , err := DB . Where ( where , args ... ) . Get ( & obj )
if err != nil {
logger . Errorf ( "mysql.error: get resource(%s)%+v fail: %s" , where , args , err )
return nil , internalServerError
}
if ! has {
return nil , nil
}
return & obj , nil
}
func ResourceUpdateNote ( ids [ ] int64 , note string ) error {
_ , err := DB . Exec ( "UPDATE resource SET note=? WHERE id in (" + str . IdsString ( ids ) + ")" , note )
if err != nil {
logger . Errorf ( "mysql.error: update resource note fail: %s" , err )
return internalServerError
}
return nil
}
// 资源tags这个更新, 一定要认真校验tags格式, 后面会把这个tags附到监控数据里
func ResourceUpdateTags ( ids [ ] int64 , tags string ) error {
tags = strings . TrimSpace ( tags )
if tags != "" {
// 不为空才值得去校验,空的字符串,没啥好校验的
arr := strings . Fields ( tags )
cnt := len ( arr )
for i := 0 ; i < cnt ; i ++ {
tagarr := strings . Split ( arr [ i ] , "=" )
if len ( tagarr ) != 2 {
return _e ( "Tags(%s) invalid" , arr [ i ] )
}
if istr . SampleKeyInvalid ( tagarr [ 0 ] ) {
return _e ( "Tags(%s) invalid" , arr [ i ] )
}
}
}
_ , err := DB . Exec ( "UPDATE resource SET tags=? WHERE id in (" + str . IdsString ( ids ) + ")" , tags )
if err != nil {
logger . Errorf ( "mysql.error: update resource tags fail: %s" , err )
return internalServerError
}
return nil
}
func ResourceUpdateMute ( ids [ ] int64 , btime , etime int64 ) error {
_ , err := DB . Exec ( "UPDATE resource SET mute_btime=?, mute_etime=? WHERE id in (" + str . IdsString ( ids ) + ")" , btime , etime )
if err != nil {
logger . Errorf ( "mysql.error: update resource mute fail: %s" , err )
return internalServerError
}
return nil
}