BrainMinder/models/type.go
2024-08-22 10:13:16 +02:00

232 lines
5.8 KiB
Go

package models
import (
"database/sql"
"errors"
"net/http"
"strconv"
"strings"
"brainminder.speedtech.it/internal/database"
"brainminder.speedtech.it/internal/funcs"
)
type TypeModel struct {
DB *database.DB
}
type Type struct {
Id int64 `db:"id"`
Title string `db:"title"`
Icon string `db:"icon"`
Description string `db:"description"`
Notebooks string `db:"notebooks"`
Show_summary int `db:"show_summary"`
Show_description int `db:"show_description"`
Sections string `db:"sections"`
}
func (model *TypeModel) One(id int64) (*Type, bool, error) {
ctx, cancel := database.GetContext()
defer cancel()
var row Type
query := `SELECT * FROM bm_type WHERE id = $1`
err := model.DB.GetContext(ctx, &row, query, id)
if errors.Is(err, sql.ErrNoRows) {
return nil, false, nil
}
return &row, true, err
}
func (model *TypeModel) Find(criteria map[string]any) ([]Type, bool, error) {
ctx, cancel := database.GetContext()
defer cancel()
var params []interface{}
var conditions []string
var cond string
query := "SELECT DISTINCT bmt.* FROM bm_type bmt "
for field, value := range criteria {
switch field {
case "Title":
valstr := value.(string)
if len(valstr) > 0 {
params = append(params, valstr)
conditions = append(conditions, "bmt.title LIKE '%' || ? || '%'")
}
case "notebook_id":
if value != nil {
valint := value.(int64)
if valint > 0 {
valstr := "|" + strconv.FormatInt(valint, 10) + "|"
params = append(params, valstr)
conditions = append(conditions, "INSTR(notebooks, ?) > 0")
}
}
}
}
for _, condition := range conditions {
if len(cond) > 0 {
cond = cond + " AND "
}
cond = cond + condition
}
if len(cond) > 0 {
query = query + "WHERE " + cond + " "
}
query = query + `ORDER BY bmt.title`
var rows []Type
err := model.DB.SelectContext(ctx, &rows, query, params...)
if errors.Is(err, sql.ErrNoRows) {
return nil, false, nil
}
return rows, true, err
}
func (model *TypeModel) FindAsOptions(criteria map[string]any) []funcs.WidgetOption {
Types, _, _ := model.Find(criteria)
var selectOptions []funcs.WidgetOption
for _, Type := range Types {
selectOptions = append(selectOptions, funcs.WidgetOption{Key: strconv.FormatInt(Type.Id, 10), Value: Type.Title})
}
return selectOptions
}
func (model *TypeModel) Delete(id int) (bool, error) {
ctx, cancel := database.GetContext()
defer cancel()
query := `DELETE FROM bm_type WHERE id = $1`
_, err := model.DB.ExecContext(ctx, query, id)
if errors.Is(err, sql.ErrNoRows) {
return false, nil
}
return true, err
}
func (model *TypeModel) Create(Type *Type) (int64, error) {
ctx, cancel := database.GetContext()
defer cancel()
query := `INSERT INTO bm_type (title, icon, description, notebooks, sections, show_summary, show_description)
VALUES (:title, :icon, :description, :notebooks, :sections, :show_summary, :show_description)`
result, err := model.DB.NamedExecContext(ctx, query, Type)
if err != nil {
return 0, err
}
id, err := result.LastInsertId()
if err != nil {
return 0, err
}
return id, err
}
func (model *TypeModel) Update(Type *Type) error {
ctx, cancel := database.GetContext()
defer cancel()
query := `UPDATE bm_type SET title=:title, icon=:icon, description=:description, notebooks=:notebooks,
sections=:sections, show_summary=:show_summary, show_description=:show_description WHERE id = :id`
_, err := model.DB.NamedExecContext(ctx, query, Type)
return err
}
func (model *TypeModel) SaveField(type_field_id int64, field *Field) error {
ctx, cancel := database.GetContext()
defer cancel()
query := `UPDATE bm_type_fields SET widget_id=:widget_id, title=:title, position=:position,
valid_values=:valid_values, show_on_list=:show_on_list, show_on_view=:show_on_view, ui_section=:ui_section, is_multiple=:is_multiple WHERE id =:type_field_id`
_, err := model.DB.NamedExecContext(ctx, query, field)
return err
}
func (model *TypeModel) RemoveField(type_field_id int64) error {
ctx, cancel := database.GetContext()
defer cancel()
//Check here if it is used
query := "DELETE FROM bm_type_fields WHERE id=$1"
_, err := model.DB.ExecContext(ctx, query, type_field_id)
return err
}
func (model *TypeModel) AddField(bmField *Field) error {
ctx, cancel := database.GetContext()
defer cancel()
query := `INSERT INTO bm_type_fields (type_id, widget_id, title, position, valid_values, show_on_list, show_on_view, ui_section, is_multiple)
VALUES (:type_id, :widget_id, :title, :position, :valid_values, :show_on_list, :show_on_view, :ui_section, :is_multiple)`
_, err := model.DB.NamedExecContext(ctx, query, bmField)
return err
}
func (model *TypeModel) AddFields(TypeId int64, r *http.Request) {
fieldsNew := make(map[int64]Field)
for name, values := range r.PostForm {
s, found := strings.CutPrefix(name, "Fields-New-")
if found {
parts := strings.Split(s, "-")
if len(parts) == 2 {
counter, _ := strconv.ParseInt(parts[0], 10, 64)
type_field_attribute := parts[1]
field, found := fieldsNew[counter]
if !found {
field := &Field{Type_id: TypeId}
fieldsNew[counter] = *field
}
field = fieldsNew[counter]
switch type_field_attribute {
case "Widget_id":
field.Widget_id, _ = strconv.ParseInt(values[0], 10, 64)
case "Title":
field.Title = values[0]
case "Valid_values":
field.Valid_values = values[0]
case "Ui_section":
field.Ui_section = values[0]
case "Is_multiple":
field.Is_multiple, _ = strconv.ParseInt(values[0], 10, 64)
case "Show_on_list":
field.Show_on_list, _ = strconv.ParseInt(values[0], 10, 64)
case "Show_on_view":
field.Show_on_view, _ = strconv.ParseInt(values[0], 10, 64)
}
fieldsNew[counter] = field
}
}
}
for _, field := range fieldsNew {
if len(field.Title) > 0 {
model.AddField(&field)
}
}
}