@sap/cds-mtx
Advanced tools
Comparing version 2.4.1 to 2.4.2
@@ -9,4 +9,13 @@ # Change Log | ||
## Version 2.4.2 - 2021-12-2 | ||
### Fixed | ||
- Authentication request for cds extension client is now returning token again | ||
- `hdbmigrationtable` files from an updated model with multiple new migration versions | ||
are now correctly merged with tenant specific `hdbmigrationtable` files | ||
## Version 2.4.1 - 2021-11-09 | ||
### Fixed | ||
@@ -13,0 +22,0 @@ - Additional HDI_DEPLOY_OPTIONS do no longer affect the stability |
@@ -149,3 +149,3 @@ const fs = require('fs'); | ||
// merge tenantMigration file with base migration file and build result migration file | ||
const finalHmt = tenantHmt.merge(newBaseHmt, buildResultHmt.table); | ||
const finalHmt = tenantHmt.merge(newBaseHmt, buildResultHmt.table, false); // TODO activate in next rel | ||
this.logger.debug(`Merged migrations for ${filename}: ${finalHmt.migrations}`); | ||
@@ -152,0 +152,0 @@ this.logger.debug(`Merged table statement for ${filename}: ${finalHmt.table}`); |
const { fs } = require('@sap/cds-foss') | ||
class MigrationTableParser { | ||
@@ -215,5 +214,5 @@ constructor() { | ||
* | ||
* A---B---E---F extension | ||
* / | ||
* A---B---C base | ||
* A---B---E---F extension X---Y extension | ||
* / / | ||
* A---B---C base A---B base | ||
* | ||
@@ -224,5 +223,5 @@ * || upgrade extension with base - migration version C is inserted into extension, its version number is updated, | ||
* | ||
* A---B---E---F---C extension | ||
* / | ||
* A---B---C base | ||
* A---B---E---F---C extension A---B---X---Y extension | ||
* / / | ||
* A---B---C base A---B base | ||
* | ||
@@ -235,13 +234,14 @@ * @param {MigrationTableModel} base The new base migration table version from which all missing migration versions | ||
*/ | ||
merge(base, targetTable) { | ||
let idxMaster = base.migrations.entries.findIndex(baseMigration => { | ||
return this.migrations.entries.some(extensionMigration => this._compareMigrations(extensionMigration, baseMigration)) | ||
}) | ||
merge(base, targetTable, addBaseVersionAnnotation) { | ||
let idxBase = this._findCommonBaseMigrationIdx(base) | ||
const mergeResult = new MigrationTableModel(targetTable, this.migrations.clone()) | ||
// insert all migration versions of master | ||
for (let idx = idxMaster === - 1 ? base.migrations.entries.length - 1 : idxMaster - 1; idx >= 0; idx--) { | ||
// insert all migration versions since the histories diverged | ||
for (let idx = idxBase >= 0 ? idxBase - 1 : base.migrations.entries.length - 1, versionNumber = this.versionNumber + 1; idx >= 0; idx--, versionNumber++) { | ||
const migration = base.migrations.entries[idx].clone(); | ||
if (addBaseVersionAnnotation) { | ||
migration._addBaseMigrationVersion(migration.versionNumber) | ||
} | ||
// update migration version number and insert at beginning | ||
migration.versionNumber = this.versionNumber + 1 | ||
mergeResult.table.versionNumber = this.versionNumber + 1 | ||
migration.versionNumber = mergeResult.table.versionNumber = versionNumber | ||
mergeResult.migrations.entries.splice(0, 0, migration) | ||
@@ -256,10 +256,60 @@ } | ||
// migrations are identical if the underlying changesets are identical | ||
_compareMigrations(migration1, migration2) { | ||
return this._compactStr(migration1.changeset) === this._compactStr(migration2.changeset) | ||
/** | ||
* Returns the index of the common base migration version (since the time their histories diverged) | ||
* or -1 if there is no common base. The index points to the base migration table model. | ||
* @param {MigrationTableModel} base The new base migration table version. | ||
* @returns The index of the common base migration, -1 if there is no common base. | ||
*/ | ||
_findCommonBaseMigrationIdx(base) { | ||
// get the index based on the annotation '-- migration-base=<version number>' | ||
const extMigration = this.migrations.entries.find(extMigration => extMigration._getBaseMigrationVersion() !== -1) | ||
// get the index based on DDL equality | ||
const idxBase = base.migrations.entries.findIndex(baseMigration => { | ||
return this.migrations.entries.some(extMigration => this._compareMigrations(baseMigration, extMigration)) | ||
}) | ||
if (!extMigration && idxBase === -1) { | ||
// no common base version - all good | ||
return -1 | ||
} | ||
if (extMigration && idxBase !== -1 && extMigration._getBaseMigrationVersion() === base.migrations.entries[idxBase].versionNumber) { | ||
// both indices refer to the same base version - all good | ||
return idxBase | ||
} | ||
// differences encountered, cause might be: | ||
// 1. older versions may not add 'migration-base' annotations | ||
// 2. the same DDL statements might exist in different migrations | ||
if (!extMigration && idxBase !== -1) { | ||
// if migration-base annotations do not exist use equality of DDL statements | ||
// older versions did not add 'migration-base' annotations - most probably all good | ||
return idxBase | ||
} | ||
if (extMigration) { | ||
// favor 'migration-base' annotation over DDL statement equality | ||
const baseVersion = extMigration._getBaseMigrationVersion() | ||
const idxBase = base.migrations.entries.findIndex(baseMigration => baseMigration.versionNumber === baseVersion) | ||
if (idxBase > -1) { | ||
return idxBase | ||
} | ||
} | ||
return idxBase | ||
} | ||
_compactStr(array) { | ||
return JSON.stringify(array.map(change => change.replace(/ /g, ''))) | ||
/** | ||
* Migrations are identical if the corresponding DDL statements are identical, | ||
* ignoring order and ignoring comments. | ||
*/ | ||
_compareMigrations(m1, m2) { | ||
if (m1.ddl.length !== m2.ddl.length) { | ||
return false | ||
} | ||
const mDdl2 = m2.ddl.map(entry => this._compactLine(entry)) | ||
return m1.ddl.some(entry => mDdl2.includes(this._compactLine(entry))) | ||
} | ||
/** | ||
* Delete comments and return only those lines representing DDL statements. | ||
*/ | ||
_compactLine(line) { | ||
return line.replace(/ /g, '') | ||
} | ||
} | ||
@@ -356,3 +406,2 @@ | ||
this._versionNumber = MigrationTableParser._parseVersionNumber(this.lines[0]) | ||
this._changeset = this._lines.filter(line => !MigrationTableParser._isMigrationMarker(line)) | ||
} | ||
@@ -386,3 +435,3 @@ | ||
get changeset() { | ||
return this._changeset | ||
return this._lines.filter(line => !MigrationTableParser._isMigrationMarker(line)) | ||
} | ||
@@ -398,2 +447,21 @@ | ||
_addBaseMigrationVersion(versionNumber) { | ||
this._addComment(1, `-- migration-base=${versionNumber}`) | ||
} | ||
_getBaseMigrationVersion() { | ||
let versionNumber = -1 | ||
if (this._lines.length > 1) { | ||
const match = this._lines[1].match(/(^\s*-- migration-base=)(\d+)\s*$/) | ||
if (match && match.length === 3) { | ||
versionNumber = parseInt(match[2]) | ||
} | ||
} | ||
return versionNumber | ||
} | ||
_addComment(start, comment) { | ||
this._lines.splice(start, 0, comment) | ||
} | ||
/** | ||
@@ -400,0 +468,0 @@ * Returns the string representation of this migration. |
@@ -103,3 +103,3 @@ const TenantMetadataPersistence = require('./tenant_metadata_persistence'); | ||
} catch (error) { | ||
if (error.statusCode === 404) { // offboarding is idempotent | ||
if (error.statusCode === 404 || error.code === 404) { // offboarding is idempotent | ||
this.logger.debug(error); | ||
@@ -223,5 +223,9 @@ } else { | ||
async _getMetadata(id, domain) { | ||
const result = await this._client.execute(CONTENT_METADATA_QUERY, [id, domain]); | ||
const [metadata] = result || []; | ||
return metadata || {}; | ||
try { | ||
const result = await this._client.execute(CONTENT_METADATA_QUERY, [id, domain]); | ||
return result && result[0] || {}; | ||
} catch (error) { | ||
this.logger.error(`Failed to query metadata for tenant '${id}' (domain: ${domain}): ${error}`); | ||
throw error; | ||
} | ||
} | ||
@@ -228,0 +232,0 @@ |
@@ -140,3 +140,3 @@ const Logger = require('../../helper/logger'); | ||
} catch (error) { | ||
if (error.statusCode === 404) { // offboarding is idempotent | ||
if (error.statusCode === 404 || error.code === 404) { // offboarding is idempotent | ||
logger.info(`Tenant ${tenantId} does not exist`); | ||
@@ -143,0 +143,0 @@ } else { |
@@ -93,3 +93,3 @@ const https = require('https'); | ||
: `/oauth/token?grant_type=password${passcode ? `&passcode=${passcode}` : ''}` | ||
) + '&scope=' + SecurityHelper.getAllRequiredScopesForRequest(); | ||
);// + '&scope=' + SecurityHelper.getAllRequiredScopesForRequest(); | ||
@@ -96,0 +96,0 @@ return { |
{ | ||
"name": "@sap/cds-mtx", | ||
"version": "2.4.1", | ||
"version": "2.4.2", | ||
"homepage": "https://cap.cloud.sap/", | ||
@@ -5,0 +5,0 @@ "author": "SAP SE (https://www.sap.com)", |
298477
5634