mirror of
https://github.com/nicotsx/ironmount.git
synced 2025-12-10 12:10:51 +01:00
Compare commits
2 Commits
v0.12.0
...
feat/multi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
967091df22 | ||
|
|
043f73ea87 |
@@ -67,9 +67,6 @@ export const backupSchedulesTable = sqliteTable("backup_schedules_table", {
|
|||||||
volumeId: int("volume_id")
|
volumeId: int("volume_id")
|
||||||
.notNull()
|
.notNull()
|
||||||
.references(() => volumesTable.id, { onDelete: "cascade" }),
|
.references(() => volumesTable.id, { onDelete: "cascade" }),
|
||||||
repositoryId: text("repository_id")
|
|
||||||
.notNull()
|
|
||||||
.references(() => repositoriesTable.id, { onDelete: "cascade" }),
|
|
||||||
enabled: int("enabled", { mode: "boolean" }).notNull().default(true),
|
enabled: int("enabled", { mode: "boolean" }).notNull().default(true),
|
||||||
cronExpression: text("cron_expression").notNull(),
|
cronExpression: text("cron_expression").notNull(),
|
||||||
retentionPolicy: text("retention_policy", { mode: "json" }).$type<{
|
retentionPolicy: text("retention_policy", { mode: "json" }).$type<{
|
||||||
@@ -90,14 +87,43 @@ export const backupSchedulesTable = sqliteTable("backup_schedules_table", {
|
|||||||
createdAt: int("created_at", { mode: "number" }).notNull().default(sql`(unixepoch())`),
|
createdAt: int("created_at", { mode: "number" }).notNull().default(sql`(unixepoch())`),
|
||||||
updatedAt: int("updated_at", { mode: "number" }).notNull().default(sql`(unixepoch())`),
|
updatedAt: int("updated_at", { mode: "number" }).notNull().default(sql`(unixepoch())`),
|
||||||
});
|
});
|
||||||
export const backupScheduleRelations = relations(backupSchedulesTable, ({ one }) => ({
|
|
||||||
|
/**
|
||||||
|
* Junction Table: Backup Schedules <-> Repositories (Many-to-Many)
|
||||||
|
*/
|
||||||
|
export const backupScheduleRepositoriesTable = sqliteTable(
|
||||||
|
"backup_schedule_repositories_table",
|
||||||
|
{
|
||||||
|
scheduleId: int("schedule_id")
|
||||||
|
.notNull()
|
||||||
|
.references(() => backupSchedulesTable.id, { onDelete: "cascade" }),
|
||||||
|
repositoryId: text("repository_id")
|
||||||
|
.notNull()
|
||||||
|
.references(() => repositoriesTable.id, { onDelete: "cascade" }),
|
||||||
|
},
|
||||||
|
(table) => ({
|
||||||
|
pk: { name: "pk_schedule_repository", columns: [table.scheduleId, table.repositoryId] },
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
export const backupScheduleRelations = relations(backupSchedulesTable, ({ one, many }) => ({
|
||||||
volume: one(volumesTable, {
|
volume: one(volumesTable, {
|
||||||
fields: [backupSchedulesTable.volumeId],
|
fields: [backupSchedulesTable.volumeId],
|
||||||
references: [volumesTable.id],
|
references: [volumesTable.id],
|
||||||
}),
|
}),
|
||||||
|
repositories: many(backupScheduleRepositoriesTable),
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const backupScheduleRepositoryRelations = relations(backupScheduleRepositoriesTable, ({ one }) => ({
|
||||||
|
schedule: one(backupSchedulesTable, {
|
||||||
|
fields: [backupScheduleRepositoriesTable.scheduleId],
|
||||||
|
references: [backupSchedulesTable.id],
|
||||||
|
}),
|
||||||
repository: one(repositoriesTable, {
|
repository: one(repositoriesTable, {
|
||||||
fields: [backupSchedulesTable.repositoryId],
|
fields: [backupScheduleRepositoriesTable.repositoryId],
|
||||||
references: [repositoriesTable.id],
|
references: [repositoriesTable.id],
|
||||||
}),
|
}),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export type BackupSchedule = typeof backupSchedulesTable.$inferSelect;
|
export type BackupSchedule = typeof backupSchedulesTable.$inferSelect;
|
||||||
|
export type BackupScheduleRepository = typeof backupScheduleRepositoriesTable.$inferSelect;
|
||||||
|
|||||||
@@ -123,7 +123,8 @@ export const repositoriesController = new Hono()
|
|||||||
const { name, snapshotId } = c.req.param();
|
const { name, snapshotId } = c.req.param();
|
||||||
const { path } = c.req.valid("query");
|
const { path } = c.req.valid("query");
|
||||||
|
|
||||||
const result = await repositoriesService.listSnapshotFiles(name, snapshotId, path);
|
const decodedPath = path ? decodeURIComponent(path) : undefined;
|
||||||
|
const result = await repositoriesService.listSnapshotFiles(name, snapshotId, decodedPath);
|
||||||
|
|
||||||
c.header("Cache-Control", "max-age=300, stale-while-revalidate=600");
|
c.header("Cache-Control", "max-age=300, stale-while-revalidate=600");
|
||||||
|
|
||||||
|
|||||||
@@ -565,7 +565,7 @@ const ls = async (config: RepositoryConfig, snapshotId: string, path?: string) =
|
|||||||
|
|
||||||
addRepoSpecificArgs(args, config, env);
|
addRepoSpecificArgs(args, config, env);
|
||||||
|
|
||||||
const res = await $`restic ${args}`.env(env).nothrow().quiet();
|
const res = await safeSpawn({ command: "restic", args, env });
|
||||||
await cleanupTemporaryKeys(config, env);
|
await cleanupTemporaryKeys(config, env);
|
||||||
|
|
||||||
if (res.exitCode !== 0) {
|
if (res.exitCode !== 0) {
|
||||||
@@ -574,7 +574,7 @@ const ls = async (config: RepositoryConfig, snapshotId: string, path?: string) =
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The output is a stream of JSON objects, first is snapshot info, rest are file/dir nodes
|
// The output is a stream of JSON objects, first is snapshot info, rest are file/dir nodes
|
||||||
const stdout = res.text();
|
const stdout = res.stdout;
|
||||||
const lines = stdout
|
const lines = stdout
|
||||||
.trim()
|
.trim()
|
||||||
.split("\n")
|
.split("\n")
|
||||||
|
|||||||
Reference in New Issue
Block a user