mirror of
https://github.com/immich-app/immich.git
synced 2025-12-11 07:11:05 -08:00
Compare commits
1 Commits
main
...
original-p
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c3d9f2ce34 |
@@ -851,4 +851,26 @@ describe('/libraries', () => {
|
|||||||
expect(existsSync(`${testAssetDir}/temp/directoryB/assetB.png`)).toBe(true);
|
expect(existsSync(`${testAssetDir}/temp/directoryB/assetB.png`)).toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('POST /search/metadata', () => {
|
||||||
|
it('should search by originalPath', async () => {
|
||||||
|
const directory = `some-61498-directory`;
|
||||||
|
const infix = 'me-61498-di';
|
||||||
|
|
||||||
|
utils.createImageFile(`${testAssetDir}/temp/${directory}/assetZ.jpg`);
|
||||||
|
await scan(admin.accessToken, library.id);
|
||||||
|
await utils.waitForWebsocketEvent({ event: 'assetUpload', total: 1 });
|
||||||
|
|
||||||
|
const { status, body } = await request(app)
|
||||||
|
.post('/search/metadata')
|
||||||
|
.send({ originalPath: infix })
|
||||||
|
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||||
|
|
||||||
|
expect(status).toBe(200);
|
||||||
|
expect(body.assets).toBeDefined();
|
||||||
|
expect(Array.isArray(body.assets.items)).toBe(true);
|
||||||
|
expect(body.assets.items).toHaveLength(1);
|
||||||
|
expect(body.assets.items[0]).toEqual(expect.objectContaining({ originalFileName: 'assetZ.jpg' }));
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -288,13 +288,6 @@ describe('/search', () => {
|
|||||||
should: 'should search by takenAfter (no results)',
|
should: 'should search by takenAfter (no results)',
|
||||||
deferred: () => ({ dto: { takenAfter: today.plus({ hour: 1 }).toJSDate() }, assets: [] }),
|
deferred: () => ({ dto: { takenAfter: today.plus({ hour: 1 }).toJSDate() }, assets: [] }),
|
||||||
},
|
},
|
||||||
// {
|
|
||||||
// should: 'should search by originalPath',
|
|
||||||
// deferred: () => ({
|
|
||||||
// dto: { originalPath: asset1.originalPath },
|
|
||||||
// assets: [asset1],
|
|
||||||
// }),
|
|
||||||
// },
|
|
||||||
{
|
{
|
||||||
should: 'should search by originalFilename',
|
should: 'should search by originalFilename',
|
||||||
deferred: () => ({
|
deferred: () => ({
|
||||||
|
|||||||
@@ -44,7 +44,8 @@ export const ASSET_CHECKSUM_CONSTRAINT = 'UQ_assets_owner_checksum';
|
|||||||
@Index('IDX_originalPath_libraryId', ['originalPath', 'libraryId'])
|
@Index('IDX_originalPath_libraryId', ['originalPath', 'libraryId'])
|
||||||
@Index('IDX_asset_id_stackId', ['id', 'stackId'])
|
@Index('IDX_asset_id_stackId', ['id', 'stackId'])
|
||||||
@Index('idx_originalFileName_trigram', { synchronize: false })
|
@Index('idx_originalFileName_trigram', { synchronize: false })
|
||||||
// For all assets, each originalpath must be unique per user and library
|
@Index('idx_originalPath_trigram', { synchronize: false })
|
||||||
|
// For all assets, each originalPath must be unique per user and library
|
||||||
export class AssetEntity {
|
export class AssetEntity {
|
||||||
@PrimaryGeneratedColumn('uuid')
|
@PrimaryGeneratedColumn('uuid')
|
||||||
id!: string;
|
id!: string;
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||||
|
|
||||||
|
export class AddAssetOriginalPathTrigramIndex1724231348454 implements MigrationInterface {
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`CREATE INDEX idx_originalPath_trigram ON assets USING gin (f_unaccent("originalPath") gin_trgm_ops)`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`DROP INDEX "idx_originalPath_trigram"`);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -75,7 +75,6 @@ FROM
|
|||||||
"asset"."fileCreatedAt" >= $1
|
"asset"."fileCreatedAt" >= $1
|
||||||
AND "exifInfo"."lensModel" = $2
|
AND "exifInfo"."lensModel" = $2
|
||||||
AND 1 = 1
|
AND 1 = 1
|
||||||
AND 1 = 1
|
|
||||||
AND (
|
AND (
|
||||||
"asset"."isFavorite" = $3
|
"asset"."isFavorite" = $3
|
||||||
AND "asset"."isArchived" = $4
|
AND "asset"."isArchived" = $4
|
||||||
@@ -169,7 +168,6 @@ WHERE
|
|||||||
"asset"."fileCreatedAt" >= $1
|
"asset"."fileCreatedAt" >= $1
|
||||||
AND "exifInfo"."lensModel" = $2
|
AND "exifInfo"."lensModel" = $2
|
||||||
AND 1 = 1
|
AND 1 = 1
|
||||||
AND 1 = 1
|
|
||||||
AND (
|
AND (
|
||||||
"asset"."isFavorite" = $3
|
"asset"."isFavorite" = $3
|
||||||
AND "asset"."isArchived" = $4
|
AND "asset"."isArchived" = $4
|
||||||
|
|||||||
@@ -71,8 +71,15 @@ export function searchAssetBuilder(
|
|||||||
builder.andWhere(`${builder.alias}.ownerId IN (:...userIds)`, { userIds: options.userIds });
|
builder.andWhere(`${builder.alias}.ownerId IN (:...userIds)`, { userIds: options.userIds });
|
||||||
}
|
}
|
||||||
|
|
||||||
const path = _.pick(options, ['encodedVideoPath', 'originalPath']);
|
if (options.encodedVideoPath) {
|
||||||
builder.andWhere(_.omitBy(path, _.isUndefined));
|
builder.andWhere({ encodedVideoPath: options.encodedVideoPath });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.originalPath) {
|
||||||
|
builder.andWhere(`f_unaccent(${builder.alias}.originalPath) ILIKE f_unaccent(:originalPath)`, {
|
||||||
|
originalPath: `%${options.originalPath}%`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (options.originalFileName) {
|
if (options.originalFileName) {
|
||||||
builder.andWhere(`f_unaccent(${builder.alias}.originalFileName) ILIKE f_unaccent(:originalFileName)`, {
|
builder.andWhere(`f_unaccent(${builder.alias}.originalFileName) ILIKE f_unaccent(:originalFileName)`, {
|
||||||
|
|||||||
Reference in New Issue
Block a user