@cumulus/db 9.8.0 → 9.9.2

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/config.d.ts CHANGED
@@ -8,6 +8,7 @@ export declare const localStackConnectionEnv: {
8
8
  PG_DATABASE: string;
9
9
  PG_PORT: string;
10
10
  };
11
+ export declare const isKnexDebugEnabled: (env?: NodeJS.ProcessEnv) => boolean;
11
12
  export declare const getSecretConnectionConfig: (SecretId: string, secretsManager: AWS.SecretsManager) => Promise<Knex.PgConnectionConfig>;
12
13
  export declare const getConnectionConfigEnv: (env: NodeJS.ProcessEnv) => Knex.PgConnectionConfig;
13
14
  /**
package/dist/config.js CHANGED
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getKnexConfig = exports.getConnectionConfig = exports.getConnectionConfigEnv = exports.getSecretConnectionConfig = exports.localStackConnectionEnv = void 0;
6
+ exports.getKnexConfig = exports.getConnectionConfig = exports.getConnectionConfigEnv = exports.getSecretConnectionConfig = exports.isKnexDebugEnabled = exports.localStackConnectionEnv = void 0;
7
7
  const aws_sdk_1 = __importDefault(require("aws-sdk"));
8
8
  const common_1 = require("@cumulus/common");
9
9
  exports.localStackConnectionEnv = {
@@ -13,6 +13,8 @@ exports.localStackConnectionEnv = {
13
13
  PG_DATABASE: 'postgres',
14
14
  PG_PORT: '5432',
15
15
  };
16
+ const isKnexDebugEnabled = (env = {}) => env.KNEX_DEBUG === 'true';
17
+ exports.isKnexDebugEnabled = isKnexDebugEnabled;
16
18
  const getSecretConnectionConfig = async (SecretId, secretsManager) => {
17
19
  var _a;
18
20
  const response = await secretsManager.getSecretValue({ SecretId }).promise();
@@ -110,7 +112,7 @@ const getKnexConfig = async ({ env = process.env, secretsManager = new aws_sdk_1
110
112
  const knexConfig = {
111
113
  client: 'pg',
112
114
  connection: await (0, exports.getConnectionConfig)({ env, secretsManager }),
113
- debug: env.KNEX_DEBUG === 'true',
115
+ debug: (0, exports.isKnexDebugEnabled)(env),
114
116
  asyncStackTraces: env.KNEX_ASYNC_STACK_TRACES === 'true',
115
117
  pool: {
116
118
  min: 0,
@@ -44,16 +44,37 @@ const log = new logger_1.default({ sender: '@cumulus/db/connection' });
44
44
  * @returns {Promise<Knex>} a Knex configuration object that has returned at least one query
45
45
  */
46
46
  const getKnexClient = async ({ env = process.env, secretsManager = new aws_sdk_1.default.SecretsManager(), knexLogger = log, } = {}) => {
47
+ if ((0, config_1.isKnexDebugEnabled)(env)) {
48
+ knexLogger.info('Initializing connection pool...');
49
+ }
47
50
  const knexConfig = await (0, config_1.getKnexConfig)({ env, secretsManager });
48
51
  const knexClient = (0, knex_1.knex)(knexConfig);
49
- //@ts-ignore
50
- // context is an internal object that isn't typed
51
- // this is needed to force tarn to log per-retry failures
52
- // and allow propagateCreateError to be set `false`
53
- knexClient.context.client.pool.on('createFail', (_, error) => {
54
- knexLogger.warn('knex failed on attempted connection', error);
55
- throw error;
56
- });
52
+ if ((0, config_1.isKnexDebugEnabled)(env)) {
53
+ //@ts-ignore
54
+ // context is an internal object that isn't typed
55
+ // this is needed to force tarn to log per-retry failures
56
+ // and allow propagateCreateError to be set `false`
57
+ knexClient.context.client.pool.on('createFail', (_, error) => {
58
+ knexLogger.warn('knex failed on attempted connection', error);
59
+ throw error;
60
+ });
61
+ //@ts-ignore
62
+ knexClient.context.client.pool.on('createSuccess', (_, resource) => {
63
+ knexLogger.info(`added connection to pool: ${JSON.stringify(resource)}`);
64
+ });
65
+ //@ts-ignore
66
+ knexClient.context.client.pool.on('acquireSuccess', (_, resource) => {
67
+ knexLogger.info(`acquired connection from pool: ${JSON.stringify(resource)}`);
68
+ });
69
+ //@ts-ignore
70
+ knexClient.context.client.pool.on('release', (resource) => {
71
+ knexLogger.info(`released connection from pool: ${JSON.stringify(resource)}`);
72
+ });
73
+ //@ts-ignore
74
+ knexClient.context.client.pool.on('poolDestroySuccess', () => {
75
+ knexLogger.info('pool is destroyed');
76
+ });
77
+ }
57
78
  return knexClient;
58
79
  };
59
80
  exports.getKnexClient = getKnexClient;
package/dist/index.d.ts CHANGED
@@ -15,14 +15,14 @@ export { PostgresGranule, PostgresGranuleRecord, } from './types/granule';
15
15
  export { PostgresPdr, PostgresPdrRecord, } from './types/pdr';
16
16
  export { PostgresFile, PostgresFileRecord, } from './types/file';
17
17
  export { translateApiAsyncOperationToPostgresAsyncOperation } from './translate/async_operations';
18
- export { translateApiFiletoPostgresFile, } from './translate/file';
18
+ export { translateApiFiletoPostgresFile, translatePostgresFileToApiFile, } from './translate/file';
19
19
  export { translateApiCollectionToPostgresCollection } from './translate/collections';
20
20
  export { translateApiProviderToPostgresProvider, } from './translate/providers';
