package storage
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
|
|
"git.brettb.xyz/goinv/server/internal/types"
|
|
"gorm.io/driver/postgres"
|
|
"gorm.io/gorm"
|
|
"gorm.io/gorm/clause"
|
|
"gorm.io/gorm/logger"
|
|
)
|
|
|
|
type DataStore struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
func NewDataStorePG(host, user, password, dbname, sslmode string) (*DataStore, error) {
|
|
dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s sslmode=%s", host, user, password, dbname, sslmode)
|
|
|
|
log.Printf("Connecting to %s@%s/%s\n", host, user, dbname)
|
|
|
|
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
|
|
Logger: logger.Default.LogMode(logger.Silent),
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
log.Printf("Auto-Migrating models")
|
|
|
|
if err := db.AutoMigrate(
|
|
&types.Asset{},
|
|
&types.Building{},
|
|
&types.Category{},
|
|
&types.ShelfLocation{},
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &DataStore{
|
|
db: db,
|
|
}, nil
|
|
}
|
|
|
|
func (s *DataStore) CreateAsset(asset *types.Asset) error {
|
|
result := s.db.Create(asset)
|
|
return result.Error
|
|
}
|
|
|
|
func (s *DataStore) UpdateAsset(id uint64, update *types.Asset) error {
|
|
result := s.db.Model(&types.Asset{}).Where("id = ?", id).Select("*").Updates(update)
|
|
return result.Error
|
|
}
|
|
|
|
func (s *DataStore) CreateBuilding(building *types.Building) error {
|
|
result := s.db.Create(building)
|
|
return result.Error
|
|
}
|
|
|
|
func (s *DataStore) CreateCategory(category *types.Category) error {
|
|
result := s.db.Create(category)
|
|
return result.Error
|
|
}
|
|
|
|
func (s *DataStore) CreateShelfLocation(shelf *types.ShelfLocation) error {
|
|
result := s.db.Create(shelf)
|
|
return result.Error
|
|
}
|
|
|
|
func (s *DataStore) UpdateShelfLocation(id uint64, update *types.ShelfLocation) error {
|
|
result := s.db.Model(&types.ShelfLocation{}).Where("id = ?", id).Select("*").Updates(update)
|
|
return result.Error
|
|
}
|
|
|
|
func (s *DataStore) GetAssetByID(id uint64) (*types.Asset, error) {
|
|
var result types.Asset
|
|
tx := s.db.Model(&types.Asset{}).Where("id = ?", id).Preload(clause.Associations).First(&result)
|
|
if tx.Error != nil {
|
|
return nil, fmt.Errorf("asset %d not found", id)
|
|
}
|
|
return &result, nil
|
|
}
|
|
|
|
func (s *DataStore) GetAssets(offset, limit uint64) ([]*types.Asset, error) {
|
|
var assets []*types.Asset
|
|
s.db.Joins("Category").Joins("ShelfLocation").Order("id asc").Offset(int(offset)).Limit(int(limit)).Find(&assets)
|
|
if len(assets) == 0 {
|
|
return nil, fmt.Errorf("no assets found")
|
|
}
|
|
return assets, nil
|
|
}
|
|
|
|
func (s *DataStore) TotalAssets() (int64, error) {
|
|
var count int64
|
|
if tx := s.db.Find(&types.Asset{}).Count(&count); tx.Error != nil {
|
|
return 0, tx.Error
|
|
}
|
|
return count, nil
|
|
}
|
|
|
|
func (s *DataStore) AssetCountInLocation(shelfId uint64) (int64, error) {
|
|
var count int64
|
|
if tx := s.db.Model(&types.Asset{}).Where("shelf_location_id = ?", shelfId).Find(&types.Asset{}).Count(&count); tx.Error != nil {
|
|
return 0, tx.Error
|
|
}
|
|
return count, nil
|
|
}
|
|
|
|
func (s *DataStore) DeleteAssetByID(id uint64) (bool, error) {
|
|
tx := s.db.Delete(&types.Asset{}, id)
|
|
if tx.Error != nil {
|
|
return false, fmt.Errorf("unable to delete: %s", tx.Error.Error())
|
|
}
|
|
return true, nil
|
|
}
|
|
|
|
func (s *DataStore) GetShelfByID(id uint64) (*types.ShelfLocation, error) {
|
|
var result types.ShelfLocation
|
|
tx := s.db.Joins("Building").Where(&types.ShelfLocation{ID: id}).First(&result)
|
|
if tx.Error != nil {
|
|
return nil, fmt.Errorf("shelf %d not found: %v", id, tx.Error)
|
|
}
|
|
return &result, nil
|
|
}
|
|
|
|
func (s *DataStore) GetShelves(offset, limit uint64) ([]*types.ShelfLocation, error) {
|
|
var shelves []*types.ShelfLocation
|
|
s.db.Joins("Building").Order("id asc").Offset(int(offset)).Limit(int(limit)).Find(&shelves)
|
|
if len(shelves) == 0 {
|
|
return nil, fmt.Errorf("no shelves found")
|
|
}
|
|
return shelves, nil
|
|
}
|
|
|
|
func (s *DataStore) TotalShelves() (int64, error) {
|
|
var count int64
|
|
if tx := s.db.Find(&types.ShelfLocation{}).Count(&count); tx.Error != nil {
|
|
return 0, tx.Error
|
|
}
|
|
return count, nil
|
|
}
|
|
|
|
func (s *DataStore) DeleteShelfByID(id uint64) (bool, error) {
|
|
tx := s.db.Delete(&types.ShelfLocation{}, id)
|
|
if tx.Error != nil {
|
|
return false, fmt.Errorf("unable to delete: %s", tx.Error.Error())
|
|
}
|
|
return true, nil
|
|
}
|
|
|
|
func (s *DataStore) GetCategoryByID(id uint64) (*types.Category, error) {
|
|
var result types.Category
|
|
tx := s.db.Model(&types.Category{}).Where("id = ?", id).First(&result)
|
|
if tx.Error != nil {
|
|
return nil, fmt.Errorf("category %d not found", id)
|
|
}
|
|
return &result, nil
|
|
}
|
|
|
|
func (s *DataStore) GetCategories(offset, limit int) ([]*types.Category, error) {
|
|
var categories []*types.Category
|
|
s.db.Offset(offset).Limit(limit).Find(&categories)
|
|
if len(categories) == 0 {
|
|
return nil, fmt.Errorf("no categories found")
|
|
}
|
|
return categories, nil
|
|
}
|
|
|
|
func (s *DataStore) TotalCategories() (int64, error) {
|
|
var count int64
|
|
if tx := s.db.Find(&types.Category{}).Count(&count); tx.Error != nil {
|
|
return 0, tx.Error
|
|
}
|
|
return count, nil
|
|
}
|
|
|
|
func (s *DataStore) DeleteCategoryByID(id uint64) (bool, error) {
|
|
tx := s.db.Delete(&types.Category{}, id)
|
|
if tx.Error != nil {
|
|
return false, fmt.Errorf("unable to delete: %s", tx.Error.Error())
|
|
}
|
|
return true, nil
|
|
}
|
|
|
|
func (s *DataStore) GetBuildings(offset, limit uint64) ([]*types.Building, error) {
|
|
var buildings []*types.Building
|
|
s.db.Order("id asc").Offset(int(offset)).Limit(int(limit)).Find(&buildings)
|
|
if len(buildings) == 0 {
|
|
return nil, fmt.Errorf("no buildings found")
|
|
}
|
|
return buildings, nil
|
|
}
|
|
|
|
func (s *DataStore) TotalBuildings() (int64, error) {
|
|
var count int64
|
|
if tx := s.db.Find(&types.Building{}).Count(&count); tx.Error != nil {
|
|
return 0, tx.Error
|
|
}
|
|
return count, nil
|
|
}
|
|
|
|
func (s *DataStore) GetBuildingByID(id uint64) (*types.Building, error) {
|
|
var result types.Building
|
|
tx := s.db.Model(&types.Building{}).Where("id = ?", id).First(&result)
|
|
if tx.Error != nil {
|
|
return nil, fmt.Errorf("building %d not found", id)
|
|
}
|
|
return &result, nil
|
|
}
|