mirror of
https://github.com/nocobase/nocobase
synced 2024-11-16 20:46:35 +00:00
chore: update collection option
This commit is contained in:
parent
5bcc44a768
commit
fc175a7730
@ -1,7 +1,11 @@
|
|||||||
import { CollectionOptions, ICollection, ICollectionManager, IRepository } from './types';
|
import { CollectionOptions, ICollection, ICollectionManager, IRepository } from './types';
|
||||||
|
import { default as lodash } from 'lodash';
|
||||||
|
import merge from 'deepmerge';
|
||||||
|
import { Field } from '@nocobase/database';
|
||||||
|
|
||||||
export class Collection implements ICollection {
|
export class Collection implements ICollection {
|
||||||
repository: IRepository;
|
repository: IRepository;
|
||||||
|
fields: Map<string, any> = new Map<string, any>();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected options: CollectionOptions,
|
protected options: CollectionOptions,
|
||||||
@ -10,6 +14,30 @@ export class Collection implements ICollection {
|
|||||||
this.setRepository(options.repository);
|
this.setRepository(options.repository);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateOptions(options: CollectionOptions, mergeOptions?: any) {
|
||||||
|
let newOptions = lodash.cloneDeep(options);
|
||||||
|
newOptions = merge(this.options, newOptions, mergeOptions);
|
||||||
|
this.options = newOptions;
|
||||||
|
|
||||||
|
if (options.repository) {
|
||||||
|
this.setRepository(options.repository);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
setField(name: string, options: any) {
|
||||||
|
const field = this.getField(name);
|
||||||
|
|
||||||
|
if (field) {
|
||||||
|
field.updateOptions(options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getField<F extends Field>(name: string): F {
|
||||||
|
return this.fields.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
protected setRepository(repository: any) {
|
protected setRepository(repository: any) {
|
||||||
this.repository = this.collectionManager.getRegisteredRepository(repository || 'Repository');
|
this.repository = this.collectionManager.getRegisteredRepository(repository || 'Repository');
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,8 @@ export type CollectionOptions = {
|
|||||||
|
|
||||||
export interface ICollection {
|
export interface ICollection {
|
||||||
repository: any;
|
repository: any;
|
||||||
|
updateOptions(options: any): void;
|
||||||
|
setField(name: string, options: any): void;
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
export interface IModel {
|
export interface IModel {
|
||||||
@ -36,11 +38,13 @@ export interface ICollectionManager {
|
|||||||
getRegisteredRepository(key: string): IRepository;
|
getRegisteredRepository(key: string): IRepository;
|
||||||
|
|
||||||
defineCollection(options: CollectionOptions): ICollection;
|
defineCollection(options: CollectionOptions): ICollection;
|
||||||
|
|
||||||
extendCollection(collectionOptions: CollectionOptions, mergeOptions?: MergeOptions): ICollection;
|
extendCollection(collectionOptions: CollectionOptions, mergeOptions?: MergeOptions): ICollection;
|
||||||
|
|
||||||
hasCollection(name: string): boolean;
|
hasCollection(name: string): boolean;
|
||||||
getCollection(name: string): ICollection;
|
getCollection(name: string): ICollection;
|
||||||
|
|
||||||
|
getCollections(): Array<ICollection>;
|
||||||
getRepository<R = IRepository>(name: string, sourceId?: string | number): R;
|
getRepository<R = IRepository>(name: string, sourceId?: string | number): R;
|
||||||
sync(): Promise<void>;
|
sync(): Promise<void>;
|
||||||
}
|
}
|
||||||
|
@ -44,57 +44,85 @@ describe('data source', async () => {
|
|||||||
expect(mockDataSource).toBeInstanceOf(MockDataSource);
|
expect(mockDataSource).toBeInstanceOf(MockDataSource);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get collections from datasource', async () => {
|
describe('data source collections', () => {
|
||||||
const loadFn = vi.fn();
|
beforeEach(async () => {
|
||||||
|
class MockCollectionManager extends CollectionManager {}
|
||||||
|
class MockDataSource extends DataSource {
|
||||||
|
async load(): Promise<void> {
|
||||||
|
this.collectionManager.defineCollection({
|
||||||
|
name: 'posts',
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
type: 'string',
|
||||||
|
name: 'title',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'hasMany',
|
||||||
|
name: 'comments',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
class MockCollectionManager extends CollectionManager {}
|
this.collectionManager.defineCollection({
|
||||||
class MockDataSource extends DataSource {
|
name: 'comments',
|
||||||
async load(): Promise<void> {
|
fields: [
|
||||||
this.collectionManager.defineCollection({
|
{
|
||||||
name: 'mock',
|
type: 'string',
|
||||||
fields: [
|
name: 'content',
|
||||||
{
|
},
|
||||||
type: 'string',
|
{
|
||||||
name: 'title',
|
type: 'belongsTo',
|
||||||
},
|
name: 'post',
|
||||||
],
|
},
|
||||||
});
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
this.collectionManager.defineCollection({
|
createCollectionManager(options?: any) {
|
||||||
name: 'mock2',
|
return new MockCollectionManager();
|
||||||
fields: [
|
}
|
||||||
{
|
|
||||||
type: 'string',
|
|
||||||
name: 'title',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
createCollectionManager(options?: any) {
|
app.dataSourceManager.factory.register('mock', MockDataSource);
|
||||||
return new MockCollectionManager();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
app.dataSourceManager.factory.register('mock', MockDataSource);
|
await app.db.getRepository('dataSources').create({
|
||||||
|
values: {
|
||||||
await app.db.getRepository('dataSources').create({
|
key: 'mockInstance1',
|
||||||
values: {
|
type: 'mock',
|
||||||
key: 'mockInstance1',
|
displayName: 'Mock',
|
||||||
type: 'mock',
|
options: {},
|
||||||
displayName: 'Mock',
|
},
|
||||||
options: {},
|
});
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const listResp = await app.agent().resource('dataSources').list();
|
it('should get collections from datasource', async () => {
|
||||||
expect(listResp.status).toBe(200);
|
const listResp = await app.agent().resource('dataSources').list();
|
||||||
|
expect(listResp.status).toBe(200);
|
||||||
|
|
||||||
// get collections
|
// get collections
|
||||||
const collectionsResp = await app.agent().resource('dataSources.collections', 'mockInstance1').list();
|
const collectionsResp = await app.agent().resource('dataSources.collections', 'mockInstance1').list();
|
||||||
expect(collectionsResp.status).toBe(200);
|
expect(collectionsResp.status).toBe(200);
|
||||||
const data = collectionsResp.body.data;
|
const data = collectionsResp.body.data;
|
||||||
|
|
||||||
expect(data.length).toBe(2);
|
expect(data.length).toBe(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should edit datasource collections', async () => {
|
||||||
|
// edit collections
|
||||||
|
const editResp = await app
|
||||||
|
.agent()
|
||||||
|
.resource('dataSources.collections', 'mockInstance1.posts')
|
||||||
|
.update({
|
||||||
|
values: {
|
||||||
|
title: '标题 Collection',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(editResp.status).toBe(200);
|
||||||
|
|
||||||
|
const dataSource = app.dataSourceManager.dataSources.get('mockInstance1');
|
||||||
|
const collection = dataSource.collectionManager.getCollection('posts');
|
||||||
|
expect(collection.options.title).toBe('标题 Collection');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -11,6 +11,7 @@ export class DataSourceModel extends MagicAttributeModel {
|
|||||||
...createOptions,
|
...createOptions,
|
||||||
name: this.get('key'),
|
name: this.get('key'),
|
||||||
});
|
});
|
||||||
|
|
||||||
await app.dataSourceManager.add(instance);
|
await app.dataSourceManager.add(instance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,9 @@ export class RemoteCollectionModel extends MagicAttributeModel {
|
|||||||
const { app } = loadOptions;
|
const { app } = loadOptions;
|
||||||
|
|
||||||
const collectionOptions = this.get();
|
const collectionOptions = this.get();
|
||||||
const databaseName = this.get('connectionName');
|
const dataSourceName = this.get('dataSourceKey');
|
||||||
const database = app.getDb(databaseName);
|
const dataSource = app.dataSourceManager.dataSources.get(dataSourceName);
|
||||||
const collectionName = this.get('name');
|
const collection = dataSource.collectionManager.getCollection(collectionOptions.name);
|
||||||
const collection = database.getCollection(collectionName);
|
|
||||||
collection.updateOptions(collectionOptions);
|
collection.updateOptions(collectionOptions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,7 +155,7 @@ export class PluginDataSourceManagerServer extends Plugin {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
this.app.db.on('remoteCollections.afterSave', async (model: RemoteCollectionModel) => {
|
this.app.db.on('dataSourcesCollections.afterSave', async (model: RemoteCollectionModel) => {
|
||||||
model.load({
|
model.load({
|
||||||
app: this.app,
|
app: this.app,
|
||||||
});
|
});
|
||||||
|
@ -47,31 +47,32 @@ export default {
|
|||||||
|
|
||||||
async update(ctx, next) {
|
async update(ctx, next) {
|
||||||
const params = ctx.action.params;
|
const params = ctx.action.params;
|
||||||
const { filterByTk: name } = params;
|
const { filterByTk: name, associatedIndex: collectionWithDataSource } = params;
|
||||||
const databaseName = ctx.get('x-database');
|
|
||||||
|
|
||||||
let remoteCollectionRecord = await ctx.db.getRepository('remoteCollections').findOne({
|
const [dataSourceKey, collectionName] = collectionWithDataSource.split('.');
|
||||||
|
|
||||||
|
let dataSourceCollectionRecord = await ctx.db.getRepository('dataSourcesCollections').findOne({
|
||||||
filter: {
|
filter: {
|
||||||
name,
|
name: collectionName,
|
||||||
connectionName: databaseName,
|
dataSourceKey,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!remoteCollectionRecord) {
|
if (!dataSourceCollectionRecord) {
|
||||||
remoteCollectionRecord = await ctx.db.getRepository('remoteCollections').create({
|
dataSourceCollectionRecord = await ctx.db.getRepository('dataSourcesCollections').create({
|
||||||
values: {
|
values: {
|
||||||
...params.values,
|
...params.values,
|
||||||
name,
|
name: collectionName,
|
||||||
connectionName: databaseName,
|
dataSourceKey,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
await remoteCollectionRecord.update({
|
await dataSourceCollectionRecord.update({
|
||||||
...params.values,
|
...params.values,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.body = remoteCollectionRecord.toJSON();
|
ctx.body = dataSourceCollectionRecord.toJSON();
|
||||||
|
|
||||||
await next();
|
await next();
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user