fix pre test
This commit is contained in:
parent
53f858d736
commit
da13426b89
|
@ -3,11 +3,10 @@
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export class OptimizeEmojiIndex1707951601000 {
|
export class OptimizeEmojiIndex1709126576000 {
|
||||||
name = 'OptimizeEmojiIndex1707951601000'
|
name = 'OptimizeEmojiIndex1709126576000'
|
||||||
|
|
||||||
async up(queryRunner) {
|
async up(queryRunner) {
|
||||||
await queryRunner.query(`CREATE INDEX "IDX_EMOJI_ALIASES_IDS" ON "emoji" using gin ("aliases")`)
|
|
||||||
await queryRunner.query(`CREATE INDEX "IDX_EMOJI_ROLE_IDS" ON "emoji" using gin ("roleIdsThatCanBeUsedThisEmojiAsReaction")`)
|
await queryRunner.query(`CREATE INDEX "IDX_EMOJI_ROLE_IDS" ON "emoji" using gin ("roleIdsThatCanBeUsedThisEmojiAsReaction")`)
|
||||||
await queryRunner.query(`CREATE INDEX "IDX_EMOJI_CATEGORY" ON "emoji" ("category")`)
|
await queryRunner.query(`CREATE INDEX "IDX_EMOJI_CATEGORY" ON "emoji" ("category")`)
|
||||||
}
|
}
|
||||||
|
@ -15,6 +14,5 @@ export class OptimizeEmojiIndex1707951601000 {
|
||||||
async down(queryRunner) {
|
async down(queryRunner) {
|
||||||
await queryRunner.query(`DROP INDEX "IDX_EMOJI_CATEGORY"`)
|
await queryRunner.query(`DROP INDEX "IDX_EMOJI_CATEGORY"`)
|
||||||
await queryRunner.query(`DROP INDEX "IDX_EMOJI_ROLE_IDS"`)
|
await queryRunner.query(`DROP INDEX "IDX_EMOJI_ROLE_IDS"`)
|
||||||
await queryRunner.query(`DROP INDEX "IDX_EMOJI_ALIASES_IDS"`)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,7 +4,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';
|
import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';
|
||||||
import { Brackets, In, IsNull, SelectQueryBuilder, WhereExpressionBuilder } from 'typeorm';
|
import { Brackets, In, IsNull, ObjectLiteral, SelectQueryBuilder, WhereExpressionBuilder } from 'typeorm';
|
||||||
import * as Redis from 'ioredis';
|
import * as Redis from 'ioredis';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import { IdService } from '@/core/IdService.js';
|
import { IdService } from '@/core/IdService.js';
|
||||||
|
@ -446,9 +446,9 @@ export class CustomEmojiService implements OnApplicationShutdown {
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async fetchEmojis(params?: FetchEmojisParams) {
|
public async fetchEmojis(params?: FetchEmojisParams) {
|
||||||
function multipleWordsToQuery(
|
function multipleWordsToQuery<T extends ObjectLiteral>(
|
||||||
query: string,
|
query: string,
|
||||||
builder: SelectQueryBuilder<MiEmoji>,
|
builder: SelectQueryBuilder<T>,
|
||||||
action: (qb: WhereExpressionBuilder, idx: number, word: string) => void,
|
action: (qb: WhereExpressionBuilder, idx: number, word: string) => void,
|
||||||
) {
|
) {
|
||||||
const words = query.split(/\s/);
|
const words = query.split(/\s/);
|
||||||
|
@ -514,12 +514,23 @@ export class CustomEmojiService implements OnApplicationShutdown {
|
||||||
}
|
}
|
||||||
if (q.aliases) {
|
if (q.aliases) {
|
||||||
// noIndexScan
|
// noIndexScan
|
||||||
multipleWordsToQuery(q.aliases, builder, (qb, idx, word) => {
|
const subQueryBuilder = builder.subQuery()
|
||||||
qb.orWhere(`emoji.aliases LIKE :aliases${idx}`, Object.fromEntries([[`aliases${idx}`, `%${word}%`]]));
|
.select('COUNT(0)', 'count')
|
||||||
|
.from(
|
||||||
|
sq2 => sq2
|
||||||
|
.select('unnest(subEmoji.aliases)', 'alias')
|
||||||
|
.addSelect('subEmoji.id', 'id')
|
||||||
|
.from('emoji', 'subEmoji'),
|
||||||
|
'aliasTable',
|
||||||
|
)
|
||||||
|
.where('"emoji"."id" = "aliasTable"."id"');
|
||||||
|
multipleWordsToQuery(q.aliases, subQueryBuilder, (qb, idx, word) => {
|
||||||
|
qb.orWhere(`"aliasTable"."alias" LIKE :aliases${idx}`, Object.fromEntries([[`aliases${idx}`, `%${word}%`]]));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
builder.andWhere(`(${subQueryBuilder.getQuery()}) > 0`);
|
||||||
}
|
}
|
||||||
if (q.category) {
|
if (q.category) {
|
||||||
// noIndexScan
|
|
||||||
multipleWordsToQuery(q.category, builder, (qb, idx, word) => {
|
multipleWordsToQuery(q.category, builder, (qb, idx, word) => {
|
||||||
qb.orWhere(`emoji.category LIKE :category${idx}`, Object.fromEntries([[`category${idx}`, `%${word}%`]]));
|
qb.orWhere(`emoji.category LIKE :category${idx}`, Object.fromEntries([[`category${idx}`, `%${word}%`]]));
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,140 +4,132 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="_gaps">
|
||||||
|
<MkFolder>
|
||||||
|
<template #icon><i class="ti ti-search"></i></template>
|
||||||
|
<template #label>{{ i18n.ts._customEmojisManager._gridCommon.searchSettings }}</template>
|
||||||
|
<template #caption>
|
||||||
|
{{ i18n.ts._customEmojisManager._gridCommon.searchSettingCaption }}
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div class="_gaps">
|
||||||
|
<div :class="[[spMode ? $style.searchAreaSp : $style.searchArea]]">
|
||||||
|
<MkInput
|
||||||
|
v-model="queryName"
|
||||||
|
type="search"
|
||||||
|
autocapitalize="off"
|
||||||
|
class="col1 row1"
|
||||||
|
@enter="onSearchRequest"
|
||||||
|
>
|
||||||
|
<template #label>name</template>
|
||||||
|
</MkInput>
|
||||||
|
<MkInput
|
||||||
|
v-model="queryCategory"
|
||||||
|
type="search"
|
||||||
|
autocapitalize="off"
|
||||||
|
class="col2 row1"
|
||||||
|
@enter="onSearchRequest"
|
||||||
|
>
|
||||||
|
<template #label>category</template>
|
||||||
|
</MkInput>
|
||||||
|
<MkInput
|
||||||
|
v-model="queryAliases"
|
||||||
|
type="search"
|
||||||
|
autocapitalize="off"
|
||||||
|
class="col3 row1"
|
||||||
|
@enter="onSearchRequest"
|
||||||
|
>
|
||||||
|
<template #label>aliases</template>
|
||||||
|
</MkInput>
|
||||||
|
|
||||||
|
<MkInput
|
||||||
|
v-model="queryType"
|
||||||
|
type="search"
|
||||||
|
autocapitalize="off"
|
||||||
|
class="col1 row2"
|
||||||
|
@enter="onSearchRequest"
|
||||||
|
>
|
||||||
|
<template #label>type</template>
|
||||||
|
</MkInput>
|
||||||
|
<MkInput
|
||||||
|
v-model="queryLicense"
|
||||||
|
type="search"
|
||||||
|
autocapitalize="off"
|
||||||
|
class="col2 row2"
|
||||||
|
@enter="onSearchRequest"
|
||||||
|
>
|
||||||
|
<template #label>license</template>
|
||||||
|
</MkInput>
|
||||||
|
<MkSelect
|
||||||
|
v-model="querySensitive"
|
||||||
|
class="col3 row2"
|
||||||
|
>
|
||||||
|
<template #label>sensitive</template>
|
||||||
|
<option :value="null">-</option>
|
||||||
|
<option :value="true">true</option>
|
||||||
|
<option :value="false">false</option>
|
||||||
|
</MkSelect>
|
||||||
|
|
||||||
|
<MkSelect
|
||||||
|
v-model="queryLocalOnly"
|
||||||
|
class="col1 row3"
|
||||||
|
>
|
||||||
|
<template #label>localOnly</template>
|
||||||
|
<option :value="null">-</option>
|
||||||
|
<option :value="true">true</option>
|
||||||
|
<option :value="false">false</option>
|
||||||
|
</MkSelect>
|
||||||
|
<MkInput
|
||||||
|
v-model="queryUpdatedAtFrom"
|
||||||
|
type="date"
|
||||||
|
autocapitalize="off"
|
||||||
|
class="col2 row3"
|
||||||
|
@enter="onSearchRequest"
|
||||||
|
>
|
||||||
|
<template #label>updatedAt(from)</template>
|
||||||
|
</MkInput>
|
||||||
|
<MkInput
|
||||||
|
v-model="queryUpdatedAtTo"
|
||||||
|
type="date"
|
||||||
|
autocapitalize="off"
|
||||||
|
class="col3 row3"
|
||||||
|
@enter="onSearchRequest"
|
||||||
|
>
|
||||||
|
<template #label>updatedAt(to)</template>
|
||||||
|
</MkInput>
|
||||||
|
|
||||||
|
<MkInput
|
||||||
|
v-model="queryRolesText"
|
||||||
|
type="text"
|
||||||
|
readonly
|
||||||
|
autocapitalize="off"
|
||||||
|
class="col1 row4"
|
||||||
|
@click="onQueryRolesEditClicked"
|
||||||
|
>
|
||||||
|
<template #label>role</template>
|
||||||
|
<template #suffix><span class="ti ti-pencil"/></template>
|
||||||
|
</MkInput>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<XSortOrderFolder :sortOrders="sortOrders" @update="onSortOrderUpdate"/>
|
||||||
|
|
||||||
|
<div :class="[[spMode ? $style.searchButtonsSp : $style.searchButtons]]">
|
||||||
|
<MkButton primary @click="onSearchRequest">
|
||||||
|
{{ i18n.ts.search }}
|
||||||
|
</MkButton>
|
||||||
|
<MkButton @click="onQueryResetButtonClicked">
|
||||||
|
{{ i18n.ts.reset }}
|
||||||
|
</MkButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</MkFolder>
|
||||||
|
|
||||||
|
<XRegisterLogsFolder :logs="requestLogs"/>
|
||||||
|
|
||||||
<div v-if="gridItems.length === 0" style="text-align: center">
|
<div v-if="gridItems.length === 0" style="text-align: center">
|
||||||
{{ i18n.ts._customEmojisManager._local._list.emojisNothing }}
|
{{ i18n.ts._customEmojisManager._local._list.emojisNothing }}
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="_gaps">
|
<template v-else>
|
||||||
<MkFolder>
|
|
||||||
<template #icon><i class="ti ti-search"></i></template>
|
|
||||||
<template #label>{{ i18n.ts._customEmojisManager._gridCommon.searchSettings }}</template>
|
|
||||||
<template #caption>
|
|
||||||
{{ i18n.ts._customEmojisManager._gridCommon.searchSettingCaption }}
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<div class="_gaps">
|
|
||||||
<div :class="[[spMode ? $style.searchAreaSp : $style.searchArea]]">
|
|
||||||
<MkInput
|
|
||||||
v-model="queryName"
|
|
||||||
:debounce="true"
|
|
||||||
type="search"
|
|
||||||
autocapitalize="off"
|
|
||||||
class="col1 row1"
|
|
||||||
@enter="onSearchRequest"
|
|
||||||
>
|
|
||||||
<template #label>name</template>
|
|
||||||
</MkInput>
|
|
||||||
<MkInput
|
|
||||||
v-model="queryCategory"
|
|
||||||
:debounce="true"
|
|
||||||
type="search"
|
|
||||||
autocapitalize="off"
|
|
||||||
class="col2 row1"
|
|
||||||
@enter="onSearchRequest"
|
|
||||||
>
|
|
||||||
<template #label>category</template>
|
|
||||||
</MkInput>
|
|
||||||
<MkInput
|
|
||||||
v-model="queryAlias"
|
|
||||||
:debounce="true"
|
|
||||||
type="search"
|
|
||||||
autocapitalize="off"
|
|
||||||
class="col3 row1"
|
|
||||||
@enter="onSearchRequest"
|
|
||||||
>
|
|
||||||
<template #label>alias</template>
|
|
||||||
</MkInput>
|
|
||||||
|
|
||||||
<MkInput
|
|
||||||
v-model="queryType"
|
|
||||||
:debounce="true"
|
|
||||||
type="search"
|
|
||||||
autocapitalize="off"
|
|
||||||
class="col1 row2"
|
|
||||||
@enter="onSearchRequest"
|
|
||||||
>
|
|
||||||
<template #label>type</template>
|
|
||||||
</MkInput>
|
|
||||||
<MkInput
|
|
||||||
v-model="queryLicense"
|
|
||||||
:debounce="true"
|
|
||||||
type="search"
|
|
||||||
autocapitalize="off"
|
|
||||||
class="col2 row2"
|
|
||||||
@enter="onSearchRequest"
|
|
||||||
>
|
|
||||||
<template #label>license</template>
|
|
||||||
</MkInput>
|
|
||||||
<MkSelect
|
|
||||||
v-model="querySensitive"
|
|
||||||
class="col3 row2"
|
|
||||||
>
|
|
||||||
<template #label>sensitive</template>
|
|
||||||
<option :value="null">-</option>
|
|
||||||
<option :value="true">true</option>
|
|
||||||
<option :value="false">false</option>
|
|
||||||
</MkSelect>
|
|
||||||
|
|
||||||
<MkSelect
|
|
||||||
v-model="queryLocalOnly"
|
|
||||||
class="col1 row3"
|
|
||||||
>
|
|
||||||
<template #label>localOnly</template>
|
|
||||||
<option :value="null">-</option>
|
|
||||||
<option :value="true">true</option>
|
|
||||||
<option :value="false">false</option>
|
|
||||||
</MkSelect>
|
|
||||||
<MkInput
|
|
||||||
v-model="queryUpdatedAtFrom"
|
|
||||||
:debounce="true"
|
|
||||||
type="date"
|
|
||||||
autocapitalize="off"
|
|
||||||
class="col2 row3"
|
|
||||||
@enter="onSearchRequest"
|
|
||||||
>
|
|
||||||
<template #label>updatedAt(from)</template>
|
|
||||||
</MkInput>
|
|
||||||
<MkInput
|
|
||||||
v-model="queryUpdatedAtTo"
|
|
||||||
:debounce="true"
|
|
||||||
type="date"
|
|
||||||
autocapitalize="off"
|
|
||||||
class="col3 row3"
|
|
||||||
@enter="onSearchRequest"
|
|
||||||
>
|
|
||||||
<template #label>updatedAt(to)</template>
|
|
||||||
</MkInput>
|
|
||||||
|
|
||||||
<MkInput
|
|
||||||
v-model="queryRolesText"
|
|
||||||
:debounce="true"
|
|
||||||
type="text"
|
|
||||||
readonly
|
|
||||||
autocapitalize="off"
|
|
||||||
class="col1 row4"
|
|
||||||
@click="onQueryRolesEditClicked"
|
|
||||||
>
|
|
||||||
<template #label>role</template>
|
|
||||||
<template #suffix><span class="ti ti-pencil"/></template>
|
|
||||||
</MkInput>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<XSortOrderFolder :sortOrders="sortOrders" @update="onSortOrderUpdate"/>
|
|
||||||
|
|
||||||
<div :class="[[spMode ? $style.searchButtonsSp : $style.searchButtons]]">
|
|
||||||
<MkButton primary @click="onSearchRequest">
|
|
||||||
{{ i18n.ts.search }}
|
|
||||||
</MkButton>
|
|
||||||
<MkButton @click="onQueryResetButtonClicked">
|
|
||||||
{{ i18n.ts.reset }}
|
|
||||||
</MkButton>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</MkFolder>
|
|
||||||
|
|
||||||
<XRegisterLogsFolder :logs="requestLogs"/>
|
|
||||||
|
|
||||||
<div :class="$style.gridArea">
|
<div :class="$style.gridArea">
|
||||||
<MkGrid :data="gridItems" :settings="setupGrid()" @event="onGridEvent"/>
|
<MkGrid :data="gridItems" :settings="setupGrid()" @event="onGridEvent"/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -155,7 +147,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<MkButton @click="onGridResetButtonClicked">{{ i18n.ts.reset }}</MkButton>
|
<MkButton @click="onGridResetButtonClicked">{{ i18n.ts.reset }}</MkButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -360,7 +352,7 @@ const currentPage = ref<number>(0);
|
||||||
|
|
||||||
const queryName = ref<string | null>(null);
|
const queryName = ref<string | null>(null);
|
||||||
const queryCategory = ref<string | null>(null);
|
const queryCategory = ref<string | null>(null);
|
||||||
const queryAlias = ref<string | null>(null);
|
const queryAliases = ref<string | null>(null);
|
||||||
const queryType = ref<string | null>(null);
|
const queryType = ref<string | null>(null);
|
||||||
const queryLicense = ref<string | null>(null);
|
const queryLicense = ref<string | null>(null);
|
||||||
const queryUpdatedAtFrom = ref<string | null>(null);
|
const queryUpdatedAtFrom = ref<string | null>(null);
|
||||||
|
@ -509,7 +501,7 @@ async function onSearchRequest() {
|
||||||
function onQueryResetButtonClicked() {
|
function onQueryResetButtonClicked() {
|
||||||
queryName.value = null;
|
queryName.value = null;
|
||||||
queryCategory.value = null;
|
queryCategory.value = null;
|
||||||
queryAlias.value = null;
|
queryAliases.value = null;
|
||||||
queryType.value = null;
|
queryType.value = null;
|
||||||
queryLicense.value = null;
|
queryLicense.value = null;
|
||||||
queryUpdatedAtFrom.value = null;
|
queryUpdatedAtFrom.value = null;
|
||||||
|
@ -552,7 +544,7 @@ async function refreshCustomEmojis() {
|
||||||
const query: Misskey.entities.AdminEmojiV2ListRequest['query'] = {
|
const query: Misskey.entities.AdminEmojiV2ListRequest['query'] = {
|
||||||
name: emptyStrToUndefined(queryName.value),
|
name: emptyStrToUndefined(queryName.value),
|
||||||
type: emptyStrToUndefined(queryType.value),
|
type: emptyStrToUndefined(queryType.value),
|
||||||
aliases: emptyStrToUndefined(queryAlias.value),
|
aliases: emptyStrToUndefined(queryAliases.value),
|
||||||
category: emptyStrToUndefined(queryCategory.value),
|
category: emptyStrToUndefined(queryCategory.value),
|
||||||
license: emptyStrToUndefined(queryLicense.value),
|
license: emptyStrToUndefined(queryLicense.value),
|
||||||
isSensitive: querySensitive.value ? Boolean(querySensitive.value).valueOf() : undefined,
|
isSensitive: querySensitive.value ? Boolean(querySensitive.value).valueOf() : undefined,
|
||||||
|
|
|
@ -17,7 +17,6 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<div :class="[[spMode ? $style.searchAreaSp : $style.searchArea]]">
|
<div :class="[[spMode ? $style.searchAreaSp : $style.searchArea]]">
|
||||||
<MkInput
|
<MkInput
|
||||||
v-model="queryName"
|
v-model="queryName"
|
||||||
:debounce="true"
|
|
||||||
type="search"
|
type="search"
|
||||||
autocapitalize="off"
|
autocapitalize="off"
|
||||||
class="col1 row1"
|
class="col1 row1"
|
||||||
|
@ -27,7 +26,6 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</MkInput>
|
</MkInput>
|
||||||
<MkInput
|
<MkInput
|
||||||
v-model="queryHost"
|
v-model="queryHost"
|
||||||
:debounce="true"
|
|
||||||
type="search"
|
type="search"
|
||||||
autocapitalize="off"
|
autocapitalize="off"
|
||||||
class="col2 row1"
|
class="col2 row1"
|
||||||
|
@ -37,7 +35,6 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</MkInput>
|
</MkInput>
|
||||||
<MkInput
|
<MkInput
|
||||||
v-model="queryUri"
|
v-model="queryUri"
|
||||||
:debounce="true"
|
|
||||||
type="search"
|
type="search"
|
||||||
autocapitalize="off"
|
autocapitalize="off"
|
||||||
class="col1 row2"
|
class="col1 row2"
|
||||||
|
@ -47,7 +44,6 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</MkInput>
|
</MkInput>
|
||||||
<MkInput
|
<MkInput
|
||||||
v-model="queryPublicUrl"
|
v-model="queryPublicUrl"
|
||||||
:debounce="true"
|
|
||||||
type="search"
|
type="search"
|
||||||
autocapitalize="off"
|
autocapitalize="off"
|
||||||
class="col2 row2"
|
class="col2 row2"
|
||||||
|
|
Loading…
Reference in New Issue