mirror of
https://github.com/xuthus83/pigallery2.git
synced 2025-01-14 14:43:17 +08:00
Caching preview in the DB to speed up directory querying #381
This commit is contained in:
parent
0b7c350f5c
commit
776c8e83fc
@ -9,7 +9,7 @@ import {ProjectPath} from '../../../ProjectPath';
|
|||||||
import {Config} from '../../../../common/config/private/Config';
|
import {Config} from '../../../../common/config/private/Config';
|
||||||
import {ISQLGalleryManager} from './IGalleryManager';
|
import {ISQLGalleryManager} from './IGalleryManager';
|
||||||
import {PhotoDTO} from '../../../../common/entities/PhotoDTO';
|
import {PhotoDTO} from '../../../../common/entities/PhotoDTO';
|
||||||
import {Connection} from 'typeorm';
|
import {Brackets, Connection, WhereExpression} from 'typeorm';
|
||||||
import {MediaEntity} from './enitites/MediaEntity';
|
import {MediaEntity} from './enitites/MediaEntity';
|
||||||
import {VideoEntity} from './enitites/VideoEntity';
|
import {VideoEntity} from './enitites/VideoEntity';
|
||||||
import {DiskMangerWorker} from '../../threading/DiskMangerWorker';
|
import {DiskMangerWorker} from '../../threading/DiskMangerWorker';
|
||||||
@ -217,20 +217,66 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets preview for the directory
|
* Sets preview for the directory and caches it in the DB
|
||||||
*/
|
*/
|
||||||
public async fillPreviewForSubDir(connection: Connection, dir: SubDirectoryDTO): Promise<void> {
|
public async fillPreviewForSubDir(connection: Connection, dir: SubDirectoryDTO): Promise<void> {
|
||||||
|
|
||||||
dir.media = [];
|
if (!dir.preview || !dir.validPreview) {
|
||||||
dir.preview = await ObjectManagers.getInstance().PreviewManager.getPreviewForDirectory(dir);
|
|
||||||
dir.isPartial = true;
|
|
||||||
|
|
||||||
|
dir.preview = await ObjectManagers.getInstance().PreviewManager.getPreviewForDirectory(dir);
|
||||||
|
// write preview back to db
|
||||||
|
await connection.createQueryBuilder()
|
||||||
|
.update(DirectoryEntity).set({preview: dir.preview, validPreview: true}).where('id = :dir', {
|
||||||
|
dir: dir.id
|
||||||
|
}).execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
dir.media = [];
|
||||||
|
dir.isPartial = true;
|
||||||
if (dir.preview) {
|
if (dir.preview) {
|
||||||
dir.preview.readyThumbnails = [];
|
dir.preview.readyThumbnails = [];
|
||||||
dir.preview.readyIcon = false;
|
dir.preview.readyIcon = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async onNewDataVersion(changedDir: ParentDirectoryDTO): Promise<void> {
|
||||||
|
// Invalidating Album preview
|
||||||
|
let fullPath = DiskMangerWorker.normalizeDirPath(path.join(changedDir.path, changedDir.name));
|
||||||
|
const query = (await SQLConnection.getConnection())
|
||||||
|
.createQueryBuilder()
|
||||||
|
.update(DirectoryEntity)
|
||||||
|
.set({validPreview: false});
|
||||||
|
|
||||||
|
let i = 0;
|
||||||
|
const root = DiskMangerWorker.pathFromRelativeDirName('.');
|
||||||
|
while (fullPath !== root) {
|
||||||
|
const name = DiskMangerWorker.dirName(fullPath);
|
||||||
|
const parentPath = DiskMangerWorker.pathFromRelativeDirName(fullPath);
|
||||||
|
fullPath = parentPath;
|
||||||
|
++i;
|
||||||
|
query.orWhere(new Brackets((q: WhereExpression) => {
|
||||||
|
const param: { [key: string]: string } = {};
|
||||||
|
param['name' + i] = name;
|
||||||
|
param['path' + i] = parentPath;
|
||||||
|
q.where(`path = :path${i}`, param);
|
||||||
|
q.andWhere(`name = :name${i}`, param);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
++i;
|
||||||
|
query.orWhere(new Brackets((q: WhereExpression) => {
|
||||||
|
const param: { [key: string]: string } = {};
|
||||||
|
param['name' + i] = DiskMangerWorker.dirName('.');
|
||||||
|
param['path' + i] = DiskMangerWorker.pathFromRelativeDirName('.');
|
||||||
|
q.where(`path = :path${i}`, param);
|
||||||
|
q.andWhere(`name = :name${i}`, param);
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
await query.execute();
|
||||||
|
}
|
||||||
|
|
||||||
protected async selectParentDir(connection: Connection, directoryName: string, directoryParent: string): Promise<ParentDirectoryDTO> {
|
protected async selectParentDir(connection: Connection, directoryName: string, directoryParent: string): Promise<ParentDirectoryDTO> {
|
||||||
const query = connection
|
const query = connection
|
||||||
.getRepository(DirectoryEntity)
|
.getRepository(DirectoryEntity)
|
||||||
@ -240,7 +286,16 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager {
|
|||||||
path: directoryParent
|
path: directoryParent
|
||||||
})
|
})
|
||||||
.leftJoinAndSelect('directory.directories', 'directories')
|
.leftJoinAndSelect('directory.directories', 'directories')
|
||||||
.leftJoinAndSelect('directory.media', 'media');
|
.leftJoinAndSelect('directory.media', 'media')
|
||||||
|
.leftJoinAndSelect('directories.preview', 'preview')
|
||||||
|
.leftJoinAndSelect('preview.directory', 'previewDirectory')
|
||||||
|
.select(['directory',
|
||||||
|
'directories',
|
||||||
|
'media',
|
||||||
|
'preview.name',
|
||||||
|
'previewDirectory.name',
|
||||||
|
'previewDirectory.path']);
|
||||||
|
|
||||||
|
|
||||||
// TODO: do better filtering
|
// TODO: do better filtering
|
||||||
// NOTE: it should not cause an issue as it also do not shave to the DB
|
// NOTE: it should not cause an issue as it also do not shave to the DB
|
||||||
@ -253,7 +308,6 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager {
|
|||||||
return await query.getOne();
|
return await query.getOne();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected async fillParentDir(connection: Connection, dir: ParentDirectoryDTO): Promise<void> {
|
protected async fillParentDir(connection: Connection, dir: ParentDirectoryDTO): Promise<void> {
|
||||||
if (dir.media) {
|
if (dir.media) {
|
||||||
const indexedFaces = await connection.getRepository(FaceRegionEntry)
|
const indexedFaces = await connection.getRepository(FaceRegionEntry)
|
||||||
|
@ -56,8 +56,13 @@ export class DirectoryEntity implements ParentDirectoryDTO<MediaDTO>, SubDirecto
|
|||||||
public directories: DirectoryEntity[];
|
public directories: DirectoryEntity[];
|
||||||
|
|
||||||
// not saving to database, it is only assigned when querying the DB
|
// not saving to database, it is only assigned when querying the DB
|
||||||
|
@ManyToOne(type => MediaEntity, {onDelete: 'SET NULL'})
|
||||||
public preview: MediaEntity;
|
public preview: MediaEntity;
|
||||||
|
|
||||||
|
// On galley change, preview will be invalid
|
||||||
|
@Column({default: false})
|
||||||
|
validPreview: boolean;
|
||||||
|
|
||||||
@OneToMany(type => MediaEntity, media => media.directory)
|
@OneToMany(type => MediaEntity, media => media.directory)
|
||||||
public media: MediaEntity[];
|
public media: MediaEntity[];
|
||||||
|
|
||||||
|
@ -34,11 +34,11 @@ export class DiskMangerWorker {
|
|||||||
return path.join(this.normalizeDirPath(path.join(parent.path, parent.name)), path.sep);
|
return path.join(this.normalizeDirPath(path.join(parent.path, parent.name)), path.sep);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static dirName(name: string): any {
|
public static dirName(dirPath: string): string {
|
||||||
if (name.trim().length === 0) {
|
if (dirPath.trim().length === 0) {
|
||||||
return '.';
|
return '.';
|
||||||
}
|
}
|
||||||
return path.basename(name);
|
return path.basename(dirPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async excludeDir(name: string, relativeDirectoryName: string, absoluteDirectoryName: string): Promise<boolean> {
|
public static async excludeDir(name: string, relativeDirectoryName: string, absoluteDirectoryName: string): Promise<boolean> {
|
||||||
@ -102,6 +102,7 @@ export class DiskMangerWorker {
|
|||||||
isPartial: false,
|
isPartial: false,
|
||||||
mediaCount: 0,
|
mediaCount: 0,
|
||||||
preview: null,
|
preview: null,
|
||||||
|
validPreview: false,
|
||||||
media: [],
|
media: [],
|
||||||
metaFile: []
|
metaFile: []
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/**
|
/**
|
||||||
* This version indicates that the SQL sql/entities/*Entity.ts files got changed and the db needs to be recreated
|
* This version indicates that the SQL sql/entities/*Entity.ts files got changed and the db needs to be recreated
|
||||||
*/
|
*/
|
||||||
export const DataStructureVersion = 25;
|
export const DataStructureVersion = 26;
|
||||||
|
@ -38,6 +38,7 @@ export interface DirectoryBaseDTO<S extends FileDTO = MediaDTO> extends Director
|
|||||||
media?: S[];
|
media?: S[];
|
||||||
metaFile?: FileDTO[];
|
metaFile?: FileDTO[];
|
||||||
preview?: PreviewPhotoDTO;
|
preview?: PreviewPhotoDTO;
|
||||||
|
validPreview?: boolean; // does not go to the client side
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ParentDirectoryDTO<S extends FileDTO = MediaDTO> extends DirectoryBaseDTO<S> {
|
export interface ParentDirectoryDTO<S extends FileDTO = MediaDTO> extends DirectoryBaseDTO<S> {
|
||||||
@ -64,6 +65,7 @@ export interface SubDirectoryDTO<S extends FileDTO = MediaDTO> extends Directory
|
|||||||
parent: ParentDirectoryDTO<S>;
|
parent: ParentDirectoryDTO<S>;
|
||||||
mediaCount: number;
|
mediaCount: number;
|
||||||
preview: PreviewPhotoDTO;
|
preview: PreviewPhotoDTO;
|
||||||
|
validPreview?: boolean; // does not go to the client side
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DirectoryDTOUtils = {
|
export const DirectoryDTOUtils = {
|
||||||
@ -116,6 +118,8 @@ export const DirectoryDTOUtils = {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete dir.validPreview; // should not go to the client side;
|
||||||
|
|
||||||
return dir;
|
return dir;
|
||||||
|
|
||||||
},
|
},
|
||||||
|
@ -4,13 +4,16 @@ import * as fs from 'fs';
|
|||||||
import {SQLConnection} from '../../src/backend/model/database/sql/SQLConnection';
|
import {SQLConnection} from '../../src/backend/model/database/sql/SQLConnection';
|
||||||
import {DatabaseType} from '../../src/common/config/private/PrivateConfig';
|
import {DatabaseType} from '../../src/common/config/private/PrivateConfig';
|
||||||
import {ProjectPath} from '../../src/backend/ProjectPath';
|
import {ProjectPath} from '../../src/backend/ProjectPath';
|
||||||
import {DirectoryBaseDTO, ParentDirectoryDTO} from '../../src/common/entities/DirectoryDTO';
|
import {DirectoryBaseDTO, ParentDirectoryDTO, SubDirectoryDTO} from '../../src/common/entities/DirectoryDTO';
|
||||||
import {ObjectManagers} from '../../src/backend/model/ObjectManagers';
|
import {ObjectManagers} from '../../src/backend/model/ObjectManagers';
|
||||||
import {DiskMangerWorker} from '../../src/backend/model/threading/DiskMangerWorker';
|
import {DiskMangerWorker} from '../../src/backend/model/threading/DiskMangerWorker';
|
||||||
import {IndexingManager} from '../../src/backend/model/database/sql/IndexingManager';
|
import {IndexingManager} from '../../src/backend/model/database/sql/IndexingManager';
|
||||||
import {GalleryManager} from '../../src/backend/model/database/sql/GalleryManager';
|
import {GalleryManager} from '../../src/backend/model/database/sql/GalleryManager';
|
||||||
import {Connection} from 'typeorm';
|
import {Connection} from 'typeorm';
|
||||||
import {Utils} from '../../src/common/Utils';
|
import {Utils} from '../../src/common/Utils';
|
||||||
|
import {TestHelper} from './unit/model/sql/TestHelper';
|
||||||
|
import {VideoDTO} from '../../src/common/entities/VideoDTO';
|
||||||
|
import {PhotoDTO} from '../../src/common/entities/PhotoDTO';
|
||||||
|
|
||||||
declare let describe: any;
|
declare let describe: any;
|
||||||
const savedDescribe = describe;
|
const savedDescribe = describe;
|
||||||
@ -42,6 +45,36 @@ export class DBTestHelper {
|
|||||||
};
|
};
|
||||||
public static readonly savedDescribe = savedDescribe;
|
public static readonly savedDescribe = savedDescribe;
|
||||||
tempDir: string;
|
tempDir: string;
|
||||||
|
public readonly testGalleyEntities: {
|
||||||
|
dir: ParentDirectoryDTO,
|
||||||
|
subDir: SubDirectoryDTO,
|
||||||
|
subDir2: SubDirectoryDTO,
|
||||||
|
v: VideoDTO,
|
||||||
|
p: PhotoDTO,
|
||||||
|
p2: PhotoDTO,
|
||||||
|
p3: PhotoDTO,
|
||||||
|
p4: PhotoDTO
|
||||||
|
} = {
|
||||||
|
/**
|
||||||
|
* dir
|
||||||
|
* |- v
|
||||||
|
* |- p
|
||||||
|
* |- p2
|
||||||
|
* |-> subDir
|
||||||
|
* |- p3
|
||||||
|
* |-> subDir2
|
||||||
|
* |- p4
|
||||||
|
*/
|
||||||
|
|
||||||
|
dir: null,
|
||||||
|
subDir: null,
|
||||||
|
subDir2: null,
|
||||||
|
v: null,
|
||||||
|
p: null,
|
||||||
|
p2: null,
|
||||||
|
p3: null,
|
||||||
|
p4: null
|
||||||
|
};
|
||||||
|
|
||||||
constructor(public dbType: DatabaseType) {
|
constructor(public dbType: DatabaseType) {
|
||||||
this.tempDir = path.join(__dirname, './tmp');
|
this.tempDir = path.join(__dirname, './tmp');
|
||||||
@ -127,7 +160,6 @@ export class DBTestHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async clearDB(): Promise<void> {
|
public async clearDB(): Promise<void> {
|
||||||
if (this.dbType === DatabaseType.sqlite) {
|
if (this.dbType === DatabaseType.sqlite) {
|
||||||
await this.clearUpSQLite();
|
await this.clearUpSQLite();
|
||||||
@ -138,6 +170,26 @@ export class DBTestHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async setUpTestGallery(): Promise<void> {
|
||||||
|
const directory: ParentDirectoryDTO = TestHelper.getDirectoryEntry();
|
||||||
|
this.testGalleyEntities.subDir = TestHelper.getDirectoryEntry(directory, 'The Phantom Menace');
|
||||||
|
this.testGalleyEntities.subDir2 = TestHelper.getDirectoryEntry(directory, 'Return of the Jedi');
|
||||||
|
this.testGalleyEntities.p = TestHelper.getRandomizedPhotoEntry(directory, 'Photo1');
|
||||||
|
this.testGalleyEntities.p2 = TestHelper.getRandomizedPhotoEntry(directory, 'Photo2');
|
||||||
|
this.testGalleyEntities.p3 = TestHelper.getRandomizedPhotoEntry(this.testGalleyEntities.subDir, 'Photo3');
|
||||||
|
this.testGalleyEntities.p4 = TestHelper.getRandomizedPhotoEntry(this.testGalleyEntities.subDir2, 'Photo4');
|
||||||
|
this.testGalleyEntities.v = TestHelper.getVideoEntry1(directory);
|
||||||
|
|
||||||
|
this.testGalleyEntities.dir = await DBTestHelper.persistTestDir(directory);
|
||||||
|
this.testGalleyEntities.subDir = this.testGalleyEntities.dir.directories[0];
|
||||||
|
this.testGalleyEntities.subDir2 = this.testGalleyEntities.dir.directories[1];
|
||||||
|
this.testGalleyEntities.p = (this.testGalleyEntities.dir.media.filter(m => m.name === this.testGalleyEntities.p.name)[0] as any);
|
||||||
|
this.testGalleyEntities.p2 = (this.testGalleyEntities.dir.media.filter(m => m.name === this.testGalleyEntities.p2.name)[0] as any);
|
||||||
|
this.testGalleyEntities.v = (this.testGalleyEntities.dir.media.filter(m => m.name === this.testGalleyEntities.v.name)[0] as any);
|
||||||
|
this.testGalleyEntities.p3 = (this.testGalleyEntities.dir.directories[0].media[0] as any);
|
||||||
|
this.testGalleyEntities.p4 = (this.testGalleyEntities.dir.directories[1].media[0] as any);
|
||||||
|
}
|
||||||
|
|
||||||
private async initMySQL(): Promise<void> {
|
private async initMySQL(): Promise<void> {
|
||||||
await this.resetMySQL();
|
await this.resetMySQL();
|
||||||
}
|
}
|
||||||
|
@ -29,50 +29,12 @@ describe = DBTestHelper.describe(); // fake it os IDE plays nicely (recognize th
|
|||||||
|
|
||||||
describe('AlbumManager', (sqlHelper: DBTestHelper) => {
|
describe('AlbumManager', (sqlHelper: DBTestHelper) => {
|
||||||
describe = tmpDescribe;
|
describe = tmpDescribe;
|
||||||
/**
|
|
||||||
* dir
|
|
||||||
* |- v
|
|
||||||
* |- p
|
|
||||||
* |- p2
|
|
||||||
* |-> subDir
|
|
||||||
* |- p3
|
|
||||||
* |-> subDir2
|
|
||||||
* |- p4
|
|
||||||
*/
|
|
||||||
|
|
||||||
let dir: ParentDirectoryDTO;
|
|
||||||
let subDir: SubDirectoryDTO;
|
|
||||||
let subDir2: SubDirectoryDTO;
|
|
||||||
let v: VideoDTO;
|
|
||||||
let p: PhotoDTO;
|
|
||||||
let p2: PhotoDTO;
|
|
||||||
let p3: PhotoDTO;
|
|
||||||
let p4: PhotoDTO;
|
|
||||||
|
|
||||||
|
|
||||||
const setUpTestGallery = async (): Promise<void> => {
|
|
||||||
const directory: ParentDirectoryDTO = TestHelper.getDirectoryEntry();
|
|
||||||
subDir = TestHelper.getDirectoryEntry(directory, 'The Phantom Menace');
|
|
||||||
subDir2 = TestHelper.getDirectoryEntry(directory, 'Return of the Jedi');
|
|
||||||
p = TestHelper.getRandomizedPhotoEntry(directory, 'Photo1');
|
|
||||||
p2 = TestHelper.getRandomizedPhotoEntry(directory, 'Photo2');
|
|
||||||
p3 = TestHelper.getRandomizedPhotoEntry(subDir, 'Photo3');
|
|
||||||
p4 = TestHelper.getRandomizedPhotoEntry(subDir2, 'Photo4');
|
|
||||||
v = TestHelper.getVideoEntry1(directory);
|
|
||||||
|
|
||||||
dir = await DBTestHelper.persistTestDir(directory);
|
|
||||||
subDir = dir.directories[0];
|
|
||||||
subDir2 = dir.directories[1];
|
|
||||||
p = (dir.media.filter(m => m.name === p.name)[0] as any);
|
|
||||||
p2 = (dir.media.filter(m => m.name === p2.name)[0] as any);
|
|
||||||
v = (dir.media.filter(m => m.name === v.name)[0] as any);
|
|
||||||
p3 = (dir.directories[0].media[0] as any);
|
|
||||||
p4 = (dir.directories[1].media[0] as any);
|
|
||||||
};
|
|
||||||
|
|
||||||
const setUpSqlDB = async () => {
|
const setUpSqlDB = async () => {
|
||||||
await sqlHelper.initDB();
|
await sqlHelper.initDB();
|
||||||
await setUpTestGallery();
|
await sqlHelper.setUpTestGallery();
|
||||||
await ObjectManagers.InitSQLManagers();
|
await ObjectManagers.InitSQLManagers();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -192,7 +154,7 @@ describe('AlbumManager', (sqlHelper: DBTestHelper) => {
|
|||||||
searchQuery: query,
|
searchQuery: query,
|
||||||
locked: false,
|
locked: false,
|
||||||
count: 1,
|
count: 1,
|
||||||
preview: toAlbumPreview(p)
|
preview: toAlbumPreview(sqlHelper.testGalleyEntities.p)
|
||||||
} as SavedSearchDTO]));
|
} as SavedSearchDTO]));
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,13 +1,88 @@
|
|||||||
import {DBTestHelper} from '../../../DBTestHelper';
|
import {DBTestHelper} from '../../../DBTestHelper';
|
||||||
import {GalleryManager} from '../../../../../src/backend/model/database/sql/GalleryManager';
|
import {GalleryManager} from '../../../../../src/backend/model/database/sql/GalleryManager';
|
||||||
|
import {ObjectManagers} from '../../../../../src/backend/model/ObjectManagers';
|
||||||
|
import {SQLConnection} from '../../../../../src/backend/model/database/sql/SQLConnection';
|
||||||
|
import {DirectoryEntity} from '../../../../../src/backend/model/database/sql/enitites/DirectoryEntity';
|
||||||
|
import {ParentDirectoryDTO} from '../../../../../src/common/entities/DirectoryDTO';
|
||||||
|
import {Connection} from 'typeorm';
|
||||||
|
|
||||||
|
const deepEqualInAnyOrder = require('deep-equal-in-any-order');
|
||||||
|
const chai = require('chai');
|
||||||
|
|
||||||
|
chai.use(deepEqualInAnyOrder);
|
||||||
|
const {expect} = chai;
|
||||||
|
|
||||||
// to help WebStorm to handle the test cases
|
// to help WebStorm to handle the test cases
|
||||||
declare let describe: any;
|
declare let describe: any;
|
||||||
|
declare const before: any;
|
||||||
declare const after: any;
|
declare const after: any;
|
||||||
|
const tmpDescribe = describe;
|
||||||
describe = DBTestHelper.describe();
|
describe = DBTestHelper.describe();
|
||||||
|
|
||||||
describe('GalleryManager', (sqlHelper: DBTestHelper) => {
|
|
||||||
|
|
||||||
|
class GalleryManagerTest extends GalleryManager {
|
||||||
|
|
||||||
|
|
||||||
|
public async selectParentDir(connection: Connection, directoryName: string, directoryParent: string): Promise<ParentDirectoryDTO> {
|
||||||
|
return super.selectParentDir(connection, directoryName, directoryParent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async fillParentDir(connection: Connection, dir: ParentDirectoryDTO): Promise<void> {
|
||||||
|
return super.fillParentDir(connection, dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('GalleryManager', (sqlHelper: DBTestHelper) => {
|
||||||
|
describe = tmpDescribe;
|
||||||
|
|
||||||
|
|
||||||
|
const setUpSqlDB = async () => {
|
||||||
|
await sqlHelper.initDB();
|
||||||
|
await sqlHelper.setUpTestGallery();
|
||||||
|
await ObjectManagers.InitSQLManagers();
|
||||||
|
};
|
||||||
|
|
||||||
|
before(setUpSqlDB);
|
||||||
|
after(sqlHelper.clearDB);
|
||||||
|
|
||||||
|
it('should invalidate and update preview', async () => {
|
||||||
|
const gm = new GalleryManagerTest();
|
||||||
|
const conn = await SQLConnection.getConnection();
|
||||||
|
|
||||||
|
const selectDir = async () => {
|
||||||
|
return await conn.getRepository(DirectoryEntity).findOne({id: sqlHelper.testGalleyEntities.subDir.id}, {
|
||||||
|
join: {
|
||||||
|
alias: 'dir',
|
||||||
|
leftJoinAndSelect: {preview: 'dir.preview'}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
let subdir = await selectDir();
|
||||||
|
|
||||||
|
expect(subdir.validPreview).to.equal(true);
|
||||||
|
expect(subdir.preview.id).to.equal(1);
|
||||||
|
|
||||||
|
// new version should invalidate
|
||||||
|
await gm.onNewDataVersion(sqlHelper.testGalleyEntities.subDir as ParentDirectoryDTO);
|
||||||
|
subdir = await selectDir();
|
||||||
|
expect(subdir.validPreview).to.equal(false);
|
||||||
|
// during invalidation, we do not remove the previous preview (it's good to show at least some photo)
|
||||||
|
expect(subdir.preview.id).to.equal(1);
|
||||||
|
|
||||||
|
await conn.createQueryBuilder()
|
||||||
|
.update(DirectoryEntity)
|
||||||
|
.set({validPreview: false, preview: null}).execute();
|
||||||
|
expect((await selectDir()).preview).to.equal(null);
|
||||||
|
|
||||||
|
const res = await gm.selectParentDir(conn, sqlHelper.testGalleyEntities.dir.name, sqlHelper.testGalleyEntities.dir.path);
|
||||||
|
await gm.fillParentDir(conn, res);
|
||||||
|
subdir = await selectDir();
|
||||||
|
expect(subdir.validPreview).to.equal(true);
|
||||||
|
expect(subdir.preview.id).to.equal(1);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -134,6 +134,7 @@ describe('PreviewManager', (sqlHelper: DBTestHelper) => {
|
|||||||
delete tmpDir.directories;
|
delete tmpDir.directories;
|
||||||
delete tmpDir.media;
|
delete tmpDir.media;
|
||||||
delete tmpDir.preview;
|
delete tmpDir.preview;
|
||||||
|
delete tmpDir.validPreview;
|
||||||
delete tmpDir.metaFile;
|
delete tmpDir.metaFile;
|
||||||
const ret = Utils.clone(m);
|
const ret = Utils.clone(m);
|
||||||
delete (ret.directory as DirectoryBaseDTO).id;
|
delete (ret.directory as DirectoryBaseDTO).id;
|
||||||
|
@ -206,6 +206,7 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
|
|||||||
delete tmpDir.directories;
|
delete tmpDir.directories;
|
||||||
delete tmpDir.media;
|
delete tmpDir.media;
|
||||||
delete tmpDir.preview;
|
delete tmpDir.preview;
|
||||||
|
delete tmpDir.validPreview;
|
||||||
delete tmpDir.metaFile;
|
delete tmpDir.metaFile;
|
||||||
const ret = Utils.clone(m);
|
const ret = Utils.clone(m);
|
||||||
delete (ret.directory as DirectoryBaseDTO).lastScanned;
|
delete (ret.directory as DirectoryBaseDTO).lastScanned;
|
||||||
@ -230,6 +231,7 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
|
|||||||
delete d.directories;
|
delete d.directories;
|
||||||
delete d.media;
|
delete d.media;
|
||||||
delete d.preview;
|
delete d.preview;
|
||||||
|
delete d.validPreview;
|
||||||
delete d.metaFile;
|
delete d.metaFile;
|
||||||
const ret = Utils.clone(d);
|
const ret = Utils.clone(d);
|
||||||
d.directories = tmpD;
|
d.directories = tmpD;
|
||||||
|
@ -260,6 +260,7 @@ export class TestHelper {
|
|||||||
directories: [],
|
directories: [],
|
||||||
metaFile: [],
|
metaFile: [],
|
||||||
preview: null,
|
preview: null,
|
||||||
|
validPreview: false,
|
||||||
media: [],
|
media: [],
|
||||||
lastModified: Date.now(),
|
lastModified: Date.now(),
|
||||||
lastScanned: null,
|
lastScanned: null,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user