package db
import (
"fmt"
"git.sr.ht/~evanj/cms/internal/m/space"
"git.sr.ht/~evanj/cms/internal/m/user"
)
type Space struct {
id string
name string
desc string
}
var (
queryCreateNewSpace = `INSERT INTO cms_space (NAME, DESC) VALUES (?, ?);`
queryFindSpaceByID = `SELECT ID, NAME, DESC FROM cms_space WHERE ID = ?;`
queryDeleteSpaceByID = `DELETE FROM cms_space WHERE ID = ?;`
queryCreateNewUserToSpace = `INSERT INTO cms_user_to_space (USER_ID, SPACE_ID) VALUES (?, ?);`
queryFindUserToSpace = `SELECT SPACE_ID FROM cms_user_to_space WHERE USER_ID = ? AND SPACE_ID = ?;`
queryFindSpacesByUser = `SELECT DISTINCT cms_space.ID, NAME, DESC FROM cms_space JOIN cms_user_to_space ON cms_space.ID = cms_user_to_space.SPACE_ID WHERE USER_ID = ? LIMIT ? OFFSET ?;`
)
func (db *DB) SpaceNew(user user.User, name, desc string) (space.Space, error) {
res, err := db.Exec(queryCreateNewSpace, name, desc)
if err != nil {
db.log.Println("db.Exec", err)
return nil, fmt.Errorf("space '%s' already exists", name)
}
id, err := res.LastInsertId()
if err != nil {
db.log.Println("res.LastInsertId", err)
return nil, fmt.Errorf("failed to create space")
}
var space Space
if err := db.QueryRow(queryFindSpaceByID, id).Scan(&space.id, &space.name, &space.desc); err != nil {
db.log.Println("db.QueryRow", err)
return nil, fmt.Errorf("failed to find space created")
}
if _, err := db.Exec(queryCreateNewUserToSpace, user.ID(), space.ID()); err != nil {
db.log.Println("big problem, failed to connect user to space", err)
if _, err := db.Exec(queryDeleteSpaceByID, space.ID()); err != nil {
db.log.Println("even bigger problem, failed to delete orphan space", err)
}
return nil, fmt.Errorf("failed to attach space to user")
}
return &space, nil
}
func (db *DB) SpaceGet(user user.User, spaceID string) (space.Space, error) {
var id string
if err := db.QueryRow(queryFindUserToSpace, user.ID(), spaceID).Scan(&id); err != nil {
db.log.Println("db.QueryRow", err)
return nil, fmt.Errorf("failed to find space for user")
}
var space Space
err := db.QueryRow(queryFindSpaceByID, id).Scan(&space.id, &space.name, &space.desc)
if err != nil {
db.log.Println("db.Exec", err)
return nil, fmt.Errorf("failed to find space")
}
return &space, nil
}
func (db *DB) SpacesPerUser(user user.User, page int) ([]space.Space, error) {
var ret []space.Space
rows, err := db.Query(queryFindSpacesByUser, user.ID(), perPage, perPage*page)
if err != nil {
db.log.Println(err)
return ret, err
}
for rows.Next() {
var space Space
if err := rows.Scan(&space.id, &space.name, &space.desc); err != nil {
return nil, err
}
ret = append(ret, &space)
}
return ret, nil
}
func (s *Space) ID() string {
return s.id
}
func (s *Space) Name() string {
return s.name
}