Add runtime SQLite query targets

This commit is contained in:
npc0-hue
2026-09-01 17:15:09 +08:00
parent 65da73eff0
commit 163fbda394
17 changed files with 708 additions and 114 deletions
+40 -13
View File
@@ -67,6 +67,7 @@ type LifecycleExecutor struct {
localStartupDiagnostics bool
protectedRequests *ProtectedRequestRegistry
sqliteSchemaProbe *SQLiteSchemaProbeExecutor
sqliteQuery *SQLiteQueryExecutor
metricCollector MetricCollector
}
@@ -118,6 +119,7 @@ func NewLifecycleExecutor(options ...LifecycleExecutorOption) LifecycleExecutor
executor.fileExecutor = files
}
executor.sqliteSchemaProbe = NewSQLiteSchemaProbeExecutor(executor.workspaceRoot)
executor.sqliteQuery = NewSQLiteQueryExecutor(executor.workspaceRoot)
return executor
}
@@ -389,6 +391,9 @@ func (executor LifecycleExecutor) ExecuteContext(ctx context.Context, assignment
return lifecycleFailure("unsafe_lifecycle_command", err.Error())
}
log.Printf("RUN phase=lifecycle.command status=starting job=%s workdir=%s command=%s timeoutMs=%d envKeys=%s", assignment.JobID, safeOptional(command.WorkDir), redactedCommandLine(command.Args), command.Timeout.Milliseconds(), envKeysSummary(command.Env, nil))
command.OutputLine = func(stream string, line string) {
_ = executor.logSink.Append(ctx, assignment, stream, line)
}
result, err := executor.supervisor.Run(ctx, command)
if err != nil && ctx.Err() != nil {
log.Printf("RUN phase=lifecycle.command status=cancelled job=%s error=%s", assignment.JobID, RedactText(ctx.Err().Error()))
@@ -399,7 +404,9 @@ func (executor LifecycleExecutor) ExecuteContext(ctx context.Context, assignment
ErrorCode: "lifecycle_cancelled",
}
}
executor.writeProcessLogs(ctx, assignment, result)
if !result.OutputRelayed {
executor.writeProcessLogs(ctx, assignment, result)
}
if err != nil {
log.Printf("RUN phase=lifecycle.command status=failed job=%s exitCode=%d error=%s", assignment.JobID, result.ExitCode, RedactText(err.Error()))
return lifecycleFailure("lifecycle_process_failed", RedactText(err.Error()))
@@ -519,7 +526,7 @@ func (executor LifecycleExecutor) writeProcessLogs(ctx context.Context, assignme
{stream: "stdout", body: result.Stdout},
{stream: "stderr", body: result.Stderr},
} {
for _, line := range splitBoundedLines(item.body) {
for _, line := range splitRawLogLines(item.body) {
_ = executor.logSink.Append(ctx, assignment, item.stream, line)
}
}
@@ -919,12 +926,14 @@ type ProcessCommand struct {
JobID string
Capability string
Action string
OutputLine func(string, string)
}
type ProcessResult struct {
ExitCode int
Stdout string
Stderr string
ExitCode int
Stdout string
Stderr string
OutputRelayed bool
}
type ProcessSupervisor interface {
@@ -969,7 +978,7 @@ func (supervisor OSProcessSupervisor) Run(ctx context.Context, command ProcessCo
err := cmd.Wait()
stdoutWriter.Flush()
stderrWriter.Flush()
result := ProcessResult{Stdout: RedactText(stdout.String()), Stderr: RedactText(stderr.String())}
result := ProcessResult{Stdout: stdout.String(), Stderr: stderr.String(), OutputRelayed: command.OutputLine != nil}
if cmd.ProcessState != nil {
result.ExitCode = cmd.ProcessState.ExitCode()
}
@@ -1011,7 +1020,7 @@ func (writer *lifecycleOutputWriter) Write(p []byte) (int, error) {
if index < 0 {
break
}
line := strings.TrimRight(writer.pending[:index], "\r")
line := writer.pending[:index]
writer.pending = writer.pending[index+1:]
writer.logLine(line)
}
@@ -1021,19 +1030,17 @@ func (writer *lifecycleOutputWriter) Write(p []byte) (int, error) {
func (writer *lifecycleOutputWriter) Flush() {
writer.mu.Lock()
defer writer.mu.Unlock()
if strings.TrimSpace(writer.pending) == "" {
writer.pending = ""
if writer.pending == "" {
return
}
writer.logLine(strings.TrimRight(writer.pending, "\r"))
writer.logLine(writer.pending)
writer.pending = ""
}
func (writer *lifecycleOutputWriter) logLine(line string) {
if strings.TrimSpace(line) == "" {
return
if writer.command.OutputLine != nil {
writer.command.OutputLine(writer.stream, line)
}
log.Printf("RUN phase=process.command.output status=line job=%s capability=%s action=%s stream=%s line=%q", safeOptional(writer.command.JobID), safeOptional(writer.command.Capability), safeOptional(writer.command.Action), writer.stream, RedactText(line))
}
type ioLimitWriter struct {
@@ -1242,6 +1249,26 @@ func splitBoundedLines(value string) []string {
return out
}
// splitRawLogLines only removes the newline framing used by LogEntry. It
// deliberately preserves every other byte, including blank lines and spaces.
func splitRawLogLines(value string) []string {
if value == "" {
return nil
}
lines := make([]string, 0, strings.Count(value, "\n")+1)
for start := 0; start < len(value); {
end := strings.IndexByte(value[start:], '\n')
if end < 0 {
lines = append(lines, value[start:])
break
}
end += start
lines = append(lines, value[start:end])
start = end + 1
}
return lines
}
func checksumForText(value string) string {
sum := sha256.Sum256([]byte(value))
return "sha256:" + hex.EncodeToString(sum[:])