(db: Database, path: string)
| 11 | // A deliberately minimal helper so writeFile tests can stand alone |
| 12 | // without depending on readFile. |
| 13 | function readBack(db: Database, path: string): Uint8Array { |
| 14 | const node = resolveInode(db, path); |
| 15 | if (node === null) throw new Error(`no such path: ${path}`); |
| 16 | if (node.type !== "file") throw new Error(`not a file: ${path}`); |
| 17 | const chunks = db.all<{ hash: Uint8Array; size: number }>( |
| 18 | "SELECT hash, size FROM vfs_chunks WHERE inode = ? ORDER BY idx", |
| 19 | node.inode, |
| 20 | ); |
| 21 | const parts: Uint8Array[] = []; |
| 22 | let total = 0; |
| 23 | for (const chunk of chunks) { |
| 24 | const row = db.one<{ bytes: Uint8Array }>( |
| 25 | "SELECT bytes FROM vfs_blob_bytes WHERE hash = ?", |
| 26 | chunk.hash, |
| 27 | ); |
| 28 | if (row === undefined) throw new Error("missing blob bytes"); |
| 29 | parts.push(row.bytes); |
| 30 | total += row.bytes.byteLength; |
| 31 | } |
| 32 | const out = new Uint8Array(total); |
| 33 | let offset = 0; |
| 34 | for (const part of parts) { |
| 35 | out.set(part, offset); |
| 36 | offset += part.byteLength; |
| 37 | } |
| 38 | return out; |
| 39 | } |
| 40 | |
| 41 | function chunkRows(db: Database, path: string): Array<{ hash: Uint8Array; size: number }> { |
| 42 | const node = resolveInode(db, path); |
no test coverage detected