package model import ( "context" "time" ) // QueryType 查询类型 type QueryType string const ( // QueryTypeLatest 获取最新值 QueryTypeLatest QueryType = "latest" // QueryTypeAll 获取所有值 QueryTypeAll QueryType = "all" // QueryTypeDuration 获取持续时间 QueryTypeDuration QueryType = "duration" ) // Query 查询接口 type Query interface { Type() QueryType Params() map[string]interface{} } // Result 查询结果接口 type Result interface { IsEmpty() bool AsLatest() (DataValue, bool) AsAll() ([]DataValue, bool) AsDuration() (time.Duration, bool) } // QueryExecutor 查询执行器接口 type QueryExecutor interface { Execute(ctx context.Context, query Query) (Result, error) } // BaseQuery 基础查询实现 type BaseQuery struct { queryType QueryType params map[string]interface{} } // NewQuery 创建一个新的查询 func NewQuery(queryType QueryType, params map[string]interface{}) Query { return &BaseQuery{ queryType: queryType, params: params, } } // Type 返回查询类型 func (q *BaseQuery) Type() QueryType { return q.queryType } // Params 返回查询参数 func (q *BaseQuery) Params() map[string]interface{} { return q.params } // BaseResult 基础查询结果实现 type BaseResult struct { latest *DataValue all []DataValue duration *time.Duration } // NewLatestResult 创建一个最新值查询结果 func NewLatestResult(value DataValue) Result { return &BaseResult{ latest: &value, } } // NewAllResult 创建一个所有值查询结果 func NewAllResult(values []DataValue) Result { return &BaseResult{ all: values, } } // NewDurationResult 创建一个持续时间查询结果 func NewDurationResult(duration time.Duration) Result { return &BaseResult{ duration: &duration, } } // IsEmpty 检查结果是否为空 func (r *BaseResult) IsEmpty() bool { return r.latest == nil && len(r.all) == 0 && r.duration == nil } // AsLatest 将结果转换为最新值 func (r *BaseResult) AsLatest() (DataValue, bool) { if r.latest != nil { return *r.latest, true } return DataValue{}, false } // AsAll 将结果转换为所有值 func (r *BaseResult) AsAll() ([]DataValue, bool) { if len(r.all) > 0 { return r.all, true } return nil, false } // AsDuration 将结果转换为持续时间 func (r *BaseResult) AsDuration() (time.Duration, bool) { if r.duration != nil { return *r.duration, true } return 0, false }