@ -1,22 +1,25 @@
import { create _photo , create _album } from './media.js' ;
import { create _photo , create _album , create _tag } from './media.js' ;
export function escape _regex ( s ) {
return s . replace ( /[-\/\\^$*+?.()|[\]{}]/g , '\\$&' ) ;
} ;
export function do _image _query ( query , database , collection _path , collection _thumbs _path ) {
console . log ( "Doing image query:" , query ) ;
return new Promise ( function ( resolve , reject ) {
var queries = [ ] ;
var ids = [ ] ; // TODO: this is for always uniquifying because of GROUP BY apparent bug in AlaSQL
queries . push ( query ) ;
database . queries _async ( queries ) . then ( res => {
var photos = [ ] ;
if ( res && Array . isArray ( res ) ) {
res . forEach ( row => {
if ( ! ids . includes ( row [ "id" ] ) ) { //uniquify
ids . push ( row [ "id" ] ) ; //uniquify
var imagepath = process . env . PUBLIC _URL + collection _path + "/" + row [ "relativePath" ] + "/" + row [ "name" ] ;
var thumbpath = process . env . PUBLIC _URL + collection _thumbs _path + "/" + row [ "uniqueHash" ] + ".jpg" ;
photos . push ( create _photo ( row [ "id" ] , row [ "name" ] , imagepath , thumbpath ) ) ;
}
} ) ;
}
resolve ( photos ) ;
@ -41,6 +44,22 @@ export function do_album_query(query, database) {
} ) ;
}
export function do _tag _query ( query , database ) {
return new Promise ( function ( resolve , reject ) {
var queries = [ ] ;
queries . push ( query ) ;
database . queries _async ( queries ) . then ( res => {
var tags = [ ] ;
if ( res && Array . isArray ( res ) ) {
res . forEach ( row => {
tags . push ( create _tag ( row [ "id" ] , row [ "name" ] ) ) ;
} ) ;
}
resolve ( tags ) ;
} ) ;
} ) ;
}
export const MatchTypeEnum = {
MATCH _EQUALS : 1 ,
MATCH _REGEXP _CASEINSENSITIVE : 2 ,
@ -48,13 +67,15 @@ export const MatchTypeEnum = {
export const MatchAgainstEnum = {
MATCH _RESULT _NAME : 1 , // Match on the name of whatever object type we are querying for
MATCH _IMAGE _NAME : 2 , // Match on the name of the relevant image, if any
MATCH _ALBUM _NAME : 3 , // Match on the name of the relevant album, if any
MATCH _IMAGE _NAME : 2 , // Match on the name of the relevant image(s), if any
MATCH _ALBUM _NAME : 3 , // Match on the name of the relevant album(s), if any
MATCH _TAG _NAME : 4 , // Match on the name of the relevant tag(s), if any
}
export const ResultTypeEnum = {
IMAGE : 1 ,
ALBUM : 2 ,
TAG : 3 ,
}
export class ResultFilter {
@ -143,11 +164,14 @@ export class LogicalOperatorFilter extends ResultFilter {
export class UserQuery {
image _filter = new ConstFilter ( ResultTypeEnum . IMAGE , true ) ;
album _filter = new ConstFilter ( ResultTypeEnum . ALBUM , true ) ;
tag _filter = new ConstFilter ( ResultTypeEnum . TAG , true ) ;
}
// This query will return database entries with the fields "id", "uniqueHash", "relativePath" (of the album) and "name" for each matching image.
export function image _query _with _where ( maybe _where ) {
return "SELECT Images.id, Images.name, Images.uniqueHash, Albums.relativePath FROM Images INNER JOIN Albums ON Images.album=Albums.id " + ( maybe _where ? maybe _where : "" ) + ";" ;
return "SELECT Images.id, Images.name, Images.uniqueHash, Albums.relativePath FROM Images INNER JOIN Albums ON Images.album=Albums.id LEFT JOIN ImageTags ON Images.id=ImageTags.imageid LEFT JOIN Tags ON ImageTags.tagid=Tags.id " + ( maybe _where ? maybe _where : "" ) ;
// TODO: the following for some reason breaks the query:
//+ " GROUP BY Images.id;";
}
// This query will return database entries with the fields "id" and "relativePath" for each matching album.
@ -155,6 +179,11 @@ export function album_query_with_where(maybe_where) {
return "SELECT Albums.id, Albums.relativePath FROM Albums " + ( maybe _where ? maybe _where : "" ) + ";" ;
}
// This query will return database entries with the fields "id" and "name" for each matching tag.
export function tag _query _with _where ( maybe _where ) {
return "SELECT Tags.id, Tags.name FROM Tags " + ( maybe _where ? maybe _where : "" ) + ";" ;
}
export function maybe _image _query ( user _query ) {
var where = false ;
if ( user _query . image _filter ) {
@ -171,6 +200,14 @@ export function maybe_album_query(user_query) {
return album _query _with _where ( where ) ;
}
export function maybe _tag _query ( user _query ) {
var where = false ;
if ( user _query . tag _filter ) {
where = "WHERE (" + user _query . tag _filter . to _sql _where ( ) + " AND Tags.pid = 0 AND NOT Tags.name=\"_Digikam_Internal_Tags_\")" ; // TODO this way of doing the pid is hacky
}
return tag _query _with _where ( where ) ;
}
function filter _from _text _segment ( result _type , segment ) {
var filter = false ;
@ -205,6 +242,16 @@ function filter_from_text_segment(result_type, segment) {
segment [ 'negated' ]
) ;
filter = name _filter ;
} else if ( result _type == ResultTypeEnum . TAG ) {
// Match against the tag name.
var name _filter = new MatchingFilter (
result _type ,
"Tags.name" ,
'"' + '.*' + escape _regex ( segment [ 'text' ] ) + '.*' + '"' ,
MatchTypeEnum . MATCH _REGEXP _CASEINSENSITIVE ,
segment [ 'negated' ]
) ;
filter = name _filter ;
}
return filter ;
@ -220,11 +267,12 @@ export function user_query_from_search_string(search_string) {
var r = new UserQuery ( ) ;
texts . forEach ( text => {
console . log ( text ) ;
r . image _filter = new LogicalOperatorFilter ( ResultTypeEnum . IMAGE , r . image _filter ,
filter _from _text _segment ( ResultTypeEnum . IMAGE , text ) , LogicalOperatorEnum . AND ) ;
r . album _filter = new LogicalOperatorFilter ( ResultTypeEnum . ALBUM , r . album _filter ,
filter _from _text _segment ( ResultTypeEnum . ALBUM , text ) , LogicalOperatorEnum . AND ) ;
r . tag _filter = new LogicalOperatorFilter ( ResultTypeEnum . TAG , r . tag _filter ,
filter _from _text _segment ( ResultTypeEnum . TAG , text ) , LogicalOperatorEnum . AND ) ;
} ) ;
return r ;
@ -235,8 +283,20 @@ export function user_query_from_browsed_album(album_path) {
var match _type = MatchTypeEnum . MATCH _REGEXP _CASEINSENSITIVE ;
var match _text = '"' + escape _regex ( album _path ) + '(\/[^\/]+)*' + '"' ;
var match _against = "Albums.relativePath" ;
r . image _filter = new MatchingFilter ( ResultTypeEnum . ALBUM , match _against , match _text , match _type , false ) ;
r . image _filter = new MatchingFilter ( ResultTypeEnum . IMAGE , match _against , match _text , match _type , false ) ;
r . album _filter = new ConstFilter ( ResultTypeEnum . ALBUM , false ) ;
return r ;
}
export function user _query _from _browsed _tag ( name ) {
var r = new UserQuery ( ) ;
var match _type = MatchTypeEnum . MATCH _EQUALS ;
var match _text = '"' + name + '"' ;
var match _against = "Tags.name" ;
r . image _filter = new MatchingFilter ( ResultTypeEnum . IMAGE , match _against , match _text , match _type , false ) ;
r . album _filter = new ConstFilter ( ResultTypeEnum . ALBUM , false ) ;
r . tag _filter = new ConstFilter ( ResultTypeEnum . TAG , false ) ;
return r ;
}