@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.
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -3
- package/dist/lib/granule.d.ts +4 -33
- package/dist/lib/granule.js +10 -61
- package/dist/models/granule.js +2 -2
- package/dist/s3search/AsyncOperationS3Search.d.ts +20 -0
- package/dist/s3search/AsyncOperationS3Search.js +29 -0
- package/dist/s3search/CollectionS3Search.d.ts +39 -0
- package/dist/s3search/CollectionS3Search.js +113 -0
- package/dist/s3search/DuckDBSearchExecutor.d.ts +36 -0
- package/dist/s3search/DuckDBSearchExecutor.js +57 -0
- package/dist/s3search/ExecutionS3Search.d.ts +20 -0
- package/dist/s3search/ExecutionS3Search.js +29 -0
- package/dist/s3search/GranuleS3Search.d.ts +31 -0
- package/dist/s3search/GranuleS3Search.js +100 -0
- package/dist/s3search/PdrS3Search.d.ts +20 -0
- package/dist/s3search/PdrS3Search.js +29 -0
- package/dist/s3search/ProviderS3Search.d.ts +20 -0
- package/dist/s3search/ProviderS3Search.js +29 -0
- package/dist/s3search/ReconciliationReportS3Search.d.ts +20 -0
- package/dist/s3search/ReconciliationReportS3Search.js +29 -0
- package/dist/s3search/RuleS3Search.d.ts +20 -0
- package/dist/s3search/RuleS3Search.js +29 -0
- package/dist/s3search/StatsS3Search.d.ts +25 -0
- package/dist/s3search/StatsS3Search.js +51 -0
- package/dist/s3search/duckdbHelpers.d.ts +43 -0
- package/dist/s3search/duckdbHelpers.js +83 -0
- package/dist/s3search/s3TableSchemas.d.ts +11 -0
- package/dist/s3search/s3TableSchemas.js +272 -0
- package/dist/search/BaseSearch.d.ts +46 -2
- package/dist/search/BaseSearch.js +84 -22
- package/dist/search/CollectionSearch.d.ts +6 -4
- package/dist/search/CollectionSearch.js +2 -3
- package/dist/search/ExecutionSearch.d.ts +1 -1
- package/dist/search/ExecutionSearch.js +3 -3
- package/dist/search/GranuleSearch.d.ts +2 -3
- package/dist/search/GranuleSearch.js +3 -3
- package/dist/search/PdrSearch.js +1 -1
- package/dist/search/ReconciliationReportSearch.js +1 -1
- package/dist/search/RuleSearch.js +4 -4
- package/dist/search/StatsSearch.d.ts +15 -4
- package/dist/search/StatsSearch.js +12 -6
- package/dist/search/field-mapping.d.ts +1 -3
- package/dist/search/field-mapping.js +40 -19
- package/dist/test-duckdb-utils.d.ts +31 -0
- package/dist/test-duckdb-utils.js +125 -0
- package/dist/test-utils.js +6 -0
- package/dist/translate/async_operations.js +7 -3
- package/dist/translate/collections.js +6 -6
- package/dist/translate/executions.js +7 -7
- package/dist/translate/granules.js +16 -11
- package/dist/translate/pdr.js +4 -4
- package/dist/translate/providers.js +2 -2
- package/dist/translate/reconciliation_reports.js +5 -4
- package/dist/translate/rules.d.ts +1 -1
- package/dist/translate/rules.js +6 -6
- package/dist/types/file.d.ts +2 -0
- package/dist/types/granule.d.ts +1 -1
- 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
|