diff --git a/src/database.js b/src/database.js index 0bbff01..f868885 100644 --- a/src/database.js +++ b/src/database.js @@ -23,6 +23,34 @@ export function alasql_async_queries(alasql_object, queries) { return p; } +export function convert_sqljs_result_to_rows(result_object) { + if(result_object.length == 0) { + return []; + } + + var headers = result_object[0].columns; + var data = result_object[0].values; + var data_out = []; + data.forEach(row => { + var row_out = {}; + for(let i=0; i { if (this.props.db_target_type !== this.props.db_source_type) { db.migrate_async(this.props.db_target_type, this.props.db_target_name) @@ -260,7 +291,7 @@ export class ProvideDB extends React.Component { }) .catch(error => this.setState({ loading: false, done: false, error })); } else if (this.props.db_source_type === DBTypeEnum.ALASQL_INDEXEDDB && this.props.db_source === DBSourceEnum.CREATE) { - create_indexed_db(this.props.db_source_name) + create_indexed_db(output_db_name) .then(db => { if (this.props.db_target_type !== this.props.db_source_type) { db.migrate_async(this.props.db_target_type, this.props.db_target_name) @@ -268,7 +299,7 @@ export class ProvideDB extends React.Component { } else { this.setState({ loading: false, done: true, db: db }) }; }); } else if (this.props.db_source_type === DBTypeEnum.ALASQL_NATIVE && this.props.db_source === DBSourceEnum.CREATE) { - create_native_db(this.props.db_source_name) + create_native_db(output_db_name) .then(db => { if (this.props.db_target_type !== this.props.db_source_type) { db.migrate_async(this.props.db_target_type, this.props.db_target_name) @@ -276,7 +307,7 @@ export class ProvideDB extends React.Component { } else { this.setState({ loading: false, done: true, db: db }) }; }); } else if (this.props.db_source_type === DBTypeEnum.SQLJS_SQLITE && this.props.db_source === DBSourceEnum.ATTACHFILE) { - fetch_sqljs_db_from_sqlite(this.props.db_file, this.props.db_source_name) + fetch_sqljs_db_from_sqlite(this.props.db_file, output_db_name) .then(db => { if (this.props.db_target_type !== this.props.db_source_type) { db.migrate_async(this.props.db_target_type, this.props.db_target_name) diff --git a/src/debuggingpage.js b/src/debuggingpage.js index ce1228b..56225b5 100644 --- a/src/debuggingpage.js +++ b/src/debuggingpage.js @@ -56,7 +56,7 @@ export class ImageWhereConsole extends React.Component { onQueryChangeHandler = whereclause => { this.setState({ where: whereclause }); } onQuerySubmitHandler = () => { this.setState({ processing: true, result: false }); - this.props.database.queries_async([image_query_with_where(this.state.where)]) + this.props.database.queries_async([image_query_with_where(this.state.where, this.props.database)]) .then(result => { this.setState({ processing: false, result: JSON.stringify(result) }); }); @@ -99,8 +99,8 @@ export class TestDBStringQuery extends React.Component { onQueryChangeHandler = str => { this.setState({ string: str }); } onQuerySubmitHandler = () => { var q = user_query_from_search_string(this.state.string); - var sql_image_query = maybe_image_query(q); - var sql_album_query = maybe_album_query(q); + var sql_image_query = maybe_image_query(q, this.props.db); + var sql_album_query = maybe_album_query(q, this.props.db); this.setState({ query: q, sql_image_query: sql_image_query, sql_album_query: sql_album_query, photos: false, albums: false }); do_image_query(sql_image_query, this.props.db, "/test_photos", "/test_photos_thumbs").then(photos => { this.setState({ done: true, photos: photos }); diff --git a/src/main.js b/src/main.js index ce9bf75..5fbaba7 100644 --- a/src/main.js +++ b/src/main.js @@ -8,7 +8,7 @@ import { SearchBar } from './searchbar.js'; import { InternalErrorPage } from './error.js'; import { LoadingPage } from './loading.js'; import { ProvideDB, DBTypeEnum, DBSourceEnum } from './database.js'; -import { UserQuery, user_query_from_search_string, maybe_image_query, do_image_query, maybe_album_query, do_album_query, maybe_tag_query, do_tag_query } from './queries.js'; +import { UserQuery, user_query_from_search_string, maybe_image_query, do_image_query, maybe_album_query, do_album_query, maybe_tag_query, do_tag_query, ConstFilter, ResultTypeEnum } from './queries.js'; import { Browser } from './browser.js'; import { UserQueryWidget } from './userquerywidget.js'; import { ResultsView } from './resultsview.js'; @@ -53,6 +53,8 @@ export function LoadedMainPage(props) { useEffect(() => { // Single-fire effect to start retrieving the albums and tags lists. var blank_user_query = new UserQuery(); + blank_user_query.album_filter = new ConstFilter(ResultTypeEnum.ALBUM, true); + blank_user_query.tag_filter = new ConstFilter(ResultTypeEnum.TAG, true); var sql_album_query = maybe_album_query(blank_user_query); var sql_tag_query = maybe_tag_query(blank_user_query); @@ -78,7 +80,7 @@ export function LoadedMainPage(props) { } function updatePhotos(q) { - var sql_image_query = maybe_image_query(q); + var sql_image_query = maybe_image_query(q, database); setPhotos(false); do_image_query(sql_image_query, database, photos_dir, thumbs_dir) .then(got_photos => { @@ -87,7 +89,7 @@ export function LoadedMainPage(props) { } function updateTags(q) { - var sql_tag_query = maybe_tag_query(q); + var sql_tag_query = maybe_tag_query(q, database); setTags(false); do_tag_query(sql_tag_query, database) .then(tags => { @@ -96,7 +98,7 @@ export function LoadedMainPage(props) { } function updateAlbums(q) { - var sql_album_query = maybe_album_query(q); + var sql_album_query = maybe_album_query(q, database); setAlbums(false); do_album_query(sql_album_query, database) .then(albums => { @@ -146,14 +148,14 @@ const theme = createMuiTheme({ export function MainPage() { return ( - {({ loading, error, done, db }) => ( <> - {loading && } + {loading && } {error && } - {done && } + {done && } )} diff --git a/src/queries.js b/src/queries.js index 293c167..b9d034a 100644 --- a/src/queries.js +++ b/src/queries.js @@ -1,5 +1,6 @@ import { create_photo, create_album, create_tag } from './media.js'; +import { DBTypeEnum } from './database.js'; export function escape_regex(s) { return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); @@ -219,47 +220,57 @@ 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); + image_filter = new ConstFilter(ResultTypeEnum.IMAGE, false); + album_filter = new ConstFilter(ResultTypeEnum.ALBUM, false); + tag_filter = new ConstFilter(ResultTypeEnum.TAG, false); } // 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, " +export function image_query_with_where(maybe_where, db) { + var base_query = "SELECT Images.id, Images.name, Images.uniqueHash, Albums.relativePath, " + "ImageInformation.width, ImageInformation.height " + "FROM Images INNER JOIN Albums ON Images.album=Albums.id " + "LEFT JOIN ImageTags ON Images.id=ImageTags.imageid " + "LEFT JOIN ImageInformation ON Images.id=ImageInformation.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;"; + + if(db.state.db_type == DBTypeEnum.SQLJS_SQLITE) { + return base_query + " GROUP BY Images.id"; + } else if(db.state.db_type == DBTypeEnum.ALASQL_NATIVE || + db.state.db_type == DBTypeEnum.ALASQL_SQLITE || + db.state.db_type == DBTypeEnum.ALASQL_INDEXEDDB) { + // TODO : the GROUP BY used above for some reason breaks AlaSQL. + // For the time being, omit it at the cost of duplicate results. + return base_query; + } + + throw new Error('Unsupported database type for image query: ' + db); } // This query will return database entries with the fields "id" and "relativePath" for each matching album. -export function album_query_with_where(maybe_where) { +export function album_query_with_where(maybe_where, db) { 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) { +export function tag_query_with_where(maybe_where, db) { return "SELECT Tags.id, Tags.name FROM Tags " + (maybe_where ? maybe_where : "") + ";"; } -export function maybe_image_query(user_query) { +export function maybe_image_query(user_query, database) { var where = false; if (user_query.image_filter) { where = "WHERE " + user_query.image_filter.to_sql_where(); } - return image_query_with_where(where); + return image_query_with_where(where, database); } -export function maybe_album_query(user_query) { +export function maybe_album_query(user_query, database) { var where = false; if (user_query.album_filter) { where = "WHERE " + user_query.album_filter.to_sql_where(); } - return album_query_with_where(where); + return album_query_with_where(where, database); } export function maybe_tag_query(user_query) {