|
|
@ -386,3 +386,71 @@ export async function purgeAllDeletableOrphansGlobally(limit: number): Promise<n |
|
|
|
|
|
|
|
|
return deleted; |
|
|
return deleted; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
export type UserMediaAssetListRow = { |
|
|
|
|
|
id: number; |
|
|
|
|
|
storageKey: string; |
|
|
|
|
|
mime: string; |
|
|
|
|
|
sizeBytes: number; |
|
|
|
|
|
createdAt: Date; |
|
|
|
|
|
refCount: number; |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
export async function listUserMediaAssetsPage( |
|
|
|
|
|
userId: number, |
|
|
|
|
|
page: number, |
|
|
|
|
|
pageSize: number, |
|
|
|
|
|
): Promise<{ items: UserMediaAssetListRow[]; total: number }> { |
|
|
|
|
|
const [{ total: totalRaw }] = await dbGlobal |
|
|
|
|
|
.select({ total: count() }) |
|
|
|
|
|
.from(mediaAssets) |
|
|
|
|
|
.where(eq(mediaAssets.userId, userId)); |
|
|
|
|
|
|
|
|
|
|
|
const total = typeof totalRaw === "bigint" ? Number(totalRaw) : Number(totalRaw); |
|
|
|
|
|
|
|
|
|
|
|
const offset = (page - 1) * pageSize; |
|
|
|
|
|
const rows = await dbGlobal |
|
|
|
|
|
.select({ |
|
|
|
|
|
id: mediaAssets.id, |
|
|
|
|
|
storageKey: mediaAssets.storageKey, |
|
|
|
|
|
mime: mediaAssets.mime, |
|
|
|
|
|
sizeBytes: mediaAssets.sizeBytes, |
|
|
|
|
|
createdAt: mediaAssets.createdAt, |
|
|
|
|
|
}) |
|
|
|
|
|
.from(mediaAssets) |
|
|
|
|
|
.where(eq(mediaAssets.userId, userId)) |
|
|
|
|
|
.orderBy(desc(mediaAssets.createdAt)) |
|
|
|
|
|
.limit(pageSize) |
|
|
|
|
|
.offset(offset); |
|
|
|
|
|
|
|
|
|
|
|
if (rows.length === 0) { |
|
|
|
|
|
return { items: [], total }; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const ids = rows.map((r) => r.id); |
|
|
|
|
|
const refAgg = await dbGlobal |
|
|
|
|
|
.select({ |
|
|
|
|
|
assetId: mediaRefs.assetId, |
|
|
|
|
|
refCount: count(), |
|
|
|
|
|
}) |
|
|
|
|
|
.from(mediaRefs) |
|
|
|
|
|
.where(inArray(mediaRefs.assetId, ids)) |
|
|
|
|
|
.groupBy(mediaRefs.assetId); |
|
|
|
|
|
|
|
|
|
|
|
const refMap = new Map<number, number>(); |
|
|
|
|
|
for (const r of refAgg) { |
|
|
|
|
|
const c = r.refCount; |
|
|
|
|
|
refMap.set(r.assetId, typeof c === "bigint" ? Number(c) : Number(c)); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const items: UserMediaAssetListRow[] = rows.map((row) => ({ |
|
|
|
|
|
id: row.id, |
|
|
|
|
|
storageKey: row.storageKey, |
|
|
|
|
|
mime: row.mime, |
|
|
|
|
|
sizeBytes: row.sizeBytes, |
|
|
|
|
|
createdAt: row.createdAt, |
|
|
|
|
|
refCount: refMap.get(row.id) ?? 0, |
|
|
|
|
|
})); |
|
|
|
|
|
|
|
|
|
|
|
return { items, total }; |
|
|
|
|
|
} |
|
|
|