package storage import ( "fmt" "log" "git.brettb.xyz/goinv/server/internal/types" "gorm.io/driver/postgres" "gorm.io/gorm" "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) 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) GetAssetByID(id uint64) (*types.Asset, error) { var result types.Asset tx := s.db.Model(&types.Asset{}).Where("id = ?", id).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) 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.Model(&types.ShelfLocation{}).Where("id = ?", id).First(&result) if tx.Error != nil { return nil, fmt.Errorf("shelf %d not found", id) } return &result, nil } func (s *DataStore) GetShelves(offset, limit int) ([]*types.ShelfLocation, error) { var shelves []*types.ShelfLocation s.db.Offset(offset).Limit(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 }