diff --git a/src/queries.js b/src/queries.js index 211797a..c89d308 100644 --- a/src/queries.js +++ b/src/queries.js @@ -61,15 +61,13 @@ export function do_tag_query(query, database) { } export const MatchTypeEnum = { - MATCH_EQUALS: 1, - MATCH_NATURAL: 2, -}; - -export const MatchAgainstEnum = { - MATCH_IMAGE_NAME: 1, // Match on the name of the relevant image(s), if any - MATCH_ALBUM_NAME: 2, // Match on the name of the relevant album(s), if any - MATCH_ALBUM_NAME_IN_TREE: 3, // Match on any album name in the album tree branch, including parents - MATCH_TAG_NAME: 4, // Match on the name of the relevant tag(s), if any + MATCH_IMAGE_NAME_EQUALS: 1, + MATCH_IMAGE_NAME_NATURAL: 2, + MATCH_ALBUM_EQUALS: 3, // Match on the full name (relative path) of the relevant album, if any + MATCH_ALBUM_EQUALS_OR_CHILD: 4, // Match on the full name (relative path) of the relevant album, if any, or any of its children + MATCH_ALBUM_NATURAL: 5, + MATCH_ALBUM_NAME_EQUALS: 6, // Match on the local album name (excluding parents) + MATCH_TAG_EQUALS: 7, // Match on the name of the relevant tag(s), if any } export const ResultTypeEnum = { @@ -96,7 +94,7 @@ export class ConstFilter extends ResultFilter { to_sql_where() { return this.constval ? "(1=1)" : "(1=0)"; } - + is_true() { return this.constval; } is_false() { return !this.constval; } simplify() { return this; } @@ -116,10 +114,10 @@ export class NegationFilter extends ResultFilter { simplify() { var f = this.body.simplify(); - if(f.is_true()) { + if (f.is_true()) { return new ConstFilter(this.result_type, false); } - if(f.is_false()) { + if (f.is_false()) { return new ConstFilter(this.result_type, true); } return this; @@ -127,52 +125,39 @@ export class NegationFilter extends ResultFilter { } export class MatchingFilter extends ResultFilter { - constructor(rtype, against, from, mtype) { + constructor(rtype, from, mtype) { super(rtype); - this.match_against = against; this.match_from = from; this.match_type = mtype; } - // What string to match against. - match_against = MatchAgainstEnum.MATCH_IMAGE_NAME; - // optional string used in the filtering match_from = ""; - // How to use the matching string - match_type = MatchTypeEnum.MATCH_EQUALS; + // What and how to match + match_type = MatchTypeEnum.MATCH_IMAGE_NAME_EQUALS; to_sql_where() { - var expr; - if(this.match_against === MatchAgainstEnum.MATCH_IMAGE_NAME) { - if(this.match_type === MatchTypeEnum.MATCH_EQUALS) { - return '(Images.name="' + this.match_from + '")'; - } else if(this.match_type === MatchTypeEnum.MATCH_NATURAL) { - expr = '".*' + escape_regex(this.match_from) + '.*"'; - return "(LOWER(Images.name) REGEXP LOWER(" + expr +"))"; - } - } else if(this.match_against === MatchAgainstEnum.MATCH_TAG_NAME) { - if(this.match_type === MatchTypeEnum.MATCH_EQUALS) { - return '(Tags.name="' + this.match_from + '")'; - } else if(this.match_type === MatchTypeEnum.MATCH_NATURAL) { - expr = '".*' + escape_regex(this.match_from) + '.*"'; - return '(LOWER(Tags.name) REGEXP LOWER("' + expr + '"))'; - } - } else if(this.match_against === MatchAgainstEnum.MATCH_ALBUM_NAME) { - if(this.match_type === MatchTypeEnum.MATCH_EQUALS) { - expr = '\/(.*\/)*' + escape_regex(this.match_from); - return '(Albums.relativePath REGEXP "' + expr + '")'; - } else if(this.match_type === MatchTypeEnum.MATCH_NATURAL) { - throw new Error("Natural matching on album names is not yet supported."); - } - } else if(this.match_against === MatchAgainstEnum.MATCH_ALBUM_NAME_IN_TREE) { - if(this.match_type === MatchTypeEnum.MATCH_EQUALS) { - expr = escape_regex(this.match_from) + '(\/[^\/]+)*'; - return '(Albums.relativePath REGEXP "' + expr + '")'; - } else if(this.match_type === MatchTypeEnum.MATCH_NATURAL) { - throw new Error("Natural matching on album tree names is not yet supported."); - } + if (this.match_type == MatchTypeEnum.MATCH_IMAGE_NAME_EQUALS) { + return '(Images.name="' + this.match_from + '")'; + } else if (this.match_type == MatchTypeEnum.MATCH_IMAGE_NAME_NATURAL) { + return '(LOWER(Images.name) REGEXP LOWER(".*' + + escape_regex(this.match_from) + + ')).*"'; + } else if (this.match_type == MatchTypeEnum.MATCH_ALBUM_EQUALS) { + return '(Albums.relativePath = "' + this.match_from + '")'; + } else if (this.match_type == MatchTypeEnum.MATCH_ALBUM_EQUALS_OR_CHILD) { + return '(Albums.relativePath REGEXP "' + + escape_regex(this.match_from) + + '(\/[^\/]+)*")'; + } else if (this.match_type == MatchTypeEnum.MATCH_ALBUM_NATURAL) { + throw new Error("Natural matching on album names is not yet supported."); + } else if (this.match_type == MatchTypeEnum.MATCH_ALBUM_NAME_EQUALS) { + return '(Albums.relativePath REGEXP "\/(.*\/)*' + + escape_regex(this.match_from) + + '(\/[^\/]+)*")'; + } else if (this.match_type == MatchTypeEnum.MATCH_TAG_EQUALS) { + return '(Tags.name="' + this.match_from + '")'; } console.log(this); @@ -210,20 +195,20 @@ export class LogicalOperatorFilter extends ResultFilter { var a = this.sub_filter_a.simplify(); var b = this.sub_filter_b.simplify(); - if(this.operator === LogicalOperatorEnum.OR) { - if(a.is_true() || b.is_true()) { + if (this.operator === LogicalOperatorEnum.OR) { + if (a.is_true() || b.is_true()) { return new ConstFilter(this.return_type, true); } - if(a.is_false()) { return b; } - if(b.is_false()) { return a; } + if (a.is_false()) { return b; } + if (b.is_false()) { return a; } } - if(this.operator === LogicalOperatorEnum.AND) { - if(a.is_false() || b.is_false()) { + if (this.operator === LogicalOperatorEnum.AND) { + if (a.is_false() || b.is_false()) { return new ConstFilter(this.return_type, false); } - if(a.is_true()) { return b; } - if(b.is_true()) { return a; } + if (a.is_true()) { return b; } + if (b.is_true()) { return a; } } return this; @@ -278,7 +263,7 @@ export function maybe_tag_query(user_query) { } export function filter_is_const_false(filter) { - if(filter instanceof ConstFilter && filter.constval === false) { + if (filter instanceof ConstFilter && filter.constval === false) { return true; } // TODO resolve recursively @@ -293,45 +278,41 @@ function filter_from_text_segment(result_type, segment) { // Option 1: match on image name name_filter = new MatchingFilter( result_type, - MatchAgainstEnum.MATCH_IMAGE_NAME, segment['text'], - MatchTypeEnum.MATCH_NATURAL + MatchTypeEnum.MATCH_IMAGE_NAME_NATURAL ); - // Option 2: match on album path + // Option 2: match on album path (TODO: need natural matching) var album_filter = new MatchingFilter( result_type, - MatchAgainstEnum.MATCH_ALBUM_NAME, segment['text'], - MatchTypeEnum.MATCH_EQUALS + MatchTypeEnum.MATCH_ALBUM_NAME_EQUALS ); filter = new LogicalOperatorFilter(result_type, name_filter, album_filter, LogicalOperatorEnum.OR); - if(segment['negated']) { + if (segment['negated']) { filter = new NegationFilter(result_type, filter); } } else if (result_type === ResultTypeEnum.ALBUM) { // TODO: We need a natural matcher for album names name_filter = new MatchingFilter( result_type, - MatchAgainstEnum.MATCH_ALBUM_NAME, segment['text'], - MatchTypeEnum.MATCH_EQUALS + MatchTypeEnum.MATCH_ALBUM_NAME_EQUALS ); filter = name_filter; - if(segment['negated']) { + if (segment['negated']) { filter = new NegationFilter(result_type, filter); } } else if (result_type === ResultTypeEnum.TAG) { // Match against the tag name. name_filter = new MatchingFilter( result_type, - MatchAgainstEnum.MATCH_TAG_NAME, segment['text'], - MatchTypeEnum.MATCH_EQUALS + MatchTypeEnum.MATCH_TAG_NAME_EQUALS ); filter = name_filter; - if(segment['negated']) { + if (segment['negated']) { filter = new NegationFilter(result_type, filter); } } @@ -362,10 +343,11 @@ export function user_query_from_search_string(search_string) { export function user_query_from_browsed_album(album_path) { var r = new UserQuery(); - var match_type = MatchTypeEnum.MATCH_EQUALS; - var match_against = MatchAgainstEnum.MATCH_ALBUM_NAME_IN_TREE; - var match_text = album_path; - r.image_filter = new MatchingFilter(ResultTypeEnum.IMAGE, match_against, match_text, match_type, false).simplify(); + r.image_filter = new MatchingFilter( + ResultTypeEnum.IMAGE, + album_path, + MatchTypeEnum.MATCH_ALBUM_EQUALS_OR_CHILD, + false).simplify(); r.album_filter = new ConstFilter(ResultTypeEnum.ALBUM, false).simplify(); return r; @@ -373,10 +355,11 @@ export function user_query_from_browsed_album(album_path) { 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 = MatchAgainstEnum.MATCH_TAG_NAME; - r.image_filter = new MatchingFilter(ResultTypeEnum.IMAGE, match_against, match_text, match_type, false).simplify(); + r.image_filter = new MatchingFilter( + ResultTypeEnum.IMAGE, + name, + MatchTypeEnum.MATCH_TAG_EQUALS, + false).simplify(); r.album_filter = new ConstFilter(ResultTypeEnum.ALBUM, false).simplify(); r.tag_filter = new ConstFilter(ResultTypeEnum.TAG, false).simplify();