mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-05-01 05:03:57 +00:00
Merge branch 'master' of https://github.com/dbgate/dbgate
This commit is contained in:
@@ -82,6 +82,9 @@ async function testDatabaseDeploy(engine, conn, driver, dbModelsYaml, options) {
|
|||||||
dbdiffOptionsExtra.schemaMode = 'ignore';
|
dbdiffOptionsExtra.schemaMode = 'ignore';
|
||||||
|
|
||||||
for (const loadedDbModel of dbModelsYaml) {
|
for (const loadedDbModel of dbModelsYaml) {
|
||||||
|
if (_.isString(loadedDbModel)) {
|
||||||
|
await driver.script(conn, loadedDbModel);
|
||||||
|
} else {
|
||||||
const { sql, isEmpty } = await generateDeploySql({
|
const { sql, isEmpty } = await generateDeploySql({
|
||||||
systemConnection: conn.isPreparedOnly ? undefined : conn,
|
systemConnection: conn.isPreparedOnly ? undefined : conn,
|
||||||
connection: conn.isPreparedOnly ? conn : undefined,
|
connection: conn.isPreparedOnly ? conn : undefined,
|
||||||
@@ -106,6 +109,7 @@ async function testDatabaseDeploy(engine, conn, driver, dbModelsYaml, options) {
|
|||||||
loadedDbModel,
|
loadedDbModel,
|
||||||
dbdiffOptionsExtra,
|
dbdiffOptionsExtra,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
@@ -416,6 +420,48 @@ describe('Deploy database', () => {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
test.each(engines.map(engine => [engine.label, engine]))(
|
||||||
|
'Change column to NOT NULL column with default - %s',
|
||||||
|
testWrapper(async (conn, driver, engine) => {
|
||||||
|
await testDatabaseDeploy(engine, conn, driver, [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
name: 't1.table.yaml',
|
||||||
|
json: {
|
||||||
|
name: 't1',
|
||||||
|
columns: [
|
||||||
|
{ name: 'id', type: 'int', notNull: true },
|
||||||
|
{ name: 'val', type: 'int' },
|
||||||
|
],
|
||||||
|
|
||||||
|
primaryKey: ['id'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'insert into t1 (id, val) values (1, 1); insert into t1 (id) values (2)',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
name: 't1.table.yaml',
|
||||||
|
json: {
|
||||||
|
name: 't1',
|
||||||
|
columns: [
|
||||||
|
{ name: 'id', type: 'int', notNull: true },
|
||||||
|
{ name: 'val', type: 'int', notNull: true, default: '20' },
|
||||||
|
],
|
||||||
|
primaryKey: ['id'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
const res1 = await driver.query(conn, `select val from t1 where id = 1`);
|
||||||
|
expect(res1.rows[0].val).toEqual(1);
|
||||||
|
|
||||||
|
const res2 = await driver.query(conn, `select val from t1 where id = 2`);
|
||||||
|
expect(res2.rows[0].val).toEqual(20);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
const T1 = {
|
const T1 = {
|
||||||
name: 't1.table.yaml',
|
name: 't1.table.yaml',
|
||||||
json: {
|
json: {
|
||||||
@@ -428,6 +474,18 @@ describe('Deploy database', () => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const T2 = {
|
||||||
|
name: 't2.table.yaml',
|
||||||
|
json: {
|
||||||
|
name: 't2',
|
||||||
|
columns: [
|
||||||
|
{ name: 'id', type: 'int' },
|
||||||
|
{ name: 'val', type: 'int' },
|
||||||
|
],
|
||||||
|
primaryKey: ['id'],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
const T1_DELETED = {
|
const T1_DELETED = {
|
||||||
name: '_deleted_t1.table.yaml',
|
name: '_deleted_t1.table.yaml',
|
||||||
json: {
|
json: {
|
||||||
@@ -686,4 +744,15 @@ describe('Deploy database', () => {
|
|||||||
expect(res5.rows[0].run_count == 2).toBeTruthy();
|
expect(res5.rows[0].run_count == 2).toBeTruthy();
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
test.each(engines.map(engine => [engine.label, engine]))(
|
||||||
|
'Mark table removed, one remains - %s',
|
||||||
|
testWrapper(async (conn, driver, engine) => {
|
||||||
|
await testDatabaseDeploy(engine, conn, driver, [[T1, T2], [T2], [T2]], {
|
||||||
|
markDeleted: true,
|
||||||
|
disallowExtraObjects: true,
|
||||||
|
finalCheckAgainstModel: [T1_DELETED, T2],
|
||||||
|
});
|
||||||
|
})
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -731,6 +731,12 @@ export class SqlDumper implements AlterProcessor {
|
|||||||
this.put(formatString, optionValue);
|
this.put(formatString, optionValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fillNewNotNullDefaults(col: ColumnInfo) {
|
||||||
|
if (col.notNull && col.defaultValue != null) {
|
||||||
|
this.putCmd('^update %f ^set %i = %s ^where %i ^is ^null', col, col.columnName, col.defaultValue, col.columnName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fillPreloadedRows(
|
fillPreloadedRows(
|
||||||
table: NamedObjectInfo,
|
table: NamedObjectInfo,
|
||||||
oldRows: any[],
|
oldRows: any[],
|
||||||
|
|||||||
@@ -459,7 +459,7 @@ export class AlterPlan {
|
|||||||
// console.log('*****************RECREATED NEEDED', op, operationType, isAllowed);
|
// console.log('*****************RECREATED NEEDED', op, operationType, isAllowed);
|
||||||
// console.log(this.dialect);
|
// console.log(this.dialect);
|
||||||
|
|
||||||
if (!this.opts.allowTableRecreate) {
|
if (this.opts.noDropTable && !this.opts.allowTableRecreate) {
|
||||||
// skip this operation, as it cannot be achieved
|
// skip this operation, as it cannot be achieved
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,6 +132,7 @@ class MsSqlDumper extends SqlDumper {
|
|||||||
} else {
|
} else {
|
||||||
this.dropDefault(oldcol);
|
this.dropDefault(oldcol);
|
||||||
if (oldcol.columnName != newcol.columnName) this.renameColumn(oldcol, newcol.columnName);
|
if (oldcol.columnName != newcol.columnName) this.renameColumn(oldcol, newcol.columnName);
|
||||||
|
this.fillNewNotNullDefaults(newcol);
|
||||||
this.put('^alter ^table %f ^alter ^column %i ', oldcol, oldcol.columnName, newcol.columnName);
|
this.put('^alter ^table %f ^alter ^column %i ', oldcol, oldcol.columnName, newcol.columnName);
|
||||||
this.columnDefinition(newcol, { includeDefault: false });
|
this.columnDefinition(newcol, { includeDefault: false });
|
||||||
this.endCommand();
|
this.endCommand();
|
||||||
|
|||||||
@@ -76,10 +76,6 @@ class Dumper extends SqlDumper {
|
|||||||
if (!testEqualTypes(oldcol, newcol)) {
|
if (!testEqualTypes(oldcol, newcol)) {
|
||||||
this.putCmd('^alter ^table %f ^alter ^column %i ^type %s', oldcol, newcol.columnName, newcol.dataType);
|
this.putCmd('^alter ^table %f ^alter ^column %i ^type %s', oldcol, newcol.columnName, newcol.dataType);
|
||||||
}
|
}
|
||||||
if (oldcol.notNull != newcol.notNull) {
|
|
||||||
if (newcol.notNull) this.putCmd('^alter ^table %f ^alter ^column %i ^set ^not ^null', newcol, newcol.columnName);
|
|
||||||
else this.putCmd('^alter ^table %f ^alter ^column %i ^drop ^not ^null', newcol, newcol.columnName);
|
|
||||||
}
|
|
||||||
if (oldcol.defaultValue != newcol.defaultValue) {
|
if (oldcol.defaultValue != newcol.defaultValue) {
|
||||||
if (newcol.defaultValue == null) {
|
if (newcol.defaultValue == null) {
|
||||||
this.putCmd('^alter ^table %f ^alter ^column %i ^drop ^default', newcol, newcol.columnName);
|
this.putCmd('^alter ^table %f ^alter ^column %i ^drop ^default', newcol, newcol.columnName);
|
||||||
@@ -92,6 +88,11 @@ class Dumper extends SqlDumper {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (oldcol.notNull != newcol.notNull) {
|
||||||
|
this.fillNewNotNullDefaults(newcol);
|
||||||
|
if (newcol.notNull) this.putCmd('^alter ^table %f ^alter ^column %i ^set ^not ^null', newcol, newcol.columnName);
|
||||||
|
else this.putCmd('^alter ^table %f ^alter ^column %i ^drop ^not ^null', newcol, newcol.columnName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
putValue(value) {
|
putValue(value) {
|
||||||
|
|||||||
Reference in New Issue
Block a user