21
21
  export { translateApiRuleToPostgresRule } from './translate/rules';
22
22
  export { translateApiExecutionToPostgresExecution, translatePostgresExecutionToApiExecution, } from './translate/executions';
23
- export { translateApiGranuleToPostgresGranule } from './translate/granules';
23
+ export { translateApiGranuleToPostgresGranule, translatePostgresGranuleToApiGranule, } from './translate/granules';
24
24
  export { translateApiPdrToPostgresPdr } from './translate/pdrs';
25
- export { executionArnsFromGranuleIdsAndWorkflowNames, newestExecutionArnFromGranuleIdWorkflowName, getWorkflowNameIntersectFromGranuleIds, } from './lib/execution';
25
+ export { executionArnsFromGranuleIdsAndWorkflowNames, newestExecutionArnFromGranuleIdWorkflowName, getWorkflowNameIntersectFromGranuleIds, getApiExecutionCumulusIds, getApiGranuleExecutionCumulusIdsByExecution, getExecutionArnsByGranuleCumulusId, } from './lib/execution';
26
26
  export { getApiGranuleCumulusIds, getApiGranuleExecutionCumulusIds, upsertGranuleWithExecutionJoinRecord, } from './lib/granule';
27
27
  export { AsyncOperationPgModel } from './models/async_operation';
28
28
  export { BasePgModel } from './models/base';
package/dist/index.js CHANGED
@@ -19,7 +19,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
19
19
  return result;
20
20
  };
21
21
  Object.defineProperty(exports, "__esModule", { value: true });
22
- exports.RulePgModel = exports.ProviderPgModel = exports.PdrPgModel = exports.GranulesExecutionsPgModel = exports.GranulePgModel = exports.FilePgModel = exports.ExecutionPgModel = exports.CollectionPgModel = exports.BasePgModel = exports.AsyncOperationPgModel = exports.upsertGranuleWithExecutionJoinRecord = exports.getApiGranuleExecutionCumulusIds = exports.getApiGranuleCumulusIds = exports.getWorkflowNameIntersectFromGranuleIds = exports.newestExecutionArnFromGranuleIdWorkflowName = exports.executionArnsFromGranuleIdsAndWorkflowNames = exports.translateApiPdrToPostgresPdr = exports.translateApiGranuleToPostgresGranule = exports.translatePostgresExecutionToApiExecution = exports.translateApiExecutionToPostgresExecution = exports.translateApiRuleToPostgresRule = exports.translateApiProviderToPostgresProvider = exports.translateApiCollectionToPostgresCollection = exports.translateApiFiletoPostgresFile = exports.translateApiAsyncOperationToPostgresAsyncOperation = exports.nullifyUndefinedProviderValues = exports.validateProviderHost = exports.migrationDir = exports.TableNames = exports.createRejectableTransaction = exports.localStackConnectionEnv = exports.getKnexConfig = exports.getKnexClient = exports.generateLocalTestDb = exports.fakeRuleRecordFactory = exports.fakeProviderRecordFactory = exports.fakePdrRecordFactory = exports.fakeGranuleRecordFactory = exports.fakeFileRecordFactory = exports.fakeExecutionRecordFactory = exports.fakeCollectionRecordFactory = exports.fakeAsyncOperationRecordFactory = exports.destroyLocalTestDb = exports.deleteTestDatabase = exports.createTestDatabase = exports.Knex = void 0;
22
+ exports.ProviderPgModel = exports.PdrPgModel = exports.GranulesExecutionsPgModel = exports.GranulePgModel = exports.FilePgModel = exports.ExecutionPgModel = exports.CollectionPgModel = exports.BasePgModel = exports.AsyncOperationPgModel = exports.upsertGranuleWithExecutionJoinRecord = exports.getApiGranuleExecutionCumulusIds = exports.getApiGranuleCumulusIds = exports.getExecutionArnsByGranuleCumulusId = exports.getApiGranuleExecutionCumulusIdsByExecution = exports.getApiExecutionCumulusIds = exports.getWorkflowNameIntersectFromGranuleIds = exports.newestExecutionArnFromGranuleIdWorkflowName = exports.executionArnsFromGranuleIdsAndWorkflowNames = exports.translateApiPdrToPostgresPdr = exports.translatePostgresGranuleToApiGranule = exports.translateApiGranuleToPostgresGranule = exports.translatePostgresExecutionToApiExecution = exports.translateApiExecutionToPostgresExecution = exports.translateApiRuleToPostgresRule = exports.translateApiProviderToPostgresProvider = exports.translateApiCollectionToPostgresCollection = exports.translatePostgresFileToApiFile = exports.translateApiFiletoPostgresFile = exports.translateApiAsyncOperationToPostgresAsyncOperation = exports.nullifyUndefinedProviderValues = exports.validateProviderHost = exports.migrationDir = exports.TableNames = exports.createRejectableTransaction = exports.localStackConnectionEnv = exports.getKnexConfig = exports.getKnexClient = exports.generateLocalTestDb = exports.fakeRuleRecordFactory = exports.fakeProviderRecordFactory = exports.fakePdrRecordFactory = exports.fakeGranuleRecordFactory = exports.fakeFileRecordFactory = exports.fakeExecutionRecordFactory = exports.fakeCollectionRecordFactory = exports.fakeAsyncOperationRecordFactory = exports.destroyLocalTestDb = exports.deleteTestDatabase = exports.createTestDatabase = exports.Knex = void 0;
23
+ exports.RulePgModel = void 0;
23
24
  const path = __importStar(require("path"));
24
25
  var knex_1 = require("knex");
25
26
  Object.defineProperty(exports, "Knex", { enumerable: true, get: function () { return knex_1.Knex; } });
