feat: create with array of values (#912)

* feat: create with array of values

* chore: console.log

* chore: debug
# Conflicts:
#	packages/core/database/src/relation-repository/relation-repository.ts
This commit is contained in:
ChengLei Shao 2022-10-15 10:45:23 +08:00 committed by chenos
parent 3e22a47be6
commit 6076014c54
8 changed files with 80 additions and 6 deletions

View File

@ -12,6 +12,7 @@ export async function create(ctx: Context, next) {
updateAssociationValues, updateAssociationValues,
context: ctx, context: ctx,
}); });
ctx.body = instance; ctx.body = instance;
await next(); await next();

View File

@ -235,6 +235,29 @@ describe('belongs to many', () => {
expect(findFilterResult[0].name).toEqual('t2'); expect(findFilterResult[0].name).toEqual('t2');
}); });
test('create with array', async () => {
const p1 = await Post.repository.create({
values: {
title: 'p1',
},
});
const PostTagRepository = new BelongsToManyRepository(Post, 'tags', p1.id);
const results = await PostTagRepository.create({
values: [
{
name: 't1',
},
{
name: 't2',
},
],
});
expect(results.length).toEqual(2);
});
test('find and count', async () => { test('find and count', async () => {
const p1 = await Post.repository.create({ const p1 = await Post.repository.create({
values: { values: {

View File

@ -203,6 +203,26 @@ describe('has many repository', () => {
expect(post.userId).toEqual(u1.id); expect(post.userId).toEqual(u1.id);
}); });
test('create with array', async () => {
const u1 = await User.repository.create({
values: { name: 'u1' },
});
const UserPostRepository = new HasManyRepository(User, 'posts', u1.id);
const posts = await UserPostRepository.create({
values: [
{
title: 't1',
},
{
title: 't2',
},
],
});
expect(posts.length).toEqual(2);
});
test('update', async () => { test('update', async () => {
const u1 = await User.repository.create({ const u1 = await User.repository.create({
values: { name: 'u1' }, values: { name: 'u1' },

View File

@ -234,6 +234,21 @@ describe('repository.create', () => {
const comments = await Comment.model.findAll(); const comments = await Comment.model.findAll();
expect(comments.map((m) => m.get('postId'))).toEqual([post.get('id'), post.get('id'), post.get('id')]); expect(comments.map((m) => m.get('postId'))).toEqual([post.get('id'), post.get('id'), post.get('id')]);
}); });
it('can create with array of values', async () => {
const users = await User.repository.create({
values: [
{
name: 'u1',
},
{
name: 'u2',
},
],
});
expect(users.length).toEqual(2);
});
}); });
describe('repository.update', () => { describe('repository.update', () => {

View File

@ -37,13 +37,12 @@ export function transactionWrapperBuilder(transactionGenerator) {
throw new Error(`please provide transactionInjector for ${name} call`); throw new Error(`please provide transactionInjector for ${name} call`);
} }
const results = await oldValue.apply(this, [callArguments]); const results = await oldValue.call(this, callArguments);
await transaction.commit(); await transaction.commit();
return results; return results;
} catch (err) { } catch (err) {
// console.error({ err });
await transaction.rollback(); await transaction.rollback();
throw err; throw err;
} }

View File

@ -31,6 +31,10 @@ interface IBelongsToManyRepository<M extends Model> {
export class BelongsToManyRepository extends MultipleRelationRepository implements IBelongsToManyRepository<any> { export class BelongsToManyRepository extends MultipleRelationRepository implements IBelongsToManyRepository<any> {
@transaction() @transaction()
async create(options?: CreateBelongsToManyOptions): Promise<any> { async create(options?: CreateBelongsToManyOptions): Promise<any> {
if (Array.isArray(options.values)) {
return Promise.all(options.values.map((record) => this.create({ ...options, values: record })));
}
const transaction = await this.getTransaction(options); const transaction = await this.getTransaction(options);
const createAccessor = this.accessors().create; const createAccessor = this.accessors().create;

View File

@ -2,12 +2,12 @@ import lodash from 'lodash';
import { Association, BelongsTo, BelongsToMany, HasMany, HasOne, ModelCtor, Transaction } from 'sequelize'; import { Association, BelongsTo, BelongsToMany, HasMany, HasOne, ModelCtor, Transaction } from 'sequelize';
import { Collection } from '../collection'; import { Collection } from '../collection';
import Database from '../database'; import Database from '../database';
import { transactionWrapperBuilder } from '../decorators/transaction-decorator';
import { RelationField } from '../fields/relation-field'; import { RelationField } from '../fields/relation-field';
import FilterParser from '../filter-parser'; import FilterParser from '../filter-parser';
import { Model } from '../model'; import { Model } from '../model';
import { OptionsParser } from '../options-parser'; import { OptionsParser } from '../options-parser';
import { CreateOptions, Filter, FindOptions } from '../repository'; import { CreateOptions, Filter, FindOptions } from '../repository';
import { transactionWrapperBuilder } from '../decorators/transaction-decorator';
import { updateAssociations } from '../update-associations'; import { updateAssociations } from '../update-associations';
import { UpdateGuard } from '../update-guard'; import { UpdateGuard } from '../update-guard';
@ -53,7 +53,11 @@ export abstract class RelationRepository {
} }
@transaction() @transaction()
async create(options?: CreateOptions): Promise<Model> { async create(options?: CreateOptions): Promise<any> {
if (Array.isArray(options.values)) {
return Promise.all(options.values.map((record) => this.create({ ...options, values: record })));
}
const createAccessor = this.accessors().create; const createAccessor = this.accessors().create;
const guard = UpdateGuard.fromOptions(this.targetModel, options); const guard = UpdateGuard.fromOptions(this.targetModel, options);

View File

@ -100,7 +100,7 @@ interface FindAndCountOptions extends Omit<SequelizeAndCountOptions, 'where' | '
} }
export interface CreateOptions extends SequelizeCreateOptions { export interface CreateOptions extends SequelizeCreateOptions {
values?: Values; values?: Values | Values[];
whitelist?: WhiteList; whitelist?: WhiteList;
blacklist?: BlackList; blacklist?: BlackList;
updateAssociationValues?: AssociationKeysToBeUpdate; updateAssociationValues?: AssociationKeysToBeUpdate;
@ -307,7 +307,14 @@ export class Repository<TModelAttributes extends {} = any, TCreationAttributes e
* @param options * @param options
*/ */
@transaction() @transaction()
async create<M extends Model>(options: CreateOptions): Promise<M> { async create(options: CreateOptions) {
if (Array.isArray(options.values)) {
return this.createMany({
...options,
records: options.values,
});
}
const transaction = await this.getTransaction(options); const transaction = await this.getTransaction(options);
const guard = UpdateGuard.fromOptions(this.model, { ...options, action: 'create' }); const guard = UpdateGuard.fromOptions(this.model, { ...options, action: 'create' });
@ -356,6 +363,7 @@ export class Repository<TModelAttributes extends {} = any, TCreationAttributes e
const instance = await this.create({ values, transaction }); const instance = await this.create({ values, transaction });
instances.push(instance); instances.push(instance);
} }
return instances; return instances;
} }