Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
106 lines
2.9 KiB
Go
106 lines
2.9 KiB
Go
package workspace
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
workspacebiz "github.com/tutti-os/tutti/services/tuttid/biz/workspace"
|
|
)
|
|
|
|
func (s *SQLiteStore) GetWorkbenchSnapshot(ctx context.Context, workspaceID string) (workspacebiz.WorkbenchSnapshot, error) {
|
|
if s == nil || s.writeDB == nil {
|
|
return workspacebiz.WorkbenchSnapshot{}, errors.New("workspace database is not initialized")
|
|
}
|
|
|
|
workspaceID = strings.TrimSpace(workspaceID)
|
|
if workspaceID == "" {
|
|
return workspacebiz.WorkbenchSnapshot{}, errors.New("workspace id is required")
|
|
}
|
|
|
|
if err := ensureWorkspaceExistsOn(ctx, s.readDB, workspaceID); err != nil {
|
|
return workspacebiz.WorkbenchSnapshot{}, err
|
|
}
|
|
|
|
row := s.readDB.QueryRowContext(ctx, `
|
|
SELECT workspace_id, schema_version, snapshot_json
|
|
FROM workspace_workbench_snapshots
|
|
WHERE workspace_id = ?
|
|
`, workspaceID)
|
|
|
|
var snapshot workspacebiz.WorkbenchSnapshot
|
|
var snapshotJSON string
|
|
if err := row.Scan(&snapshot.WorkspaceID, &snapshot.SchemaVersion, &snapshotJSON); err != nil {
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
return workspacebiz.WorkbenchSnapshot{}, ErrWorkbenchSnapshotNotFound
|
|
}
|
|
return workspacebiz.WorkbenchSnapshot{}, fmt.Errorf("get workspace workbench snapshot: %w", err)
|
|
}
|
|
|
|
snapshot.JSON = []byte(snapshotJSON)
|
|
return snapshot, nil
|
|
}
|
|
|
|
func (s *SQLiteStore) PutWorkbenchSnapshot(ctx context.Context, snapshot workspacebiz.WorkbenchSnapshot) error {
|
|
if s == nil || s.writeDB == nil {
|
|
return errors.New("workspace database is not initialized")
|
|
}
|
|
|
|
workspaceID := strings.TrimSpace(snapshot.WorkspaceID)
|
|
if workspaceID == "" {
|
|
return errors.New("workspace id is required")
|
|
}
|
|
if snapshot.SchemaVersion <= 0 {
|
|
return errors.New("workbench snapshot schema version is required")
|
|
}
|
|
if len(snapshot.JSON) == 0 {
|
|
return errors.New("workbench snapshot json is required")
|
|
}
|
|
|
|
if err := ensureWorkspaceExistsOn(ctx, s.writeDB, workspaceID); err != nil {
|
|
return err
|
|
}
|
|
|
|
now := unixMs(time.Now().UTC())
|
|
_, err := s.writeDB.ExecContext(ctx, `
|
|
INSERT INTO workspace_workbench_snapshots (
|
|
workspace_id,
|
|
schema_version,
|
|
snapshot_json,
|
|
created_at_unix_ms,
|
|
updated_at_unix_ms
|
|
)
|
|
VALUES (?, ?, ?, ?, ?)
|
|
ON CONFLICT(workspace_id) DO UPDATE SET
|
|
schema_version = excluded.schema_version,
|
|
snapshot_json = excluded.snapshot_json,
|
|
updated_at_unix_ms = excluded.updated_at_unix_ms
|
|
`, workspaceID, snapshot.SchemaVersion, string(snapshot.JSON), now, now)
|
|
if err != nil {
|
|
return fmt.Errorf("put workspace workbench snapshot: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func ensureWorkspaceExistsOn(ctx context.Context, db *sql.DB, workspaceID string) error {
|
|
row := db.QueryRowContext(ctx, `
|
|
SELECT 1
|
|
FROM workspaces
|
|
WHERE id = ?
|
|
`, workspaceID)
|
|
|
|
var exists int
|
|
if err := row.Scan(&exists); err != nil {
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
return ErrWorkspaceNotFound
|
|
}
|
|
return fmt.Errorf("check workspace exists: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|