This repository has been archived on 2023-11-13. You can view files and clone it, but cannot push or open issues or pull requests.
imagini/internal/db/db.go

156 lines
3.1 KiB
Go
Raw Normal View History

2021-01-16 22:00:17 +00:00
package db
2021-01-06 19:36:09 +00:00
import (
2021-02-04 10:16:13 +00:00
"fmt"
"path"
2021-02-09 00:42:20 +00:00
"reflect"
2021-01-08 02:45:59 +00:00
2021-02-09 00:42:20 +00:00
"github.com/iancoleman/strcase"
2021-02-04 10:16:13 +00:00
log "github.com/sirupsen/logrus"
2021-02-09 00:42:20 +00:00
2021-02-04 10:16:13 +00:00
// "gorm.io/gorm/logger"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
2021-01-08 02:45:59 +00:00
2021-02-04 10:16:13 +00:00
"reichard.io/imagini/graph/model"
"reichard.io/imagini/internal/config"
2021-01-06 19:36:09 +00:00
)
2021-01-16 22:00:17 +00:00
type DBManager struct {
2021-02-04 10:16:13 +00:00
db *gorm.DB
2021-01-16 22:00:17 +00:00
}
func NewMgr(c *config.Config) *DBManager {
2021-02-04 10:16:13 +00:00
gormConfig := &gorm.Config{
PrepareStmt: true,
// Logger: logger.Default.LogMode(logger.Silent),
}
// Create manager
dbm := &DBManager{}
if c.DBType == "SQLite" {
dbLocation := path.Join(c.ConfigPath, "imagini.db")
dbm.db, _ = gorm.Open(sqlite.Open(dbLocation), gormConfig)
2021-02-09 00:42:20 +00:00
dbm.db = dbm.db.Debug()
2021-02-04 10:16:13 +00:00
} else {
log.Fatal("Unsupported Database")
}
// Initialize database
dbm.db.AutoMigrate(&model.Device{})
dbm.db.AutoMigrate(&model.User{})
dbm.db.AutoMigrate(&model.MediaItem{})
dbm.db.AutoMigrate(&model.Tag{})
dbm.db.AutoMigrate(&model.Album{})
// Determine whether to bootstrap
var count int64
dbm.db.Model(&model.User{}).Count(&count)
if count == 0 {
dbm.bootstrapDatabase()
}
return dbm
2021-01-06 19:36:09 +00:00
}
2021-01-16 22:00:17 +00:00
func (dbm *DBManager) bootstrapDatabase() {
2021-02-04 10:16:13 +00:00
log.Info("[query] Bootstrapping database.")
2021-02-02 20:34:10 +00:00
2021-02-04 10:16:13 +00:00
password := "admin"
user := &model.User{
Username: "admin",
AuthType: "Local",
Password: &password,
Role: model.RoleAdmin,
}
2021-02-02 20:34:10 +00:00
2021-02-04 10:16:13 +00:00
err := dbm.CreateUser(user)
2021-01-12 22:06:27 +00:00
2021-02-04 10:16:13 +00:00
if err != nil {
log.Fatal("[query] Unable to bootstrap database.")
}
2021-01-12 22:06:27 +00:00
}
2021-02-01 23:24:09 +00:00
2021-02-09 00:42:20 +00:00
func (dbm *DBManager) generateBaseQuery(tx *gorm.DB, filter interface{}, page *model.Page, order *model.Order) (*gorm.DB, model.PageResponse) {
tx = dbm.generateFilter(tx, filter)
tx = dbm.generateOrder(tx, order, filter)
tx, pageResponse := dbm.generatePage(tx, page)
return tx, pageResponse
}
2021-02-04 10:16:13 +00:00
2021-02-09 00:42:20 +00:00
func (dbm *DBManager) generateOrder(tx *gorm.DB, order *model.Order, filter interface{}) *gorm.DB {
// Set Defaults
orderBy := "created_at"
orderDirection := model.OrderDirectionDesc
if order == nil {
order = &model.Order{
By: &orderBy,
Direction: &orderDirection,
}
}
if order.By == nil {
order.By = &orderBy
}
if order.Direction == nil {
order.Direction = &orderDirection
}
// Get Possible Values
ptr := reflect.New(reflect.TypeOf(filter).Elem())
v := reflect.Indirect(ptr)
isValid := false
for i := 0; i < v.NumField(); i++ {
fieldName := v.Type().Field(i).Name
if strcase.ToSnake(*order.By) == strcase.ToSnake(fieldName) {
isValid = true
break
}
2021-02-04 10:16:13 +00:00
}
2021-02-09 00:42:20 +00:00
if isValid {
tx = tx.Order(fmt.Sprintf("%s %s", strcase.ToSnake(*order.By), order.Direction.String()))
}
return tx
}
func (dbm *DBManager) generatePage(tx *gorm.DB, page *model.Page) (*gorm.DB, model.PageResponse) {
// Set Defaults
2021-02-04 10:16:13 +00:00
var count int64
2021-02-09 00:42:20 +00:00
pageSize := 50
pageNum := 1
if page == nil {
page = &model.Page{
Size: &pageSize,
Page: &pageNum,
}
}
if page.Size == nil {
page.Size = &pageSize
}
if page.Page == nil {
page.Page = &pageNum
}
// Acquire Counts Before Pagination
tx.Count(&count)
// Calculate Offset
calculatedOffset := (*page.Page - 1) * *page.Size
tx = tx.Limit(*page.Size).Offset(calculatedOffset)
return tx, model.PageResponse{
Page: *page.Page,
Size: *page.Size,
Total: int(count),
}
2021-02-01 23:24:09 +00:00
}