Add multiple terminals per task and saved commands that start one
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
CREATE TABLE saved_commands (
|
||||
id TEXT PRIMARY KEY,
|
||||
owner TEXT NOT NULL REFERENCES users(login),
|
||||
name TEXT NOT NULL,
|
||||
command TEXT NOT NULL
|
||||
);
|
||||
CREATE INDEX saved_commands_owner ON saved_commands(owner, name);
|
||||
@@ -0,0 +1,83 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"g.fc.run/ai/byre/internal/api"
|
||||
"g.fc.run/ai/byre/internal/ids"
|
||||
)
|
||||
|
||||
func (s *Store) SavedCommands(ctx context.Context, owner string) ([]api.SavedCommand, error) {
|
||||
rows, err := s.db.QueryContext(ctx, `SELECT id, name, command FROM saved_commands WHERE owner = ? ORDER BY name, id`, owner)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
cmds := []api.SavedCommand{}
|
||||
for rows.Next() {
|
||||
c := api.SavedCommand{}
|
||||
err = rows.Scan(&c.Id, &c.Name, &c.Command)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmds = append(cmds, c)
|
||||
}
|
||||
return cmds, rows.Err()
|
||||
}
|
||||
|
||||
func (s *Store) SavedCommand(ctx context.Context, owner, id string) (api.SavedCommand, error) {
|
||||
c := api.SavedCommand{Id: id}
|
||||
err := s.db.QueryRowContext(ctx, `SELECT name, command FROM saved_commands WHERE id = ? AND owner = ?`, id, owner).Scan(&c.Name, &c.Command)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return c, fmt.Errorf("saved command %s: %w", id, ErrNotFound)
|
||||
}
|
||||
return c, err
|
||||
}
|
||||
|
||||
func (s *Store) SaveSavedCommand(ctx context.Context, owner, id, name, command, actor string) (api.SavedCommand, error) {
|
||||
c := api.SavedCommand{Id: id, Name: name, Command: command}
|
||||
err := s.write(ctx, func(tx *sql.Tx, emit emitFunc) error {
|
||||
if id == "" {
|
||||
c.Id = ids.New(ids.SavedCommand)
|
||||
_, err := tx.ExecContext(ctx, `INSERT INTO saved_commands (id, owner, name, command) VALUES (?, ?, ?, ?)`, c.Id, owner, name, command)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
res, err := tx.ExecContext(ctx, `UPDATE saved_commands SET name = ?, command = ? WHERE id = ? AND owner = ?`, name, command, id, owner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
n, err := res.RowsAffected()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if n == 0 {
|
||||
return fmt.Errorf("saved command %s: %w", id, ErrNotFound)
|
||||
}
|
||||
}
|
||||
return emit(api.Event{Kind: "command.saved", Owner: &owner, Actor: actor, Payload: ToPayload(c)})
|
||||
})
|
||||
return c, err
|
||||
}
|
||||
|
||||
func (s *Store) DeleteSavedCommand(ctx context.Context, owner, id, actor string) error {
|
||||
return s.write(ctx, func(tx *sql.Tx, emit emitFunc) error {
|
||||
res, err := tx.ExecContext(ctx, `DELETE FROM saved_commands WHERE id = ? AND owner = ?`, id, owner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
n, err := res.RowsAffected()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if n == 0 {
|
||||
return fmt.Errorf("saved command %s: %w", id, ErrNotFound)
|
||||
}
|
||||
return emit(api.Event{Kind: "command.deleted", Owner: &owner, Actor: actor, Payload: map[string]any{"id": id}})
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user