package store import ( "context" "database/sql" ) // CodeSlot is a player's saved source code. type CodeSlot struct { Slot int Name string Source string } // ListCodeSlots returns the names of a player's saved slots, keyed by slot number. func (q *Q) ListCodeSlots(ctx context.Context, owner int64) (map[int]string, error) { rows, err := q.query(ctx, `SELECT slot, name FROM code_slots WHERE player_id = ?`, owner) if err != nil { return nil, err } defer rows.Close() out := map[int]string{} for rows.Next() { var n int var name string if err := rows.Scan(&n, &name); err != nil { return nil, err } out[n] = name } return out, rows.Err() } // GetCodeSlot returns one saved slot, or ErrNotFound if it is empty. func (q *Q) GetCodeSlot(ctx context.Context, owner int64, slot int) (CodeSlot, error) { cs := CodeSlot{Slot: slot} err := q.row(ctx, `SELECT name, source FROM code_slots WHERE player_id = ? AND slot = ?`, owner, slot).Scan(&cs.Name, &cs.Source) if err == sql.ErrNoRows { return cs, ErrNotFound } return cs, err } // PutCodeSlot saves source in a slot, replacing whatever was there. func (q *Q) PutCodeSlot(ctx context.Context, owner int64, slot int, name, source, at string) error { _, err := q.exec(ctx, `INSERT INTO code_slots (player_id, slot, name, source, updated_at) VALUES (?, ?, ?, ?, ?) ON CONFLICT (player_id, slot) DO UPDATE SET name = excluded.name, source = excluded.source, updated_at = excluded.updated_at`, owner, slot, name, source, at) return err } // DeleteCodeSlot empties a slot. Emptying an empty slot is not an error. func (q *Q) DeleteCodeSlot(ctx context.Context, owner int64, slot int) error { _, err := q.exec(ctx, `DELETE FROM code_slots WHERE player_id = ? AND slot = ?`, owner, slot) return err } // LaunchWithProgram seals prog into a docked ship and queues it for launch in // one step, replacing any program it already had. func (q *Q) LaunchWithProgram(ctx context.Context, owner, ship int64, prog []byte) error { if _, err := q.ownedStatus(ctx, owner, ship); err != nil { return err } res, err := q.exec(ctx, `UPDATE ships SET program = ?, status = ? WHERE id = ? AND owner_id = ? AND status = ?`, prog, StatusLaunching, ship, owner, StatusInventory) return q.requireOneRow(res, err) }