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,
context: ctx,
});
ctx.body = instance;
await next();

View File

@ -235,6 +235,29 @@ describe('belongs to many', () => {
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 () => {
const p1 = await Post.repository.create({
values: {

View File

@ -203,6 +203,26 @@ describe('has many repository', () => {
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 () => {
const u1 = await User.repository.create({
values: { name: 'u1' },

View File

@ -234,6 +234,21 @@ describe('repository.create', () => {
const comments = await Comment.model.findAll();
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', () => {

View File

@ -37,13 +37,12 @@ export function transactionWrapperBuilder(transactionGenerator) {
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();
return results;
} catch (err) {
// console.error({ err });
await transaction.rollback();
throw err;
}

View File

@ -31,6 +31,10 @@ interface IBelongsToManyRepository<M extends Model> {
export class BelongsToManyRepository extends MultipleRelationRepository implements IBelongsToManyRepository<any> {
@transaction()
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 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 { Collection } from '../collection';
import Database from '../database';
import { transactionWrapperBuilder } from '../decorators/transaction-decorator';
import { RelationField } from '../fields/relation-field';
import FilterParser from '../filter-parser';
import { Model } from '../model';
import { OptionsParser } from '../options-parser';
import { CreateOptions, Filter, FindOptions } from '../repository';
import { transactionWrapperBuilder } from '../decorators/transaction-decorator';
import { updateAssociations } from '../update-associations';
import { UpdateGuard } from '../update-guard';
@ -53,7 +53,11 @@ export abstract class RelationRepository {
}
@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 guard = UpdateGuard.fromOptions(this.targetModel, options);

View File

@ -100,7 +100,7 @@ interface FindAndCountOptions extends Omit<SequelizeAndCountOptions, 'where' | '
}
export interface CreateOptions extends SequelizeCreateOptions {
values?: Values;
values?: Values | Values[];
whitelist?: WhiteList;
blacklist?: BlackList;
updateAssociationValues?: AssociationKeysToBeUpdate;
@ -307,7 +307,14 @@ export class Repository<TModelAttributes extends {} = any, TCreationAttributes e
* @param options
*/
@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 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 });
instances.push(instance);
}
return instances;
}