Extract repository helpers to pkg/rh package

This commit is contained in:
Denis Arh
2019-08-14 17:18:35 +02:00
parent 9f58f8e83e
commit 3e68bfa7e0
5 changed files with 141 additions and 68 deletions
+2 -2
View File
@@ -11,8 +11,8 @@ import (
"gopkg.in/Masterminds/squirrel.v1"
"github.com/cortezaproject/corteza-server/compose/internal/repository/ql"
"github.com/cortezaproject/corteza-server/compose/types"
"github.com/cortezaproject/corteza-server/pkg/rh"
)
type (
@@ -117,7 +117,7 @@ func (r record) Report(module *types.Module, metrics, dimensions, filter string)
func (r record) Find(module *types.Module, filter types.RecordFilter) (set types.RecordSet, f types.RecordFilter, err error) {
var query squirrel.SelectBuilder
f = filter
f.PerPage = normalizePerPage(f.PerPage, 5, 100, 50)
f.PerPage = rh.NormalizePerPage(f.PerPage, 5, 100, 50)
query, err = r.buildQuery(module, filter)
if err != nil {
+6 -66
View File
@@ -3,12 +3,11 @@ package repository
import (
"context"
"github.com/lann/builder"
"github.com/pkg/errors"
"github.com/titpetric/factory"
"gopkg.in/Masterminds/squirrel.v1"
"github.com/cortezaproject/corteza-server/internal/auth"
"github.com/cortezaproject/corteza-server/pkg/rh"
)
type (
@@ -51,82 +50,23 @@ func (r *repository) db() *factory.DB {
// Fetches single row from table
func (r repository) fetchOne(one interface{}, q squirrel.SelectBuilder) (err error) {
var (
sql string
args []interface{}
)
if sql, args, err = q.ToSql(); err != nil {
return
}
if err = r.db().Get(one, sql, args...); err != nil {
return
}
return
return rh.FetchOne(r.db(), q, one)
}
// Counts all rows that match conditions from given query builder
func (r repository) count(q squirrel.SelectBuilder) (uint, error) {
var (
count uint
cq = q.Column("COUNT(*)")
)
// Remove order-bys for counting
cq = builder.Delete(cq, "OrderBys").(squirrel.SelectBuilder)
if sqlSelect, argsSelect, err := cq.ToSql(); err != nil {
return 0, err
} else {
if err := r.db().Get(&count, sqlSelect, argsSelect...); err != nil {
return 0, err
}
}
return count, nil
return rh.Count(r.db(), q)
}
// Fetches paged rows
func (r repository) fetchPaged(set interface{}, q squirrel.SelectBuilder, page, perPage uint) error {
if perPage > 0 {
q = q.Limit(uint64(perPage))
}
if page > 0 {
q = q.Offset(uint64(page * perPage))
}
if sqlSelect, argsSelect, err := q.ToSql(); err != nil {
return err
} else {
return r.db().Select(set, sqlSelect, argsSelect...)
}
return rh.FetchPaged(r.db(), q, page, perPage, set)
}
func normalizePerPage(val, min, max, def uint) uint {
if val == 0 {
return def
}
if max > 0 && val > max {
return max
}
if min > 0 && val < min {
return min
}
return val
return rh.NormalizePerPage(val, min, max, def)
}
func isFound(err error, valid bool, nerr error) error {
if err != nil {
return errors.WithStack(err)
} else if !valid {
return errors.WithStack(nerr)
}
return nil
return rh.IsFound(err, valid, nerr)
}
+4
View File
@@ -0,0 +1,4 @@
# (rh) Repository Helpers
Package name is short an abbreviated to avoid
colliding with per-service repository package names.
+99
View File
@@ -0,0 +1,99 @@
package rh
import (
"github.com/lann/builder"
"github.com/pkg/errors"
"github.com/titpetric/factory"
"gopkg.in/Masterminds/squirrel.v1"
)
// FetchOne fetches single row from table
func FetchOne(db *factory.DB, q squirrel.SelectBuilder, one interface{}) (err error) {
var (
sql string
args []interface{}
)
if sql, args, err = q.ToSql(); err != nil {
return
}
if err = db.Get(one, sql, args...); err != nil {
return
}
return
}
// Count counts all rows that match conditions from given query builder
func Count(db *factory.DB, q squirrel.SelectBuilder) (count uint, err error) {
// Remove order-bys for counting
q = builder.Delete(q, "OrderBys").(squirrel.SelectBuilder)
// Replace columns
q = builder.Delete(q, "Columns").(squirrel.SelectBuilder).Column("COUNT(*)")
if sqlSelect, argsSelect, err := q.ToSql(); err != nil {
return 0, err
} else {
if err := db.Get(&count, sqlSelect, argsSelect...); err != nil {
return 0, err
}
}
return count, nil
}
// FetchPaged fetches paged rows
func FetchPaged(db *factory.DB, q squirrel.SelectBuilder, page, perPage uint, set interface{}) error {
if perPage > 0 {
q = q.Limit(uint64(perPage))
}
if page > 0 {
q = q.Offset(uint64(page * perPage))
}
if sqlSelect, argsSelect, err := q.ToSql(); err != nil {
return err
} else {
return db.Select(set, sqlSelect, argsSelect...)
}
}
// FetchPaged fetches paged rows
func FetchAll(db *factory.DB, q squirrel.SelectBuilder, set interface{}) error {
if sqlSelect, argsSelect, err := q.ToSql(); err != nil {
return err
} else {
return db.Select(set, sqlSelect, argsSelect...)
}
}
// NormalizePerPage normalize page number
func NormalizePerPage(val, min, max, def uint) uint {
if val == 0 {
return def
}
if max > 0 && val > max {
return max
}
if min > 0 && val < min {
return min
}
return val
}
// IsFound helps with one-row results
func IsFound(err error, valid bool, nerr error) error {
if err != nil {
return errors.WithStack(err)
} else if !valid {
return errors.WithStack(nerr)
}
return nil
}
+30
View File
@@ -0,0 +1,30 @@
package rh
const (
PER_PAGE_DEFAULT uint = 50
PER_PAGE_MAX = 200
PER_PAGE_MIN = 10
)
type (
PageFilter struct {
Page uint `json:"page"`
PerPage uint `json:"perPage"`
Count uint `json:"count"`
}
)
func Paging(page, perPage uint) PageFilter {
return PageFilter{
Page: page,
PerPage: perPage,
}
}
func (pf *PageFilter) NormalizePerPage(min, max, def uint) {
pf.PerPage = NormalizePerPage(pf.PerPage, min, max, def)
}
func (pf *PageFilter) NormalizePerPageWithDefaults() {
pf.PerPage = NormalizePerPage(pf.PerPage, PER_PAGE_MIN, PER_PAGE_MAX, PER_PAGE_DEFAULT)
}