Bluemage/go/api/devices_list.go

92 lines
2.8 KiB
Go
Raw Normal View History

2024-08-07 23:59:29 +07:00
package api
import (
"strings"
"github.com/stephenafamo/bob"
"github.com/stephenafamo/bob/dialect/sqlite"
"github.com/stephenafamo/bob/dialect/sqlite/dialect"
"github.com/stephenafamo/bob/dialect/sqlite/sm"
"github.com/tigorlazuardi/bluemage/go/gen/converter"
"github.com/tigorlazuardi/bluemage/go/gen/models"
device "github.com/tigorlazuardi/bluemage/go/gen/proto/device/v1"
"github.com/tigorlazuardi/bluemage/go/pkg/errs"
"golang.org/x/net/context"
)
var convert converter.DeviceConverterImpl
func queryFromListDeviceRequest(req *device.ListDevicesRequest) (expr []bob.Mod[*dialect.SelectQuery]) {
expr = countQueryFromListDeviceRequest(req)
if req.Limit > 0 {
expr = append(expr, sm.Limit(req.Limit))
}
if req.Offset > 0 {
expr = append(expr, sm.Offset(req.Offset))
}
if req.OrderBy == device.OrderBy_ORDER_BY_UNSPECIFIED {
return append(expr, sm.OrderBy(models.DeviceColumns.CreatedAt).Desc())
}
orderByField, _ := strings.CutPrefix(device.OrderBy_name[int32(req.OrderBy)], "ORDER_BY_")
orderByField = strings.ToLower(orderByField)
orderBy := sm.OrderBy(sqlite.Quote(orderByField))
if req.Sort == device.Sort_SORT_DESCENDING {
expr = append(expr, orderBy.Desc())
} else {
expr = append(expr, orderBy.Asc())
}
return expr
}
func countQueryFromListDeviceRequest(req *device.ListDevicesRequest) (expr []bob.Mod[*dialect.SelectQuery]) {
switch req.Disabled {
case device.DisabledFilter_DISABLED_FILTER_TRUE:
expr = append(expr, models.SelectWhere.Devices.Disabled.EQ(1))
case device.DisabledFilter_DISABLED_FILTER_FALSE:
expr = append(expr, models.SelectWhere.Devices.Disabled.EQ(0))
}
if req.Search != "" {
arg := sqlite.Arg("%" + req.Search + "%")
expr = append(expr,
sm.Where(
models.DeviceColumns.Name.Like(arg).Or(models.DeviceColumns.Slug.Like(arg)),
),
)
}
return expr
}
func (api *API) DevicesList(ctx context.Context, req *device.ListDevicesRequest) (resp *device.ListDevicesResponse, err error) {
resp = &device.ListDevicesResponse{}
results, err := models.Devices.Query(ctx, api.DB, queryFromListDeviceRequest(req)...).All()
if err != nil {
return resp, errs.Wrapw(err, "failed to list devices", "request", req)
}
if req.Disabled == device.DisabledFilter_DISABLED_FILTER_UNSPECIFIED && req.Search == "" {
const metricName = "devices.count"
metric, err := models.FindMetric(ctx, api.DB, metricName)
if err != nil {
return resp, errs.Wrapw(err, "failed to find devices count metric", "metric", metricName)
}
resp.Count = uint64(metric.Value)
} else {
count, err := models.Devices.Query(ctx, api.DB, countQueryFromListDeviceRequest(req)...).Count()
if err != nil {
return resp, errs.Wrapw(err, "failed to count query result")
}
resp.Count = uint64(count)
}
for _, result := range results {
resp.Devices = append(resp.Devices, convert.ModelsDeviceToGetDeviceResponse(result))
}
return resp, err
}