File size: 2,274 Bytes
253e783 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | import type { DatabaseSync } from "node:sqlite";
import type { Selectable } from "kysely";
import {
executeSqliteQuerySync,
executeSqliteQueryTakeFirstSync,
getNodeSqliteKysely,
} from "../infra/kysely-sync.js";
import type { DB as OpenClawStateKyselyDatabase } from "../state/openclaw-state-db.generated.js";
import { createOpenClawStateSchemaEnsurer } from "../state/openclaw-state-feature-schema.js";
export type ProjectRegistryIdentity = {
id: string;
repoRoot: string;
originUrl?: string;
source: "workspace" | "registered" | "cloned";
};
type ProjectsDatabase = Pick<OpenClawStateKyselyDatabase, "projects">;
type ProjectRow = Selectable<ProjectsDatabase["projects"]>;
export const ensureProjectRegistrySchema = createOpenClawStateSchemaEnsurer({
table: "projects",
operationLabel: "projects.registry.schema.ensure",
});
export function resolveRecordedProjectRootInDatabase(
database: DatabaseSync,
repoRoot: string,
): string | undefined {
const db = getNodeSqliteKysely<ProjectsDatabase>(database);
return executeSqliteQueryTakeFirstSync(
database,
db.selectFrom("projects").select("repo_root").where("repo_root", "=", repoRoot),
)?.repo_root;
}
function matchesProjectRecord(row: ProjectRow, project: ProjectRegistryIdentity): boolean {
return (
row.id === project.id &&
row.repo_root === project.repoRoot &&
row.source === project.source &&
(row.origin_url ?? undefined) === project.originUrl
);
}
export function readMatchingProjectRow(
database: DatabaseSync,
project: ProjectRegistryIdentity,
): ProjectRow | undefined {
const db = getNodeSqliteKysely<ProjectsDatabase>(database);
const row = executeSqliteQueryTakeFirstSync(
database,
db.selectFrom("projects").selectAll().where("id", "=", project.id),
);
return row && matchesProjectRecord(row, project) ? row : undefined;
}
export function removeProjectRegistryInDatabase(
database: DatabaseSync,
project: ProjectRegistryIdentity,
): boolean {
if (!readMatchingProjectRow(database, project)) {
return false;
}
const db = getNodeSqliteKysely<ProjectsDatabase>(database);
return (
executeSqliteQuerySync(database, db.deleteFrom("projects").where("id", "=", project.id))
.numAffectedRows === 1n
);
}
|