feat(models): mounts/media_items/playback_progress/danmaku_cache
This commit is contained in:
parent
3143a9c7d0
commit
f94aabe8a5
|
|
@ -0,0 +1,20 @@
|
|||
import { sql } from "drizzle-orm";
|
||||
import { integer, sqliteTable, text, uniqueIndex } from "drizzle-orm/sqlite-core";
|
||||
|
||||
export const danmakuCache = sqliteTable(
|
||||
"danmaku_cache",
|
||||
{
|
||||
id: text("id")
|
||||
.primaryKey()
|
||||
.$defaultFn(() => crypto.randomUUID()),
|
||||
matchKey: text("match_key").notNull(),
|
||||
payload: text("payload").notNull(),
|
||||
source: text("source").notNull().default("open-network"),
|
||||
expiresAt: integer("expires_at", { mode: "timestamp" }),
|
||||
createdAt: integer("created_at", { mode: "timestamp" })
|
||||
.notNull()
|
||||
.default(sql`(unixepoch())`),
|
||||
},
|
||||
(t) => [uniqueIndex("danmaku_match_key_uq").on(t.matchKey)],
|
||||
);
|
||||
export type DanmakuCacheRow = typeof danmakuCache.$inferSelect;
|
||||
|
|
@ -5,3 +5,11 @@ export { sessions } from "./sessions.js";
|
|||
export type { Session, NewSession } from "./sessions.js";
|
||||
export { passwordResets } from "./password-resets.js";
|
||||
export type { PasswordReset, NewPasswordReset } from "./password-resets.js";
|
||||
export { mounts } from "./mounts.js";
|
||||
export type { Mount, NewMount } from "./mounts.js";
|
||||
export { mediaItems } from "./media-items.js";
|
||||
export type { MediaItem, NewMediaItem } from "./media-items.js";
|
||||
export { playbackProgress } from "./playback-progress.js";
|
||||
export type { PlaybackProgress } from "./playback-progress.js";
|
||||
export { danmakuCache } from "./danmaku-cache.js";
|
||||
export type { DanmakuCacheRow } from "./danmaku-cache.js";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
import { sql } from "drizzle-orm";
|
||||
import { integer, sqliteTable, text, uniqueIndex } from "drizzle-orm/sqlite-core";
|
||||
import { users } from "./users.js";
|
||||
import { mounts } from "./mounts.js";
|
||||
|
||||
export const mediaItems = sqliteTable(
|
||||
"media_items",
|
||||
{
|
||||
id: text("id")
|
||||
.primaryKey()
|
||||
.$defaultFn(() => crypto.randomUUID()),
|
||||
userId: text("user_id")
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: "cascade" }),
|
||||
mountId: text("mount_id").references(() => mounts.id, { onDelete: "set null" }),
|
||||
path: text("path").notNull(),
|
||||
rawName: text("raw_name").notNull(),
|
||||
title: text("title").notNull(),
|
||||
size: integer("size").notNull().default(0),
|
||||
mime: text("mime"),
|
||||
bangumiId: integer("bangumi_id"),
|
||||
epNumber: integer("ep_number"),
|
||||
scrapeStatus: text("scrape_status").notNull().default("pending"),
|
||||
scrapedAt: integer("scraped_at", { mode: "timestamp" }),
|
||||
posterUrl: text("poster_url"),
|
||||
matchedHash: text("matched_hash"),
|
||||
scannedAt: integer("scanned_at", { mode: "timestamp" })
|
||||
.notNull()
|
||||
.default(sql`(unixepoch())`),
|
||||
updatedAt: integer("updated_at", { mode: "timestamp" })
|
||||
.notNull()
|
||||
.default(sql`(unixepoch())`),
|
||||
},
|
||||
(t) => [uniqueIndex("media_user_path_uq").on(t.userId, t.path)],
|
||||
);
|
||||
export type MediaItem = typeof mediaItems.$inferSelect;
|
||||
export type NewMediaItem = typeof mediaItems.$inferInsert;
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
import { sql } from "drizzle-orm";
|
||||
import { integer, sqliteTable, text, uniqueIndex } from "drizzle-orm/sqlite-core";
|
||||
import { users } from "./users.js";
|
||||
|
||||
export const mounts = sqliteTable(
|
||||
"mounts",
|
||||
{
|
||||
id: text("id")
|
||||
.primaryKey()
|
||||
.$defaultFn(() => crypto.randomUUID()),
|
||||
userId: text("user_id")
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: "cascade" }),
|
||||
name: text("name").notNull(),
|
||||
type: text("type").notNull().default("webdav"),
|
||||
baseUrl: text("base_url").notNull(),
|
||||
username: text("username"),
|
||||
/** AES-GCM 密文(base64),永不回传前端 */
|
||||
secretEnc: text("secret_enc").notNull().default(""),
|
||||
rootPath: text("root_path").notNull().default("/"),
|
||||
enabled: integer("enabled", { mode: "boolean" }).notNull().default(true),
|
||||
createdAt: integer("created_at", { mode: "timestamp" })
|
||||
.notNull()
|
||||
.default(sql`(unixepoch())`),
|
||||
updatedAt: integer("updated_at", { mode: "timestamp" })
|
||||
.notNull()
|
||||
.default(sql`(unixepoch())`),
|
||||
},
|
||||
(t) => [uniqueIndex("mounts_user_name_uq").on(t.userId, t.name)],
|
||||
);
|
||||
export type Mount = typeof mounts.$inferSelect;
|
||||
export type NewMount = typeof mounts.$inferInsert;
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
import { sql } from "drizzle-orm";
|
||||
import { integer, sqliteTable, text, uniqueIndex } from "drizzle-orm/sqlite-core";
|
||||
import { users } from "./users.js";
|
||||
import { mediaItems } from "./media-items.js";
|
||||
|
||||
export const playbackProgress = sqliteTable(
|
||||
"playback_progress",
|
||||
{
|
||||
id: text("id")
|
||||
.primaryKey()
|
||||
.$defaultFn(() => crypto.randomUUID()),
|
||||
userId: text("user_id")
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: "cascade" }),
|
||||
mediaItemId: text("media_item_id")
|
||||
.notNull()
|
||||
.references(() => mediaItems.id, { onDelete: "cascade" }),
|
||||
positionMs: integer("position_ms").notNull().default(0),
|
||||
durationMs: integer("duration_ms").notNull().default(0),
|
||||
updatedAt: integer("updated_at", { mode: "timestamp" })
|
||||
.notNull()
|
||||
.default(sql`(unixepoch())`),
|
||||
},
|
||||
(t) => [uniqueIndex("progress_user_media_uq").on(t.userId, t.mediaItemId)],
|
||||
);
|
||||
export type PlaybackProgress = typeof playbackProgress.$inferSelect;
|
||||
Loading…
Reference in New Issue