|
1 | 1 | import fs from 'node:fs' |
2 | 2 | import path from 'node:path' |
3 | | -import { fileCatalog, icebergAppend, icebergCreateTable, icebergRead, loadLatestFileCatalogMetadata } from 'icebird' |
| 3 | +import { fileCatalog, icebergAppend, icebergCreateTable, icebergDataSource, icebergRead, loadLatestFileCatalogMetadata } from 'icebird' |
4 | 4 | import { createLocalIcebergIO, tableUrlForDir } from './resolver.js' |
5 | 5 | import { icebergSchemaForColumns, rowsToIcebergRecords } from './schema.js' |
6 | 6 |
|
@@ -81,3 +81,36 @@ export async function readRowsFromCursor(cursor) { |
81 | 81 | const rows = await icebergRead({ tableUrl, metadata, resolver }) |
82 | 82 | return /** @type {Record<string, unknown>[]} */ (rows) |
83 | 83 | } |
| 84 | + |
| 85 | +/** |
| 86 | + * @param {QueryCacheCursor} cursor |
| 87 | + * @param {string[]} columns |
| 88 | + * @returns {AsyncGenerator<Record<string, unknown>>} |
| 89 | + */ |
| 90 | +export async function* scanRowsFromCursor(cursor, columns) { |
| 91 | + if (!queryCacheTableExists(cursor.table_path)) return |
| 92 | + const { resolver, lister } = await createLocalIcebergIO() |
| 93 | + const tableUrl = cursor.table_url || queryCacheTableUrl(cursor.table_path) |
| 94 | + const { metadata } = await loadLatestFileCatalogMetadata({ tableUrl, resolver, lister }) |
| 95 | + if (metadata['current-snapshot-id'] === undefined || !metadata.snapshots?.length) return |
| 96 | + const source = await icebergDataSource({ tableUrl, metadata, resolver, lister }) |
| 97 | + const scan = source.scan({ columns }) |
| 98 | + for await (const row of scan.rows()) { |
| 99 | + yield await resolveAsyncRow(row, columns) |
| 100 | + } |
| 101 | +} |
| 102 | + |
| 103 | +/** |
| 104 | + * @param {import('squirreling').AsyncRow} row |
| 105 | + * @param {string[]} columns |
| 106 | + * @returns {Promise<Record<string, unknown>>} |
| 107 | + */ |
| 108 | +async function resolveAsyncRow(row, columns) { |
| 109 | + /** @type {Record<string, unknown>} */ |
| 110 | + const out = row.resolved ? { ...row.resolved } : {} |
| 111 | + for (const column of columns) { |
| 112 | + if (Object.prototype.hasOwnProperty.call(out, column)) continue |
| 113 | + out[column] = await row.cells[column]?.() |
| 114 | + } |
| 115 | + return out |
| 116 | +} |
0 commit comments