1
0
mirror of https://github.com/xuthus83/pigallery2.git synced 2024-11-03 21:04:03 +08:00

Adopting date pattern search to MySQL #660

This commit is contained in:
Patrik J. Braun 2023-06-24 13:11:56 +02:00
parent 5793655e8d
commit 3fb31f17a8
2 changed files with 47 additions and 25 deletions

View File

@ -161,7 +161,7 @@ export class SearchManager {
.groupBy(
'photo.metadata.positionData.country, photo.metadata.positionData.state, photo.metadata.positionData.city'
)
.limit(Config.Search.AutoComplete.ItemsPerCategory.position )
.limit(Config.Search.AutoComplete.ItemsPerCategory.position)
.getRawMany()
)
.filter((pm): boolean => !!pm)
@ -658,6 +658,9 @@ export class SearchManager {
});
case SearchQueryTypes.date_pattern: {
if (directoryOnly) {
throw new Error('not supported in directoryOnly mode');
}
const tq = query as DatePatternSearch;
return new Brackets((q): unknown => {
@ -719,33 +722,40 @@ export class SearchManager {
const relationTop = tq.negate ? '>' : '<=';
const relationBottom = tq.negate ? '<=' : '>';
const addWhere = (duration: string) => {
if (Config.Database.type === DatabaseType.sqlite) {
q.where(
`CAST(strftime('${duration}',media.metadataCreationDate/1000, 'unixepoch') AS INTEGER) ${relationTop} CAST(strftime('${duration}','now') AS INTEGER)`
).andWhere(`CAST(strftime('${duration}',media.metadataCreationDate/1000, 'unixepoch') AS INTEGER) ${relationBottom} CAST(strftime('${duration}','now','-:diff${queryId} day') AS INTEGER)`,
textParam);
} else {
q.where(
`CAST(FROM_UNIXTIME(media.metadataCreationDate/1000, '${duration}') AS SIGNED) ${relationTop} CAST(DATE_FORMAT(CURDATE(),'${duration}') AS SIGNED)`
).andWhere(`CAST(FROM_UNIXTIME(media.metadataCreationDate/1000, '${duration}') AS SIGNED) ${relationBottom} CAST(DATE_FORMAT((DATE_ADD(curdate(), INTERVAL -:diff${queryId} DAY)),'${duration}') AS SIGNED)`,
textParam);
}
};
switch (tq.frequency) {
case DatePatternFrequency.every_year:
if (tq.daysLength >= 365) {
return q;
}
q.where(
`CAST(strftime('%j',media.metadataCreationDate/1000, 'unixepoch') AS INTEGER) ${relationTop} CAST(strftime('%j','now') AS INTEGER)`
).andWhere(`CAST(strftime('%j',media.metadataCreationDate/1000, 'unixepoch') AS INTEGER) ${relationBottom} CAST(strftime('%j','now','-:diff${queryId} day') AS INTEGER)`,
textParam);
addWhere('%j');
break;
case DatePatternFrequency.every_month:
if (tq.daysLength >= 31) {
return q;
}
q.where(
`CAST(strftime('%d',media.metadataCreationDate/1000, 'unixepoch') AS INTEGER) ${relationTop} CAST(strftime('%d','now') AS INTEGER)`
).andWhere(`CAST(strftime('%d',media.metadataCreationDate/1000, 'unixepoch') AS INTEGER) ${relationBottom} CAST(strftime('%d','now','-:diff${queryId} day') AS INTEGER)`,
textParam);
addWhere('%d');
break;
case DatePatternFrequency.every_week:
if (tq.daysLength >= 7) {
return q;
}
q.where(
`CAST(strftime('%w',media.metadataCreationDate/1000, 'unixepoch') AS INTEGER) ${relationTop} CAST(strftime('%w','now') AS INTEGER)`
).andWhere(`CAST(strftime('%w',media.metadataCreationDate/1000, 'unixepoch') AS INTEGER) ${relationBottom} CAST(strftime('%w','now','-:diff${queryId} day') AS INTEGER)`,
textParam);
addWhere('%w');
break;
}

View File

@ -118,6 +118,7 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
p4.metadata.creationDate = Date.now() - 60 * 60 * 24 * 366 * 1000;
const pFaceLessTmp = TestHelper.getPhotoEntry3(subDir);
delete pFaceLessTmp.metadata.faces;
pFaceLessTmp.metadata.creationDate = Date.now() - 60 * 60 * 24 * 32 * 1000;
dir = await DBTestHelper.persistTestDir(directory);
@ -189,19 +190,14 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
Config.Search.AutoComplete.ItemsPerCategory.maxItems = 1;
expect((await sm.autocomplete('a', SearchQueryTypes.any_text))).to.deep.equalInAnyOrder([
new AutoCompleteItem('Ajan Kloss', SearchQueryTypes.position),
new AutoCompleteItem('Tipoca City', SearchQueryTypes.position),
new AutoCompleteItem('Amber stone', SearchQueryTypes.caption),
new AutoCompleteItem('Millennium falcon', SearchQueryTypes.caption),
new AutoCompleteItem('star wars', SearchQueryTypes.keyword),
new AutoCompleteItem('Anakin Skywalker', SearchQueryTypes.person),
new AutoCompleteItem('Obivan Kenobi', SearchQueryTypes.person),
new AutoCompleteItem('Castilon', SearchQueryTypes.position),
new AutoCompleteItem('Devaron', SearchQueryTypes.position),
new AutoCompleteItem('Jedha', SearchQueryTypes.position),
new AutoCompleteItem('wars dir', SearchQueryTypes.directory),
new AutoCompleteItem('The Phantom Menace', SearchQueryTypes.directory)]);
new AutoCompleteItem('Han Solo', SearchQueryTypes.person),
new AutoCompleteItem('Han Solo\'s dice', SearchQueryTypes.caption),
new AutoCompleteItem('Research City', SearchQueryTypes.position),
new AutoCompleteItem('death star', SearchQueryTypes.keyword),
new AutoCompleteItem('wars dir', SearchQueryTypes.directory)]);
Config.Search.AutoComplete.ItemsPerCategory.maxItems = 5;
Config.Search.AutoComplete.ItemsPerCategory.fileName = 5;
Config.Search.AutoComplete.ItemsPerCategory.fileName = 5;
expect((await sm.autocomplete('sw', SearchQueryTypes.any_text))).to.deep.equalInAnyOrder([
new AutoCompleteItem('sw1.jpg', SearchQueryTypes.file_name),
@ -991,6 +987,22 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
resultOverflow: false
} as SearchResultDTO));
query = {
daysLength: 3,
agoNumber: 1,
frequency: DatePatternFrequency.months_ago,
type: SearchQueryTypes.date_pattern
} as DatePatternSearch;
expect(Utils.clone(await sm.search(query)))
.to.deep.equalInAnyOrder(removeDir({
searchQuery: query,
directories: [],
media: [pFaceLess],
metaFile: [],
resultOverflow: false
} as SearchResultDTO));
query = {
daysLength: 366,
frequency: DatePatternFrequency.every_year,