@@ -53,6 +54,7 @@ var async_operations_1 = require("./translate/async_operations");
53
54
  Object.defineProperty(exports, "translateApiAsyncOperationToPostgresAsyncOperation", { enumerable: true, get: function () { return async_operations_1.translateApiAsyncOperationToPostgresAsyncOperation; } });
54
55
  var file_1 = require("./translate/file");
55
56
  Object.defineProperty(exports, "translateApiFiletoPostgresFile", { enumerable: true, get: function () { return file_1.translateApiFiletoPostgresFile; } });
57
+ Object.defineProperty(exports, "translatePostgresFileToApiFile", { enumerable: true, get: function () { return file_1.translatePostgresFileToApiFile; } });
56
58
  var collections_1 = require("./translate/collections");
57
59
  Object.defineProperty(exports, "translateApiCollectionToPostgresCollection", { enumerable: true, get: function () { return collections_1.translateApiCollectionToPostgresCollection; } });
58
60
  var providers_1 = require("./translate/providers");
@@ -64,12 +66,16 @@ Object.defineProperty(exports, "translateApiExecutionToPostgresExecution", { enu
64
66
  Object.defineProperty(exports, "translatePostgresExecutionToApiExecution", { enumerable: true, get: function () { return executions_1.translatePostgresExecutionToApiExecution; } });
65
67
  var granules_1 = require("./translate/granules");
66
68
  Object.defineProperty(exports, "translateApiGranuleToPostgresGranule", { enumerable: true, get: function () { return granules_1.translateApiGranuleToPostgresGranule; } });
69
+ Object.defineProperty(exports, "translatePostgresGranuleToApiGranule", { enumerable: true, get: function () { return granules_1.translatePostgresGranuleToApiGranule; } });
67
70
  var pdrs_1 = require("./translate/pdrs");
68
71
  Object.defineProperty(exports, "translateApiPdrToPostgresPdr", { enumerable: true, get: function () { return pdrs_1.translateApiPdrToPostgresPdr; } });
69
72
  var execution_1 = require("./lib/execution");
70
73
  Object.defineProperty(exports, "executionArnsFromGranuleIdsAndWorkflowNames", { enumerable: true, get: function () { return execution_1.executionArnsFromGranuleIdsAndWorkflowNames; } });
71
74
  Object.defineProperty(exports, "newestExecutionArnFromGranuleIdWorkflowName", { enumerable: true, get: function () { return execution_1.newestExecutionArnFromGranuleIdWorkflowName; } });
72
75
  Object.defineProperty(exports, "getWorkflowNameIntersectFromGranuleIds", { enumerable: true, get: function () { return execution_1.getWorkflowNameIntersectFromGranuleIds; } });
76
+ Object.defineProperty(exports, "getApiExecutionCumulusIds", { enumerable: true, get: function () { return execution_1.getApiExecutionCumulusIds; } });
77
+ Object.defineProperty(exports, "getApiGranuleExecutionCumulusIdsByExecution", { enumerable: true, get: function () { return execution_1.getApiGranuleExecutionCumulusIdsByExecution; } });
78
+ Object.defineProperty(exports, "getExecutionArnsByGranuleCumulusId", { enumerable: true, get: function () { return execution_1.getExecutionArnsByGranuleCumulusId; } });
73
79
  var granule_1 = require("./lib/granule");
74
80
  Object.defineProperty(exports, "getApiGranuleCumulusIds", { enumerable: true, get: function () { return granule_1.getApiGranuleCumulusIds; } });
75
81
  Object.defineProperty(exports, "getApiGranuleExecutionCumulusIds", { enumerable: true, get: function () { return granule_1.getApiGranuleExecutionCumulusIds; } });
@@ -1,7 +1,20 @@
1
1
  import { Knex } from 'knex';
2
+ import { ExecutionPgModel } from '../models/execution';
3
+ import { GranulesExecutionsPgModel } from '../models/granules-executions';
2
4
  export interface ArnRecord {
3
5
  arn: string;
4
6
  }
7
+ /**
8
+ * Returns a list of executionArns sorted by most recent first, for an input
9
+ * Granule Cumulus ID.
10
+ *
11
+ * @param {Knex | Knex.Transaction} knexOrTransaction
12
+ * Knex client for reading from RDS database
13
+ * @param {number} granuleCumulusId - The primary ID for a Granule
14
+ * @param {number} limit - limit to number of executions to query
15
+ * @returns {Promise<ArnRecord[]>} - Array of arn objects with the most recent first.
16
+ */
17
+ export declare const getExecutionArnsByGranuleCumulusId: (knexOrTransaction: Knex | Knex.Transaction, granuleCumulusId: Number, limit?: number | undefined) => Promise<ArnRecord[]>;
5
18
  /**
6
19
  * Returns a list of executionArns sorted by most recent first, for an input
7
20
  * list of granuleIds and workflowNames.
@@ -33,4 +46,29 @@ export declare const newestExecutionArnFromGranuleIdWorkflowName: (granuleId: st
33
46
  * @throws {RecordNotFound}
34
47
  */
35
48
  export declare const getWorkflowNameIntersectFromGranuleIds: (knexOrTransaction: Knex | Knex.Transaction, granuleCumulusIds: Array<number> | number) => Promise<Array<string>>;
49
+ /**
50
+ * Get cumulus IDs for list of executions
51
+ *
52
+ * @param {Knex | Knex.Transaction} knexOrTransaction -
53
+ * DB client or transaction
54
+ * @param {Array<Object>} executions - array of executions
55
+ * @param {Object} [executionPgModel] - Execution PG model class instance
56
+ * @returns {Promise<number[]>}
57
+ */
58
+ export declare const getApiExecutionCumulusIds: (knexOrTransaction: Knex | Knex.Transaction, executions: Array<{
59
+ arn: string;
60
+ }>, executionPgModel?: ExecutionPgModel) => Promise<number[]>;
61
+ /**
62
+ * Get cumulus IDs for all granules associated to a set of executions
63
+ *
64
+ * @param {Knex | Knex.Transaction} knexOrTransaction -
65
+ * DB client or transaction
66
+ * @param {Array<Object>} executions - array of executions
67
+ * @param {Object} [executionsPgModel]
68
+ * Executions PG model class instance
69
+ * @returns {Promise<number[]>}
70
+ */
71
+ export declare const getApiGranuleExecutionCumulusIdsByExecution: (knexOrTransaction: Knex | Knex.Transaction, executions: Array<{
72
+ arn: string;
73
+ }>, executionPgModel?: ExecutionPgModel, granulesExecutionsPgModel?: GranulesExecutionsPgModel) => Promise<Array<number>>;
36
74
  //# sourceMappingURL=execution.d.ts.map
@@ -1,11 +1,36 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getWorkflowNameIntersectFromGranuleIds = exports.newestExecutionArnFromGranuleIdWorkflowName = exports.executionArnsFromGranuleIdsAndWorkflowNames = void 0;
3
+ exports.getApiGranuleExecutionCumulusIdsByExecution = exports.getApiExecutionCumulusIds = exports.getWorkflowNameIntersectFromGranuleIds = exports.newestExecutionArnFromGranuleIdWorkflowName = exports.executionArnsFromGranuleIdsAndWorkflowNames = exports.getExecutionArnsByGranuleCumulusId = void 0;
4
4
  const errors_1 = require("@cumulus/errors");
5
+ const execution_1 = require("../models/execution");
6
+ const granules_executions_1 = require("../models/granules-executions");
5
7
  const tables_1 = require("../tables");
6
8
  const Logger = require('@cumulus/logger');
7
9
  const { getKnexClient } = require('../connection');
8
10
  const log = new Logger({ sender: '@cumulus/db/lib/execution' });
11
+ /**
12
+ * Returns a list of executionArns sorted by most recent first, for an input
13
+ * Granule Cumulus ID.
14
+ *
15
+ * @param {Knex | Knex.Transaction} knexOrTransaction
16
+ * Knex client for reading from RDS database
17
+ * @param {number} granuleCumulusId - The primary ID for a Granule
18
+ * @param {number} limit - limit to number of executions to query
19
+ * @returns {Promise<ArnRecord[]>} - Array of arn objects with the most recent first.
20
+ */
21
+ const getExecutionArnsByGranuleCumulusId = async (knexOrTransaction, granuleCumulusId, limit) => {
22
+ const knexQuery = knexOrTransaction(tables_1.TableNames.executions)
23
+ .select(`${tables_1.TableNames.executions}.arn`)
24
+ .where(`${tables_1.TableNames.granules}.cumulus_id`, granuleCumulusId)
25
+ .join(tables_1.TableNames.granulesExecutions, `${tables_1.TableNames.executions}.cumulus_id`, `${tables_1.TableNames.granulesExecutions}.execution_cumulus_id`)
26
+ .join(tables_1.TableNames.granules, `${tables_1.TableNames.granules}.cumulus_id`, `${tables_1.TableNames.granulesExecutions}.granule_cumulus_id`)
27
+ .orderBy(`${tables_1.TableNames.executions}.timestamp`, 'desc');
28
+ if (limit) {
29
+ knexQuery.limit(limit);
30
+ }
31
+ return await knexQuery;
32
+ };
33
+ exports.getExecutionArnsByGranuleCumulusId = getExecutionArnsByGranuleCumulusId;
9
34
  /**
10
35
  * Returns a list of executionArns sorted by most recent first, for an input
11
36
  * list of granuleIds and workflowNames.
@@ -79,4 +104,37 @@ const getWorkflowNameIntersectFromGranuleIds = async (knexOrTransaction, granule
79
104
  .map((workflowCounts) => workflowCounts.workflow_name);
80
105
  };
81
106
  exports.getWorkflowNameIntersectFromGranuleIds = getWorkflowNameIntersectFromGranuleIds;
107
+ /**
108
+ * Get cumulus IDs for list of executions
109
+ *
110
+ * @param {Knex | Knex.Transaction} knexOrTransaction -
111
+ * DB client or transaction
112
+ * @param {Array<Object>} executions - array of executions
113
+ * @param {Object} [executionPgModel] - Execution PG model class instance
114
+ * @returns {Promise<number[]>}
115
+ */
116
+ const getApiExecutionCumulusIds = async (knexOrTransaction, executions, executionPgModel = new execution_1.ExecutionPgModel()) => {
117
+ const executionCumulusIds = await Promise.all(executions.map(async (execution) => await executionPgModel.getRecordCumulusId(knexOrTransaction, {
118
+ arn: execution.arn,
119
+ })));
120
+ return [...new Set(executionCumulusIds)];
121
+ };
122
+ exports.getApiExecutionCumulusIds = getApiExecutionCumulusIds;
123
+ /**
124
+ * Get cumulus IDs for all granules associated to a set of executions
125
+ *
126
+ * @param {Knex | Knex.Transaction} knexOrTransaction -
127
+ * DB client or transaction
128
+ * @param {Array<Object>} executions - array of executions
129
+ * @param {Object} [executionsPgModel]
130
+ * Executions PG model class instance
131
+ * @returns {Promise<number[]>}
132
+ */
133
+ const getApiGranuleExecutionCumulusIdsByExecution = async (knexOrTransaction, executions, executionPgModel = new execution_1.ExecutionPgModel(), granulesExecutionsPgModel = new granules_executions_1.GranulesExecutionsPgModel()) => {
134
+ const executionCumulusIds = await (0, exports.getApiExecutionCumulusIds)(knexOrTransaction, executions, executionPgModel);
135
+ const granuleCumulusIds = await granulesExecutionsPgModel
136
+ .searchByExecutionCumulusIds(knexOrTransaction, executionCumulusIds);
137
+ return granuleCumulusIds;
138
+ };
139
+ exports.getApiGranuleExecutionCumulusIdsByExecution = getApiGranuleExecutionCumulusIdsByExecution;
82
140
  //# sourceMappingURL=execution.js.map
@@ -0,0 +1,4 @@
1
+ import { Knex } from 'knex';
2
+ export declare const up: (knex: Knex) => Promise<void>;
3
+ export declare const down: (knex: Knex) => Promise<void>;
4
+ //# sourceMappingURL=20220126172008_files_granule_id_index.d.ts.map
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.down = exports.up = void 0;
4
+ const up = async (knex) => {
5
+ await knex.schema.table('files', (table) => {
6
+ table.index('granule_cumulus_id');
7
+ });
8
+ };
9
+ exports.up = up;
10
+ const down = async (knex) => {
11
+ await knex.schema.table('files', (table) => {
12
+ table.dropIndex('granule_cumulus_id');
13
+ });
14
+ };
15
+ exports.down = down;
16
+ //# sourceMappingURL=20220126172008_files_granule_id_index.js.map
@@ -22,7 +22,7 @@ declare class BasePgModel<ItemType, RecordType extends {
22
22
  * Fetches multiple items from Postgres
23
23
  *
24
24
  * @param {Knex | Knex.Transaction} knexOrTransaction - DB client or transaction
25
- * @param {Partial<RecordType>} params - An object or any portion of an object of type RecordType
25
+ * @param {Object} params - An object or any portion of an object of type RecordType
26
26
  * @returns {Promise<RecordType[]>} List of returned records
27
27
  */
28
28
  search(knexOrTransaction: Knex | Knex.Transaction, params: Partial<RecordType>): Promise<RecordType[]>;
@@ -41,7 +41,7 @@ declare class BasePgModel<ItemType, RecordType extends {
41
41
  *
42
42
  * @param {Knex | Knex.Transaction} knexOrTransaction -
43
43
  * DB client or transaction
44
- * @param {Array<keyof RecordType>} columnNames - column names for whereIn query
44
+ * @param {Array<string>} columnNames - column names for whereIn query
45
45
  * @param {Array<string>} values - record values for whereIn query
46
46
  * @returns {Promise<Array<number>>} An array of cumulus_ids for the returned records
47
47
  */
@@ -40,7 +40,7 @@ class BasePgModel {
40
40
  * Fetches multiple items from Postgres
41
41
  *
42
42
  * @param {Knex | Knex.Transaction} knexOrTransaction - DB client or transaction
43
- * @param {Partial<RecordType>} params - An object or any portion of an object of type RecordType
43
+ * @param {Object} params - An object or any portion of an object of type RecordType
44
44
  * @returns {Promise<RecordType[]>} List of returned records
45
45
  */
46
46
  async search(knexOrTransaction, params) {
@@ -72,7 +72,7 @@ class BasePgModel {
72
72
  *
73
73
  * @param {Knex | Knex.Transaction} knexOrTransaction -
74
74
  * DB client or transaction
75
- * @param {Array<keyof RecordType>} columnNames - column names for whereIn query
75
+ * @param {Array<string>} columnNames - column names for whereIn query
76
76
  * @param {Array<string>} values - record values for whereIn query
77
77
  * @returns {Promise<Array<number>>} An array of cumulus_ids for the returned records
78
78
  */
@@ -36,6 +36,22 @@ export default class GranulePgModel extends BasePgModel<PostgresGranule, Postgre
36
36
  */
37
37
  get(knexOrTransaction: Knex | Knex.Transaction, params: PostgresGranuleUniqueColumns | RecordSelect): Promise<PostgresGranuleRecord>;
38
38
  upsert(knexOrTrx: Knex | Knex.Transaction, granule: PostgresGranule, executionCumulusId?: number, granulesExecutionsPgModel?: GranulesExecutionsPgModel): Promise<any[]>;
39
+ /**
40
+ * Get granules from the granule cumulus_id
41
+ *
42
+ * @param {Knex | Knex.Transaction} knexOrTrx -
43
+ * DB client or transaction
44
+ * @param {Array<number>} granuleCumulusIds -
45
+ * single granule cumulus_id or array of granule cumulus_ids
46
+ * @param {Object} [params] - Optional object with addition params for query
47
+ * @param {number} [params.limit] - number of records to be returned
48
+ * @param {number} [params.offset] - record offset
49
+ * @returns {Promise<Array<PostgresGranuleRecord>>} An array of granules
50
+ */
51
+ searchByCumulusIds(knexOrTrx: Knex | Knex.Transaction, granuleCumulusIds: Array<number> | number, params: {
52
+ limit: number;
53
+ offset: number;
54
+ }): Promise<Array<PostgresGranuleRecord>>;
39
55
  }
40
56
  export { GranulePgModel };
41
57
  //# sourceMappingURL=granule.d.ts.map
@@ -6,6 +6,7 @@ const tables_1 = require("../tables");
6
6
  const base_1 = require("./base");
7
7
  const granules_executions_1 = require("./granules-executions");
8
8
  const timestamp_1 = require("../lib/timestamp");
9
+ const sort_1 = require("../lib/sort");
9
10
  function isRecordSelect(param) {
10
11
  return param.cumulus_id !== undefined;
11
12
  }
@@ -97,6 +98,39 @@ class GranulePgModel extends base_1.BasePgModel {
97
98
  .where(knexOrTrx.raw(`${this.tableName}.created_at <= to_timestamp(${(0, timestamp_1.translateDateToUTC)(granule.created_at)})`))
98
99
  .returning('cumulus_id');
99
100
  }
101
+ /**
102
+ * Get granules from the granule cumulus_id
103
+ *
104
+ * @param {Knex | Knex.Transaction} knexOrTrx -
105
+ * DB client or transaction
106
+ * @param {Array<number>} granuleCumulusIds -
107
+ * single granule cumulus_id or array of granule cumulus_ids
108
+ * @param {Object} [params] - Optional object with addition params for query
109
+ * @param {number} [params.limit] - number of records to be returned
110
+ * @param {number} [params.offset] - record offset
111
+ * @returns {Promise<Array<PostgresGranuleRecord>>} An array of granules
112
+ */
113
+ async searchByCumulusIds(knexOrTrx, granuleCumulusIds, params) {
114
+ const { limit, offset, ...sortQueries } = params || {};
115
+ const sortFields = (0, sort_1.getSortFields)(sortQueries);
116
+ const granuleCumulusIdsArray = [granuleCumulusIds].flat();
117
+ const granules = await knexOrTrx(this.tableName)
118
+ .whereIn('cumulus_id', granuleCumulusIdsArray)
119
+ .modify((queryBuilder) => {
120
+ if (limit)
121
+ queryBuilder.limit(limit);
122
+ if (offset)
123
+ queryBuilder.offset(offset);
124
+ if (sortFields.length >= 1) {
125
+ sortFields.forEach((sortObject) => {
126
+ const sortField = Object.keys(sortObject)[0];
127
+ const { order } = sortObject[sortField];
128
+ queryBuilder.orderBy(sortField, order);
129
+ });
130
+ }
131
+ });
132
+ return granules;
133
+ }
100
134
  }
101
135
  exports.default = GranulePgModel;
102
136
  exports.GranulePgModel = GranulePgModel;
@@ -17,6 +17,16 @@ export default class GranulesExecutionsPgModel {
17
17
  * @returns {Promise<Array<number>>} An array of execution_cumulus_ids
18
18
  */
19
19
  searchByGranuleCumulusIds(knexOrTransaction: Knex | Knex.Transaction, granuleCumulusIds: Array<number> | number): Promise<Array<number>>;
20
+ /**
21
+ * Get granule_cumulus_id column values from the execution_cumulus_id
22
+ *
23
+ * @param {Knex | Knex.Transaction} knexOrTransaction -
24
+ * DB client or transaction
25
+ * @param {number | Array<number>} executionCumulusIds -
26
+ * single execution_cumulus_id or array of execution_cumulus_ids
27
+ * @returns {Promise<Array<number>>} An array of granule_cumulus_ids
28
+ */
29
+ searchByExecutionCumulusIds(knexOrTransaction: Knex | Knex.Transaction, executionCumulusIds: Array<number> | number): Promise<Array<number>>;
20
30
  delete(knexTransaction: Knex.Transaction, params: Partial<PostgresGranuleExecution>): Promise<number>;
21
31
  search(knexTransaction: Knex | Knex.Transaction, query: Partial<PostgresGranuleExecution>): Knex.QueryBuilder<PostgresGranuleExecution, {
22
32
  _base: PostgresGranuleExecution;
@@ -38,6 +38,23 @@ class GranulesExecutionsPgModel {
38
38
  .groupBy('execution_cumulus_id');
39
39
  return granuleExecutions.map((granuleExecution) => granuleExecution.execution_cumulus_id);
40
40
  }
41
+ /**
42
+ * Get granule_cumulus_id column values from the execution_cumulus_id
43
+ *
44
+ * @param {Knex | Knex.Transaction} knexOrTransaction -
45
+ * DB client or transaction
46
+ * @param {number | Array<number>} executionCumulusIds -
47
+ * single execution_cumulus_id or array of execution_cumulus_ids
48
+ * @returns {Promise<Array<number>>} An array of granule_cumulus_ids
49
+ */
50
+ async searchByExecutionCumulusIds(knexOrTransaction, executionCumulusIds) {
51
+ const executionCumulusIdsArray = [executionCumulusIds].flat();
52
+ const granuleExecutions = await knexOrTransaction(this.tableName)
53
+ .select('granule_cumulus_id')
54
+ .whereIn('execution_cumulus_id', executionCumulusIdsArray)
55
+ .groupBy('granule_cumulus_id');
56
+ return granuleExecutions.map((granuleExecution) => granuleExecution.granule_cumulus_id);
57
+ }
41
58
  async delete(knexTransaction, params) {
42
59
  return await knexTransaction(this.tableName)
43
60
  .where(params)
@@ -1,4 +1,5 @@
1
1
  import { ApiFile } from '@cumulus/types/api/files';
2
- import { PostgresFile } from '../types/file';
2
+ import { PostgresFile, PostgresFileRecord } from '../types/file';
3
+ export declare const translatePostgresFileToApiFile: (filePgRecord: PostgresFileRecord) => Omit<ApiFile, 'granuleId'>;
3
4
  export declare const translateApiFiletoPostgresFile: (file: ApiFile) => Omit<PostgresFile, 'granule_cumulus_id'>;
4
5
  //# sourceMappingURL=file.d.ts.map
@@ -1,7 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.translateApiFiletoPostgresFile = void 0;
3
+ exports.translateApiFiletoPostgresFile = exports.translatePostgresFileToApiFile = void 0;
4
4
  const { parseS3Uri } = require('@cumulus/aws-client/S3');
5
+ const { removeNilProperties } = require('@cumulus/common/util');
5
6
  const getBucket = (file) => {
6
7
  if (file.bucket)
7
8
  return file.bucket;
@@ -16,6 +17,16 @@ const getKey = (file) => {
16
17
  return parseS3Uri(file.filename).Key;
17
18
  return undefined;
18
19
  };
20
+ const translatePostgresFileToApiFile = (filePgRecord) => removeNilProperties({
21
+ bucket: filePgRecord.bucket,
22
+ checksum: filePgRecord.checksum_value,
23
+ checksumType: filePgRecord.checksum_type,
24
+ fileName: filePgRecord.file_name,
25
+ key: filePgRecord.key,
26
+ size: filePgRecord.file_size ? filePgRecord.file_size : undefined,
27
+ source: filePgRecord.source,
28
+ });
29
+ exports.translatePostgresFileToApiFile = translatePostgresFileToApiFile;
19
30
  const translateApiFiletoPostgresFile = (file) => {
20
31
  const bucket = getBucket(file);
21
32
  const key = getKey(file);
@@ -1,8 +1,34 @@
1
1
  import { Knex } from 'knex';
2
+ import { ApiGranule } from '@cumulus/types/api/granules';
2
3
  import { CollectionPgModel } from '../models/collection';
3
4
  import { PdrPgModel } from '../models/pdr';
4
- import { PostgresGranule } from '../types/granule';
5
+ import { PostgresGranule, PostgresGranuleRecord } from '../types/granule';
5
6
  import { ProviderPgModel } from '../models/provider';
7
+ import { FilePgModel } from '../models/file';
8
+ import { PostgresCollectionRecord } from '../types/collection';
9
+ /**
10
+ * Generate an API Granule object from a Postgres Granule with associated Files.
11
+ *
12
+ * @param {Object} params
13
+ * @param {PostgresGranuleRecord} params.granulePgRecord - Granule from Postgres
14
+ * @param {PostgresCollectionRecord} params.collectionPgRecord - Collection from Postgres
15
+ * @param {Knex | Knex.Transaction} params.knexOrTransaction
16
+ * Knex client for reading from RDS database
17
+ * @param {Object} [params.collectionPgModel] - Instance of the collection database model
18
+ * @param {Object} [params.pdrPgModel] - Instance of the pdr database model
19
+ * @param {Object} [params.providerPgModel] - Instance of the provider database model
20
+ * @param {Object} [params.filePgModel] - Instance of the file database model
21
+ * @returns {Object} An API Granule with associated Files
22
+ */
23
+ export declare const translatePostgresGranuleToApiGranule: ({ granulePgRecord, collectionPgRecord, knexOrTransaction, collectionPgModel, pdrPgModel, providerPgModel, filePgModel, }: {
24
+ granulePgRecord: PostgresGranuleRecord;
25
+ collectionPgRecord: PostgresCollectionRecord;
26
+ knexOrTransaction: Knex | Knex.Transaction;
27
+ collectionPgModel?: CollectionPgModel | undefined;
28
+ pdrPgModel?: PdrPgModel | undefined;
29
+ providerPgModel?: ProviderPgModel | undefined;
30
+ filePgModel?: FilePgModel | undefined;
31
+ }) => Promise<ApiGranule>;
6
32
  /**
7
33
  * Generate a Postgres granule record from a DynamoDB record.
8
34
  *
@@ -1,10 +1,78 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.translateApiGranuleToPostgresGranule = void 0;
3
+ exports.translateApiGranuleToPostgresGranule = exports.translatePostgresGranuleToApiGranule = void 0;
4
+ const Collections_1 = require("@cumulus/message/Collections");
5
+ const Executions_1 = require("@cumulus/message/Executions");
6
+ const util_1 = require("@cumulus/common/util");
7
+ const errors_1 = require("@cumulus/errors");
4
8
  const collection_1 = require("../models/collection");
5
9
  const pdr_1 = require("../models/pdr");
6
10
  const provider_1 = require("../models/provider");
7
- const { deconstructCollectionId } = require('@cumulus/message/Collections');
11
+ const file_1 = require("../models/file");
12
+ const file_2 = require("./file");
13
+ const execution_1 = require("../lib/execution");
14
+ /**
15
+ * Generate an API Granule object from a Postgres Granule with associated Files.
16
+ *
17
+ * @param {Object} params
18
+ * @param {PostgresGranuleRecord} params.granulePgRecord - Granule from Postgres
19
+ * @param {PostgresCollectionRecord} params.collectionPgRecord - Collection from Postgres
20
+ * @param {Knex | Knex.Transaction} params.knexOrTransaction
21
+ * Knex client for reading from RDS database
22
+ * @param {Object} [params.collectionPgModel] - Instance of the collection database model
23
+ * @param {Object} [params.pdrPgModel] - Instance of the pdr database model
24
+ * @param {Object} [params.providerPgModel] - Instance of the provider database model
25
+ * @param {Object} [params.filePgModel] - Instance of the file database model
26
+ * @returns {Object} An API Granule with associated Files
27
+ */
28
+ const translatePostgresGranuleToApiGranule = async ({ granulePgRecord, collectionPgRecord, knexOrTransaction, collectionPgModel = new collection_1.CollectionPgModel(), pdrPgModel = new pdr_1.PdrPgModel(), providerPgModel = new provider_1.ProviderPgModel(), filePgModel = new file_1.FilePgModel(), }) => {
29
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
30
+ const collection = collectionPgRecord || await collectionPgModel.get(knexOrTransaction, { cumulus_id: granulePgRecord.collection_cumulus_id });
31
+ if (granulePgRecord.collection_cumulus_id !== collection.cumulus_id) {
32
+ throw new errors_1.ValidationError(`Collection ${collection.cumulus_id} does not match the Granule's Collection ${granulePgRecord.collection_cumulus_id}`);
33
+ }
34
+ const files = await filePgModel.search(knexOrTransaction, { granule_cumulus_id: granulePgRecord.cumulus_id });
35
+ const executionArns = await (0, execution_1.getExecutionArnsByGranuleCumulusId)(knexOrTransaction, granulePgRecord.cumulus_id, 1);
36
+ let pdr;
37
+ if (granulePgRecord.pdr_cumulus_id) {
38
+ pdr = await pdrPgModel.get(knexOrTransaction, { cumulus_id: granulePgRecord.pdr_cumulus_id });
39
+ }
40
+ let provider;
41
+ if (granulePgRecord.provider_cumulus_id) {
42
+ provider = await providerPgModel.get(knexOrTransaction, { cumulus_id: granulePgRecord.provider_cumulus_id });
43
+ }
44
+ const apiGranule = (0, util_1.removeNilProperties)({
45
+ beginningDateTime: (_a = granulePgRecord.beginning_date_time) === null || _a === void 0 ? void 0 : _a.toISOString(),
46
+ cmrLink: granulePgRecord.cmr_link,
47
+ collectionId: (0, Collections_1.constructCollectionId)(collection.name, collection.version),
48
+ createdAt: (_b = granulePgRecord.created_at) === null || _b === void 0 ? void 0 : _b.getTime(),
49
+ duration: granulePgRecord.duration,
50
+ endingDateTime: (_c = granulePgRecord.ending_date_time) === null || _c === void 0 ? void 0 : _c.toISOString(),
51
+ error: granulePgRecord.error,
52
+ execution: executionArns[0] ? (0, Executions_1.getExecutionUrlFromArn)(executionArns[0].arn) : undefined,
53
+ files: files.map((file) => ({
54
+ ...(0, file_2.translatePostgresFileToApiFile)(file),
55
+ })),
56
+ granuleId: granulePgRecord.granule_id,
57
+ lastUpdateDateTime: (_d = granulePgRecord.last_update_date_time) === null || _d === void 0 ? void 0 : _d.toISOString(),
58
+ pdrName: pdr ? pdr.name : undefined,
59
+ processingEndDateTime: (_e = granulePgRecord.processing_end_date_time) === null || _e === void 0 ? void 0 : _e.toISOString(),
60
+ processingStartDateTime: (_f = granulePgRecord.processing_start_date_time) === null || _f === void 0 ? void 0 : _f.toISOString(),
61
+ productionDateTime: (_g = granulePgRecord.production_date_time) === null || _g === void 0 ? void 0 : _g.toISOString(),
62
+ productVolume: granulePgRecord.product_volume
63
+ ? granulePgRecord.product_volume : undefined,
64
+ provider: provider ? provider.name : undefined,
65
+ published: granulePgRecord.published,
66
+ queryFields: granulePgRecord.query_fields,
67
+ status: granulePgRecord.status,
68
+ timestamp: (_h = granulePgRecord.timestamp) === null || _h === void 0 ? void 0 : _h.getTime(),
69
+ timeToArchive: granulePgRecord.time_to_archive,
70
+ timeToPreprocess: granulePgRecord.time_to_process,
71
+ updatedAt: (_j = granulePgRecord.updated_at) === null || _j === void 0 ? void 0 : _j.getTime(),
72
+ });
73
+ return apiGranule;
74
+ };
75
+ exports.translatePostgresGranuleToApiGranule = translatePostgresGranuleToApiGranule;
8
76
  /**
9
77
  * Generate a Postgres granule record from a DynamoDB record.
10
78
  *
@@ -18,7 +86,7 @@ const { deconstructCollectionId } = require('@cumulus/message/Collections');
18
86
  * @returns {Object} A granule PG record
19
87
  */
20
88
  const translateApiGranuleToPostgresGranule = async (dynamoRecord, knexOrTransaction, collectionPgModel = new collection_1.CollectionPgModel(), pdrPgModel = new pdr_1.PdrPgModel(), providerPgModel = new provider_1.ProviderPgModel()) => {
21
- const { name, version } = deconstructCollectionId(dynamoRecord.collectionId);
89
+ const { name, version } = (0, Collections_1.deconstructCollectionId)(dynamoRecord.collectionId);
22
90
  const granuleRecord = {
23
91
  granule_id: dynamoRecord.granuleId,
24
92
  status: dynamoRecord.status,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cumulus/db",
3
- "version": "9.8.0",
3
+ "version": "9.9.2",
4
4
  "description": "Utilities for working with the Cumulus DB",
5
5
  "license": "Apache-2.0",
6
6
  "main": "./dist/index.js",
@@ -29,22 +29,22 @@
29
29
  "node": ">=12.18.0"
30
30
  },
31
31
  "dependencies": {
32
- "@cumulus/aws-client": "9.8.0",
33
- "@cumulus/common": "9.8.0",
34
- "@cumulus/errors": "9.8.0",
35
- "@cumulus/logger": "9.8.0",
36
- "@cumulus/message": "9.8.0",
37
- "@cumulus/types": "9.8.0",
32
+ "@cumulus/aws-client": "9.9.2",
33
+ "@cumulus/common": "9.9.2",
34
+ "@cumulus/errors": "9.9.2",
35
+ "@cumulus/logger": "9.9.2",
36
+ "@cumulus/message": "9.9.2",
37
+ "@cumulus/types": "9.9.2",
38
38
  "crypto-random-string": "^3.2.0",
39
39
  "is-valid-hostname": "0.0.1",
40
40
  "knex": "0.95.11",
41
41
  "lodash": "^4.17.20",
42
42
  "pg": "^8.3.0",
43
43
  "snake-camel": "^1.0.6",
44
- "uuid": "8.3.1"
44
+ "uuid": "8.3.2"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@types/uuid": "^8.0.0"
48
48
  },
49
- "gitHead": "913034ba6814e562b7f3d58bb39cf086255a6efd"
49
+ "gitHead": "0bfe94a0c4919567a35fc8bcff24643ba84a6547"
50
50
  }