feat: live progress + clean final count for bulk copy path

The bulk path showed no progress during a load (only the final count). Emit
an in-place counter (\r + rows) every 10k rows from the BulkSource adapter,
which the caller pulls one row at a time, so it streams live. Prefix the
final count print with \r so it starts a fresh line instead of concatenating
onto the last tick (which produced a garbage row count like 3000035000).

Verified: ticks emit at 10k/20k/30k, final row_count parses correctly, and
pipekit's progress-collapse renders it as a single updating line.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Paul Trowbridge 2026-06-18 08:08:39 -04:00
parent 7be85a2da1
commit dc2f850530

View File

@ -325,8 +325,10 @@ public class jrunner {
BulkSource src = new BulkSource(rs, cols, dtn, trim); BulkSource src = new BulkSource(rs, cols, dtn, trim);
bulkCopy.writeToServer(src); bulkCopy.writeToServer(src);
bulkCopy.close(); bulkCopy.close();
// print the count so the trailing " rows written" line is parseable // leading \r starts a fresh line so the count doesn't concatenate
System.out.print(src.rowsWritten()); // onto the last progress tick; the trailing " rows written" makes
// it parseable.
System.out.print("\r" + src.rowsWritten());
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
System.exit(0); System.exit(0);
@ -604,6 +606,9 @@ public class jrunner {
public Object[] getRowData() throws SQLServerException { public Object[] getRowData() throws SQLServerException {
rows++; rows++;
// live progress: emit an in-place counter every 10k rows (the
// caller pulls one row at a time, so this runs during the load).
if (rows % 10000 == 0) { System.out.print("\r" + rows); System.out.flush(); }
Object[] row = new Object[cols]; Object[] row = new Object[cols];
try { try {
for (int i = 1; i <= cols; i++) { for (int i = 1; i <= cols; i++) {