package postgres import ( "database/sql" "log" "github.com/dustinpianalto/quartermaster" ) type locationService struct { db *sql.DB } func (s locationService) Location(id int, user *quartermaster.User) (*quartermaster.Location, error) { var l quartermaster.Location var parent_id sql.NullInt32 queryString := "SELECT id, name, description, parent_id FROM locations WHERE id = $1 AND owner_id = $2" row := s.db.QueryRow(queryString, id, user.ID) err := row.Scan(&l.ID, &l.Name, &l.Description, &parent_id) if err != nil { return nil, err } if parent_id.Valid { p, err := s.Location(int(parent_id.Int32), user) if err != nil { return nil, err } l.Parent = p } return &l, nil } func (s locationService) AddLocation(l *quartermaster.Location, user *quartermaster.User) (*quartermaster.Location, error) { queryString := "INSERT INTO locations (name, description, parent_id, owner_id) VALUES ($1, $2, $3, $4) RETURNING id" var err error if l.Parent != nil { err = s.db.QueryRow(queryString, l.Name, l.Description, l.Parent.ID, user.ID).Scan(&l.ID) } else { err = s.db.QueryRow(queryString, l.Name, l.Description, nil, user.ID).Scan(&l.ID) } return l, err } func (s locationService) UpdateLocation(l *quartermaster.Location, user *quartermaster.User) error { queryString := "UPDATE locations SET name = $2, description = $3, parent_id = $4 WHERE id = $1 AND owner_id = $5" var err error if l.Parent != nil { _, err = s.db.Exec(queryString, l.ID, l.Name, l.Description, l.Parent.ID, user.ID) } else { _, err = s.db.Exec(queryString, l.ID, l.Name, l.Description, nil, user.ID) } return err } func (s locationService) DeleteLocation(l *quartermaster.Location, user *quartermaster.User) error { queryString := "DELETE FROM locations WHERE id = $1 AND owner_id = $2" _, err := s.db.Exec(queryString, l.ID, user.ID) return err } func (s locationService) GetChildren(l *quartermaster.Location, user *quartermaster.User) ([]*quartermaster.Location, error) { var locations []*quartermaster.Location queryString := "SELECT id FROM locations WHERE parent_id = $1 AND owner_id = $2" rows, err := s.db.Query(queryString, l.ID, user.ID) if err != nil { return nil, err } for rows.Next() { var id int err = rows.Scan(&id) if err != nil { log.Println(err) continue } location, err := s.Location(id, user) if err != nil { log.Println(err) continue } locations = append(locations, location) } return locations, nil } func (s locationService) GetItems(l *quartermaster.Location, user *quartermaster.User) (map[*quartermaster.Item]int, error) { items := make(map[*quartermaster.Item]int) queryString := "SELECT item_id, count FROM x_items_locations WHERE location_id = $1" rows, err := s.db.Query(queryString, l.ID) if err != nil { return nil, err } for rows.Next() { var id, count int err = rows.Scan(&id, &count) if err != nil { log.Println(err) continue } item, err := ItemService.Item(id, user) if err != nil { log.Println(err) continue } items[item] = count } return items, nil } func (s locationService) GetItemCount(l *quartermaster.Location, i *quartermaster.Item, user *quartermaster.User) (int, error) { var count int queryString := "SELECT count FROM x_items_locations WHERE location_id = $1 AND item_id = $2" row := s.db.QueryRow(queryString, l.ID, i.ID) err := row.Scan(&count) if err != nil { return 0, err } return count, nil } func (s locationService) GetTopLocations(user *quartermaster.User) ([]*quartermaster.Location, error) { var locations []*quartermaster.Location queryString := "SELECT id FROM locations WHERE parent_id IS NULL AND owner_id = $1" rows, err := s.db.Query(queryString, user.ID) if err != nil { return nil, err } for rows.Next() { var id int err = rows.Scan(&id) if err != nil { log.Println(err) continue } l, err := s.Location(id, user) if err != nil { log.Println(err) continue } locations = append(locations, l) } return locations, nil }