fix: sync main data source fields for renamed view collections (#9155)

This commit is contained in:
YANG QIA
2026-04-20 10:16:30 +08:00
committed by GitHub
parent fdfbf4256c
commit 321345fc05
2 changed files with 68 additions and 1 deletions
+3 -1
View File
@@ -119,7 +119,9 @@ export class MainDataSource extends SequelizeDataSource {
const loadedData = {};
for (const collection of collections) {
const c = db.getCollection(collection.name);
loadedData[c.tableName()] = {
// Use the physical table/view name so view collections whose logical name
// differs from `viewName` can still be matched during introspection sync.
loadedData[c.model.tableName] = {
...collection.toJSON(),
fields: collection.fields.map((field: Model) => {
const f = c.getField(field.name);
@@ -412,6 +412,71 @@ SELECT * FROM numbers;
expect(viewCollectionWithEmail.getField('email')).toBeTruthy();
});
it.each([
{ collectionName: 'view', viewName: 'test_view' },
{ collectionName: 'test_view', viewName: 'test_view' },
])(
'should sync main data source fields when collection name is $collectionName and underlying view is $viewName',
async ({ collectionName, viewName }) => {
await app.db.getRepository('collections').create({
values: {
name: 'users',
fields: [
{
name: 'name',
type: 'string',
},
],
},
context: {},
});
await app.db.sync();
const UserCollection = app.db.getCollection('users');
const createViewName = app.db.options.schema ? `${app.db.options.schema}.${viewName}` : viewName;
const dropSQL = `DROP VIEW IF EXISTS ${createViewName}`;
await app.db.sequelize.query(dropSQL);
const viewSQL = `CREATE VIEW ${createViewName} AS SELECT * FROM ${UserCollection.quotedTableName()}`;
await app.db.sequelize.query(viewSQL);
const viewDetailResponse = await agent.resource('dbViews').get({
filterByTk: viewName,
schema: app.db.options.schema,
});
await app.db.getRepository('collections').create({
values: {
name: collectionName,
view: true,
viewName,
schema: app.db.inDialect('postgres') ? app.db.options.schema || 'public' : undefined,
fields: Object.values(viewDetailResponse.body.data.fields),
},
context: {},
});
UserCollection.addField('email', { type: 'string' });
await app.db.sync();
await app.db.sequelize.query(dropSQL);
const viewSQL2 = `CREATE VIEW ${createViewName} AS SELECT * FROM ${UserCollection.quotedTableName()}`;
await app.db.sequelize.query(viewSQL2);
const syncResponse = await agent.resource('mainDataSource').syncFields();
expect(syncResponse.status).toEqual(200);
const viewCollectionModel = await app.db.getRepository('collections').findOne({
filter: {
name: collectionName,
},
appends: ['fields'],
});
expect(viewCollectionModel.fields.some((field) => field.name === 'email')).toBeTruthy();
},
);
it('should access view collection resource', async () => {
const UserCollection = app.db.collection({
name: 'users',