Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/reference/sparql-anything.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ Set `extension` for a tool that reads the format from the file name – SPARQL A

**Splitting is by line**, so every record must be one line. A delimited format that wraps a field in quotes to carry a newline inside it would be cut in two; tab-separated exports, N-Triples and NDJSON are one record per line by definition. Line endings are normalised to `\n`.

Chunks of the same input left by an earlier call are removed first, so a re-run cannot leave a longer run's tail behind for something to pick up. Only those: everything else in the directory is the caller's.
Chunks of the same input left by an earlier call are removed first, so a re-run cannot leave a longer run's tail behind for something to pick up. Only those: everything else in the directory is the caller's. Take the paths `chunk()` returns as the list of chunks to convert, rather than rediscovering them by name in the directory – a listing would also pick up whatever else is there.

An input with no rows is an error rather than an empty set of chunks: a step that produced an empty file has already failed.

Expand Down
4 changes: 3 additions & 1 deletion packages/sparql-anything/src/chunk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,10 @@ async function removeChunksOf(
extension: string,
into: string,
): Promise<void> {
// Four digits or more: the index is padded to four, and grows past them
// from the 10,000th chunk on.
const chunkFile = new RegExp(
`^${escapeForRegExp(name)}-\\d{4}${escapeForRegExp(extension)}$`,
`^${escapeForRegExp(name)}-\\d{4,}${escapeForRegExp(extension)}$`,
);
const entries = await readdir(into, { withFileTypes: true });
await Promise.all(
Expand Down
23 changes: 23 additions & 0 deletions packages/sparql-anything/test/chunk.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,29 @@ describe('chunk', () => {
]);
});

// Writing 10,001 files takes a few seconds, so leave it room on a slow runner.
it(
'removes chunks past the 10,000th, whose index has five digits',
{ timeout: 30_000 },
async () => {
const into = join(workDir, 'chunks');
const input = join(workDir, 'places.txt');
// One character per row keeps 10,001 rows small.
await writeFile(input, 'x\n'.repeat(10_001));
const firstPaths = await chunk(input, { rows: 1, into });
expect(firstPaths[10_000].endsWith('places-10000.txt')).toBe(true);

const secondPaths = await chunk(input, { rows: 5_000, into });

expect(secondPaths).toHaveLength(3);
expect((await readdir(into)).sort()).toEqual([
'places-0000.txt',
'places-0001.txt',
'places-0002.txt',
]);
},
);

it('refuses an extension without its leading dot', async () => {
const input = await writeInput(2);

Expand Down