diff --git a/app/lib/app_init.dart b/app/lib/app_init.dart index 6cb6de7c..944e67f5 100644 --- a/app/lib/app_init.dart +++ b/app/lib/app_init.dart @@ -24,8 +24,8 @@ import 'package:nc_photos/entity/share.dart'; import 'package:nc_photos/entity/share/data_source.dart'; import 'package:nc_photos/entity/sharee.dart'; import 'package:nc_photos/entity/sharee/data_source.dart'; -import 'package:nc_photos/entity/sqlite_table.dart' as sql; -import 'package:nc_photos/entity/sqlite_table_isolate.dart' as sql_isolate; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; +import 'package:nc_photos/entity/sqlite/isolate_util.dart' as sql_isolate; import 'package:nc_photos/entity/tag.dart'; import 'package:nc_photos/entity/tag/data_source.dart'; import 'package:nc_photos/entity/tagged_file.dart'; diff --git a/app/lib/bloc/settings/expert.dart b/app/lib/bloc/settings/expert.dart index ade8f1f6..e1b58468 100644 --- a/app/lib/bloc/settings/expert.dart +++ b/app/lib/bloc/settings/expert.dart @@ -4,7 +4,7 @@ import 'package:bloc/bloc.dart'; import 'package:copy_with/copy_with.dart'; import 'package:logging/logging.dart'; import 'package:nc_photos/di_container.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; import 'package:np_codegen/np_codegen.dart'; import 'package:to_string/to_string.dart'; diff --git a/app/lib/di_container.dart b/app/lib/di_container.dart index 7c1044f6..a0ed4ca7 100644 --- a/app/lib/di_container.dart +++ b/app/lib/di_container.dart @@ -7,7 +7,7 @@ import 'package:nc_photos/entity/person.dart'; import 'package:nc_photos/entity/search.dart'; import 'package:nc_photos/entity/share.dart'; import 'package:nc_photos/entity/sharee.dart'; -import 'package:nc_photos/entity/sqlite_table.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; import 'package:nc_photos/entity/tag.dart'; import 'package:nc_photos/entity/tagged_file.dart'; import 'package:nc_photos/or_null.dart'; diff --git a/app/lib/entity/album/data_source.dart b/app/lib/entity/album/data_source.dart index 7a7c63af..eb85b617 100644 --- a/app/lib/entity/album/data_source.dart +++ b/app/lib/entity/album/data_source.dart @@ -11,9 +11,8 @@ import 'package:nc_photos/entity/album/upgrader.dart'; import 'package:nc_photos/entity/file.dart'; import 'package:nc_photos/entity/file/data_source.dart'; import 'package:nc_photos/entity/file_descriptor.dart'; -import 'package:nc_photos/entity/sqlite_table.dart' as sql; -import 'package:nc_photos/entity/sqlite_table_converter.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; +import 'package:nc_photos/entity/sqlite/type_converter.dart'; import 'package:nc_photos/exception.dart'; import 'package:nc_photos/exception_event.dart'; import 'package:nc_photos/future_util.dart' as future_util; diff --git a/app/lib/entity/file/data_source.dart b/app/lib/entity/file/data_source.dart index 0e5ec09f..ca79d79e 100644 --- a/app/lib/entity/file/data_source.dart +++ b/app/lib/entity/file/data_source.dart @@ -11,8 +11,8 @@ import 'package:nc_photos/entity/file.dart'; import 'package:nc_photos/entity/file/file_cache_manager.dart'; import 'package:nc_photos/entity/file_descriptor.dart'; import 'package:nc_photos/entity/file_util.dart' as file_util; -import 'package:nc_photos/entity/sqlite_table.dart' as sql; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; +import 'package:nc_photos/entity/sqlite/files_query_builder.dart' as sql; import 'package:nc_photos/entity/webdav_response_parser.dart'; import 'package:nc_photos/exception.dart'; import 'package:nc_photos/iterable_extension.dart'; diff --git a/app/lib/entity/file/file_cache_manager.dart b/app/lib/entity/file/file_cache_manager.dart index 493debcf..b2baf4e3 100644 --- a/app/lib/entity/file/file_cache_manager.dart +++ b/app/lib/entity/file/file_cache_manager.dart @@ -8,9 +8,9 @@ import 'package:nc_photos/entity/file.dart'; import 'package:nc_photos/entity/file/data_source.dart'; import 'package:nc_photos/entity/file_descriptor.dart'; import 'package:nc_photos/entity/file_util.dart' as file_util; -import 'package:nc_photos/entity/sqlite_table.dart' as sql; -import 'package:nc_photos/entity/sqlite_table_converter.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; +import 'package:nc_photos/entity/sqlite/files_query_builder.dart' as sql; +import 'package:nc_photos/entity/sqlite/type_converter.dart'; import 'package:nc_photos/exception.dart'; import 'package:nc_photos/iterable_extension.dart'; import 'package:nc_photos/list_util.dart' as list_util; diff --git a/app/lib/entity/person/data_source.dart b/app/lib/entity/person/data_source.dart index 187894a7..68a521d3 100644 --- a/app/lib/entity/person/data_source.dart +++ b/app/lib/entity/person/data_source.dart @@ -4,9 +4,8 @@ import 'package:logging/logging.dart'; import 'package:nc_photos/account.dart'; import 'package:nc_photos/api/api.dart'; import 'package:nc_photos/entity/person.dart'; -import 'package:nc_photos/entity/sqlite_table.dart' as sql; -import 'package:nc_photos/entity/sqlite_table_converter.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; +import 'package:nc_photos/entity/sqlite/type_converter.dart'; import 'package:nc_photos/exception.dart'; import 'package:nc_photos/type.dart'; import 'package:np_codegen/np_codegen.dart'; diff --git a/app/lib/entity/search.dart b/app/lib/entity/search.dart index 6e7fd840..2411c745 100644 --- a/app/lib/entity/search.dart +++ b/app/lib/entity/search.dart @@ -1,7 +1,7 @@ import 'package:nc_photos/account.dart'; import 'package:nc_photos/entity/file.dart'; import 'package:nc_photos/entity/file_util.dart' as file_util; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/files_query_builder.dart' as sql; import 'package:nc_photos/iterable_extension.dart'; import 'package:to_string/to_string.dart'; diff --git a/app/lib/entity/search/data_source.dart b/app/lib/entity/search/data_source.dart index 92045171..f5c8e481 100644 --- a/app/lib/entity/search/data_source.dart +++ b/app/lib/entity/search/data_source.dart @@ -7,8 +7,9 @@ import 'package:nc_photos/entity/file.dart'; import 'package:nc_photos/entity/file_descriptor.dart'; import 'package:nc_photos/entity/search.dart'; import 'package:nc_photos/entity/search_util.dart' as search_util; -import 'package:nc_photos/entity/sqlite_table_converter.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; +import 'package:nc_photos/entity/sqlite/files_query_builder.dart' as sql; +import 'package:nc_photos/entity/sqlite/type_converter.dart'; import 'package:nc_photos/iterable_extension.dart'; import 'package:nc_photos/object_extension.dart'; import 'package:nc_photos/use_case/list_tagged_file.dart'; diff --git a/app/lib/entity/sqlite/database.dart b/app/lib/entity/sqlite/database.dart new file mode 100644 index 00000000..7de7502d --- /dev/null +++ b/app/lib/entity/sqlite/database.dart @@ -0,0 +1,131 @@ +import 'package:drift/drift.dart'; +import 'package:logging/logging.dart'; +import 'package:nc_photos/account.dart' as app; +import 'package:nc_photos/entity/file.dart' as app; +import 'package:nc_photos/entity/file_descriptor.dart'; +import 'package:nc_photos/entity/file_util.dart' as file_util; +import 'package:nc_photos/entity/sqlite/files_query_builder.dart'; +import 'package:nc_photos/entity/sqlite/isolate_util.dart'; +import 'package:nc_photos/entity/sqlite/table.dart'; +import 'package:nc_photos/entity/sqlite/type_converter.dart'; +import 'package:nc_photos/future_extension.dart'; +import 'package:nc_photos/iterable_extension.dart'; +import 'package:nc_photos/k.dart' as k; +import 'package:nc_photos/mobile/platform.dart' + if (dart.library.html) 'package:nc_photos/web/platform.dart' as platform; +import 'package:nc_photos/object_extension.dart'; +import 'package:nc_photos/platform/k.dart' as platform_k; +import 'package:np_codegen/np_codegen.dart'; + +part 'database.g.dart'; +part 'database_extension.dart'; + +// remember to also update the truncate method after adding a new table +@npLog +@DriftDatabase( + tables: [ + Servers, + Accounts, + Files, + Images, + ImageLocations, + Trashes, + AccountFiles, + DirFiles, + Albums, + AlbumShares, + Tags, + Persons, + ], +) +class SqliteDb extends _$SqliteDb { + SqliteDb({ + QueryExecutor? executor, + }) : super(executor ?? platform.openSqliteConnection()); + + SqliteDb.connect(DatabaseConnection connection) : super.connect(connection); + + @override + get schemaVersion => 4; + + @override + get migration => MigrationStrategy( + onCreate: (m) async { + await customStatement("PRAGMA journal_mode=WAL;"); + await m.createAll(); + + await m.createIndex(Index("files_server_index", + "CREATE INDEX files_server_index ON files(server);")); + await m.createIndex(Index("files_file_id_index", + "CREATE INDEX files_file_id_index ON files(file_id);")); + await m.createIndex(Index("files_content_type_index", + "CREATE INDEX files_content_type_index ON files(content_type);")); + + await m.createIndex(Index("account_files_file_index", + "CREATE INDEX account_files_file_index ON account_files(file);")); + await m.createIndex(Index("account_files_relative_path_index", + "CREATE INDEX account_files_relative_path_index ON account_files(relative_path);")); + await m.createIndex(Index("account_files_best_date_time_index", + "CREATE INDEX account_files_best_date_time_index ON account_files(best_date_time);")); + + await m.createIndex(Index("dir_files_dir_index", + "CREATE INDEX dir_files_dir_index ON dir_files(dir);")); + await m.createIndex(Index("dir_files_child_index", + "CREATE INDEX dir_files_child_index ON dir_files(child);")); + + await m.createIndex(Index("album_shares_album_index", + "CREATE INDEX album_shares_album_index ON album_shares(album);")); + + await _createIndexV2(m); + await _createIndexV3(m); + }, + onUpgrade: (m, from, to) async { + _log.info("[onUpgrade] $from -> $to"); + try { + await transaction(() async { + if (from < 2) { + await m.createTable(tags); + await m.createTable(persons); + await _createIndexV2(m); + } + if (from < 3) { + await m.createTable(imageLocations); + await _createIndexV3(m); + } + if (from < 4) { + await m.addColumn(albums, albums.fileEtag); + } + }); + } catch (e, stackTrace) { + _log.shout("[onUpgrade] Failed upgrading sqlite db", e, stackTrace); + rethrow; + } + }, + beforeOpen: (details) async { + await customStatement("PRAGMA foreign_keys = ON;"); + // technically we have a platform side lock to ensure only one + // transaction is running in any isolates, but for some reason we are + // still seeing database is locked error in crashlytics, let see if + // this helps + await customStatement("PRAGMA busy_timeout = 5000;"); + }, + ); + + Future _createIndexV2(Migrator m) async { + await m.createIndex(Index("tags_server_index", + "CREATE INDEX tags_server_index ON tags(server);")); + await m.createIndex(Index("persons_account_index", + "CREATE INDEX persons_account_index ON persons(account);")); + } + + Future _createIndexV3(Migrator m) async { + await m.createIndex(Index("image_locations_name_index", + "CREATE INDEX image_locations_name_index ON image_locations(name);")); + await m.createIndex(Index("image_locations_country_code_index", + "CREATE INDEX image_locations_country_code_index ON image_locations(country_code);")); + await m.createIndex(Index("image_locations_admin1_index", + "CREATE INDEX image_locations_admin1_index ON image_locations(admin1);")); + await m.createIndex(Index("image_locations_admin2_index", + "CREATE INDEX image_locations_admin2_index ON image_locations(admin2);")); + } +} diff --git a/app/lib/entity/sqlite_table.g.dart b/app/lib/entity/sqlite/database.g.dart similarity index 99% rename from app/lib/entity/sqlite_table.g.dart rename to app/lib/entity/sqlite/database.g.dart index 222db5cc..473f536f 100644 --- a/app/lib/entity/sqlite_table.g.dart +++ b/app/lib/entity/sqlite/database.g.dart @@ -1,6 +1,6 @@ // GENERATED CODE - DO NOT MODIFY BY HAND -part of 'sqlite_table.dart'; +part of 'database.dart'; // ************************************************************************** // MoorGenerator @@ -989,7 +989,7 @@ class $FilesTable extends Files with TableInfo<$FilesTable, File> { } static TypeConverter $converter0 = - const _DateTimeConverter(); + const SqliteDateTimeConverter(); } class AccountFile extends DataClass implements Insertable { @@ -1428,9 +1428,9 @@ class $AccountFilesTable extends AccountFiles } static TypeConverter $converter0 = - const _DateTimeConverter(); + const SqliteDateTimeConverter(); static TypeConverter $converter1 = - const _DateTimeConverter(); + const SqliteDateTimeConverter(); } class Image extends DataClass implements Insertable { @@ -1815,9 +1815,9 @@ class $ImagesTable extends Images with TableInfo<$ImagesTable, Image> { } static TypeConverter $converter0 = - const _DateTimeConverter(); + const SqliteDateTimeConverter(); static TypeConverter $converter1 = - const _DateTimeConverter(); + const SqliteDateTimeConverter(); } class ImageLocation extends DataClass implements Insertable { @@ -2489,7 +2489,7 @@ class $TrashesTable extends Trashes with TableInfo<$TrashesTable, Trash> { } static TypeConverter $converter0 = - const _DateTimeConverter(); + const SqliteDateTimeConverter(); } class DirFile extends DataClass implements Insertable { @@ -3253,7 +3253,7 @@ class $AlbumsTable extends Albums with TableInfo<$AlbumsTable, Album> { } static TypeConverter $converter0 = - const _DateTimeConverter(); + const SqliteDateTimeConverter(); } class AlbumShare extends DataClass implements Insertable { @@ -3515,7 +3515,7 @@ class $AlbumSharesTable extends AlbumShares } static TypeConverter $converter0 = - const _DateTimeConverter(); + const SqliteDateTimeConverter(); } class Tag extends DataClass implements Insertable { @@ -4199,5 +4199,5 @@ extension _$SqliteDbNpLog on SqliteDb { // ignore: unused_element Logger get _log => log; - static final log = Logger("entity.sqlite_table.SqliteDb"); + static final log = Logger("entity.sqlite.database.SqliteDb"); } diff --git a/app/lib/entity/sqlite_table_extension.dart b/app/lib/entity/sqlite/database_extension.dart similarity index 71% rename from app/lib/entity/sqlite_table_extension.dart rename to app/lib/entity/sqlite/database_extension.dart index 81556418..f252e11b 100644 --- a/app/lib/entity/sqlite_table_extension.dart +++ b/app/lib/entity/sqlite/database_extension.dart @@ -1,24 +1,4 @@ -import 'package:drift/drift.dart'; -import 'package:logging/logging.dart'; -import 'package:nc_photos/account.dart' as app; -import 'package:nc_photos/ci_string.dart'; -import 'package:nc_photos/entity/file.dart' as app; -import 'package:nc_photos/entity/file_descriptor.dart'; -import 'package:nc_photos/entity/file_util.dart' as file_util; -import 'package:nc_photos/entity/sqlite_table.dart'; -import 'package:nc_photos/entity/sqlite_table_converter.dart'; -import 'package:nc_photos/entity/sqlite_table_isolate.dart'; -import 'package:nc_photos/future_extension.dart'; -import 'package:nc_photos/iterable_extension.dart'; -import 'package:nc_photos/k.dart' as k; -import 'package:nc_photos/location_util.dart' as location_util; -import 'package:nc_photos/mobile/platform.dart' - if (dart.library.html) 'package:nc_photos/web/platform.dart' as platform; -import 'package:nc_photos/object_extension.dart'; -import 'package:nc_photos/platform/k.dart' as platform_k; -import 'package:np_codegen/np_codegen.dart'; - -part 'sqlite_table_extension.g.dart'; +part of 'database.dart'; const maxByFileIdsSize = 30000; @@ -95,7 +75,6 @@ class AccountFileRowIdsWithFileId { final int fileId; } -@npLog extension SqliteDbExtension on SqliteDb { /// Start a transaction and run [block] /// @@ -592,221 +571,6 @@ extension SqliteDbExtension on SqliteDb { } } -enum FilesQueryMode { - file, - completeFile, - expression, -} - -typedef FilesQueryRelativePathBuilder = Expression Function( - GeneratedColumn relativePath); - -/// Build a Files table query -/// -/// If you call more than one by* methods, the condition will be added up -/// instead of replaced. No validations will be made to make sure the resulting -/// conditions make sense -class FilesQueryBuilder { - FilesQueryBuilder(this.db); - - /// Set the query mode - /// - /// If [mode] == FilesQueryMode.expression, [expressions] must be defined and - /// not empty - void setQueryMode( - FilesQueryMode mode, { - Iterable? expressions, - }) { - assert( - (mode == FilesQueryMode.expression) != (expressions?.isEmpty != false)); - _queryMode = mode; - _selectExpressions = expressions; - } - - void setSqlAccount(Account account) { - assert(_appAccount == null); - _sqlAccount = account; - } - - void setAppAccount(app.Account account) { - assert(_sqlAccount == null); - _appAccount = account; - } - - void setAccountless() { - assert(_sqlAccount == null && _appAccount == null); - _isAccountless = true; - } - - void byRowId(int rowId) { - _byRowId = rowId; - } - - void byFileId(int fileId) { - _byFileId = fileId; - } - - void byFileIds(Iterable fileIds) { - _byFileIds = fileIds; - } - - void byRelativePath(String path) { - _byRelativePath = path; - } - - void byOrRelativePath(String path) { - _byOrRelativePathBuilder((relativePath) => relativePath.equals(path)); - } - - void byOrRelativePathPattern(String pattern) { - _byOrRelativePathBuilder((relativePath) => relativePath.like(pattern)); - } - - void byMimePattern(String pattern) { - (_byMimePatterns ??= []).add(pattern); - } - - void byFavorite(bool favorite) { - _byFavorite = favorite; - } - - void byDirRowId(int dirRowId) { - _byDirRowId = dirRowId; - } - - void byServerRowId(int serverRowId) { - _byServerRowId = serverRowId; - } - - void byLocation(String location) { - _byLocation = location; - } - - JoinedSelectStatement build() { - if (_sqlAccount == null && _appAccount == null && !_isAccountless) { - throw StateError("Invalid query: missing account"); - } - final dynamic select = _queryMode == FilesQueryMode.expression - ? db.selectOnly(db.files) - : db.select(db.files); - final query = select.join([ - innerJoin(db.accountFiles, db.accountFiles.file.equalsExp(db.files.rowId), - useColumns: _queryMode == FilesQueryMode.completeFile), - if (_appAccount != null) ...[ - innerJoin( - db.accounts, db.accounts.rowId.equalsExp(db.accountFiles.account), - useColumns: false), - innerJoin(db.servers, db.servers.rowId.equalsExp(db.accounts.server), - useColumns: false), - ], - if (_byDirRowId != null) - innerJoin(db.dirFiles, db.dirFiles.child.equalsExp(db.files.rowId), - useColumns: false), - if (_queryMode == FilesQueryMode.completeFile) ...[ - leftOuterJoin( - db.images, db.images.accountFile.equalsExp(db.accountFiles.rowId)), - leftOuterJoin(db.imageLocations, - db.imageLocations.accountFile.equalsExp(db.accountFiles.rowId)), - leftOuterJoin(db.trashes, db.trashes.file.equalsExp(db.files.rowId)), - ], - ]) as JoinedSelectStatement; - if (_queryMode == FilesQueryMode.expression) { - query.addColumns(_selectExpressions!); - } - - if (_sqlAccount != null) { - query.where(db.accountFiles.account.equals(_sqlAccount!.rowId)); - } else if (_appAccount != null) { - query - ..where(db.servers.address.equals(_appAccount!.url)) - ..where(db.accounts.userId - .equals(_appAccount!.userId.toCaseInsensitiveString())); - } - - if (_byRowId != null) { - query.where(db.files.rowId.equals(_byRowId)); - } - if (_byFileId != null) { - query.where(db.files.fileId.equals(_byFileId)); - } - if (_byFileIds != null) { - query.where(db.files.fileId.isIn(_byFileIds!)); - } - if (_byRelativePath != null) { - query.where(db.accountFiles.relativePath.equals(_byRelativePath)); - } - if (_byOrRelativePathBuilders?.isNotEmpty == true) { - final expression = _byOrRelativePathBuilders! - .sublist(1) - .fold>( - _byOrRelativePathBuilders![0](db.accountFiles.relativePath), - (previousValue, builder) => - previousValue | builder(db.accountFiles.relativePath)); - query.where(expression); - } - if (_byMimePatterns?.isNotEmpty == true) { - final expression = _byMimePatterns!.sublist(1).fold>( - db.files.contentType.like(_byMimePatterns![0]), - (previousValue, element) => - previousValue | db.files.contentType.like(element)); - query.where(expression); - } - if (_byFavorite != null) { - if (_byFavorite!) { - query.where(db.accountFiles.isFavorite.equals(true)); - } else { - // null are treated as false - query.where(db.accountFiles.isFavorite.equals(true).not()); - } - } - if (_byDirRowId != null) { - query.where(db.dirFiles.dir.equals(_byDirRowId)); - } - if (_byServerRowId != null) { - query.where(db.files.server.equals(_byServerRowId)); - } - if (_byLocation != null) { - var clause = db.imageLocations.name.like(_byLocation!) | - db.imageLocations.admin1.like(_byLocation!) | - db.imageLocations.admin2.like(_byLocation!); - final countryCode = location_util.nameToAlpha2Code(_byLocation!.toCi()); - if (countryCode != null) { - clause = clause | db.imageLocations.countryCode.equals(countryCode); - } else if (_byLocation!.length == 2 && - location_util.alpha2CodeToName(_byLocation!.toUpperCase()) != null) { - clause = clause | - db.imageLocations.countryCode.equals(_byLocation!.toUpperCase()); - } - query.where(clause); - } - return query; - } - - void _byOrRelativePathBuilder(FilesQueryRelativePathBuilder builder) { - (_byOrRelativePathBuilders ??= []).add(builder); - } - - final SqliteDb db; - - FilesQueryMode _queryMode = FilesQueryMode.file; - Iterable? _selectExpressions; - - Account? _sqlAccount; - app.Account? _appAccount; - bool _isAccountless = false; - - int? _byRowId; - int? _byFileId; - Iterable? _byFileIds; - String? _byRelativePath; - List? _byOrRelativePathBuilders; - List? _byMimePatterns; - bool? _byFavorite; - int? _byDirRowId; - int? _byServerRowId; - String? _byLocation; -} - app.File _covertSqliteDbFile(Map map) { final userId = map["userId"] as String; final file = map["completeFile"] as CompleteFile; diff --git a/app/lib/entity/sqlite/files_query_builder.dart b/app/lib/entity/sqlite/files_query_builder.dart new file mode 100644 index 00000000..85bba8dd --- /dev/null +++ b/app/lib/entity/sqlite/files_query_builder.dart @@ -0,0 +1,220 @@ +import 'package:drift/drift.dart'; +import 'package:nc_photos/account.dart' as app; +import 'package:nc_photos/ci_string.dart'; +import 'package:nc_photos/entity/sqlite/database.dart'; +import 'package:nc_photos/location_util.dart' as location_util; + +enum FilesQueryMode { + file, + completeFile, + expression, +} + +typedef FilesQueryRelativePathBuilder = Expression Function( + GeneratedColumn relativePath); + +/// Build a Files table query +/// +/// If you call more than one by* methods, the condition will be added up +/// instead of replaced. No validations will be made to make sure the resulting +/// conditions make sense +class FilesQueryBuilder { + FilesQueryBuilder(this.db); + + /// Set the query mode + /// + /// If [mode] == FilesQueryMode.expression, [expressions] must be defined and + /// not empty + void setQueryMode( + FilesQueryMode mode, { + Iterable? expressions, + }) { + assert( + (mode == FilesQueryMode.expression) != (expressions?.isEmpty != false)); + _queryMode = mode; + _selectExpressions = expressions; + } + + void setSqlAccount(Account account) { + assert(_appAccount == null); + _sqlAccount = account; + } + + void setAppAccount(app.Account account) { + assert(_sqlAccount == null); + _appAccount = account; + } + + void setAccountless() { + assert(_sqlAccount == null && _appAccount == null); + _isAccountless = true; + } + + void byRowId(int rowId) { + _byRowId = rowId; + } + + void byFileId(int fileId) { + _byFileId = fileId; + } + + void byFileIds(Iterable fileIds) { + _byFileIds = fileIds; + } + + void byRelativePath(String path) { + _byRelativePath = path; + } + + void byOrRelativePath(String path) { + _byOrRelativePathBuilder((relativePath) => relativePath.equals(path)); + } + + void byOrRelativePathPattern(String pattern) { + _byOrRelativePathBuilder((relativePath) => relativePath.like(pattern)); + } + + void byMimePattern(String pattern) { + (_byMimePatterns ??= []).add(pattern); + } + + void byFavorite(bool favorite) { + _byFavorite = favorite; + } + + void byDirRowId(int dirRowId) { + _byDirRowId = dirRowId; + } + + void byServerRowId(int serverRowId) { + _byServerRowId = serverRowId; + } + + void byLocation(String location) { + _byLocation = location; + } + + JoinedSelectStatement build() { + if (_sqlAccount == null && _appAccount == null && !_isAccountless) { + throw StateError("Invalid query: missing account"); + } + final dynamic select = _queryMode == FilesQueryMode.expression + ? db.selectOnly(db.files) + : db.select(db.files); + final query = select.join([ + innerJoin(db.accountFiles, db.accountFiles.file.equalsExp(db.files.rowId), + useColumns: _queryMode == FilesQueryMode.completeFile), + if (_appAccount != null) ...[ + innerJoin( + db.accounts, db.accounts.rowId.equalsExp(db.accountFiles.account), + useColumns: false), + innerJoin(db.servers, db.servers.rowId.equalsExp(db.accounts.server), + useColumns: false), + ], + if (_byDirRowId != null) + innerJoin(db.dirFiles, db.dirFiles.child.equalsExp(db.files.rowId), + useColumns: false), + if (_queryMode == FilesQueryMode.completeFile) ...[ + leftOuterJoin( + db.images, db.images.accountFile.equalsExp(db.accountFiles.rowId)), + leftOuterJoin(db.imageLocations, + db.imageLocations.accountFile.equalsExp(db.accountFiles.rowId)), + leftOuterJoin(db.trashes, db.trashes.file.equalsExp(db.files.rowId)), + ], + ]) as JoinedSelectStatement; + if (_queryMode == FilesQueryMode.expression) { + query.addColumns(_selectExpressions!); + } + + if (_sqlAccount != null) { + query.where(db.accountFiles.account.equals(_sqlAccount!.rowId)); + } else if (_appAccount != null) { + query + ..where(db.servers.address.equals(_appAccount!.url)) + ..where(db.accounts.userId + .equals(_appAccount!.userId.toCaseInsensitiveString())); + } + + if (_byRowId != null) { + query.where(db.files.rowId.equals(_byRowId)); + } + if (_byFileId != null) { + query.where(db.files.fileId.equals(_byFileId)); + } + if (_byFileIds != null) { + query.where(db.files.fileId.isIn(_byFileIds!)); + } + if (_byRelativePath != null) { + query.where(db.accountFiles.relativePath.equals(_byRelativePath)); + } + if (_byOrRelativePathBuilders?.isNotEmpty == true) { + final expression = _byOrRelativePathBuilders! + .sublist(1) + .fold>( + _byOrRelativePathBuilders![0](db.accountFiles.relativePath), + (previousValue, builder) => + previousValue | builder(db.accountFiles.relativePath)); + query.where(expression); + } + if (_byMimePatterns?.isNotEmpty == true) { + final expression = _byMimePatterns!.sublist(1).fold>( + db.files.contentType.like(_byMimePatterns![0]), + (previousValue, element) => + previousValue | db.files.contentType.like(element)); + query.where(expression); + } + if (_byFavorite != null) { + if (_byFavorite!) { + query.where(db.accountFiles.isFavorite.equals(true)); + } else { + // null are treated as false + query.where(db.accountFiles.isFavorite.equals(true).not()); + } + } + if (_byDirRowId != null) { + query.where(db.dirFiles.dir.equals(_byDirRowId)); + } + if (_byServerRowId != null) { + query.where(db.files.server.equals(_byServerRowId)); + } + if (_byLocation != null) { + var clause = db.imageLocations.name.like(_byLocation!) | + db.imageLocations.admin1.like(_byLocation!) | + db.imageLocations.admin2.like(_byLocation!); + final countryCode = location_util.nameToAlpha2Code(_byLocation!.toCi()); + if (countryCode != null) { + clause = clause | db.imageLocations.countryCode.equals(countryCode); + } else if (_byLocation!.length == 2 && + location_util.alpha2CodeToName(_byLocation!.toUpperCase()) != null) { + clause = clause | + db.imageLocations.countryCode.equals(_byLocation!.toUpperCase()); + } + query.where(clause); + } + return query; + } + + void _byOrRelativePathBuilder(FilesQueryRelativePathBuilder builder) { + (_byOrRelativePathBuilders ??= []).add(builder); + } + + final SqliteDb db; + + FilesQueryMode _queryMode = FilesQueryMode.file; + Iterable? _selectExpressions; + + Account? _sqlAccount; + app.Account? _appAccount; + bool _isAccountless = false; + + int? _byRowId; + int? _byFileId; + Iterable? _byFileIds; + String? _byRelativePath; + List? _byOrRelativePathBuilders; + List? _byMimePatterns; + bool? _byFavorite; + int? _byDirRowId; + int? _byServerRowId; + String? _byLocation; +} diff --git a/app/lib/entity/sqlite_table_isolate.dart b/app/lib/entity/sqlite/isolate_util.dart similarity index 98% rename from app/lib/entity/sqlite_table_isolate.dart rename to app/lib/entity/sqlite/isolate_util.dart index eb828811..2d344d4b 100644 --- a/app/lib/entity/sqlite_table_isolate.dart +++ b/app/lib/entity/sqlite/isolate_util.dart @@ -6,7 +6,7 @@ import 'package:flutter/foundation.dart'; import 'package:kiwi/kiwi.dart'; import 'package:nc_photos/app_init.dart' as app_init; import 'package:nc_photos/di_container.dart'; -import 'package:nc_photos/entity/sqlite_table.dart'; +import 'package:nc_photos/entity/sqlite/database.dart'; import 'package:nc_photos/mobile/platform.dart' if (dart.library.html) 'package:nc_photos/web/platform.dart' as platform; import 'package:nc_photos/platform/k.dart' as platform_k; diff --git a/app/lib/entity/sqlite_table.dart b/app/lib/entity/sqlite/table.dart similarity index 53% rename from app/lib/entity/sqlite_table.dart rename to app/lib/entity/sqlite/table.dart index 5a3fb648..4abd51c0 100644 --- a/app/lib/entity/sqlite_table.dart +++ b/app/lib/entity/sqlite/table.dart @@ -1,10 +1,4 @@ import 'package:drift/drift.dart'; -import 'package:logging/logging.dart'; -import 'package:nc_photos/mobile/platform.dart' - if (dart.library.html) 'package:nc_photos/web/platform.dart' as platform; -import 'package:np_codegen/np_codegen.dart'; - -part 'sqlite_table.g.dart'; class Servers extends Table { IntColumn get rowId => integer().autoIncrement()(); @@ -33,7 +27,7 @@ class Files extends Table { TextColumn get contentType => text().nullable()(); TextColumn get etag => text().nullable()(); DateTimeColumn get lastModified => - dateTime().map(const _DateTimeConverter()).nullable()(); + dateTime().map(const SqliteDateTimeConverter()).nullable()(); BoolColumn get isCollection => boolean().nullable()(); IntColumn get usedBytes => integer().nullable()(); BoolColumn get hasPreview => boolean().nullable()(); @@ -59,9 +53,9 @@ class AccountFiles extends Table { BoolColumn get isFavorite => boolean().nullable()(); BoolColumn get isArchived => boolean().nullable()(); DateTimeColumn get overrideDateTime => - dateTime().map(const _DateTimeConverter()).nullable()(); + dateTime().map(const SqliteDateTimeConverter()).nullable()(); DateTimeColumn get bestDateTime => - dateTime().map(const _DateTimeConverter())(); + dateTime().map(const SqliteDateTimeConverter())(); @override get uniqueKeys => [ @@ -76,7 +70,7 @@ class Images extends Table { IntColumn get accountFile => integer().references(AccountFiles, #rowId, onDelete: KeyAction.cascade)(); DateTimeColumn get lastUpdated => - dateTime().map(const _DateTimeConverter())(); + dateTime().map(const SqliteDateTimeConverter())(); TextColumn get fileEtag => text().nullable()(); IntColumn get width => integer().nullable()(); IntColumn get height => integer().nullable()(); @@ -84,7 +78,7 @@ class Images extends Table { // exif columns DateTimeColumn get dateTimeOriginal => - dateTime().map(const _DateTimeConverter()).nullable()(); + dateTime().map(const SqliteDateTimeConverter()).nullable()(); @override get primaryKey => {accountFile}; @@ -114,7 +108,7 @@ class Trashes extends Table { TextColumn get filename => text()(); TextColumn get originalLocation => text()(); DateTimeColumn get deletionTime => - dateTime().map(const _DateTimeConverter())(); + dateTime().map(const SqliteDateTimeConverter())(); @override get primaryKey => {file}; @@ -140,7 +134,7 @@ class Albums extends Table { TextColumn get fileEtag => text().nullable()(); IntColumn get version => integer()(); DateTimeColumn get lastUpdated => - dateTime().map(const _DateTimeConverter())(); + dateTime().map(const SqliteDateTimeConverter())(); TextColumn get name => text()(); // provider @@ -161,7 +155,8 @@ class AlbumShares extends Table { integer().references(Albums, #rowId, onDelete: KeyAction.cascade)(); TextColumn get userId => text()(); TextColumn get displayName => text().nullable()(); - DateTimeColumn get sharedAt => dateTime().map(const _DateTimeConverter())(); + DateTimeColumn get sharedAt => + dateTime().map(const SqliteDateTimeConverter())(); @override get primaryKey => {album, userId}; @@ -196,118 +191,8 @@ class Persons extends Table { ]; } -// remember to also update the truncate method after adding a new table -@npLog -@DriftDatabase( - tables: [ - Servers, - Accounts, - Files, - Images, - ImageLocations, - Trashes, - AccountFiles, - DirFiles, - Albums, - AlbumShares, - Tags, - Persons, - ], -) -class SqliteDb extends _$SqliteDb { - SqliteDb({ - QueryExecutor? executor, - }) : super(executor ?? platform.openSqliteConnection()); - - SqliteDb.connect(DatabaseConnection connection) : super.connect(connection); - - @override - get schemaVersion => 4; - - @override - get migration => MigrationStrategy( - onCreate: (m) async { - await customStatement("PRAGMA journal_mode=WAL;"); - await m.createAll(); - - await m.createIndex(Index("files_server_index", - "CREATE INDEX files_server_index ON files(server);")); - await m.createIndex(Index("files_file_id_index", - "CREATE INDEX files_file_id_index ON files(file_id);")); - await m.createIndex(Index("files_content_type_index", - "CREATE INDEX files_content_type_index ON files(content_type);")); - - await m.createIndex(Index("account_files_file_index", - "CREATE INDEX account_files_file_index ON account_files(file);")); - await m.createIndex(Index("account_files_relative_path_index", - "CREATE INDEX account_files_relative_path_index ON account_files(relative_path);")); - await m.createIndex(Index("account_files_best_date_time_index", - "CREATE INDEX account_files_best_date_time_index ON account_files(best_date_time);")); - - await m.createIndex(Index("dir_files_dir_index", - "CREATE INDEX dir_files_dir_index ON dir_files(dir);")); - await m.createIndex(Index("dir_files_child_index", - "CREATE INDEX dir_files_child_index ON dir_files(child);")); - - await m.createIndex(Index("album_shares_album_index", - "CREATE INDEX album_shares_album_index ON album_shares(album);")); - - await _createIndexV2(m); - await _createIndexV3(m); - }, - onUpgrade: (m, from, to) async { - _log.info("[onUpgrade] $from -> $to"); - try { - await transaction(() async { - if (from < 2) { - await m.createTable(tags); - await m.createTable(persons); - await _createIndexV2(m); - } - if (from < 3) { - await m.createTable(imageLocations); - await _createIndexV3(m); - } - if (from < 4) { - await m.addColumn(albums, albums.fileEtag); - } - }); - } catch (e, stackTrace) { - _log.shout("[onUpgrade] Failed upgrading sqlite db", e, stackTrace); - rethrow; - } - }, - beforeOpen: (details) async { - await customStatement("PRAGMA foreign_keys = ON;"); - // technically we have a platform side lock to ensure only one - // transaction is running in any isolates, but for some reason we are - // still seeing database is locked error in crashlytics, let see if - // this helps - await customStatement("PRAGMA busy_timeout = 5000;"); - }, - ); - - Future _createIndexV2(Migrator m) async { - await m.createIndex(Index("tags_server_index", - "CREATE INDEX tags_server_index ON tags(server);")); - await m.createIndex(Index("persons_account_index", - "CREATE INDEX persons_account_index ON persons(account);")); - } - - Future _createIndexV3(Migrator m) async { - await m.createIndex(Index("image_locations_name_index", - "CREATE INDEX image_locations_name_index ON image_locations(name);")); - await m.createIndex(Index("image_locations_country_code_index", - "CREATE INDEX image_locations_country_code_index ON image_locations(country_code);")); - await m.createIndex(Index("image_locations_admin1_index", - "CREATE INDEX image_locations_admin1_index ON image_locations(admin1);")); - await m.createIndex(Index("image_locations_admin2_index", - "CREATE INDEX image_locations_admin2_index ON image_locations(admin2);")); - } -} - -class _DateTimeConverter extends TypeConverter { - const _DateTimeConverter(); +class SqliteDateTimeConverter extends TypeConverter { + const SqliteDateTimeConverter(); @override DateTime? mapToDart(DateTime? fromDb) => fromDb?.toUtc(); diff --git a/app/lib/entity/sqlite_table_converter.dart b/app/lib/entity/sqlite/type_converter.dart similarity index 98% rename from app/lib/entity/sqlite_table_converter.dart rename to app/lib/entity/sqlite/type_converter.dart index 508cf7e8..708e6247 100644 --- a/app/lib/entity/sqlite_table_converter.dart +++ b/app/lib/entity/sqlite/type_converter.dart @@ -10,8 +10,7 @@ import 'package:nc_photos/entity/exif.dart'; import 'package:nc_photos/entity/file.dart'; import 'package:nc_photos/entity/file_descriptor.dart'; import 'package:nc_photos/entity/person.dart'; -import 'package:nc_photos/entity/sqlite_table.dart' as sql; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; import 'package:nc_photos/entity/tag.dart'; import 'package:nc_photos/iterable_extension.dart'; import 'package:nc_photos/object_extension.dart'; diff --git a/app/lib/entity/sqlite_table_extension.g.dart b/app/lib/entity/sqlite_table_extension.g.dart deleted file mode 100644 index 0085d569..00000000 --- a/app/lib/entity/sqlite_table_extension.g.dart +++ /dev/null @@ -1,14 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'sqlite_table_extension.dart'; - -// ************************************************************************** -// NpLogGenerator -// ************************************************************************** - -extension _$SqliteDbExtensionNpLog on SqliteDb { - // ignore: unused_element - Logger get _log => log; - - static final log = Logger("entity.sqlite_table_extension.SqliteDbExtension"); -} diff --git a/app/lib/entity/tag/data_source.dart b/app/lib/entity/tag/data_source.dart index 6fa3c07f..5fb08623 100644 --- a/app/lib/entity/tag/data_source.dart +++ b/app/lib/entity/tag/data_source.dart @@ -2,9 +2,8 @@ import 'package:logging/logging.dart'; import 'package:nc_photos/account.dart'; import 'package:nc_photos/api/api.dart'; import 'package:nc_photos/entity/file.dart'; -import 'package:nc_photos/entity/sqlite_table.dart' as sql; -import 'package:nc_photos/entity/sqlite_table_converter.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; +import 'package:nc_photos/entity/sqlite/type_converter.dart'; import 'package:nc_photos/entity/tag.dart'; import 'package:nc_photos/entity/webdav_response_parser.dart'; import 'package:nc_photos/exception.dart'; diff --git a/app/lib/legacy/sign_in.dart b/app/lib/legacy/sign_in.dart index 7d4161d3..01d49573 100644 --- a/app/lib/legacy/sign_in.dart +++ b/app/lib/legacy/sign_in.dart @@ -7,7 +7,7 @@ import 'package:nc_photos/account.dart'; import 'package:nc_photos/app_localizations.dart'; import 'package:nc_photos/ci_string.dart'; import 'package:nc_photos/di_container.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; import 'package:nc_photos/help_utils.dart' as help_utils; import 'package:nc_photos/iterable_extension.dart'; import 'package:nc_photos/legacy/connect.dart'; diff --git a/app/lib/use_case/cache_favorite.dart b/app/lib/use_case/cache_favorite.dart index c4f4cc30..99de33ba 100644 --- a/app/lib/use_case/cache_favorite.dart +++ b/app/lib/use_case/cache_favorite.dart @@ -5,8 +5,8 @@ import 'package:kiwi/kiwi.dart'; import 'package:logging/logging.dart'; import 'package:nc_photos/account.dart'; import 'package:nc_photos/di_container.dart'; -import 'package:nc_photos/entity/sqlite_table.dart' as sql; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; +import 'package:nc_photos/entity/sqlite/files_query_builder.dart' as sql; import 'package:nc_photos/event/event.dart'; import 'package:nc_photos/iterable_extension.dart'; import 'package:nc_photos/list_util.dart' as list_util; diff --git a/app/lib/use_case/compat/v46.dart b/app/lib/use_case/compat/v46.dart index fe745711..31a28125 100644 --- a/app/lib/use_case/compat/v46.dart +++ b/app/lib/use_case/compat/v46.dart @@ -1,6 +1,5 @@ import 'package:logging/logging.dart'; -import 'package:nc_photos/entity/sqlite_table.dart' as sql; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; import 'package:nc_photos/pref.dart'; import 'package:np_codegen/np_codegen.dart'; diff --git a/app/lib/use_case/compat/v55.dart b/app/lib/use_case/compat/v55.dart index 52255348..d32dd2e3 100644 --- a/app/lib/use_case/compat/v55.dart +++ b/app/lib/use_case/compat/v55.dart @@ -2,8 +2,7 @@ import 'package:drift/drift.dart' as sql; import 'package:flutter/foundation.dart'; import 'package:logging/logging.dart'; import 'package:nc_photos/entity/file_util.dart' as file_util; -import 'package:nc_photos/entity/sqlite_table.dart' as sql; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; import 'package:nc_photos/iterable_extension.dart'; import 'package:np_codegen/np_codegen.dart'; import 'package:tuple/tuple.dart'; diff --git a/app/lib/use_case/find_file.dart b/app/lib/use_case/find_file.dart index 3adf4a8d..7d462f47 100644 --- a/app/lib/use_case/find_file.dart +++ b/app/lib/use_case/find_file.dart @@ -2,7 +2,7 @@ import 'package:logging/logging.dart'; import 'package:nc_photos/account.dart'; import 'package:nc_photos/di_container.dart'; import 'package:nc_photos/entity/file.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; import 'package:nc_photos/iterable_extension.dart'; import 'package:np_codegen/np_codegen.dart'; diff --git a/app/lib/use_case/list_favorite_offline.dart b/app/lib/use_case/list_favorite_offline.dart index b9075876..6505495f 100644 --- a/app/lib/use_case/list_favorite_offline.dart +++ b/app/lib/use_case/list_favorite_offline.dart @@ -1,7 +1,7 @@ import 'package:nc_photos/account.dart'; import 'package:nc_photos/di_container.dart'; import 'package:nc_photos/entity/file.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; class ListFavoriteOffline { ListFavoriteOffline(this._c) : assert(require(_c)); diff --git a/app/lib/use_case/list_location_file.dart b/app/lib/use_case/list_location_file.dart index 25869b0e..7005bb18 100644 --- a/app/lib/use_case/list_location_file.dart +++ b/app/lib/use_case/list_location_file.dart @@ -3,8 +3,9 @@ import 'package:nc_photos/account.dart'; import 'package:nc_photos/di_container.dart'; import 'package:nc_photos/entity/file.dart'; import 'package:nc_photos/entity/file_descriptor.dart'; -import 'package:nc_photos/entity/sqlite_table_converter.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; +import 'package:nc_photos/entity/sqlite/files_query_builder.dart' as sql; +import 'package:nc_photos/entity/sqlite/type_converter.dart'; import 'package:nc_photos/location_util.dart' as location_util; import 'package:nc_photos/object_extension.dart'; diff --git a/app/lib/use_case/list_location_group.dart b/app/lib/use_case/list_location_group.dart index eba8d182..0b6b6616 100644 --- a/app/lib/use_case/list_location_group.dart +++ b/app/lib/use_case/list_location_group.dart @@ -3,8 +3,7 @@ import 'package:equatable/equatable.dart'; import 'package:logging/logging.dart'; import 'package:nc_photos/account.dart'; import 'package:nc_photos/di_container.dart'; -import 'package:nc_photos/entity/sqlite_table.dart' as sql; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; import 'package:nc_photos/location_util.dart' as location_util; import 'package:np_codegen/np_codegen.dart'; import 'package:to_string/to_string.dart'; diff --git a/app/lib/use_case/populate_person.dart b/app/lib/use_case/populate_person.dart index 82b1edca..93ae8a61 100644 --- a/app/lib/use_case/populate_person.dart +++ b/app/lib/use_case/populate_person.dart @@ -4,7 +4,7 @@ import 'package:nc_photos/account.dart'; import 'package:nc_photos/di_container.dart'; import 'package:nc_photos/entity/face.dart'; import 'package:nc_photos/entity/file.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; import 'package:np_codegen/np_codegen.dart'; part 'populate_person.g.dart'; diff --git a/app/lib/use_case/scan_dir_offline.dart b/app/lib/use_case/scan_dir_offline.dart index 8267efe3..41131cd5 100644 --- a/app/lib/use_case/scan_dir_offline.dart +++ b/app/lib/use_case/scan_dir_offline.dart @@ -3,8 +3,9 @@ import 'package:nc_photos/account.dart'; import 'package:nc_photos/di_container.dart'; import 'package:nc_photos/entity/file.dart'; import 'package:nc_photos/entity/file_descriptor.dart'; -import 'package:nc_photos/entity/sqlite_table_converter.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; +import 'package:nc_photos/entity/sqlite/files_query_builder.dart' as sql; +import 'package:nc_photos/entity/sqlite/type_converter.dart'; import 'package:nc_photos/object_extension.dart'; import 'package:nc_photos/remote_storage_util.dart' as remote_storage_util; diff --git a/app/lib/use_case/sync_dir.dart b/app/lib/use_case/sync_dir.dart index 250ac474..142d3160 100644 --- a/app/lib/use_case/sync_dir.dart +++ b/app/lib/use_case/sync_dir.dart @@ -6,7 +6,8 @@ import 'package:nc_photos/di_container.dart'; import 'package:nc_photos/entity/file.dart'; import 'package:nc_photos/entity/file/data_source.dart'; import 'package:nc_photos/entity/file_descriptor.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; +import 'package:nc_photos/entity/sqlite/files_query_builder.dart' as sql; import 'package:nc_photos/object_extension.dart'; import 'package:nc_photos/progress_util.dart'; import 'package:nc_photos/remote_storage_util.dart' as remote_storage_util; diff --git a/app/lib/use_case/sync_person.dart b/app/lib/use_case/sync_person.dart index b26d1f77..12966a31 100644 --- a/app/lib/use_case/sync_person.dart +++ b/app/lib/use_case/sync_person.dart @@ -4,9 +4,8 @@ import 'package:logging/logging.dart'; import 'package:nc_photos/account.dart'; import 'package:nc_photos/di_container.dart'; import 'package:nc_photos/entity/person.dart'; -import 'package:nc_photos/entity/sqlite_table.dart' as sql; -import 'package:nc_photos/entity/sqlite_table_converter.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; +import 'package:nc_photos/entity/sqlite/type_converter.dart'; import 'package:nc_photos/exception.dart'; import 'package:nc_photos/iterable_extension.dart'; import 'package:nc_photos/list_util.dart' as list_util; diff --git a/app/lib/use_case/sync_tag.dart b/app/lib/use_case/sync_tag.dart index b452b73b..3358348f 100644 --- a/app/lib/use_case/sync_tag.dart +++ b/app/lib/use_case/sync_tag.dart @@ -3,9 +3,8 @@ import 'package:drift/drift.dart' as sql; import 'package:logging/logging.dart'; import 'package:nc_photos/account.dart'; import 'package:nc_photos/di_container.dart'; -import 'package:nc_photos/entity/sqlite_table.dart' as sql; -import 'package:nc_photos/entity/sqlite_table_converter.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; +import 'package:nc_photos/entity/sqlite/type_converter.dart'; import 'package:nc_photos/entity/tag.dart'; import 'package:nc_photos/iterable_extension.dart'; import 'package:nc_photos/list_util.dart' as list_util; diff --git a/app/lib/web/db_util.dart b/app/lib/web/db_util.dart index 522819de..7c242f82 100644 --- a/app/lib/web/db_util.dart +++ b/app/lib/web/db_util.dart @@ -2,7 +2,7 @@ import 'package:drift/drift.dart'; import 'package:drift/wasm.dart'; import 'package:flutter/services.dart' show rootBundle; import 'package:http/http.dart' as http; -import 'package:nc_photos/entity/sqlite_table.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; import 'package:sqlite3/wasm.dart'; Future> getSqliteConnectionArgs() async => {}; diff --git a/app/lib/widget/account_picker_dialog.dart b/app/lib/widget/account_picker_dialog.dart index 018c0120..38a8f968 100644 --- a/app/lib/widget/account_picker_dialog.dart +++ b/app/lib/widget/account_picker_dialog.dart @@ -6,7 +6,7 @@ import 'package:logging/logging.dart'; import 'package:nc_photos/account.dart'; import 'package:nc_photos/app_localizations.dart'; import 'package:nc_photos/di_container.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; import 'package:nc_photos/exception_util.dart' as exception_util; import 'package:nc_photos/k.dart' as k; import 'package:nc_photos/pref.dart'; diff --git a/app/lib/widget/home_photos.dart b/app/lib/widget/home_photos.dart index 284182ac..037ecc4c 100644 --- a/app/lib/widget/home_photos.dart +++ b/app/lib/widget/home_photos.dart @@ -20,7 +20,7 @@ import 'package:nc_photos/di_container.dart'; import 'package:nc_photos/download_handler.dart'; import 'package:nc_photos/entity/album.dart'; import 'package:nc_photos/entity/file_descriptor.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; import 'package:nc_photos/event/event.dart'; import 'package:nc_photos/event/native_event.dart'; import 'package:nc_photos/exception_util.dart' as exception_util; diff --git a/app/lib/widget/settings.dart b/app/lib/widget/settings.dart index 4afb1895..e51af555 100644 --- a/app/lib/widget/settings.dart +++ b/app/lib/widget/settings.dart @@ -8,7 +8,7 @@ import 'package:nc_photos/account.dart'; import 'package:nc_photos/app_localizations.dart'; import 'package:nc_photos/debug_util.dart'; import 'package:nc_photos/di_container.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; import 'package:nc_photos/event/event.dart'; import 'package:nc_photos/exception_util.dart' as exception_util; import 'package:nc_photos/k.dart' as k; diff --git a/app/lib/widget/sign_in.dart b/app/lib/widget/sign_in.dart index 2116a5b6..37d198f9 100644 --- a/app/lib/widget/sign_in.dart +++ b/app/lib/widget/sign_in.dart @@ -7,7 +7,7 @@ import 'package:logging/logging.dart'; import 'package:nc_photos/account.dart'; import 'package:nc_photos/app_localizations.dart'; import 'package:nc_photos/di_container.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; import 'package:nc_photos/iterable_extension.dart'; import 'package:nc_photos/legacy/sign_in.dart' as legacy; import 'package:nc_photos/pref.dart'; diff --git a/app/lib/widget/splash.dart b/app/lib/widget/splash.dart index ea337122..ae94868a 100644 --- a/app/lib/widget/splash.dart +++ b/app/lib/widget/splash.dart @@ -6,7 +6,7 @@ import 'package:kiwi/kiwi.dart'; import 'package:logging/logging.dart'; import 'package:nc_photos/app_localizations.dart'; import 'package:nc_photos/di_container.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; import 'package:nc_photos/k.dart' as k; import 'package:nc_photos/mobile/android/activity.dart'; import 'package:nc_photos/platform/k.dart' as platform_k; diff --git a/app/test/bloc/list_album_share_outlier_test.dart b/app/test/bloc/list_album_share_outlier_test.dart index a82d4958..8badffda 100644 --- a/app/test/bloc/list_album_share_outlier_test.dart +++ b/app/test/bloc/list_album_share_outlier_test.dart @@ -2,7 +2,7 @@ import 'package:bloc_test/bloc_test.dart'; import 'package:nc_photos/bloc/list_album_share_outlier.dart'; import 'package:nc_photos/ci_string.dart'; import 'package:nc_photos/di_container.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; import 'package:test/test.dart'; import '../mock_type.dart'; diff --git a/app/test/entity/album/data_source_test.dart b/app/test/entity/album/data_source_test.dart index 69079e04..18896dfe 100644 --- a/app/test/entity/album/data_source_test.dart +++ b/app/test/entity/album/data_source_test.dart @@ -6,7 +6,7 @@ import 'package:nc_photos/entity/album/data_source.dart'; import 'package:nc_photos/entity/album/item.dart'; import 'package:nc_photos/entity/album/provider.dart'; import 'package:nc_photos/entity/album/sort_provider.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; import 'package:nc_photos/exception.dart'; import 'package:nc_photos/or_null.dart'; import 'package:test/test.dart'; diff --git a/app/test/entity/file/data_source_test.dart b/app/test/entity/file/data_source_test.dart index 8023e89a..de04063d 100644 --- a/app/test/entity/file/data_source_test.dart +++ b/app/test/entity/file/data_source_test.dart @@ -1,7 +1,7 @@ import 'package:nc_photos/di_container.dart'; import 'package:nc_photos/entity/file.dart'; import 'package:nc_photos/entity/file/data_source.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; import 'package:nc_photos/list_extension.dart'; import 'package:nc_photos/or_null.dart'; import 'package:test/test.dart'; diff --git a/app/test/entity/file/file_cache_manager_test.dart b/app/test/entity/file/file_cache_manager_test.dart index a85801dc..7f7e2aa1 100644 --- a/app/test/entity/file/file_cache_manager_test.dart +++ b/app/test/entity/file/file_cache_manager_test.dart @@ -2,7 +2,7 @@ import 'package:nc_photos/di_container.dart'; import 'package:nc_photos/entity/file.dart'; import 'package:nc_photos/entity/file/data_source.dart'; import 'package:nc_photos/entity/file/file_cache_manager.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; import 'package:nc_photos/int_extension.dart'; import 'package:nc_photos/list_extension.dart'; import 'package:nc_photos/or_null.dart'; diff --git a/app/test/entity/sqlite_table_extension_test.dart b/app/test/entity/sqlite_table_extension_test.dart index 35848002..2a00487f 100644 --- a/app/test/entity/sqlite_table_extension_test.dart +++ b/app/test/entity/sqlite_table_extension_test.dart @@ -1,7 +1,6 @@ import 'package:nc_photos/di_container.dart'; import 'package:nc_photos/entity/file.dart'; -import 'package:nc_photos/entity/sqlite_table.dart' as sql; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; import 'package:nc_photos/object_extension.dart'; import 'package:test/test.dart'; diff --git a/app/test/test_util.dart b/app/test/test_util.dart index 81cd23bd..735fdfd4 100644 --- a/app/test/test_util.dart +++ b/app/test/test_util.dart @@ -15,9 +15,8 @@ import 'package:nc_photos/entity/file.dart'; import 'package:nc_photos/entity/file_descriptor.dart'; import 'package:nc_photos/entity/share.dart'; import 'package:nc_photos/entity/sharee.dart'; -import 'package:nc_photos/entity/sqlite_table.dart' as sql; -import 'package:nc_photos/entity/sqlite_table_converter.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; +import 'package:nc_photos/entity/sqlite/type_converter.dart'; import 'package:nc_photos/iterable_extension.dart'; import 'package:nc_photos/or_null.dart'; import 'package:tuple/tuple.dart'; diff --git a/app/test/use_case/add_to_album_test.dart b/app/test/use_case/add_to_album_test.dart index fd1b8e90..018dccef 100644 --- a/app/test/use_case/add_to_album_test.dart +++ b/app/test/use_case/add_to_album_test.dart @@ -8,7 +8,7 @@ import 'package:nc_photos/entity/album/item.dart'; import 'package:nc_photos/entity/album/provider.dart'; import 'package:nc_photos/entity/album/sort_provider.dart'; import 'package:nc_photos/entity/file.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; import 'package:nc_photos/or_null.dart'; import 'package:nc_photos/pref.dart'; import 'package:nc_photos/use_case/add_to_album.dart'; diff --git a/app/test/use_case/find_file_test.dart b/app/test/use_case/find_file_test.dart index ebc4edaf..58a51a10 100644 --- a/app/test/use_case/find_file_test.dart +++ b/app/test/use_case/find_file_test.dart @@ -1,5 +1,5 @@ import 'package:nc_photos/di_container.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; import 'package:nc_photos/use_case/find_file.dart'; import 'package:test/test.dart'; diff --git a/app/test/use_case/inflate_file_descriptor_test.dart b/app/test/use_case/inflate_file_descriptor_test.dart index 71105127..02d0097f 100644 --- a/app/test/use_case/inflate_file_descriptor_test.dart +++ b/app/test/use_case/inflate_file_descriptor_test.dart @@ -1,6 +1,6 @@ import 'package:nc_photos/di_container.dart'; import 'package:nc_photos/entity/file_descriptor.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; import 'package:nc_photos/list_extension.dart'; import 'package:nc_photos/use_case/inflate_file_descriptor.dart'; import 'package:test/test.dart'; diff --git a/app/test/use_case/list_location_group_test.dart b/app/test/use_case/list_location_group_test.dart index a19189ba..35deceb2 100644 --- a/app/test/use_case/list_location_group_test.dart +++ b/app/test/use_case/list_location_group_test.dart @@ -1,6 +1,6 @@ import 'package:nc_photos/di_container.dart'; import 'package:nc_photos/entity/file.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; import 'package:nc_photos/use_case/list_location_group.dart'; import 'package:test/test.dart'; diff --git a/app/test/use_case/remove_album_test.dart b/app/test/use_case/remove_album_test.dart index 6df8a68b..24497b08 100644 --- a/app/test/use_case/remove_album_test.dart +++ b/app/test/use_case/remove_album_test.dart @@ -1,7 +1,7 @@ import 'package:event_bus/event_bus.dart'; import 'package:kiwi/kiwi.dart'; import 'package:nc_photos/di_container.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; import 'package:nc_photos/pref.dart'; import 'package:nc_photos/use_case/remove_album.dart'; import 'package:test/test.dart'; diff --git a/app/test/use_case/remove_from_album_test.dart b/app/test/use_case/remove_from_album_test.dart index e059ec55..3a0b5706 100644 --- a/app/test/use_case/remove_from_album_test.dart +++ b/app/test/use_case/remove_from_album_test.dart @@ -5,7 +5,7 @@ import 'package:nc_photos/entity/album.dart'; import 'package:nc_photos/entity/album/cover_provider.dart'; import 'package:nc_photos/entity/album/provider.dart'; import 'package:nc_photos/entity/album/sort_provider.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; import 'package:nc_photos/or_null.dart'; import 'package:nc_photos/use_case/remove_from_album.dart'; import 'package:test/test.dart'; diff --git a/app/test/use_case/remove_test.dart b/app/test/use_case/remove_test.dart index 7746fb7d..cf10e94e 100644 --- a/app/test/use_case/remove_test.dart +++ b/app/test/use_case/remove_test.dart @@ -5,7 +5,7 @@ import 'package:nc_photos/entity/album.dart'; import 'package:nc_photos/entity/album/cover_provider.dart'; import 'package:nc_photos/entity/album/provider.dart'; import 'package:nc_photos/entity/album/sort_provider.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; import 'package:nc_photos/or_null.dart'; import 'package:nc_photos/pref.dart'; import 'package:nc_photos/use_case/remove.dart'; diff --git a/app/test/use_case/scan_dir_offline_test.dart b/app/test/use_case/scan_dir_offline_test.dart index 25df8dc8..8e01fbd1 100644 --- a/app/test/use_case/scan_dir_offline_test.dart +++ b/app/test/use_case/scan_dir_offline_test.dart @@ -1,7 +1,7 @@ import 'package:nc_photos/di_container.dart'; import 'package:nc_photos/entity/file.dart'; import 'package:nc_photos/entity/file_util.dart' as file_util; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; import 'package:nc_photos/use_case/scan_dir_offline.dart'; import 'package:test/test.dart'; diff --git a/app/test/use_case/sync_favorite_test.dart b/app/test/use_case/sync_favorite_test.dart index 0df42bca..73cce347 100644 --- a/app/test/use_case/sync_favorite_test.dart +++ b/app/test/use_case/sync_favorite_test.dart @@ -3,8 +3,7 @@ import 'package:event_bus/event_bus.dart'; import 'package:kiwi/kiwi.dart'; import 'package:nc_photos/di_container.dart'; import 'package:nc_photos/entity/favorite.dart'; -import 'package:nc_photos/entity/sqlite_table.dart' as sql; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; import 'package:nc_photos/use_case/sync_favorite.dart'; import 'package:test/test.dart'; diff --git a/app/test/use_case/sync_person_test.dart b/app/test/use_case/sync_person_test.dart index b346ed65..eef1d95a 100644 --- a/app/test/use_case/sync_person_test.dart +++ b/app/test/use_case/sync_person_test.dart @@ -2,9 +2,8 @@ import 'package:drift/drift.dart' as sql; import 'package:nc_photos/di_container.dart'; import 'package:nc_photos/entity/person.dart'; import 'package:nc_photos/entity/person/data_source.dart'; -import 'package:nc_photos/entity/sqlite_table.dart' as sql; -import 'package:nc_photos/entity/sqlite_table_converter.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; +import 'package:nc_photos/entity/sqlite/type_converter.dart'; import 'package:nc_photos/use_case/sync_person.dart'; import 'package:test/test.dart'; import 'package:tuple/tuple.dart'; diff --git a/app/test/use_case/sync_tag_test.dart b/app/test/use_case/sync_tag_test.dart index f705f90e..4798a9d3 100644 --- a/app/test/use_case/sync_tag_test.dart +++ b/app/test/use_case/sync_tag_test.dart @@ -1,9 +1,8 @@ import 'package:drift/drift.dart' as sql; import 'package:nc_photos/account.dart'; import 'package:nc_photos/di_container.dart'; -import 'package:nc_photos/entity/sqlite_table.dart' as sql; -import 'package:nc_photos/entity/sqlite_table_converter.dart'; -import 'package:nc_photos/entity/sqlite_table_extension.dart' as sql; +import 'package:nc_photos/entity/sqlite/database.dart' as sql; +import 'package:nc_photos/entity/sqlite/type_converter.dart'; import 'package:nc_photos/entity/tag.dart'; import 'package:nc_photos/entity/tag/data_source.dart'; import 'package:nc_photos/use_case/sync_tag.dart';