fix(database): index invalid (#564)
* fix(database): index invalid * fix: test error
This commit is contained in:
parent
41cb3da448
commit
70ab4dcf1f
@ -13,6 +13,22 @@ describe('collection', () => {
|
||||
await db.close();
|
||||
});
|
||||
|
||||
test.skip('indexes', async () => {
|
||||
await db.clean({ drop: true });
|
||||
const collection = db.collection({
|
||||
name: 'test',
|
||||
fields: [
|
||||
{
|
||||
type: 'string',
|
||||
name: 'name',
|
||||
index: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
collection.removeField('name');
|
||||
await db.sync();
|
||||
});
|
||||
|
||||
test('removeFromDb', async () => {
|
||||
await db.clean({ drop: true });
|
||||
const collection = db.collection({
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Collection } from '../collection';
|
||||
import { Database } from '../database';
|
||||
import { updateAssociation, updateAssociations } from '../update-associations';
|
||||
import { updateAssociations } from '../update-associations';
|
||||
import { mockDatabase } from './';
|
||||
|
||||
describe('update associations', () => {
|
||||
@ -356,13 +356,14 @@ describe('update associations', () => {
|
||||
});
|
||||
|
||||
describe('belongsToMany', () => {
|
||||
let db;
|
||||
let Post;
|
||||
let Tag;
|
||||
let PostTag;
|
||||
let db: Database;
|
||||
let Post: Collection;
|
||||
let Tag: Collection;
|
||||
let PostTag: Collection;
|
||||
|
||||
beforeEach(async () => {
|
||||
db = mockDatabase();
|
||||
await db.clean({ drop: true });
|
||||
PostTag = db.collection({
|
||||
name: 'posts_tags',
|
||||
fields: [{ type: 'string', name: 'tagged_at' }],
|
||||
@ -389,7 +390,7 @@ describe('update associations', () => {
|
||||
afterEach(async () => {
|
||||
await db.close();
|
||||
});
|
||||
test('set through value', async () => {
|
||||
test.only('set through value', async () => {
|
||||
const p1 = await Post.repository.create({
|
||||
values: {
|
||||
title: 'hello',
|
||||
@ -404,9 +405,12 @@ describe('update associations', () => {
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const t1 = (await p1.getTags())[0];
|
||||
expect(t1.posts_tags.tagged_at).toEqual('123');
|
||||
const count = await PostTag.repository.count({
|
||||
filter: {
|
||||
tagged_at: '123',
|
||||
},
|
||||
});
|
||||
expect(count).toEqual(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,7 +1,14 @@
|
||||
import merge from 'deepmerge';
|
||||
import { EventEmitter } from 'events';
|
||||
import { default as lodash, default as _ } from 'lodash';
|
||||
import { ModelCtor, ModelOptions, QueryInterfaceDropTableOptions, SyncOptions, Transactionable } from 'sequelize';
|
||||
import {
|
||||
ModelCtor,
|
||||
ModelOptions,
|
||||
QueryInterfaceDropTableOptions,
|
||||
SyncOptions,
|
||||
Transactionable,
|
||||
Utils
|
||||
} from 'sequelize';
|
||||
import { Database } from './database';
|
||||
import { Field, FieldOptions } from './fields';
|
||||
import { Model } from './model';
|
||||
@ -278,6 +285,67 @@ export class Collection<
|
||||
this.setField(options.name || name, options);
|
||||
}
|
||||
|
||||
addIndex(index: any) {
|
||||
if (!index) {
|
||||
return;
|
||||
}
|
||||
let indexes: any = this.model.options.indexes || [];
|
||||
let indexName = [];
|
||||
let indexItem;
|
||||
if (typeof index === 'string') {
|
||||
indexItem = {
|
||||
fields: [index],
|
||||
};
|
||||
indexName = [index];
|
||||
} else if (Array.isArray(index)) {
|
||||
indexItem = {
|
||||
fields: index,
|
||||
};
|
||||
indexName = index;
|
||||
} else if (index?.fields) {
|
||||
indexItem = index;
|
||||
indexName = index.fields;
|
||||
}
|
||||
if (lodash.isEqual(this.model.primaryKeyAttributes, indexName)) {
|
||||
return;
|
||||
}
|
||||
const name: string = this.model.primaryKeyAttributes.join(',');
|
||||
if (name.startsWith(`${indexName.join(',')},`)) {
|
||||
return;
|
||||
}
|
||||
for (const item of indexes) {
|
||||
if (lodash.isEqual(item.fields, indexName)) {
|
||||
return;
|
||||
}
|
||||
const name: string = item.fields.join(',');
|
||||
if (name.startsWith(`${indexName.join(',')},`)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!indexItem) {
|
||||
return;
|
||||
}
|
||||
indexes.push(indexItem);
|
||||
this.model.options.indexes = indexes;
|
||||
const tableName = this.model.getTableName();
|
||||
// @ts-ignore
|
||||
this.model._indexes = this.model.options.indexes
|
||||
// @ts-ignore
|
||||
.map((index) => Utils.nameIndex(this.model._conformIndex(index), tableName));
|
||||
}
|
||||
|
||||
removeIndex(fields: any) {
|
||||
if (!fields) {
|
||||
return;
|
||||
}
|
||||
// @ts-ignore
|
||||
const indexes: any[] = this.model._indexes;
|
||||
// @ts-ignore
|
||||
this.model._indexes = indexes.filter((item) => {
|
||||
return !lodash.isEqual(item.fields, fields);
|
||||
});
|
||||
}
|
||||
|
||||
async sync(syncOptions?: SyncOptions) {
|
||||
const modelNames = [this.model.name];
|
||||
|
||||
|
@ -46,7 +46,7 @@ export class BelongsToField extends RelationField {
|
||||
// @ts-ignore
|
||||
this.options.sourceKey = association.sourceKey;
|
||||
}
|
||||
|
||||
this.collection.addIndex([this.options.foreignKey]);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -68,6 +68,7 @@ export class BelongsToField extends RelationField {
|
||||
delete collection.model.associations[this.name];
|
||||
// @ts-ignore
|
||||
collection.model.refreshAttributes();
|
||||
// this.collection.removeIndex([this.options.foreignKey]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,6 +58,8 @@ export class BelongsToManyField extends RelationField {
|
||||
if (!this.options.through) {
|
||||
this.options.through = this.through;
|
||||
}
|
||||
Through.addIndex([this.options.foreignKey]);
|
||||
Through.addIndex([this.options.otherKey]);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -171,11 +171,17 @@ export abstract class Field {
|
||||
model.rawAttributes[this.name] = this.toSequelize();
|
||||
// @ts-ignore
|
||||
model.refreshAttributes();
|
||||
if (this.options.index) {
|
||||
this.context.collection.addIndex([this.name]);
|
||||
}
|
||||
}
|
||||
|
||||
unbind() {
|
||||
const { model } = this.context.collection;
|
||||
model.removeAttribute(this.name);
|
||||
if (this.options.index) {
|
||||
this.context.collection.removeIndex([this.name]);
|
||||
}
|
||||
}
|
||||
|
||||
toSequelize(): any {
|
||||
|
@ -7,7 +7,7 @@ import {
|
||||
HasManyOptions as SequelizeHasManyOptions,
|
||||
Utils
|
||||
} from 'sequelize';
|
||||
|
||||
import { Collection } from '../collection';
|
||||
import { MultipleRelationFieldOptions, RelationField } from './relation-field';
|
||||
|
||||
export interface HasManyFieldOptions extends HasManyOptions {
|
||||
@ -98,7 +98,6 @@ export class HasManyField extends RelationField {
|
||||
as: this.name,
|
||||
foreignKey: this.foreignKey,
|
||||
});
|
||||
|
||||
// inverse relation
|
||||
// this.TargetModel.belongsTo(collection.model);
|
||||
|
||||
@ -112,6 +111,15 @@ export class HasManyField extends RelationField {
|
||||
// @ts-ignore
|
||||
this.options.sourceKey = association.sourceKey;
|
||||
}
|
||||
let tcoll: Collection;
|
||||
if (this.target === collection.name) {
|
||||
tcoll = collection;
|
||||
} else {
|
||||
tcoll = database.getCollection(this.target);
|
||||
}
|
||||
if (tcoll) {
|
||||
tcoll.addIndex([this.options.foreignKey]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -120,7 +128,7 @@ export class HasManyField extends RelationField {
|
||||
// 如果关系字段还没建立就删除了,也同步删除待建立关联的关系字段
|
||||
database.removePendingField(this);
|
||||
// 如果关系表内没有显式的创建外键字段,删除关系时,外键也删除掉
|
||||
const tcoll = database.collections.get(this.target);
|
||||
const tcoll = database.getCollection(this.target);
|
||||
const foreignKey = this.options.foreignKey;
|
||||
const field = tcoll.findField((field) => {
|
||||
if (field.name === foreignKey) {
|
||||
|
@ -7,6 +7,7 @@ import {
|
||||
HasOneOptions as SequelizeHasOneOptions,
|
||||
Utils
|
||||
} from 'sequelize';
|
||||
import { Collection } from '../collection';
|
||||
import { BaseRelationFieldOptions, RelationField } from './relation-field';
|
||||
|
||||
export interface HasOneFieldOptions extends HasOneOptions {
|
||||
@ -106,6 +107,15 @@ export class HasOneField extends RelationField {
|
||||
// @ts-ignore
|
||||
this.options.sourceKey = association.sourceKey;
|
||||
}
|
||||
let tcoll: Collection;
|
||||
if (this.target === collection.name) {
|
||||
tcoll = collection;
|
||||
} else {
|
||||
tcoll = database.getCollection(this.target);
|
||||
}
|
||||
if (tcoll) {
|
||||
tcoll.addIndex([this.options.foreignKey]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@ export default defineCollection({
|
||||
{
|
||||
type: 'string',
|
||||
name: 'recordId',
|
||||
index: true,
|
||||
},
|
||||
{
|
||||
type: 'string',
|
||||
|
@ -44,6 +44,7 @@ export default {
|
||||
targetKey: 'name',
|
||||
foreignKey: 'collectionName',
|
||||
sortBy: 'sort',
|
||||
constraints: true,
|
||||
},
|
||||
],
|
||||
} as CollectionOptions;
|
||||
|
@ -26,12 +26,14 @@ export default defineCollection({
|
||||
target: 'uiRoutes',
|
||||
sourceKey: 'key',
|
||||
foreignKey: 'parentKey',
|
||||
constraints: true,
|
||||
},
|
||||
{
|
||||
type: 'belongsTo',
|
||||
name: 'uiSchema',
|
||||
target: 'uiSchemas',
|
||||
foreignKey: 'uiSchemaUid'
|
||||
foreignKey: 'uiSchemaUid',
|
||||
constraints: true,
|
||||
},
|
||||
{
|
||||
type: 'json',
|
||||
|
@ -63,8 +63,7 @@ export default class UsersPlugin extends Plugin<UserPluginConfig> {
|
||||
dataIndex: 'state.currentUser.id',
|
||||
createOnly: true,
|
||||
visible: true,
|
||||
onDelete: 'SET NULL',
|
||||
onUpdate: 'CASCADE',
|
||||
index: true,
|
||||
});
|
||||
collection.setField('createdBy', {
|
||||
type: 'belongsTo',
|
||||
@ -79,8 +78,7 @@ export default class UsersPlugin extends Plugin<UserPluginConfig> {
|
||||
dataType: 'integer',
|
||||
dataIndex: 'state.currentUser.id',
|
||||
visible: true,
|
||||
onDelete: 'SET NULL',
|
||||
onUpdate: 'CASCADE',
|
||||
index: true,
|
||||
});
|
||||
collection.setField('updatedBy', {
|
||||
type: 'belongsTo',
|
||||
|
Loading…
Reference in New Issue
Block a user