Files
agent-radar 2ed3415fb7
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
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

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
}