@cumulus/db 13.3.3-alpha.1 → 14.0.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 CHANGED
@@ -27,7 +27,7 @@ export { translateApiPdrToPostgresPdr, translatePostgresPdrToApiPdr, } from './t
27
27
  export { getCollectionsByGranuleIds, } from './lib/collection';
28
28
  export { executionArnsFromGranuleIdsAndWorkflowNames, newestExecutionArnFromGranuleIdWorkflowName, getWorkflowNameIntersectFromGranuleIds, getApiExecutionCumulusIds, getApiGranuleExecutionCumulusIdsByExecution, getExecutionInfoByGranuleCumulusId, } from './lib/execution';
29
29
  export { getFilesAndGranuleInfoQuery, } from './lib/file';
30
- export { getApiGranuleCumulusIds, getApiGranuleExecutionCumulusIds, getGranuleCollectionId, getUniqueGranuleByGranuleId, upsertGranuleWithExecutionJoinRecord, getGranulesByApiPropertiesQuery, } from './lib/granule';
30
+ export { getApiGranuleCumulusIds, getApiGranuleExecutionCumulusIds, getGranuleCollectionId, getUniqueGranuleByGranuleId, upsertGranuleWithExecutionJoinRecord, getGranulesByApiPropertiesQuery, getGranulesByGranuleId, } from './lib/granule';
31
31
  export { QuerySearchClient, } from './lib/QuerySearchClient';
32
32
  export { AsyncOperationPgModel } from './models/async_operation';
33
33
  export { BasePgModel } from './models/base';
package/dist/index.js CHANGED
@@ -24,7 +24,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.getApiGranuleCumulusIds = exports.getFilesAndGranuleInfoQuery = exports.getExecutionInfoByGranuleCumulusId = exports.getApiGranuleExecutionCumulusIdsByExecution = exports.getApiExecutionCumulusIds = exports.getWorkflowNameIntersectFromGranuleIds = exports.newestExecutionArnFromGranuleIdWorkflowName = exports.executionArnsFromGranuleIdsAndWorkflowNames = exports.getCollectionsByGranuleIds = exports.translatePostgresPdrToApiPdr = exports.translateApiPdrToPostgresPdr = exports.translatePostgresGranuleResultToApiGranule = exports.translatePostgresGranuleToApiGranule = exports.translateApiGranuleToPostgresGranuleWithoutNilsRemoved = exports.translateApiGranuleToPostgresGranule = exports.translatePostgresExecutionToApiExecution = exports.translateApiExecutionToPostgresExecution = exports.translateApiRuleToPostgresRuleRaw = exports.translateApiRuleToPostgresRule = exports.translatePostgresRuleToApiRule = exports.translatePostgresProviderToApiProvider = exports.translateApiProviderToPostgresProvider = exports.translatePostgresCollectionToApiCollection = exports.translateApiCollectionToPostgresCollection = exports.translatePostgresFileToApiFile = exports.translateApiFiletoPostgresFile = exports.translatePostgresAsyncOperationToApiAsyncOperation = exports.translateApiAsyncOperationToPostgresAsyncOperation = exports.nullifyUndefinedProviderValues = exports.validateProviderHost = exports.migrationDir = exports.TableNames = exports.createRejectableTransaction = exports.localStackConnectionEnv = exports.getKnexConfig = exports.getKnexClient = exports.isCollisionError = 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;
27
- exports.RulePgModel = exports.ProviderPgModel = exports.PdrPgModel = exports.GranulesExecutionsPgModel = exports.GranulePgModel = exports.FilePgModel = exports.ExecutionPgModel = exports.CollectionPgModel = exports.BasePgModel = exports.AsyncOperationPgModel = exports.QuerySearchClient = exports.getGranulesByApiPropertiesQuery = exports.upsertGranuleWithExecutionJoinRecord = exports.getUniqueGranuleByGranuleId = exports.getGranuleCollectionId = exports.getApiGranuleExecutionCumulusIds = void 0;
27
+ exports.RulePgModel = exports.ProviderPgModel = exports.PdrPgModel = exports.GranulesExecutionsPgModel = exports.GranulePgModel = exports.FilePgModel = exports.ExecutionPgModel = exports.CollectionPgModel = exports.BasePgModel = exports.AsyncOperationPgModel = exports.QuerySearchClient = exports.getGranulesByGranuleId = exports.getGranulesByApiPropertiesQuery = exports.upsertGranuleWithExecutionJoinRecord = exports.getUniqueGranuleByGranuleId = exports.getGranuleCollectionId = exports.getApiGranuleExecutionCumulusIds = void 0;
28
28
  const path = __importStar(require("path"));
29
29
  var knex_1 = require("knex");
