@cumulus/db 21.3.1 → 21.3.2-testlerna.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/dist/index.d.ts +2 -1
  2. package/dist/index.js +3 -3
  3. package/dist/lib/granule.d.ts +4 -33
  4. package/dist/lib/granule.js +10 -61
  5. package/dist/models/granule.js +2 -2
  6. package/dist/s3search/AsyncOperationS3Search.d.ts +20 -0
  7. package/dist/s3search/AsyncOperationS3Search.js +29 -0
  8. package/dist/s3search/CollectionS3Search.d.ts +39 -0
  9. package/dist/s3search/CollectionS3Search.js +113 -0
  10. package/dist/s3search/DuckDBSearchExecutor.d.ts +36 -0
  11. package/dist/s3search/DuckDBSearchExecutor.js +57 -0
  12. package/dist/s3search/ExecutionS3Search.d.ts +20 -0
  13. package/dist/s3search/ExecutionS3Search.js +29 -0
  14. package/dist/s3search/GranuleS3Search.d.ts +31 -0
  15. package/dist/s3search/GranuleS3Search.js +100 -0
  16. package/dist/s3search/PdrS3Search.d.ts +20 -0
  17. package/dist/s3search/PdrS3Search.js +29 -0
  18. package/dist/s3search/ProviderS3Search.d.ts +20 -0
  19. package/dist/s3search/ProviderS3Search.js +29 -0
  20. package/dist/s3search/ReconciliationReportS3Search.d.ts +20 -0
  21. package/dist/s3search/ReconciliationReportS3Search.js +29 -0
  22. package/dist/s3search/RuleS3Search.d.ts +20 -0
  23. package/dist/s3search/RuleS3Search.js +29 -0
  24. package/dist/s3search/StatsS3Search.d.ts +25 -0
  25. package/dist/s3search/StatsS3Search.js +51 -0
  26. package/dist/s3search/duckdbHelpers.d.ts +43 -0
  27. package/dist/s3search/duckdbHelpers.js +83 -0
  28. package/dist/s3search/s3TableSchemas.d.ts +11 -0
  29. package/dist/s3search/s3TableSchemas.js +272 -0
  30. package/dist/search/BaseSearch.d.ts +46 -2
  31. package/dist/search/BaseSearch.js +84 -22
  32. package/dist/search/CollectionSearch.d.ts +6 -4
  33. package/dist/search/CollectionSearch.js +2 -3
  34. package/dist/search/ExecutionSearch.d.ts +1 -1
  35. package/dist/search/ExecutionSearch.js +3 -3
  36. package/dist/search/GranuleSearch.d.ts +2 -3
  37. package/dist/search/GranuleSearch.js +3 -3
  38. package/dist/search/PdrSearch.js +1 -1
  39. package/dist/search/ReconciliationReportSearch.js +1 -1
  40. package/dist/search/RuleSearch.js +4 -4
  41. package/dist/search/StatsSearch.d.ts +15 -4
  42. package/dist/search/StatsSearch.js +12 -6
  43. package/dist/search/field-mapping.d.ts +1 -3
  44. package/dist/search/field-mapping.js +40 -19
  45. package/dist/test-duckdb-utils.d.ts +31 -0
  46. package/dist/test-duckdb-utils.js +125 -0
  47. package/dist/test-utils.js +6 -0
  48. package/dist/translate/async_operations.js +7 -3
  49. package/dist/translate/collections.js +6 -6
  50. package/dist/translate/executions.js +7 -7
  51. package/dist/translate/granules.js +16 -11
  52. package/dist/translate/pdr.js +4 -4
  53. package/dist/translate/providers.js +2 -2
  54. package/dist/translate/reconciliation_reports.js +5 -4
  55. package/dist/translate/rules.d.ts +1 -1
  56. package/dist/translate/rules.js +6 -6
  57. package/dist/types/file.d.ts +2 -0
  58. package/dist/types/granule.d.ts +1 -1
  59. package/package.json +12 -11
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.GranuleS3Search = void 0;
7
+ const pick_1 = __importDefault(require("lodash/pick"));
8
+ const logger_1 = __importDefault(require("@cumulus/logger"));
9
+ const duckdbHelpers_1 = require("./duckdbHelpers");
10
+ const DuckDBSearchExecutor_1 = require("./DuckDBSearchExecutor");
11
+ const GranuleSearch_1 = require("../search/GranuleSearch");
12
+ const granules_1 = require("../translate/granules");
13
+ const log = new logger_1.default({ sender: '@cumulus/db/GranuleS3Search' });
14
+ /**
15
+ * Class to build and execute DuckDB search query for granules
16
+ */
17
+ class GranuleS3Search extends GranuleSearch_1.GranuleSearch {
18
+ constructor(event, dbConnection) {
19
+ super(event, false); // disables estimateTableRowCount
20
+ this.dbConnection = dbConnection;
21
+ this.duckDBSearchExecutor = new DuckDBSearchExecutor_1.DuckDBSearchExecutor({
22
+ dbConnection,
23
+ dbQueryParameters: this.dbQueryParameters,
24
+ getMetaTemplate: this._metaTemplate.bind(this),
25
+ translateRecords: this.translatePostgresRecordsToApiRecords.bind(this),
26
+ });
27
+ }
28
+ /**
29
+ * Translate postgres records to api records
30
+ *
31
+ * @param pgRecords - postgres records returned from query
32
+ * @param knexClient - DB client
33
+ * @returns translated api records
34
+ */
35
+ async translatePostgresRecordsToApiRecords(pgRecords, knexClient) {
36
+ log.debug(`translatePostgresRecordsToApiRecords number of records ${pgRecords.length} `);
37
+ const { fields, includeFullRecord } = this.dbQueryParameters;
38
+ const fileMapping = {};
39
+ const executionMapping = {};
40
+ const cumulusIds = pgRecords.map((record) => record.cumulus_id);
41
+ if (includeFullRecord) {
42
+ //get files
43
+ const files = await (0, duckdbHelpers_1.getFilesByGranuleCumulusIds)({
44
+ connection: this.dbConnection,
45
+ granuleCumulusIds: cumulusIds,
46
+ knexBuilder: knexClient,
47
+ });
48
+ files.forEach((file) => {
49
+ if (!(file.granule_cumulus_id in fileMapping)) {
50
+ fileMapping[file.granule_cumulus_id] = [];
51
+ }
52
+ fileMapping[file.granule_cumulus_id].push(file);
53
+ });
54
+ //get Executions
55
+ const executions = await (0, duckdbHelpers_1.getExecutionInfoByGranuleCumulusIds)({
56
+ connection: this.dbConnection,
57
+ granuleCumulusIds: cumulusIds,
58
+ knexBuilder: knexClient,
59
+ });
60
+ executions.forEach((execution) => {
61
+ if (!(execution.granule_cumulus_id in executionMapping)) {
62
+ executionMapping[execution.granule_cumulus_id] = execution;
63
+ }
64
+ });
65
+ }
66
+ const apiRecords = pgRecords.map((item) => {
67
+ const collectionPgRecord = {
68
+ cumulus_id: item.collection_cumulus_id,
69
+ name: item.collectionName,
70
+ version: item.collectionVersion,
71
+ };
72
+ const executionUrls = executionMapping[item.cumulus_id]?.url
73
+ ? [{ url: executionMapping[item.cumulus_id].url }]
74
+ : [];
75
+ const pdr = item.pdrName ? { name: item.pdrName } : undefined;
76
+ const providerPgRecord = item.providerName ? { name: item.providerName } : undefined;
77
+ const fileRecords = fileMapping[item.cumulus_id] || [];
78
+ const apiRecord = (0, granules_1.translatePostgresGranuleToApiGranuleWithoutDbQuery)({
79
+ granulePgRecord: item,
80
+ collectionPgRecord,
81
+ pdr,
82
+ providerPgRecord,
83
+ files: fileRecords,
84
+ executionUrls,
85
+ });
86
+ return fields ? (0, pick_1.default)(apiRecord, fields) : apiRecord;
87
+ });
88
+ return apiRecords;
89
+ }
90
+ /**
91
+ * Build and execute search query
92
+ *
93
+ * @returns search result
94
+ */
95
+ async query() {
96
+ return this.duckDBSearchExecutor.query((knexBuilder) => this.buildSearch(knexBuilder));
97
+ }
98
+ }
99
+ exports.GranuleS3Search = GranuleS3Search;
100
+ //# sourceMappingURL=GranuleS3Search.js.map
@@ -0,0 +1,20 @@
1
+ import { DuckDBConnection } from '@duckdb/node-api';
2
+ import { PdrSearch } from '../search/PdrSearch';
3
+ import { QueryEvent } from '../types/search';
4
+ /**
5
+ * Class to build and execute DuckDB search query for PDRs
6
+ */
7
+ export declare class PdrS3Search extends PdrSearch {
8
+ private duckDBSearchExecutor;
9
+ constructor(event: QueryEvent, dbConnection: DuckDBConnection);
10
+ /**
11
+ * Build and execute search query
12
+ *
13
+ * @returns search result
14
+ */
15
+ query(): Promise<{
16
+ meta: import("../search/BaseSearch").Meta;
17
+ results: any[];
18
+ }>;
19
+ }
20
+ //# sourceMappingURL=PdrS3Search.d.ts.map
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PdrS3Search = void 0;
4
+ const DuckDBSearchExecutor_1 = require("./DuckDBSearchExecutor");
5
+ const PdrSearch_1 = require("../search/PdrSearch");
6
+ /**
7
+ * Class to build and execute DuckDB search query for PDRs
8
+ */
9
+ class PdrS3Search extends PdrSearch_1.PdrSearch {
10
+ constructor(event, dbConnection) {
11
+ super(event);
12
+ this.duckDBSearchExecutor = new DuckDBSearchExecutor_1.DuckDBSearchExecutor({
13
+ dbConnection,
14
+ dbQueryParameters: this.dbQueryParameters,
15
+ getMetaTemplate: this._metaTemplate.bind(this),
16
+ translateRecords: this.translatePostgresRecordsToApiRecords.bind(this),
17
+ });
18
+ }
19
+ /**
20
+ * Build and execute search query
21
+ *
22
+ * @returns search result
23
+ */
24
+ async query() {
25
+ return this.duckDBSearchExecutor.query((knexBuilder) => this.buildSearch(knexBuilder));
26
+ }
27
+ }
28
+ exports.PdrS3Search = PdrS3Search;
29
+ //# sourceMappingURL=PdrS3Search.js.map
@@ -0,0 +1,20 @@
1
+ import { DuckDBConnection } from '@duckdb/node-api';
2
+ import { ProviderSearch } from '../search/ProviderSearch';
3
+ import { QueryEvent } from '../types/search';
4
+ /**
5
+ * Class to build and execute DuckDB search query for providers
6
+ */
7
+ export declare class ProviderS3Search extends ProviderSearch {
8
+ private duckDBSearchExecutor;
9
+ constructor(event: QueryEvent, dbConnection: DuckDBConnection);
10
+ /**
11
+ * Build and execute search query
12
+ *
13
+ * @returns search result
14
+ */
15
+ query(): Promise<{
16
+ meta: import("../search/BaseSearch").Meta;
17
+ results: any[];
18
+ }>;
19
+ }
20
+ //# sourceMappingURL=ProviderS3Search.d.ts.map
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProviderS3Search = void 0;
4
+ const DuckDBSearchExecutor_1 = require("./DuckDBSearchExecutor");
5
+ const ProviderSearch_1 = require("../search/ProviderSearch");
6
+ /**
7
+ * Class to build and execute DuckDB search query for providers
8
+ */
9
+ class ProviderS3Search extends ProviderSearch_1.ProviderSearch {
10
+ constructor(event, dbConnection) {
11
+ super(event);
12
+ this.duckDBSearchExecutor = new DuckDBSearchExecutor_1.DuckDBSearchExecutor({
13
+ dbConnection,
14
+ dbQueryParameters: this.dbQueryParameters,
15
+ getMetaTemplate: this._metaTemplate.bind(this),
16
+ translateRecords: this.translatePostgresRecordsToApiRecords.bind(this),
17
+ });
18
+ }
19
+ /**
20
+ * Build and execute search query
21
+ *
22
+ * @returns search result
23
+ */
24
+ async query() {
25
+ return this.duckDBSearchExecutor.query((knexBuilder) => this.buildSearch(knexBuilder));
26
+ }
27
+ }
28
+ exports.ProviderS3Search = ProviderS3Search;
29
+ //# sourceMappingURL=ProviderS3Search.js.map
@@ -0,0 +1,20 @@
1
+ import { DuckDBConnection } from '@duckdb/node-api';
2
+ import { ReconciliationReportSearch } from '../search/ReconciliationReportSearch';
3
+ import { QueryEvent } from '../types/search';
4
+ /**
5
+ * Class to build and execute DuckDB search query for Reconciliation Report
6
+ */
7
+ export declare class ReconciliationReportS3Search extends ReconciliationReportSearch {
8
+ private duckDBSearchExecutor;
9
+ constructor(event: QueryEvent, dbConnection: DuckDBConnection);
10
+ /**
11
+ * Build and execute search query
12
+ *
13
+ * @returns search result
14
+ */
15
+ query(): Promise<{
16
+ meta: import("../search/BaseSearch").Meta;
17
+ results: any[];
18
+ }>;
19
+ }
20
+ //# sourceMappingURL=ReconciliationReportS3Search.d.ts.map
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ReconciliationReportS3Search = void 0;
4
+ const DuckDBSearchExecutor_1 = require("./DuckDBSearchExecutor");
5
+ const ReconciliationReportSearch_1 = require("../search/ReconciliationReportSearch");
6
+ /**
7
+ * Class to build and execute DuckDB search query for Reconciliation Report
8
+ */
9
+ class ReconciliationReportS3Search extends ReconciliationReportSearch_1.ReconciliationReportSearch {
10
+ constructor(event, dbConnection) {
11
+ super(event);
12
+ this.duckDBSearchExecutor = new DuckDBSearchExecutor_1.DuckDBSearchExecutor({
13
+ dbConnection,
14
+ dbQueryParameters: this.dbQueryParameters,
15
+ getMetaTemplate: this._metaTemplate.bind(this),
16
+ translateRecords: this.translatePostgresRecordsToApiRecords.bind(this),
17
+ });
18
+ }
19
+ /**
20
+ * Build and execute search query
21
+ *
22
+ * @returns search result
23
+ */
24
+ async query() {
25
+ return this.duckDBSearchExecutor.query((knexBuilder) => this.buildSearch(knexBuilder));
26
+ }
27
+ }
28
+ exports.ReconciliationReportS3Search = ReconciliationReportS3Search;
29
+ //# sourceMappingURL=ReconciliationReportS3Search.js.map
@@ -0,0 +1,20 @@
1
+ import { DuckDBConnection } from '@duckdb/node-api';
2
+ import { RuleSearch } from '../search/RuleSearch';
3
+ import { QueryEvent } from '../types/search';
4
+ /**
5
+ * Class to build and execute DuckDB search query for rules
6
+ */
7
+ export declare class RuleS3Search extends RuleSearch {
8
+ private duckDBSearchExecutor;
9
+ constructor(event: QueryEvent, dbConnection: DuckDBConnection);
10
+ /**
11
+ * Build and execute search query
12
+ *
13
+ * @returns search result
14
+ */
15
+ query(): Promise<{
16
+ meta: import("../search/BaseSearch").Meta;
17
+ results: any[];
18
+ }>;
19
+ }
20
+ //# sourceMappingURL=RuleS3Search.d.ts.map
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RuleS3Search = void 0;
4
+ const DuckDBSearchExecutor_1 = require("./DuckDBSearchExecutor");
5
+ const RuleSearch_1 = require("../search/RuleSearch");
6
+ /**
7
+ * Class to build and execute DuckDB search query for rules
8
+ */
9
+ class RuleS3Search extends RuleSearch_1.RuleSearch {
10
+ constructor(event, dbConnection) {
11
+ super(event);
12
+ this.duckDBSearchExecutor = new DuckDBSearchExecutor_1.DuckDBSearchExecutor({
13
+ dbConnection,
14
+ dbQueryParameters: this.dbQueryParameters,
15
+ getMetaTemplate: this._metaTemplate.bind(this),
16
+ translateRecords: this.translatePostgresRecordsToApiRecords.bind(this),
17
+ });
18
+ }
19
+ /**
20
+ * Build and execute search query
21
+ *
22
+ * @returns search result
23
+ */
24
+ async query() {
25
+ return this.duckDBSearchExecutor.query((knexBuilder) => this.buildSearch(knexBuilder));
26
+ }
27
+ }
28
+ exports.RuleS3Search = RuleS3Search;
29
+ //# sourceMappingURL=RuleS3Search.js.map
@@ -0,0 +1,25 @@
1
+ import { DuckDBConnection } from '@duckdb/node-api';
2
+ import { QueryEvent } from '../types/search';
3
+ import { ApiAggregateResult, StatsSearch, SummaryResult } from '../search/StatsSearch';
4
+ /**
5
+ * A class to query postgres for the STATS and STATS/AGGREGATE endpoints
6
+ */
7
+ declare class StatsS3Search extends StatsSearch {
8
+ private dbConnection;
9
+ private knexBuilder;
10
+ constructor(event: QueryEvent, type: string, dbConnection: DuckDBConnection);
11
+ /**
12
+ * Queries postgres for a summary of statistics around the granules in the system
13
+ *
14
+ * @returns the postgres aggregations based on query
15
+ */
16
+ summary(): Promise<SummaryResult>;
17
+ /**
18
+ * Executes the aggregate search query
19
+ *
20
+ * @returns the aggregate query results in api format
21
+ */
22
+ aggregate(): Promise<ApiAggregateResult>;
23
+ }
24
+ export { StatsS3Search };
25
+ //# sourceMappingURL=StatsS3Search.d.ts.map
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.StatsS3Search = void 0;
7
+ const knex_1 = require("knex");
8
+ const logger_1 = __importDefault(require("@cumulus/logger"));
9
+ const StatsSearch_1 = require("../search/StatsSearch");
10
+ const duckdbHelpers_1 = require("./duckdbHelpers");
11
+ const log = new logger_1.default({ sender: '@cumulus/db/StatsSearch' });
12
+ /**
13
+ * A class to query postgres for the STATS and STATS/AGGREGATE endpoints
14
+ */
15
+ class StatsS3Search extends StatsSearch_1.StatsSearch {
16
+ constructor(event, type, dbConnection) {
17
+ super(event, type);
18
+ this.dbConnection = dbConnection;
19
+ // Use 'pg' dialect to generate DuckDB-compatible SQL ($1, $2, etc.)
20
+ this.knexBuilder = (0, knex_1.knex)({ client: 'pg' });
21
+ }
22
+ /**
23
+ * Queries postgres for a summary of statistics around the granules in the system
24
+ *
25
+ * @returns the postgres aggregations based on query
26
+ */
27
+ async summary() {
28
+ const aggregateQuery = this.buildSummaryQuery(this.knexBuilder);
29
+ log.debug(`summary about to execute query: ${aggregateQuery?.toSQL().sql}`);
30
+ const { sql, bindings } = aggregateQuery.toSQL().toNative();
31
+ const reader = await this.dbConnection.runAndReadAll(sql, (0, duckdbHelpers_1.prepareBindings)([...bindings]) // prepareBindings must be imported/defined in scope
32
+ );
33
+ const aggregateQueryRes = reader.getRowObjectsJson();
34
+ return this.formatSummaryResult(aggregateQueryRes[0]);
35
+ }
36
+ /**
37
+ * Executes the aggregate search query
38
+ *
39
+ * @returns the aggregate query results in api format
40
+ */
41
+ async aggregate() {
42
+ const { searchQuery } = this.buildSearch(this.knexBuilder);
43
+ const { sql, bindings } = searchQuery.toSQL().toNative();
44
+ const reader = await this.dbConnection.runAndReadAll(sql, (0, duckdbHelpers_1.prepareBindings)([...bindings]) // prepareBindings must be imported/defined in scope
45
+ );
46
+ const records = reader.getRowObjectsJson();
47
+ return this.formatAggregateResult(records);
48
+ }
49
+ }
50
+ exports.StatsS3Search = StatsS3Search;
51
+ //# sourceMappingURL=StatsS3Search.js.map
@@ -0,0 +1,43 @@
1
+ import { DuckDBValue, DuckDBConnection } from '@duckdb/node-api';
2
+ import { Knex } from 'knex';
3
+ import { PostgresFileRecord } from '../types/file';
4
+ export declare function prepareBindings(bindings: ReadonlyArray<any>): DuckDBValue[];
5
+ /**
6
+ * Returns execution records sorted by most recent first for an input
7
+ * set of Granule Cumulus IDs.
8
+ *
9
+ * @param {object} params - The function parameters.
10
+ * @param {DuckDBConnection} params.connection - The active DuckDB connection.
11
+ * @param {number[]} params.granuleCumulusIds - Array of granule IDs to filter by.
12
+ * @param {Knex} [params.knexBuilder] - Optional Knex instance (defaults to 'pg' client).
13
+ * @param {number} [params.limit] - Optional limit for the number of records returned.
14
+ * @returns {Promise<{ granule_cumulus_id: number, url: string }[]>}
15
+ * Array of objects containing granule_cumulus_id and execution url, sorted by timestamp desc.
16
+ */
17
+ export declare const getExecutionInfoByGranuleCumulusIds: ({ connection, granuleCumulusIds, knexBuilder, limit, }: {
18
+ connection: DuckDBConnection;
19
+ granuleCumulusIds: number[];
20
+ knexBuilder: Knex;
21
+ limit?: number | undefined;
22
+ }) => Promise<{
23
+ granule_cumulus_id: number;
24
+ url: string;
25
+ }[]>;
26
+ /**
27
+ * Searches for file records by granule cumulus IDs using a DuckDB connection.
28
+ *
29
+ * @param params - Function parameters
30
+ * @param params.connection - Active DuckDB connection used to execute the query
31
+ * @param params.granuleCumulusIds - Array of granule Cumulus IDs to filter by
32
+ * @param [params.columns='*'] - Columns to select (string or string array)
33
+ * @param [params.knexBuilder] - Optional Knex instance (defaults to PostgreSQL dialect)
34
+ * @returns Promise resolving to an array of normalized `PostgresFileRecord` objects
35
+ * @throws If the DuckDB query execution fails
36
+ */
37
+ export declare const getFilesByGranuleCumulusIds: ({ connection, granuleCumulusIds, columns, knexBuilder, }: {
38
+ connection: DuckDBConnection;
39
+ granuleCumulusIds: number[];
40
+ columns?: string | string[] | undefined;
41
+ knexBuilder?: Knex<any, any[]> | undefined;
42
+ }) => Promise<PostgresFileRecord[]>;
43
+ //# sourceMappingURL=duckdbHelpers.d.ts.map
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getFilesByGranuleCumulusIds = exports.getExecutionInfoByGranuleCumulusIds = exports.prepareBindings = void 0;
7
+ const knex_1 = require("knex");
8
+ const logger_1 = __importDefault(require("@cumulus/logger"));
9
+ const tables_1 = require("../tables");
10
+ const log = new logger_1.default({ sender: '@cumulus/db/duckdbHelpers' });
11
+ function prepareBindings(bindings) {
12
+ return bindings.map((value) => {
13
+ if (value instanceof Date)
14
+ return value.toISOString();
15
+ if (value !== null && typeof value === 'object')
16
+ return JSON.stringify(value);
17
+ return value;
18
+ });
19
+ }
20
+ exports.prepareBindings = prepareBindings;
21
+ /**
22
+ * Returns execution records sorted by most recent first for an input
23
+ * set of Granule Cumulus IDs.
24
+ *
25
+ * @param {object} params - The function parameters.
26
+ * @param {DuckDBConnection} params.connection - The active DuckDB connection.
27
+ * @param {number[]} params.granuleCumulusIds - Array of granule IDs to filter by.
28
+ * @param {Knex} [params.knexBuilder] - Optional Knex instance (defaults to 'pg' client).
29
+ * @param {number} [params.limit] - Optional limit for the number of records returned.
30
+ * @returns {Promise<{ granule_cumulus_id: number, url: string }[]>}
31
+ * Array of objects containing granule_cumulus_id and execution url, sorted by timestamp desc.
32
+ */
33
+ const getExecutionInfoByGranuleCumulusIds = async ({ connection, granuleCumulusIds, knexBuilder = (0, knex_1.knex)({ client: 'pg' }), limit, }) => {
34
+ const knexQuery = knexBuilder(tables_1.TableNames.executions)
35
+ .select([
36
+ `${tables_1.TableNames.executions}.url`,
37
+ `${tables_1.TableNames.granulesExecutions}.granule_cumulus_id`,
38
+ ])
39
+ .join(tables_1.TableNames.granulesExecutions, `${tables_1.TableNames.executions}.cumulus_id`, `${tables_1.TableNames.granulesExecutions}.execution_cumulus_id`)
40
+ .whereIn(`${tables_1.TableNames.granulesExecutions}.granule_cumulus_id`, granuleCumulusIds)
41
+ .orderBy(`${tables_1.TableNames.executions}.timestamp`, 'desc');
42
+ if (limit)
43
+ knexQuery.limit(limit);
44
+ const { sql, bindings } = knexQuery.toSQL().toNative();
45
+ log.debug(`getExecutionInfoByGranuleCumulusIds query: ${sql}`);
46
+ // Use spread operator to convert ReadonlyArray to mutable array
47
+ const reader = await connection.runAndReadAll(sql, prepareBindings([...bindings]));
48
+ return reader.getRowObjectsJson();
49
+ };
50
+ exports.getExecutionInfoByGranuleCumulusIds = getExecutionInfoByGranuleCumulusIds;
51
+ /**
52
+ * Searches for file records by granule cumulus IDs using a DuckDB connection.
53
+ *
54
+ * @param params - Function parameters
55
+ * @param params.connection - Active DuckDB connection used to execute the query
56
+ * @param params.granuleCumulusIds - Array of granule Cumulus IDs to filter by
57
+ * @param [params.columns='*'] - Columns to select (string or string array)
58
+ * @param [params.knexBuilder] - Optional Knex instance (defaults to PostgreSQL dialect)
59
+ * @returns Promise resolving to an array of normalized `PostgresFileRecord` objects
60
+ * @throws If the DuckDB query execution fails
61
+ */
62
+ const getFilesByGranuleCumulusIds = async ({ connection, granuleCumulusIds, columns = '*', knexBuilder = (0, knex_1.knex)({ client: 'pg' }), }) => {
63
+ const knexQuery = knexBuilder(tables_1.TableNames.files)
64
+ .select(columns)
65
+ .whereIn('granule_cumulus_id', granuleCumulusIds);
66
+ const { sql, bindings } = knexQuery.toSQL().toNative();
67
+ // Execute using DuckDB connection
68
+ const reader = await connection.runAndReadAll(sql, prepareBindings([...bindings]) // prepareBindings must be imported/defined in scope
69
+ );
70
+ const rows = reader.getRowObjectsJson();
71
+ // Mapping resolves TS errors and handles DuckDB type conversions
72
+ return rows.map((row) => ({
73
+ ...row,
74
+ // Ensure IDs are numbers (handles DuckDB BigInt/String return types)
75
+ cumulus_id: Number(row.cumulus_id),
76
+ granule_cumulus_id: Number(row.granule_cumulus_id),
77
+ // Convert ISO timestamp strings back to JS Date objects
78
+ created_at: row.created_at ? new Date(row.created_at) : undefined,
79
+ updated_at: row.updated_at ? new Date(row.updated_at) : undefined,
80
+ }));
81
+ };
82
+ exports.getFilesByGranuleCumulusIds = getFilesByGranuleCumulusIds;
83
+ //# sourceMappingURL=duckdbHelpers.js.map
@@ -0,0 +1,11 @@
1
+ export declare const asyncOperationsS3TableSql: (tableName?: string) => string;
2
+ export declare const collectionsS3TableSql: (tableName?: string) => string;
3
+ export declare const executionsS3TableSql: (tableName?: string) => string;
4
+ export declare const filesS3TableSql: (tableName?: string) => string;
5
+ export declare const granulesS3TableSql: (tableName?: string) => string;
6
+ export declare const granulesExecutionsS3TableSql: (tableName?: string) => string;
7
+ export declare const pdrsS3TableSql: (tableName?: string) => string;
8
+ export declare const providersS3TableSql: (tableName?: string) => string;
9
+ export declare const reconciliationReportsS3TableSql: (tableName?: string) => string;
10
+ export declare const rulesS3TableSql: (tableName?: string) => string;
11
+ //# sourceMappingURL=s3TableSchemas.d.ts.map