173 lines
4.6 KiB
Go
173 lines
4.6 KiB
Go
/**
|
|
* file: database/productTag.go
|
|
* author: Theo Technicguy
|
|
* license: Apache 2.0
|
|
*
|
|
* Product tags database table connector
|
|
*/
|
|
|
|
package database
|
|
|
|
import (
|
|
"database/sql"
|
|
|
|
"git.licolas.net/hoffman/server/types"
|
|
)
|
|
|
|
const (
|
|
sqlDropProductTags = "DROP TABLE ProductTag;"
|
|
sqlCreateProductTags = `CREATE TABLE ProductTag (
|
|
TagID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
|
Name VARCHAR(64) UNIQUE NOT NULL,
|
|
Color INT
|
|
);`
|
|
sqlSelectAllProductTags = "SELECT * FROM ProductTag;"
|
|
sqlSelectProductTagById = "SELECT * FROM ProductTag WHERE TagID = ?;"
|
|
sqlSelectProductTagByName = "SELECT * FROM ProductTag WHERE Name = ?;"
|
|
sqlSelectProductTagsLikeName = "SELECT * FROM ProductTag WHERE Name LIKE %%?%%;"
|
|
sqlInsertProductTag = "INSERT INTO ProductTag (Name, Color) VALUES (?, ?);"
|
|
sqlUpdateProductTag = "UPDATE ProductTag SET Name = ?, Color = ? WHERE TagID = ?;"
|
|
sqlDeleteProductTag = "DELETE FROM ProductTag WHERE TagID = ?"
|
|
)
|
|
|
|
func (r *R) scanProductTags(tx *sql.Tx, query string, args ...any) ([]*types.Tag, error) {
|
|
logger.Trace().Bool("transaction", tx != nil).Str("query", query).Any("args", args).Msg("excuting query and scanning tags")
|
|
if tx == nil {
|
|
var err error
|
|
tx, err = r.db.Begin()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
defer tx.Rollback()
|
|
}
|
|
|
|
rows, err := tx.Query(query, args...)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
var tags []*types.Tag = []*types.Tag{}
|
|
for rows.Next() {
|
|
var tag types.Tag
|
|
|
|
if err := rows.Scan(&tag.Id, &tag.Name, &tag.Color); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
logger.Trace().Any("tag", tag).Msg("adding found tag")
|
|
tags = append(tags, &tag)
|
|
}
|
|
|
|
logger.Trace().Int("tags", len(tags)).Msg("done querying and scanning tags")
|
|
return tags, nil
|
|
}
|
|
|
|
func (r *R) scanUniqueProductTag(tx *sql.Tx, query string, args ...any) (tag *types.Tag, err error) {
|
|
logger.Trace().Bool("transaction", tx != nil).Str("query", query).Any("args", args).Msg("excuting query and scanning one tag")
|
|
|
|
tags, err := r.scanProductTags(tx, query, args...)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
switch len(tags) {
|
|
case 0:
|
|
tag, err = new(types.Tag), nil
|
|
case 1:
|
|
tag, err = tags[0], nil
|
|
default:
|
|
tag, err = nil, ErrNonUniqueIdentifier
|
|
}
|
|
|
|
logger.Trace().Any("tag", tag).Msg("found tag")
|
|
return
|
|
}
|
|
|
|
func (r *R) DropProductTagTable() error {
|
|
logger.Info().Msg("dropping product tag table")
|
|
_, err := r.db.Exec(sqlDropProductTags)
|
|
return err
|
|
}
|
|
|
|
func (r *R) CreateProductTagTable() error {
|
|
logger.Info().Msg("creating product tag table")
|
|
_, err := r.db.Exec(sqlCreateProductTags)
|
|
return err
|
|
}
|
|
|
|
func (r *R) SelectAllProductTags() ([]*types.Tag, error) {
|
|
logger.Trace().Msg("selecting all tags")
|
|
return r.scanProductTags(nil, sqlSelectAllProductTags)
|
|
}
|
|
|
|
func (r *R) SelectProductTagById(id uint) (*types.Tag, error) {
|
|
logger.Trace().Uint("id", id).Msg("selecting tag by id")
|
|
return r.scanUniqueProductTag(nil, sqlSelectProductTagById, id)
|
|
}
|
|
|
|
func (r *R) SelectProductTagByName(name string) (*types.Tag, error) {
|
|
logger.Trace().Str("name", name).Msg("selecting tag by name")
|
|
return r.scanUniqueProductTag(nil, sqlSelectProductTagByName, name)
|
|
}
|
|
|
|
func (r *R) SelectProductTagsLikeName(name string) ([]*types.Tag, error) {
|
|
logger.Trace().Str("name", name).Msg("selecting tag like name")
|
|
return r.scanProductTags(nil, sqlSelectProductTagsLikeName, name)
|
|
}
|
|
|
|
func (r *R) InsertProductTag(tag *types.Tag) error {
|
|
logger.Trace().Any("tag", tag).Msg("inserting new tag")
|
|
result, err := r.db.Exec(sqlInsertProductTag, tag.Name, tag.Color)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
id, err := result.LastInsertId()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
tag.Id = uint(id)
|
|
logger.Trace().Uint("new-id", tag.Id).Msg("new tag id")
|
|
|
|
return nil
|
|
}
|
|
|
|
func (r *R) UpdateProductTag(tag *types.Tag) (*types.Tag, error) {
|
|
logger.Trace().Any("tag", tag).Msg("updating tag")
|
|
if _, err := r.db.Exec(sqlUpdateProductTag, tag.Name, tag.Color, tag.Id); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return r.scanUniqueProductTag(nil, sqlSelectProductTagById, tag.Id)
|
|
}
|
|
|
|
func (r *R) DeleteProductTag(id uint) (*types.Tag, error) {
|
|
logger := logger.With().Uint("tag-id", id).Logger()
|
|
logger.Trace().Msg("deleting tag")
|
|
tx, err := r.db.Begin()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer tx.Rollback()
|
|
|
|
logger.Trace().Msg("selecting tag")
|
|
tags, err := r.scanProductTags(tx, sqlSelectProductTagById, id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
logger.Trace().Msg("deleting taggings")
|
|
if _, err := tx.Exec(sqlDeleteTagProductTagging, id); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
logger.Trace().Msg("deleting tag")
|
|
if _, err := tx.Exec(sqlDeleteProductTag, id); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return tags[0], tx.Commit()
|
|
}
|