Halfway moving back to SQLite, seems to work better.

master
Sander Vocke 6 years ago
parent 28e8038e75
commit d27ceea10f
  1. 43
      src/database.js
  2. 6
      src/debuggingpage.js
  3. 16
      src/main.js
  4. 37
      src/queries.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<row.length; i++) {
row_out[headers[i]] = row[i];
}
data_out.push(row_out);
});
return data_out;
}
export async function sqljs_async_queries(sqljs_object, queries) {
for (let i = 0; i < (queries.length - 1); i++) {
var r = sqljs_object.exec(queries[i]);
console.log("Ran: ", queries[i], ". Output: ", r);
}
var ret = sqljs_object.exec(queries[queries.length - 1]);
console.log("Ran: ", queries[queries.length - 1], ". Output: ", ret);
return convert_sqljs_result_to_rows(ret);
}
export class DB {
state = {
db_type: false,
@ -43,8 +71,9 @@ export class DB {
if (this.state.db_type === DBTypeEnum.ALASQL_SQLITE ||
this.state.db_type === DBTypeEnum.ALASQL_INDEXEDDB ||
this.state.db_type === DBTypeEnum.ALASQL_NATIVE) {
var self = this;
return alasql_async_queries(self.state.db_object, s);
return alasql_async_queries(this.state.db_object, s);
} else if (this.state.db_type === DBTypeEnum.SQLJS_SQLITE) {
return sqljs_async_queries(this.state.db_object, s);
}
throw new Error("Unsupported database type for async operations: " + this.state.db_type);
}
@ -250,8 +279,10 @@ export class ProvideDB extends React.Component {
};
componentDidMount() {
var output_db_name = (this.props.db_source_type === this.props.db_target_type) ?
this.props.db_source_name : this.props.db_target_name;
if (this.props.db_source_type === DBTypeEnum.ALASQL_SQLITE && this.props.db_source === DBSourceEnum.ATTACHFILE) {
fetch_db_from_sqlite(this.props.db_file, this.props.db_source_name)
fetch_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)
@ -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)

@ -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 });

@ -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 (
<ThemeProvider theme={theme}>
<ProvideDB db_file={process.env.PUBLIC_URL + "/test_many_photos_db/digikam4.db"} db_source_type={DBTypeEnum.SQLJS_SQLITE} db_target_type={DBTypeEnum.ALASQL_NATIVE}
<ProvideDB db_file={"https://192.168.1.101/digikam-fatclient-data/digikam4.db"} db_source_type={DBTypeEnum.SQLJS_SQLITE} db_target_type={DBTypeEnum.SQLJS_SQLITE}
db_source_name="sqlite_db" db_target_name="db" db_source={DBSourceEnum.ATTACHFILE}>
{({ loading, error, done, db }) => (
<>
{loading && <LoadingPage file={process.env.PUBLIC_URL + "/test_many_photos_db/digikam4.db"} />}
{loading && <LoadingPage file={"digikam4.db"} />}
{error && <InternalErrorPage message={error} />}
{done && <LoadedMainPage database={db} photos_dir="/test_many_photos" thumbs_dir="/test_many_photos_thumbs" />}
{done && <LoadedMainPage database={db} photos_dir="https://192.168.1.101/digikam-fatclient-data/photos" thumbs_dir="https://192.168.1.101/digikam-fatclient-data/thumbs" />}
</>
)}
</ProvideDB>

@ -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) {

Loading…
Cancel
Save