import db from '@adonisjs/lucid/services/db' import { sevenZipVolume } from '#lib/sevenzip/index' /** * The database side of 7z listings (CONCEPT.md D19): which volumes make up * an archive. Listing itself (first segment, tail, bsdtar) is * lib/sevenzip/list.ts, run by inspection here or on a node. */ class SevenZipService { /** * The volumes of the archive `file` belongs to, in order, when all of them * up to the highest number seen are there; null otherwise. An unsplit (or * unnamed) archive is its own only volume. */ async volumes(file: any): Promise { const name = String(file.real_name ?? file.filename) const volume = sevenZipVolume(name) if (!volume) return [file] if (!file.release_id) return null const base = name.replace(/\.\d+$/, '').toLowerCase() const rows = await db .from('files') .where('release_id', file.release_id) .whereRaw(`lower(coalesce(real_name, filename)) LIKE ? ESCAPE '\\'`, [`${base.replace(/[\\%_]/g, '\\$&')}.%`]) const byNumber = new Map() for (const row of rows) { const n = sevenZipVolume(String(row.real_name ?? row.filename)) if (n && !byNumber.has(n)) byNumber.set(n, row) } const max = Math.max(0, ...byNumber.keys()) const ordered = Array.from({ length: max }, (_, i) => byNumber.get(i + 1)) return max > 0 && ordered.every(Boolean) ? ordered : null } } export default new SevenZipService()