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 }