30
30
  Object.defineProperty(exports, "Knex", { enumerable: true, get: function () { return knex_1.Knex; } });
@@ -101,6 +101,7 @@ Object.defineProperty(exports, "getGranuleCollectionId", { enumerable: true, get
101
101
  Object.defineProperty(exports, "getUniqueGranuleByGranuleId", { enumerable: true, get: function () { return granule_1.getUniqueGranuleByGranuleId; } });
102
102
  Object.defineProperty(exports, "upsertGranuleWithExecutionJoinRecord", { enumerable: true, get: function () { return granule_1.upsertGranuleWithExecutionJoinRecord; } });
103
103
  Object.defineProperty(exports, "getGranulesByApiPropertiesQuery", { enumerable: true, get: function () { return granule_1.getGranulesByApiPropertiesQuery; } });
104
+ Object.defineProperty(exports, "getGranulesByGranuleId", { enumerable: true, get: function () { return granule_1.getGranulesByGranuleId; } });
104
105
  var QuerySearchClient_1 = require("./lib/QuerySearchClient");
105
106
  Object.defineProperty(exports, "QuerySearchClient", { enumerable: true, get: function () { return QuerySearchClient_1.QuerySearchClient; } });
106
107
  var async_operation_1 = require("./models/async_operation");
@@ -16,7 +16,14 @@ export declare const getGranuleCollectionId: (knexOrTransaction: Knex | Knex.Tra
16
16
  * Granules/executions PG model class instance
17
17
  * @returns {Promise<PostgresGranuleRecord[]>}
18
18
  */
19
- export declare const upsertGranuleWithExecutionJoinRecord: (knexTransaction: Knex.Transaction, granule: PostgresGranule, executionCumulusId?: number, granulePgModel?: GranulePgModel, granulesExecutionsPgModel?: GranulesExecutionsPgModel) => Promise<PostgresGranuleRecord[]>;
19
+ export declare const upsertGranuleWithExecutionJoinRecord: ({ knexTransaction, granule, executionCumulusId, granulePgModel, granulesExecutionsPgModel, writeConstraints, }: {
20
+ knexTransaction: Knex.Transaction;
21
+ granule: PostgresGranule;
22
+ executionCumulusId?: number | undefined;
23
+ granulePgModel?: GranulePgModel | undefined;
24
+ granulesExecutionsPgModel?: GranulesExecutionsPgModel | undefined;
25
+ writeConstraints?: boolean | undefined;
26
+ }) => Promise<PostgresGranuleRecord[]>;
20
27
  /**
21
28
  * Get cumulus IDs for list of granules
22
29
  *
@@ -64,7 +71,7 @@ export declare const getApiGranuleExecutionCumulusIds: (knexOrTransaction: Knex
64
71
  * @param {Object} searchParams
65
72
  * @param {string | Array<string>} [searchParams.collectionIds] - Collection ID
66
73
  * @param {string | Array<string>} [searchParams.granuleIds] - array of granule IDs
67
- * @param {string} [searchParams.providerName] - Provider name
74
+ * @param {string} [searchParams.providerNames] - Provider names
68
75
  * @param {UpdatedAtRange} [searchParams.updatedAtRange] - Date range for updated_at column
69
76
  * @param {string} [searchParams.status] - Granule status to search by
70
77
  * @param {string | Array<string>} [sortByFields] - Field(s) to sort by
@@ -77,4 +84,12 @@ export declare const getGranulesByApiPropertiesQuery: (knex: Knex, { collectionI
77
84
  updatedAtRange?: UpdatedAtRange | undefined;
78
85
  status?: string | undefined;
79
86
  }, sortByFields?: string | string[]) => Knex.QueryBuilder;
87
+ /**
88
+ * Get granules from table where granule_id matches provided granuleId
89
+ *
90
+ * @param {Knex | Knex.Transaction} knexOrTransaction - DB client or transaction
91
+ * @param {string} granuleId - Granule ID
92
+ * @returns {Promise<Array<PostgresGranuleRecord>} The returned list of records
93
+ */
94
+ export declare const getGranulesByGranuleId: (knexOrTransaction: Knex | Knex.Transaction, granuleId: string) => Promise<Array<PostgresGranuleRecord>>;
80
95
  //# sourceMappingURL=granule.d.ts.map
@@ -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.getGranulesByApiPropertiesQuery = exports.getApiGranuleExecutionCumulusIds = exports.getUniqueGranuleByGranuleId = exports.getApiGranuleCumulusIds = exports.upsertGranuleWithExecutionJoinRecord = exports.getGranuleCollectionId = void 0;
6
+ exports.getGranulesByGranuleId = exports.getGranulesByApiPropertiesQuery = exports.getApiGranuleExecutionCumulusIds = exports.getUniqueGranuleByGranuleId = exports.getApiGranuleCumulusIds = exports.upsertGranuleWithExecutionJoinRecord = exports.getGranuleCollectionId = void 0;
7
7
  const Collections_1 = require("@cumulus/message/Collections");
8
8
  const errors_1 = require("@cumulus/errors");
9
9
  const logger_1 = __importDefault(require("@cumulus/logger"));
@@ -28,8 +28,13 @@ exports.getGranuleCollectionId = getGranuleCollectionId;
28
28
  * Granules/executions PG model class instance
29
29
  * @returns {Promise<PostgresGranuleRecord[]>}
30
30
  */
31
- const upsertGranuleWithExecutionJoinRecord = async (knexTransaction, granule, executionCumulusId, granulePgModel = new granule_1.GranulePgModel(), granulesExecutionsPgModel = new granules_executions_1.GranulesExecutionsPgModel()) => {
32
- const [pgGranule] = await granulePgModel.upsert(knexTransaction, granule, executionCumulusId);
31
+ const upsertGranuleWithExecutionJoinRecord = async ({ knexTransaction, granule, executionCumulusId, granulePgModel = new granule_1.GranulePgModel(), granulesExecutionsPgModel = new granules_executions_1.GranulesExecutionsPgModel(), writeConstraints = true, }) => {
32
+ const [pgGranule] = await granulePgModel.upsert({
33
+ knexOrTrx: knexTransaction,
34
+ granule: granule,
35
+ executionCumulusId,
36
+ writeConstraints,
37
+ });
33
38
  // granuleCumulusId could be undefined if the upsert affected no rows due to its
34
39
  // conditional logic. In that case, we assume that the execution history for the
35
40
  // granule was already written and return early. Execution history cannot be written
@@ -124,7 +129,7 @@ exports.getApiGranuleExecutionCumulusIds = getApiGranuleExecutionCumulusIds;
124
129
  * @param {Object} searchParams
125
130
  * @param {string | Array<string>} [searchParams.collectionIds] - Collection ID
126
131
  * @param {string | Array<string>} [searchParams.granuleIds] - array of granule IDs
127
- * @param {string} [searchParams.providerName] - Provider name
132
+ * @param {string} [searchParams.providerNames] - Provider names
128
133
  * @param {UpdatedAtRange} [searchParams.updatedAtRange] - Date range for updated_at column
129
134
  * @param {string} [searchParams.status] - Granule status to search by
130
135
  * @param {string | Array<string>} [sortByFields] - Field(s) to sort by
@@ -177,4 +182,18 @@ const getGranulesByApiPropertiesQuery = (knex, { collectionIds, granuleIds, prov
177
182
  .groupBy(`${providersTable}.cumulus_id`);
178
183
  };
179
184
  exports.getGranulesByApiPropertiesQuery = getGranulesByApiPropertiesQuery;
185
+ /**
186
+ * Get granules from table where granule_id matches provided granuleId
187
+ *
188
+ * @param {Knex | Knex.Transaction} knexOrTransaction - DB client or transaction
189
+ * @param {string} granuleId - Granule ID
190
+ * @returns {Promise<Array<PostgresGranuleRecord>} The returned list of records
191
+ */
192
+ const getGranulesByGranuleId = async (knexOrTransaction, granuleId) => {
193
+ const { granules: granulesTable, } = TableNames;
194
+ const records = await knexOrTransaction(granulesTable)
195
+ .where({ granule_id: granuleId });
196
+ return records;
197
+ };
198
+ exports.getGranulesByGranuleId = getGranulesByGranuleId;
180
199
  //# sourceMappingURL=granule.js.map
@@ -46,7 +46,13 @@ export default class GranulePgModel extends BasePgModel<PostgresGranule, Postgre
46
46
  _intersectProps: {};
47
47
  _unionProps: never;
48
48
  }[]>;
49
- upsert(knexOrTrx: Knex | Knex.Transaction, granule: PostgresGranule, executionCumulusId?: number, executionPgModel?: ExecutionPgModel): Promise<any[]>;
49
+ upsert({ knexOrTrx, granule, executionCumulusId, executionPgModel, writeConstraints, }: {
50
+ knexOrTrx: Knex | Knex.Transaction;
51
+ granule: PostgresGranule;
52
+ executionCumulusId?: number;
53
+ executionPgModel?: ExecutionPgModel;
54
+ writeConstraints: boolean;
55
+ }): Promise<any[]>;
50
56
  /**
51
57
  * Get granules from the granule cumulus_id
52
58
  *
@@ -69,19 +69,19 @@ class GranulePgModel extends base_1.BasePgModel {
69
69
  return super.get(knexOrTransaction, params);
70
70
  }
71
71
  _buildExclusionClause(executionPgModel, executionCumulusId, knexOrTrx, status) {
72
+ // if granule is queued, search for existing execution entry and
73
+ // don't allow queued update in case of existing execution entry
72
74
  const queryBuilder = executionPgModel.queryBuilderSearch(knexOrTrx, {
73
75
  cumulus_id: executionCumulusId,
74
76
  });
77
+ // if granule is running, make sure the execution doesn't exist in a *completed* status
75
78
  if (status === 'running') {
76
79
  queryBuilder.whereIn('status', execution_1.ExecutionPgModel.nonActiveStatuses);
77
80
  }
78
81
  return queryBuilder;
79
82
  }
80
- async upsert(knexOrTrx, granule, executionCumulusId, executionPgModel = new execution_1.ExecutionPgModel()) {
81
- if (!granule.created_at) {
82
- throw new Error(`To upsert granule record must have 'created_at' set: ${JSON.stringify(granule)}`);
83
- }
84
- if (granule.status === 'running' || granule.status === 'queued') {
83
+ async upsert({ knexOrTrx, granule, executionCumulusId, executionPgModel = new execution_1.ExecutionPgModel(), writeConstraints = true, }) {
84
+ if (writeConstraints && (granule.status === 'running' || granule.status === 'queued')) {
85
85
  const upsertQuery = knexOrTrx(this.tableName)
86
86
  .insert(granule)
87
87
  .onConflict(['granule_id', 'collection_cumulus_id'])
@@ -90,10 +90,15 @@ class GranulePgModel extends base_1.BasePgModel {
90
90
  timestamp: granule.timestamp,
91
91
  updated_at: granule.updated_at,
92
92
  created_at: granule.created_at,
93
- })
94
- .where(knexOrTrx.raw(`${this.tableName}.created_at <= to_timestamp(${(0, timestamp_1.translateDateToUTC)(granule.created_at)})`));
93
+ });
94
+ // If upsert called with optional write constraints
95
+ if (!granule.created_at) {
96
+ throw new Error(`Granule upsert called with write constraints but no createdAt set: ${JSON.stringify(granule)}`);
97
+ }
98
+ upsertQuery.where(knexOrTrx.raw(`${this.tableName}.created_at <= to_timestamp(${(0, timestamp_1.translateDateToUTC)(granule.created_at)})`));
95
99
  // In reality, the only place where executionCumulusId should be
96
100
  // undefined is from the data migrations OR a queued granule from reingest
101
+ // OR a patch API request
97
102
  if (executionCumulusId) {
98
103
  const exclusionClause = this._buildExclusionClause(executionPgModel, executionCumulusId, knexOrTrx, granule.status);
99
104
  // Only do the upsert if there is no execution that matches the exclusionClause
@@ -105,12 +110,18 @@ class GranulePgModel extends base_1.BasePgModel {
105
110
  upsertQuery.returning('*');
106
111
  return await upsertQuery;
107
112
  }
108
- return await knexOrTrx(this.tableName)
113
+ const upsertQuery = knexOrTrx(this.tableName)
109
114
  .insert(granule)
110
115
  .onConflict(['granule_id', 'collection_cumulus_id'])
111
- .merge()
112
- .where(knexOrTrx.raw(`${this.tableName}.created_at <= to_timestamp(${(0, timestamp_1.translateDateToUTC)(granule.created_at)})`))
113
- .returning('*');
116
+ .merge();
117
+ if (writeConstraints) {
118
+ if (!granule.created_at) {
119
+ throw new Error(`Granule upsert called with write constraints but no created_at set: ${JSON.stringify(granule)}`);
120
+ }
121
+ upsertQuery.where(knexOrTrx.raw(`${this.tableName}.created_at <= to_timestamp(${(0, timestamp_1.translateDateToUTC)(granule.created_at)})`));
122
+ }
123
+ upsertQuery.returning('*');
124
+ return await upsertQuery;
114
125
  }
115
126
  /**
116
127
  * Get granules from the granule cumulus_id
@@ -1,5 +1,5 @@
1
1
  import { Knex } from 'knex';
2
- import { ApiGranule } from '@cumulus/types/api/granules';
2
+ import { ApiGranule, ApiGranuleRecord } from '@cumulus/types/api/granules';
3
3
  import { CollectionPgModel } from '../models/collection';
4
4
  import { PdrPgModel } from '../models/pdr';
5
5
  import { ProviderPgModel } from '../models/provider';
@@ -31,22 +31,22 @@ export declare const translatePostgresGranuleToApiGranule: ({ granulePgRecord, c
31
31
  pdrPgModel?: PdrPgModel | undefined;
32
32
  providerPgModel?: ProviderPgModel | undefined;
33
33
  filePgModel?: FilePgModel | undefined;
34
- }) => Promise<ApiGranule>;
34
+ }) => Promise<ApiGranuleRecord>;
35
35
  /**
36
36
  * Generate a Postgres granule record from a DynamoDB record.
37
37
  *
38
38
  * @param {Object} params
39
- * @param {AWS.DynamoDB.DocumentClient.AttributeMap} params.dynamoRecord
39
+ * @param {ApiGranule} params.dynamoRecord
40
40
  * Record from DynamoDB
41
41
  * @param {Knex | Knex.Transaction} params.knexOrTransaction
42
42
  * Knex client for reading from RDS database
43
- * @param {Object} params.collectionPgModel - Instance of the collection database model
44
- * @param {Object} params.pdrPgModel - Instance of the pdr database model
45
- * @param {Object} params.providerPgModel - Instance of the provider database model
46
- * @returns {Object} A granule PG record
43
+ * @param {CollectionPgModel} params.collectionPgModel - Instance of the collection database model
44
+ * @param {PdrPgModel} params.pdrPgModel - Instance of the pdr database model
45
+ * @param {ProviderPgModel} params.providerPgModel - Instance of the provider database model
46
+ * @returns {PostgresGranule} A granule PG record
47
47
  */
48
48
  export declare const translateApiGranuleToPostgresGranuleWithoutNilsRemoved: ({ dynamoRecord, knexOrTransaction, collectionPgModel, pdrPgModel, providerPgModel, }: {
49
- dynamoRecord: AWS.DynamoDB.DocumentClient.AttributeMap;
49
+ dynamoRecord: ApiGranule;
50
50
  knexOrTransaction: Knex | Knex.Transaction;
51
51
  collectionPgModel?: CollectionPgModel | undefined;
52
52
  pdrPgModel?: PdrPgModel | undefined;
@@ -57,17 +57,17 @@ export declare const translateApiGranuleToPostgresGranuleWithoutNilsRemoved: ({
57
57
  * any null/undefined properties.
58
58
  *
59
59
  * @param {Object} params
60
- * @param {AWS.DynamoDB.DocumentClient.AttributeMap} params.dynamoRecord
60
+ * @param {ApiGranule} params.dynamoRecord
61
61
  * Record from DynamoDB
62
62
  * @param {Knex | Knex.Transaction} params.knexOrTransaction
63
63
  * Knex client for reading from RDS database
64
- * @param {Object} params.collectionPgModel - Instance of the collection database model
65
- * @param {Object} params.pdrPgModel - Instance of the pdr database model
66
- * @param {Object} params.providerPgModel - Instance of the provider database model
67
- * @returns {Object} A granule PG record with null/undefined properties removed
64
+ * @param {CollectionPgModel} params.collectionPgModel - Instance of the collection database model
65
+ * @param {PdrPgModel} params.pdrPgModel - Instance of the pdr database model
66
+ * @param {ProviderPgModel} params.providerPgModel - Instance of the provider database model
67
+ * @returns {PostgresGranule} A granule PG record with null/undefined properties removed
68
68
  */
69
69
  export declare const translateApiGranuleToPostgresGranule: ({ dynamoRecord, knexOrTransaction, collectionPgModel, pdrPgModel, providerPgModel, }: {
70
- dynamoRecord: AWS.DynamoDB.DocumentClient.AttributeMap;
70
+ dynamoRecord: ApiGranule;
71
71
  knexOrTransaction: Knex | Knex.Transaction;
72
72
  collectionPgModel?: CollectionPgModel | undefined;
73
73
  pdrPgModel?: PdrPgModel | undefined;
@@ -1,9 +1,14 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.translatePostgresGranuleResultToApiGranule = exports.translateApiGranuleToPostgresGranule = exports.translateApiGranuleToPostgresGranuleWithoutNilsRemoved = exports.translatePostgresGranuleToApiGranule = void 0;
4
7
  const Collections_1 = require("@cumulus/message/Collections");
5
8
  const util_1 = require("@cumulus/common/util");
6
9
  const errors_1 = require("@cumulus/errors");
10
+ const isNil_1 = __importDefault(require("lodash/isNil"));
11
+ const isNull_1 = __importDefault(require("lodash/isNull"));
7
12
  const collection_1 = require("../models/collection");
8
13
  const pdr_1 = require("../models/pdr");
9
14
  const provider_1 = require("../models/provider");
@@ -57,7 +62,7 @@ const translatePostgresGranuleToApiGranule = async ({ granulePgRecord, collectio
57
62
  endingDateTime: (_c = granulePgRecord.ending_date_time) === null || _c === void 0 ? void 0 : _c.toISOString(),
58
63
  error: granulePgRecord.error,
59
64
  execution: executionUrls[0] ? executionUrls[0].url : undefined,
60
- files: files.length > 0 ? files.map((file) => (0, file_2.translatePostgresFileToApiFile)(file)) : undefined,
65
+ files: files.length > 0 ? files.map((file) => (0, file_2.translatePostgresFileToApiFile)(file)) : [],
61
66
  granuleId: granulePgRecord.granule_id,
62
67
  lastUpdateDateTime: (_d = granulePgRecord.last_update_date_time) === null || _d === void 0 ? void 0 : _d.toISOString(),
63
68
  pdrName: pdr ? pdr.name : undefined,
@@ -77,21 +82,63 @@ const translatePostgresGranuleToApiGranule = async ({ granulePgRecord, collectio
77
82
  return apiGranule;
78
83
  };
79
84
  exports.translatePostgresGranuleToApiGranule = translatePostgresGranuleToApiGranule;
85
+ const returnNullOrUndefinedOrDate = (dateVal) => ((0, isNil_1.default)(dateVal) ? dateVal : new Date(dateVal));
86
+ /**
87
+ * Validate translation request doesn't contain invalid null files based
88
+ * on onPostgresGranule typings. Throw if invalid nulls detected
89
+ *
90
+ * @param {Object} params
91
+ * @param {ApiGranule} apiGranule
92
+ * Record from DynamoDB
93
+ * @returns {undefined}
94
+ */
95
+ const validateApiToPostgresGranuleObject = (apiGranule) => {
96
+ if ((0, isNil_1.default)(apiGranule.collectionId)) {
97
+ throw new errors_1.ValidationError('collectionId cannot be undefined on a granule, granules must have a collection and a granule ID');
98
+ }
99
+ if ((0, isNil_1.default)(apiGranule.granuleId)) {
100
+ throw new errors_1.ValidationError('granuleId cannot be undefined on a granule, granules must have a collection and a granule ID');
101
+ }
102
+ if ((0, isNull_1.default)(apiGranule.status)) {
103
+ throw new errors_1.ValidationError('status cannot be null on a granule, granules must have a collection and a granule ID');
104
+ }
105
+ };
80
106
  /**
81
107
  * Generate a Postgres granule record from a DynamoDB record.
82
108
  *
83
109
  * @param {Object} params
84
- * @param {AWS.DynamoDB.DocumentClient.AttributeMap} params.dynamoRecord
110
+ * @param {ApiGranule} params.dynamoRecord
85
111
  * Record from DynamoDB
86
112
  * @param {Knex | Knex.Transaction} params.knexOrTransaction
87
113
  * Knex client for reading from RDS database
88
- * @param {Object} params.collectionPgModel - Instance of the collection database model
89
- * @param {Object} params.pdrPgModel - Instance of the pdr database model
90
- * @param {Object} params.providerPgModel - Instance of the provider database model
91
- * @returns {Object} A granule PG record
114
+ * @param {CollectionPgModel} params.collectionPgModel - Instance of the collection database model
115
+ * @param {PdrPgModel} params.pdrPgModel - Instance of the pdr database model
116
+ * @param {ProviderPgModel} params.providerPgModel - Instance of the provider database model
117
+ * @returns {PostgresGranule} A granule PG record
92
118
  */
93
119
  const translateApiGranuleToPostgresGranuleWithoutNilsRemoved = async ({ dynamoRecord, knexOrTransaction, collectionPgModel = new collection_1.CollectionPgModel(), pdrPgModel = new pdr_1.PdrPgModel(), providerPgModel = new provider_1.ProviderPgModel(), }) => {
120
+ // Invalid Null values should be validated as the primary use in Core
121
+ // is the non-typescripted API package.
122
+ validateApiToPostgresGranuleObject(dynamoRecord);
94
123
  const { name, version } = (0, Collections_1.deconstructCollectionId)(dynamoRecord.collectionId);
124
+ // eslint-disable-next-line @typescript-eslint/naming-convention
125
+ let pdr_cumulus_id;
126
+ if ((0, isNil_1.default)(dynamoRecord.pdrName)) {
127
+ pdr_cumulus_id = dynamoRecord.pdrName;
128
+ }
129
+ else {
130
+ pdr_cumulus_id = await pdrPgModel.getRecordCumulusId(knexOrTransaction, {
131
+ name: dynamoRecord.pdrName,
132
+ });
133
+ }
134
+ // eslint-disable-next-line @typescript-eslint/naming-convention
135
+ let provider_cumulus_id;
136
+ if ((0, isNil_1.default)(dynamoRecord.provider)) {
137
+ provider_cumulus_id = dynamoRecord.provider;
138
+ }
139
+ else {
140
+ provider_cumulus_id = await providerPgModel.getRecordCumulusId(knexOrTransaction, { name: dynamoRecord.provider });
141
+ }
95
142
  const granuleRecord = {
96
143
  granule_id: dynamoRecord.granuleId,
97
144
  status: dynamoRecord.status,
@@ -100,30 +147,23 @@ const translateApiGranuleToPostgresGranuleWithoutNilsRemoved = async ({ dynamoRe
100
147
  duration: dynamoRecord.duration,
101
148
  time_to_archive: dynamoRecord.timeToArchive,
102
149
  time_to_process: dynamoRecord.timeToPreprocess,
103
- product_volume: dynamoRecord.productVolume,
150
+ product_volume: (0, isNil_1.default)(dynamoRecord.productVolume)
151
+ ? dynamoRecord.productVolume
152
+ : dynamoRecord.productVolume,
104
153
  error: dynamoRecord.error,
105
154
  cmr_link: dynamoRecord.cmrLink,
106
- pdr_cumulus_id: dynamoRecord.pdrName
107
- ? await pdrPgModel.getRecordCumulusId(knexOrTransaction, { name: dynamoRecord.pdrName })
108
- : undefined,
109
- provider_cumulus_id: dynamoRecord.provider ? await providerPgModel.getRecordCumulusId(knexOrTransaction, { name: dynamoRecord.provider }) : undefined,
155
+ pdr_cumulus_id,
156
+ provider_cumulus_id,
110
157
  query_fields: dynamoRecord.queryFields,
111
- beginning_date_time: dynamoRecord.beginningDateTime
112
- ? new Date(dynamoRecord.beginningDateTime) : undefined,
113
- ending_date_time: dynamoRecord.endingDateTime
114
- ? new Date(dynamoRecord.endingDateTime) : undefined,
115
- last_update_date_time: dynamoRecord.lastUpdateDateTime
116
- ? new Date(dynamoRecord.lastUpdateDateTime) : undefined,
117
- processing_end_date_time: dynamoRecord.processingEndDateTime
118
- ? new Date(dynamoRecord.processingEndDateTime) : undefined,
119
- processing_start_date_time: dynamoRecord.processingStartDateTime
120
- ? new Date(dynamoRecord.processingStartDateTime) : undefined,
121
- production_date_time: dynamoRecord.productionDateTime
122
- ? new Date(dynamoRecord.productionDateTime) : undefined,
123
- timestamp: dynamoRecord.timestamp
124
- ? new Date(dynamoRecord.timestamp) : undefined,
125
- created_at: new Date(dynamoRecord.createdAt),
126
- updated_at: new Date(dynamoRecord.updatedAt),
158
+ beginning_date_time: returnNullOrUndefinedOrDate(dynamoRecord.beginningDateTime),
159
+ ending_date_time: returnNullOrUndefinedOrDate(dynamoRecord.endingDateTime),
160
+ last_update_date_time: returnNullOrUndefinedOrDate(dynamoRecord.lastUpdateDateTime),
161
+ processing_end_date_time: returnNullOrUndefinedOrDate(dynamoRecord.processingEndDateTime),
162
+ processing_start_date_time: returnNullOrUndefinedOrDate(dynamoRecord.processingStartDateTime),
163
+ production_date_time: returnNullOrUndefinedOrDate(dynamoRecord.productionDateTime),
164
+ timestamp: returnNullOrUndefinedOrDate(dynamoRecord.timestamp),
165
+ created_at: returnNullOrUndefinedOrDate(dynamoRecord.createdAt),
166
+ updated_at: returnNullOrUndefinedOrDate(dynamoRecord.updatedAt),
127
167
  };
128
168
  return granuleRecord;
129
169
  };
@@ -133,14 +173,14 @@ exports.translateApiGranuleToPostgresGranuleWithoutNilsRemoved = translateApiGra
133
173
  * any null/undefined properties.
134
174
  *
135
175
  * @param {Object} params
136
- * @param {AWS.DynamoDB.DocumentClient.AttributeMap} params.dynamoRecord
176
+ * @param {ApiGranule} params.dynamoRecord
137
177
  * Record from DynamoDB
138
178
  * @param {Knex | Knex.Transaction} params.knexOrTransaction
139
179
  * Knex client for reading from RDS database
140
- * @param {Object} params.collectionPgModel - Instance of the collection database model
141
- * @param {Object} params.pdrPgModel - Instance of the pdr database model
142
- * @param {Object} params.providerPgModel - Instance of the provider database model
143
- * @returns {Object} A granule PG record with null/undefined properties removed
180
+ * @param {CollectionPgModel} params.collectionPgModel - Instance of the collection database model
181
+ * @param {PdrPgModel} params.pdrPgModel - Instance of the pdr database model
182
+ * @param {ProviderPgModel} params.providerPgModel - Instance of the provider database model
183
+ * @returns {PostgresGranule} A granule PG record with null/undefined properties removed
144
184
  */
145
185
  const translateApiGranuleToPostgresGranule = async ({ dynamoRecord, knexOrTransaction, collectionPgModel = new collection_1.CollectionPgModel(), pdrPgModel = new pdr_1.PdrPgModel(), providerPgModel = new provider_1.ProviderPgModel(), }) => (0, util_1.removeNilProperties)(await (0, exports.translateApiGranuleToPostgresGranuleWithoutNilsRemoved)({
146
186
  dynamoRecord,
@@ -1,33 +1,35 @@
1
+ export declare type GranuleStatus = 'completed' | 'failed' | 'running' | 'queued';
1
2
  export interface PostgresGranuleUniqueColumns {
2
3
  granule_id: string;
3
4
  collection_cumulus_id: number;
4
5
  }
5
6
  export interface PostgresGranule extends PostgresGranuleUniqueColumns {
6
- status: string;
7
- cmr_link?: string;
8
- error?: object;
9
- published?: boolean;
10
- duration?: number;
11
- product_volume?: number;
12
- time_to_process?: number;
13
- time_to_archive?: number;
14
- provider_cumulus_id?: number;
15
- pdr_cumulus_id?: number;
16
- created_at?: Date;
17
- updated_at?: Date;
18
- timestamp?: Date;
19
- beginning_date_time?: Date;
20
- ending_date_time?: Date;
21
- production_date_time?: Date;
22
- last_update_date_time?: Date;
23
- processing_start_date_time?: Date;
24
- processing_end_date_time?: Date;
25
- query_fields?: unknown;
7
+ status?: GranuleStatus;
8
+ cmr_link?: string | null;
9
+ error?: object | null;
10
+ published?: boolean | null;
11
+ duration?: number | null;
12
+ product_volume?: string | null;
13
+ time_to_process?: number | null;
14
+ time_to_archive?: number | null;
15
+ provider_cumulus_id?: number | null;
16
+ pdr_cumulus_id?: number | null;
17
+ created_at?: Date | null;
18
+ updated_at?: Date | null;
19
+ timestamp?: Date | null;
20
+ beginning_date_time?: Date | null;
21
+ ending_date_time?: Date | null;
22
+ production_date_time?: Date | null;
23
+ last_update_date_time?: Date | null;
24
+ processing_start_date_time?: Date | null;
25
+ processing_end_date_time?: Date | null;
26
+ query_fields?: unknown | null;
26
27
  }
27
28
  export interface PostgresGranuleRecord extends Omit<PostgresGranule, 'product_volume'> {
28
29
  cumulus_id: number;
29
30
  product_volume?: string;
30
31
  created_at: Date;
31
32
  updated_at: Date;
33
+ status: GranuleStatus;
32
34
  }
33
35
  //# sourceMappingURL=granule.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cumulus/db",
3
- "version": "13.3.3-alpha.1",
3
+ "version": "14.0.0",
4
4
  "description": "Utilities for working with the Cumulus DB",
5
5
  "license": "Apache-2.0",
6
6
  "main": "./dist/index.js",
@@ -29,12 +29,12 @@
29
29
  "node": ">=14.19.1"
30
30
  },
31
31
  "dependencies": {
32
- "@cumulus/aws-client": "13.3.3-alpha.1",
33
- "@cumulus/common": "13.3.3-alpha.1",
34
- "@cumulus/errors": "13.3.3-alpha.1",
35
- "@cumulus/logger": "13.3.3-alpha.1",
36
- "@cumulus/message": "13.3.3-alpha.1",
37
- "@cumulus/types": "13.3.3-alpha.1",
32
+ "@cumulus/aws-client": "14.0.0",
33
+ "@cumulus/common": "14.0.0",
34
+ "@cumulus/errors": "14.0.0",
35
+ "@cumulus/logger": "14.0.0",
36
+ "@cumulus/message": "14.0.0",
37
+ "@cumulus/types": "14.0.0",
38
38
  "crypto-random-string": "^3.2.0",
39
39
  "is-valid-hostname": "1.0.2",
40
40
  "knex": "0.95.15",
@@ -46,5 +46,5 @@
46
46
  "devDependencies": {
47
47
  "@types/uuid": "^8.0.0"
48
48
  },
49
- "gitHead": "090ed401e9e31ba52c070e4a5ab5125aedf90396"
49
+ "gitHead": "bc0cd0857e007b64e4e8809f7de16a4aeb1e6840"
50
50
  }