Basic query construction done.

master
Sander Vocke 6 years ago
parent f3cf9928b8
commit 6690c6ff2b
  1. 149
      src/queries.js

@ -24,54 +24,118 @@ export const MatchTypeEnum = {
MATCH_LIKE: 2, MATCH_LIKE: 2,
}; };
export const ResultFilterTypeEnum = { export const MatchAgainstEnum = {
MATCH_NAME: 1, 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
} }
export const ResultTypeEnum = { export const ResultTypeEnum = {
IMAGE: 1, IMAGE: 1,
ALBUM: 2,
} }
export class ResultFilter { export class ResultFilter {
constructor(type) { this.result_type = type; }
result_type = ResultTypeEnum.IMAGE;
to_sql_where() { return "(1=1)"; }
}
export class ConstFilter extends ResultFilter {
constructor(type, val) { super(type); this.constval = val; }
constval = true; // True lets everything through, false rejects everything
to_sql_where() {
return this.constval ? "(1=1)" : "(1=0)";
}
}
function match_column_name(result_type, match_against) {
if(match_against == MatchAgainstEnum.MATCH_IMAGE_NAME) {
return "Image.name";
}
if(match_against == MatchAgainstEnum.MATCH_ALBUM_NAME) {
return "Album.name";
}
if(match_against == MatchAgainstEnum.MATCH_RESULT_NAME) {
if(result_type == ResultTypeEnum.IMAGE) {
return match_column_name(result_type, MatchAgainstEnum.MATCH_IMAGE_NAME);
}
if(result_type == ResultTypeEnum.ALBUM) {
return match_column_name(result_type, MatchAgainstEnum.MATCH_ALBUM_NAME);
}
}
throw new Error("Could not get column name for matching properties passed.");
}
export class MatchingFilter extends ResultFilter {
constructor(rtype, against, from, mtype, negate) {
super(rtype);
this.match_against = against;
this.match_from = from;
this.match_type = mtype;
this.negate = negate;
}
// What kind of filtering to apply // What kind of filtering to apply
type = ResultFilterTypeEnum.MATCH_NAME; match_against = MatchAgainstEnum.MATCH_RESULT_NAME;
// optional string used in the filtering // optional string used in the filtering
match_against = ""; match_from = "";
// How to use the matching string // How to use the matching string
match_type = MatchTypeEnum.MATCH_EQUALS; match_type = MatchTypeEnum.MATCH_EQUALS;
// On which types of results to apply the filter
result_types = [];
// If true, negates the filter // If true, negates the filter
negate = false; negate = false;
}
export class UserQuery { to_sql_where() {
result_filters = []; var match_against_str = match_column_name(this.result_type, this.match_against);
include_result_types = [ ResultTypeEnum.IMAGE ]; var match_type_str = false;
if(this.match_type == MatchTypeEnum.MATCH_EQUALS) {
match_type_str = "=";
} else if(this.match_type == MatchTypeEnum.MATCH_LIKE) {
match_type_str = " LIKE ";
} else {
throw new Error('Unsupported match type: ' + this.match_type);
}
return "(" + (this.negate ? "NOT " : "") + match_against_str + "\"" + match_type_str + "\"" + this.match_from + ")";
}
} }
export function image_filter_to_where(image_filter) { export const LogicalOperatorEnum = {
var match_from = false; AND: 1,
var match_to = image_filter.match_against; OR: 2,
var match_operator = false; }
if(image_filter.type == ResultFilterTypeEnum.MATCH_NAME) {
match_from = "Image.name";
} else {
throw new Error("Unsupported image filter type: " + image_filter.type);
}
if(image_filter.match_type == MatchTypeEnum.MATCH_EQUALS) { export class LogicalOperatorFilter extends ResultFilter {
match_operator = "="; constructor(type, a, b, op) { super(type); this.sub_filter_a = a; this.sub_filter_b = b; this.operator = op; }
} else if(image_filter.match_type == MatchTypeEnum.MATCH_LIKE) { sub_filter_a = false;
match_operator = " LIKE "; sub_filter_b = false;
operator = LogicalOperatorEnum.AND;
to_sql_where() {
var where1 = this.sub_filter_a.to_sql_where();
var where2 = this.sub_filter_b.to_sql_where();
var operator_str = "";
if(this.operator == LogicalOperatorEnum.AND) {
operator_str = " AND ";
} else if(this.operator == LogicalOperatorEnum.OR) {
operator_str = " OR ";
} else {
throw new Error('Unsupported logical operator: ' + this.operator);
}
return "(" + where1 + operator_str + where2 + ")";
} }
}
return match_from + match_operator + match_to; export class UserQuery {
image_filter = new ConstFilter(ResultTypeEnum.IMAGE, true);
album_filter = new ConstFilter(ResultTypeEnum.ALBUM, true);
} }
// This query will return database entries with the fields "id", "uniqueHash", "relativePath" (of the album) and "name" for each matching image. // This query will return database entries with the fields "id", "uniqueHash", "relativePath" (of the album) and "name" for each matching image.
@ -80,32 +144,16 @@ export function image_query_with_where(maybe_where) {
} }
export function maybe_image_query(user_query) { export function maybe_image_query(user_query) {
if(!user_query.include_result_types.includes(ResultTypeEnum.IMAGE)) {
return false;
}
var where = false; var where = false;
if(user_query.image_filters.length) { if(user_query.image_filter) {
where = "WHERE "; where = "WHERE " + user_query.image_filter.to_sql_where();
var i = 0;
user_query.image_filters.forEach(elem => {
if(i > 0) {
where += "AND";
}
where += image_filter_to_where(elem) + " ";
i++;
});
} }
return image_query_with_where(where); return image_query_with_where(where);
} }
function filter_from_text_segment(segment) { function filter_from_text_segment(result_type, segment) {
var r = new ResultFilter(); return new MatchingFilter(result_type, MatchAgainstEnum.MATCH_RESULT_NAME,
r.match_against = segment['text']; segment['text'], MatchTypeEnum.MATCH_EQUALS, segment['negated']);
r.negate = segment['negated'];
r.match_type = MatchTypeEnum.MATCH_EQUALS;
r.type = ResultFilterTypeEnum.MATCH_NAME;
return r;
} }
export function user_query_from_search_string(search_string) { export function user_query_from_search_string(search_string) {
@ -118,9 +166,14 @@ export function user_query_from_search_string(search_string) {
var r = new UserQuery(); var r = new UserQuery();
texts.forEach(text => { texts.forEach(text => {
r.result_filters.push(filter_from_text_segment(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);
}); });
console.log(search_string); console.log(search_string);
console.log(r); console.log(r);
console.log(maybe_image_query(r));
} }
Loading…
Cancel
Save