diff --git a/src/browser.js b/src/browser.js
index a9e972e..487aedd 100644
--- a/src/browser.js
+++ b/src/browser.js
@@ -22,25 +22,25 @@ class NavTreeItem {
}
}
-export function split_relative_path(path) {
+export function split_path(path) {
var r = path.split("/");
- r.shift();
+ if(path[0] === '/') { r.shift(); }
return r;
}
export function insert_into_album_tree(treebaseitem, treeitem) {
- var parts = split_relative_path(treeitem.data);
+ var parts = split_path(treeitem.data);
var current_item = treebaseitem;
for (var i = 0; i < parts.length; i++) {
var part = parts[i];
var subitem = false;
- var required_relative_path = (current_item.data === "/") ?
+ var required_path = (current_item.data === "/") ?
current_item.data + part :
current_item.data + "/" + part;
for (var j = 0; j < current_item.children.length; j++) {
var child = current_item.children[j];
- if (child.data === required_relative_path) {
+ if (child.data === required_path) {
subitem = child;
break;
}
@@ -48,7 +48,7 @@ export function insert_into_album_tree(treebaseitem, treeitem) {
if (!subitem) {
var new_sub = new NavTreeItem(
part,
- required_relative_path,
+ required_path,
[]
);
current_item.children.push(new_sub);
@@ -75,7 +75,33 @@ export function build_albums_tree(all_db_albums) {
}
export function insert_into_tag_tree(treebaseitem, treeitem) {
- treebaseitem.children.push(treeitem);
+ var parts = split_path(treeitem.data);
+ var current_item = treebaseitem;
+ for (var i = 0; i < parts.length; i++) {
+ var part = parts[i];
+ var subitem = false;
+ var required_path = (current_item.data === "") ?
+ current_item.data + part :
+ current_item.data + "/" + part;
+
+ for (var j = 0; j < current_item.children.length; j++) {
+ var child = current_item.children[j];
+ if (child.data === required_path) {
+ subitem = child;
+ break;
+ }
+ }
+ if (!subitem) {
+ var new_sub = new NavTreeItem(
+ part,
+ required_path,
+ []
+ );
+ current_item.children.push(new_sub);
+ subitem = new_sub;
+ }
+ current_item = subitem;
+ };
}
export function build_tags_tree(all_db_tags) {
@@ -84,11 +110,12 @@ export function build_tags_tree(all_db_tags) {
var tag = all_db_tags[i];
var item = new NavTreeItem(
tag.state.name,
- tag.state.name,
+ tag.state.fullname,
[]
);
insert_into_tag_tree(tree, item);
};
+
return tree;
}
diff --git a/src/database.js b/src/database.js
index d0b289a..437b783 100644
--- a/src/database.js
+++ b/src/database.js
@@ -4,9 +4,19 @@ import NodeEnvironment from 'jest-environment-node';
export async function sqljs_async_queries(sqljs_object, queries) {
//var t0 = performance.now();
for (let i = 0; i < (queries.length - 1); i++) {
- sqljs_object.exec(queries[i]);
+ console.log("Query: ", queries[i]);
+ try {
+ sqljs_object.exec(queries[i]);
+ } catch (e) {
+ throw e;
+ }
+ }
+ console.log("Query: ", queries[queries.length - 1]);
+ try {
+ var r = sqljs_object.exec(queries[queries.length - 1]);
+ } catch (e) {
+ throw e;
}
- var r = sqljs_object.exec(queries[queries.length - 1]);
//console.log("Queries took ", (performance.now() - t0), " ms.");
//console.log("Query result for ", queries[queries.length - 1], ": ", r);
return r;
@@ -87,7 +97,9 @@ export async function add_full_tag_info(db) {
db.exec(query);
});
- var r = db.exec("SELECT * FROM Tags;");
+ console.log(db.exec("PRAGMA table_info([Tags]);"));
+
+ return db;
}
export function ProvideDB(props) {
@@ -98,10 +110,10 @@ export function ProvideDB(props) {
useEffect(() => {
fetch_sqljs_db_from_sqlite(db_url)
.then(db => {
- add_full_tag_info(db).then(() => {
- add_custom_functions(db);
+ add_full_tag_info(db).then((newdb) => {
+ add_custom_functions(newdb);
setError(false);
- setDb(db);
+ setDb(newdb);
})
})
.catch(error => { setError(error); });
@@ -112,5 +124,9 @@ export function ProvideDB(props) {
db_error: error,
};
+ if (db != null) {
+ console.log("Provided DB tags schema:", db.exec("PRAGMA table_info([Tags]);"));
+ }
+
return children({ ...child_props });
}
\ No newline at end of file
diff --git a/src/main.js b/src/main.js
index bbb5b57..10a1704 100644
--- a/src/main.js
+++ b/src/main.js
@@ -109,7 +109,6 @@ export function LoadedMainPage(props) {
}
function onNewQuery(q) {
- console.log(q.image_filter, " ?= ", gallery_user_query.image_filter);
var do_update_photos = !_.isEqual(q.image_filter, gallery_user_query.image_filter);
var do_update_albums = !_.isEqual(q.album_filter, gallery_user_query.album_filter);
var do_update_tags = !_.isEqual(q.tag_filter, gallery_user_query.tag_filter);
diff --git a/src/media.js b/src/media.js
index d1951d2..8b54922 100644
--- a/src/media.js
+++ b/src/media.js
@@ -24,7 +24,8 @@ export class Album extends Media {
export class Tag extends Media {
state = {
id: false,
- name: false
+ name: false, // This is the name of the leaf only, like "Sander"
+ fullname: false, // this is the full "path" to the tag, like "People/Sander"
}
}
@@ -51,10 +52,11 @@ export function create_album(maybe_id, maybe_name, maybe_relative_path) {
return a;
}
-export function create_tag(maybe_id, maybe_name) {
+export function create_tag(maybe_id, maybe_name, maybe_fullname) {
var t = new Tag();
if (maybe_id) { t.state.id = maybe_id; }
if (maybe_name) { t.state.name = maybe_name; }
+ if (maybe_fullname) { t.state.fullname = maybe_fullname }
return t;
}
diff --git a/src/queries.js b/src/queries.js
index 521138e..a743b32 100644
--- a/src/queries.js
+++ b/src/queries.js
@@ -11,6 +11,7 @@ export function do_image_query(query, database, collection_path, collection_thum
var queries = [];
queries.push(query);
sqljs_async_queries(database, queries).then(res => {
+ console.log("response: ", res);
var photos = [];
if (res && Array.isArray(res) && res.length > 0) {
var cols = res[0].columns;
@@ -30,7 +31,8 @@ export function do_image_query(query, database, collection_path, collection_thum
});
}
resolve(photos);
- });
+ })
+ .catch(err => { throw err; });
});
}
@@ -58,13 +60,14 @@ export function do_tag_query(query, database) {
return new Promise(function (resolve, reject) {
var queries = [];
queries.push(query);
+ console.log("Provided DB tags schema before query:", database.exec("PRAGMA table_info([Tags]);"));
sqljs_async_queries(database, queries).then(res => {
var tags = [];
if (res && Array.isArray(res) && res.length > 0) {
var cols = res[0].columns;
var data = res[0].values;
data.forEach(row => {
- tags.push(create_tag(row[cols.indexOf("id")], row[cols.indexOf("fullname")]));
+ tags.push(create_tag(row[cols.indexOf("id")], row[cols.indexOf("name")], row[cols.indexOf("fullname")]));
});
}
resolve(tags);
@@ -79,7 +82,10 @@ export const MatchTypeEnum = {
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
+ MATCH_TAG_EQUALS: 7, // Match on the full name (relative path) of the relevant tag, if any
+ MATCH_TAG_EQUALS_OR_CHILD: 8, // Match on the full name (path) of the relevant tag, if any, or any of its children
+ MATCH_TAG_NATURAL: 9,
+ MATCH_TAG_NAME_EQUALS: 10, // Match on the local tag name (excluding parents)
}
export const ResultTypeEnum = {
@@ -164,7 +170,7 @@ export class MatchingFilter extends ResultFilter {
+ escape_regex(this.match_from)
+ '.*"))';
} else if (this.match_type == MatchTypeEnum.MATCH_ALBUM_EQUALS) {
- return '(Albums.relativePath = "' + this.match_from + '")';
+ return '(Albums.relativePath="' + this.match_from + '")';
} else if (this.match_type == MatchTypeEnum.MATCH_ALBUM_EQUALS_OR_CHILD) {
return 'REGEXP(Albums.relativePath, "'
+ escape_regex(this.match_from)
@@ -176,7 +182,17 @@ export class MatchingFilter extends ResultFilter {
+ escape_regex(this.match_from)
+ '(\/[^\/]+)*")';
} else if (this.match_type == MatchTypeEnum.MATCH_TAG_EQUALS) {
- return '(Tags.name="' + this.match_from + '")';
+ return '(Tags.fullname="' + this.match_from + '")';
+ } else if (this.match_type == MatchTypeEnum.MATCH_TAG_EQUALS_OR_CHILD) {
+ return '(Tags.fullname NOT NULL AND REGEXP(Tags.fullname, "'
+ + escape_regex(this.match_from)
+ + '(\/[^\/]+)*"))';
+ } else if (this.match_type == MatchTypeEnum.MATCH_TAG_NATURAL) {
+ throw new Error("Natural matching on tag names is not yet supported.");
+ } else if (this.match_type == MatchTypeEnum.MATCH_TAG_NAME_EQUALS) {
+ return 'REGEXP(Tags.fullname, "\/(.*\/)*'
+ + escape_regex(this.match_from)
+ + '(\/[^\/]+)*")';
}
console.log(this);
@@ -314,7 +330,7 @@ function filter_from_text_segment(result_type, segment) {
var album_filter = new MatchingFilter(
result_type,
segment['text'],
- MatchTypeEnum.MATCH_ALBUM_NAME_EQUALS
+ MatchTypeEnum.MATCH_ALBUM_NAME_EQUALS_OR_CHILD
);
filter = new LogicalOperatorFilter(result_type, name_filter, album_filter, LogicalOperatorEnum.OR);
@@ -326,18 +342,18 @@ function filter_from_text_segment(result_type, segment) {
name_filter = new MatchingFilter(
result_type,
segment['text'],
- MatchTypeEnum.MATCH_ALBUM_NAME_EQUALS
+ MatchTypeEnum.MATCH_ALBUM_NAME_EQUALS_OR_CHILD
);
filter = name_filter;
if (segment['negated']) {
filter = new NegationFilter(result_type, filter);
}
} else if (result_type === ResultTypeEnum.TAG) {
- // Match against the tag name.
+ // TODO: We need a natural matcher for tag names
name_filter = new MatchingFilter(
result_type,
segment['text'],
- MatchTypeEnum.MATCH_TAG_EQUALS
+ MatchTypeEnum.MATCH_TAG_NAME_EQUALS_OR_CHILD
);
filter = name_filter;
if (segment['negated']) {
@@ -371,26 +387,51 @@ export function user_query_from_search_string(search_string) {
export function user_query_from_browsed_album(album_path) {
var r = new UserQuery();
- 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();
- r.tag_filter = new ConstFilter(ResultTypeEnum.TAG, false).simplify();
-
+ r.image_filter =
+ new MatchingFilter(
+ ResultTypeEnum.IMAGE,
+ album_path,
+ MatchTypeEnum.MATCH_ALBUM_EQUALS_OR_CHILD,
+ false).simplify();
+ /*
+ r.album_filter =
+ new MatchingFilter(
+ ResultTypeEnum.ALBUM,
+ album_path,
+ MatchTypeEnum.MATCH_ALBUM_EQUALS_OR_CHILD,
+ false).simplify();
+ r.tag_filter =
+ new MatchingFilter(
+ ResultTypeEnum.TAG,
+ album_path,
+ MatchTypeEnum.MATCH_ALBUM_EQUALS_OR_CHILD,
+ false).simplify();
+ */
return r;
}
-export function user_query_from_browsed_tag(name) {
+export function user_query_from_browsed_tag(tag_path) {
var r = new UserQuery();
- 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();
+ r.image_filter =
+ new MatchingFilter(
+ ResultTypeEnum.IMAGE,
+ tag_path,
+ MatchTypeEnum.MATCH_TAG_EQUALS_OR_CHILD,
+ false).simplify();
+ /*
+ r.album_filter =
+ new MatchingFilter(
+ ResultTypeEnum.ALBUM,
+ tag_path,
+ MatchTypeEnum.MATCH_TAG_EQUALS_OR_CHILD,
+ false).simplify();
+ r.tag_filter =
+ new MatchingFilter(
+ ResultTypeEnum.TAG,
+ tag_path,
+ MatchTypeEnum.MATCH_TAG_EQUALS_OR_CHILD,
+ false).simplify();
+ */
return r;
}
\ No newline at end of file
diff --git a/src/userquerywidget.js b/src/userquerywidget.js
index cf18280..55e0993 100644
--- a/src/userquerywidget.js
+++ b/src/userquerywidget.js
@@ -138,6 +138,9 @@ export function EditMatchingFilterExpression(props) {
+
+
+
@@ -311,6 +314,8 @@ export function MatchingFilterExpressionControl(props) {
.replace(/"$/g, '');
if (expr.match_type === MatchTypeEnum.MATCH_TAG_EQUALS) {
return
+ } else if (expr.match_type === MatchTypeEnum.MATCH_TAG_EQUALS_OR_CHILD) {
+ return
} else if (expr.match_type === MatchTypeEnum.MATCH_ALBUM_EQUALS) {
return
} else if (expr.match_type === MatchTypeEnum.MATCH_ALBUM_EQUALS_OR_CHILD) {