mirror of
https://github.com/openfoodfacts/smooth-app.git
synced 2025-08-26 11:16:45 +08:00
chore: Migration to Dart 3.8 (#6668)
* Migration to Dart 3.8 * New GA * Fix dartdoc
This commit is contained in:
@ -36,7 +36,8 @@ class BulkManager {
|
||||
}
|
||||
if (parameters.length % numCols != 0) {
|
||||
throw Exception(
|
||||
'Parameter list size (${parameters.length}) cannot be divided by $numCols');
|
||||
'Parameter list size (${parameters.length}) cannot be divided by $numCols',
|
||||
);
|
||||
}
|
||||
final String variables = '?${',?' * (columnNames.length - 1)}';
|
||||
final int maxSlice = (SQLITE_MAX_VARIABLE_NUMBER ~/ numCols) * numCols;
|
||||
|
@ -46,30 +46,32 @@ class DaoOsmLocation extends AbstractSqlDao {
|
||||
final int newVersion,
|
||||
) async {
|
||||
if (oldVersion < 6) {
|
||||
await db.execute('create table $_table('
|
||||
' $_columnId INT NOT NULL'
|
||||
',$_columnType TEXT NOT NULL'
|
||||
',$_columnLongitude REAL NOT NULL'
|
||||
',$_columnLatitude REAL NOT NULL'
|
||||
',$_columnName TEXT'
|
||||
',$_columnStreet TEXT'
|
||||
',$_columnCity TEXT'
|
||||
',$_columnPostCode TEXT'
|
||||
',$_columnCountry TEXT'
|
||||
',$_columnCountryCode TEXT'
|
||||
',$_columnLastAccess INT NOT NULL'
|
||||
// cf. https://www.sqlite.org/lang_conflict.html
|
||||
',PRIMARY KEY($_columnId,$_columnType) on conflict replace'
|
||||
')');
|
||||
await db.execute(
|
||||
'create table $_table('
|
||||
' $_columnId INT NOT NULL'
|
||||
',$_columnType TEXT NOT NULL'
|
||||
',$_columnLongitude REAL NOT NULL'
|
||||
',$_columnLatitude REAL NOT NULL'
|
||||
',$_columnName TEXT'
|
||||
',$_columnStreet TEXT'
|
||||
',$_columnCity TEXT'
|
||||
',$_columnPostCode TEXT'
|
||||
',$_columnCountry TEXT'
|
||||
',$_columnCountryCode TEXT'
|
||||
',$_columnLastAccess INT NOT NULL'
|
||||
// cf. https://www.sqlite.org/lang_conflict.html
|
||||
',PRIMARY KEY($_columnId,$_columnType) on conflict replace'
|
||||
')',
|
||||
);
|
||||
}
|
||||
|
||||
/// Not brilliant, but for historical reasons we have to catch that here.
|
||||
bool isDuplicateColumnException(
|
||||
final DatabaseException e,
|
||||
final String column,
|
||||
) =>
|
||||
e.toString().startsWith(
|
||||
'DatabaseException(duplicate column name: $column (code 1 SQLITE_ERROR');
|
||||
) => e.toString().startsWith(
|
||||
'DatabaseException(duplicate column name: $column (code 1 SQLITE_ERROR',
|
||||
);
|
||||
|
||||
if (oldVersion < 7) {
|
||||
try {
|
||||
@ -80,8 +82,9 @@ class DaoOsmLocation extends AbstractSqlDao {
|
||||
}
|
||||
}
|
||||
try {
|
||||
await db
|
||||
.execute('alter table $_table add column $_columnOsmValue TEXT');
|
||||
await db.execute(
|
||||
'alter table $_table add column $_columnOsmValue TEXT',
|
||||
);
|
||||
} on DatabaseException catch (e) {
|
||||
if (!isDuplicateColumnException(e, _columnOsmValue)) {
|
||||
rethrow;
|
||||
@ -101,12 +104,8 @@ class DaoOsmLocation extends AbstractSqlDao {
|
||||
/// Returns all the [OsmLocation]s, ordered by descending last access.
|
||||
Future<List<OsmLocation>> getAll() async {
|
||||
final List<OsmLocation> result = <OsmLocation>[];
|
||||
final List<Map<String, dynamic>> queryResults =
|
||||
await localDatabase.database.query(
|
||||
_table,
|
||||
columns: _columns,
|
||||
orderBy: '$_columnLastAccess DESC',
|
||||
);
|
||||
final List<Map<String, dynamic>> queryResults = await localDatabase.database
|
||||
.query(_table, columns: _columns, orderBy: '$_columnLastAccess DESC');
|
||||
for (final Map<String, dynamic> row in queryResults) {
|
||||
final OsmLocation? item = _getItemFromQueryResult(row);
|
||||
if (item != null) {
|
||||
@ -117,28 +116,26 @@ class DaoOsmLocation extends AbstractSqlDao {
|
||||
}
|
||||
|
||||
Future<int> put(final OsmLocation osmLocation) async =>
|
||||
localDatabase.database.insert(
|
||||
_table,
|
||||
<String, Object?>{
|
||||
_columnId: osmLocation.osmId,
|
||||
_columnType: osmLocation.osmType.offTag,
|
||||
_columnLongitude: osmLocation.longitude,
|
||||
_columnLatitude: osmLocation.latitude,
|
||||
_columnName: osmLocation.name,
|
||||
_columnStreet: osmLocation.street,
|
||||
_columnCity: osmLocation.city,
|
||||
_columnPostCode: osmLocation.postcode,
|
||||
_columnCountry: osmLocation.country,
|
||||
_columnCountryCode: osmLocation.countryCode,
|
||||
_columnOsmKey: osmLocation.osmKey,
|
||||
_columnOsmValue: osmLocation.osmValue,
|
||||
_columnLastAccess: LocalDatabase.nowInMillis(),
|
||||
},
|
||||
);
|
||||
localDatabase.database.insert(_table, <String, Object?>{
|
||||
_columnId: osmLocation.osmId,
|
||||
_columnType: osmLocation.osmType.offTag,
|
||||
_columnLongitude: osmLocation.longitude,
|
||||
_columnLatitude: osmLocation.latitude,
|
||||
_columnName: osmLocation.name,
|
||||
_columnStreet: osmLocation.street,
|
||||
_columnCity: osmLocation.city,
|
||||
_columnPostCode: osmLocation.postcode,
|
||||
_columnCountry: osmLocation.country,
|
||||
_columnCountryCode: osmLocation.countryCode,
|
||||
_columnOsmKey: osmLocation.osmKey,
|
||||
_columnOsmValue: osmLocation.osmValue,
|
||||
_columnLastAccess: LocalDatabase.nowInMillis(),
|
||||
});
|
||||
|
||||
OsmLocation? _getItemFromQueryResult(final Map<String, dynamic> row) {
|
||||
final LocationOSMType? type =
|
||||
LocationOSMType.fromOffTag(row[_columnType] as String);
|
||||
final LocationOSMType? type = LocationOSMType.fromOffTag(
|
||||
row[_columnType] as String,
|
||||
);
|
||||
if (type == null) {
|
||||
// very very unlikely
|
||||
return null;
|
||||
|
@ -35,28 +35,32 @@ class DaoProduct extends AbstractSqlDao implements BulkDeletable {
|
||||
final int newVersion,
|
||||
) async {
|
||||
if (oldVersion < 2) {
|
||||
await db.execute('create table $_TABLE_PRODUCT('
|
||||
// cf. https://www.sqlite.org/lang_conflict.html
|
||||
'$_TABLE_PRODUCT_COLUMN_BARCODE TEXT PRIMARY KEY on conflict replace'
|
||||
',$_TABLE_PRODUCT_COLUMN_GZIPPED_JSON BLOB NOT NULL'
|
||||
',$_TABLE_PRODUCT_COLUMN_LAST_UPDATE INT NOT NULL'
|
||||
')');
|
||||
await db.execute(
|
||||
'create table $_TABLE_PRODUCT('
|
||||
// cf. https://www.sqlite.org/lang_conflict.html
|
||||
'$_TABLE_PRODUCT_COLUMN_BARCODE TEXT PRIMARY KEY on conflict replace'
|
||||
',$_TABLE_PRODUCT_COLUMN_GZIPPED_JSON BLOB NOT NULL'
|
||||
',$_TABLE_PRODUCT_COLUMN_LAST_UPDATE INT NOT NULL'
|
||||
')',
|
||||
);
|
||||
}
|
||||
if (oldVersion < 4) {
|
||||
await db.execute('alter table $_TABLE_PRODUCT add column '
|
||||
'$_TABLE_PRODUCT_COLUMN_LANGUAGE TEXT');
|
||||
await db.execute(
|
||||
'alter table $_TABLE_PRODUCT add column '
|
||||
'$_TABLE_PRODUCT_COLUMN_LANGUAGE TEXT',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the [Product] that matches the [barcode], or null.
|
||||
Future<Product?> get(final String barcode) async {
|
||||
final List<Map<String, dynamic>> queryResults =
|
||||
await localDatabase.database.query(
|
||||
_TABLE_PRODUCT,
|
||||
columns: _columns,
|
||||
where: '$_TABLE_PRODUCT_COLUMN_BARCODE = ?',
|
||||
whereArgs: <String>[barcode],
|
||||
);
|
||||
final List<Map<String, dynamic>> queryResults = await localDatabase.database
|
||||
.query(
|
||||
_TABLE_PRODUCT,
|
||||
columns: _columns,
|
||||
where: '$_TABLE_PRODUCT_COLUMN_BARCODE = ?',
|
||||
whereArgs: <String>[barcode],
|
||||
);
|
||||
// O or 1 row expected
|
||||
for (final Map<String, dynamic> row in queryResults) {
|
||||
return _getProductFromQueryResult(row);
|
||||
@ -70,20 +74,23 @@ class DaoProduct extends AbstractSqlDao implements BulkDeletable {
|
||||
if (barcodes.isEmpty) {
|
||||
return result;
|
||||
}
|
||||
for (int start = 0;
|
||||
start < barcodes.length;
|
||||
start += BulkManager.SQLITE_MAX_VARIABLE_NUMBER) {
|
||||
for (
|
||||
int start = 0;
|
||||
start < barcodes.length;
|
||||
start += BulkManager.SQLITE_MAX_VARIABLE_NUMBER
|
||||
) {
|
||||
final int size = min(
|
||||
barcodes.length - start,
|
||||
BulkManager.SQLITE_MAX_VARIABLE_NUMBER,
|
||||
);
|
||||
final List<Map<String, dynamic>> queryResults =
|
||||
await localDatabase.database.query(
|
||||
_TABLE_PRODUCT,
|
||||
columns: _columns,
|
||||
where: '$_TABLE_PRODUCT_COLUMN_BARCODE in(? ${',?' * (size - 1)})',
|
||||
whereArgs: barcodes.sublist(start, start + size),
|
||||
);
|
||||
final List<Map<String, dynamic>> queryResults = await localDatabase
|
||||
.database
|
||||
.query(
|
||||
_TABLE_PRODUCT,
|
||||
columns: _columns,
|
||||
where: '$_TABLE_PRODUCT_COLUMN_BARCODE in(? ${',?' * (size - 1)})',
|
||||
whereArgs: barcodes.sublist(start, start + size),
|
||||
);
|
||||
for (final Map<String, dynamic> row in queryResults) {
|
||||
result[row[_TABLE_PRODUCT_COLUMN_BARCODE] as String] =
|
||||
_getProductFromQueryResult(row);
|
||||
@ -100,20 +107,23 @@ class DaoProduct extends AbstractSqlDao implements BulkDeletable {
|
||||
if (barcodes.isEmpty) {
|
||||
return result;
|
||||
}
|
||||
for (int start = 0;
|
||||
start < barcodes.length;
|
||||
start += BulkManager.SQLITE_MAX_VARIABLE_NUMBER) {
|
||||
for (
|
||||
int start = 0;
|
||||
start < barcodes.length;
|
||||
start += BulkManager.SQLITE_MAX_VARIABLE_NUMBER
|
||||
) {
|
||||
final int size = min(
|
||||
barcodes.length - start,
|
||||
BulkManager.SQLITE_MAX_VARIABLE_NUMBER,
|
||||
);
|
||||
final List<Map<String, dynamic>> queryResults =
|
||||
await localDatabase.database.query(
|
||||
_TABLE_PRODUCT,
|
||||
columns: _columns,
|
||||
where: '$_TABLE_PRODUCT_COLUMN_BARCODE in(? ${',?' * (size - 1)})',
|
||||
whereArgs: barcodes.sublist(start, start + size),
|
||||
);
|
||||
final List<Map<String, dynamic>> queryResults = await localDatabase
|
||||
.database
|
||||
.query(
|
||||
_TABLE_PRODUCT,
|
||||
columns: _columns,
|
||||
where: '$_TABLE_PRODUCT_COLUMN_BARCODE in(? ${',?' * (size - 1)})',
|
||||
whereArgs: barcodes.sublist(start, start + size),
|
||||
);
|
||||
for (final Map<String, dynamic> row in queryResults) {
|
||||
final Product product = _getProductFromQueryResult(row);
|
||||
final ProductType productType = product.productType ?? ProductType.food;
|
||||
@ -133,11 +143,8 @@ class DaoProduct extends AbstractSqlDao implements BulkDeletable {
|
||||
final String Function(Product) splitFunction,
|
||||
) async {
|
||||
final Map<String, List<String>> result = <String, List<String>>{};
|
||||
final List<Map<String, dynamic>> queryResults =
|
||||
await localDatabase.database.query(
|
||||
_TABLE_PRODUCT,
|
||||
columns: _columns,
|
||||
);
|
||||
final List<Map<String, dynamic>> queryResults = await localDatabase.database
|
||||
.query(_TABLE_PRODUCT, columns: _columns);
|
||||
for (final Map<String, dynamic> row in queryResults) {
|
||||
final Product product = _getProductFromQueryResult(row);
|
||||
final String splitValue = splitFunction(product);
|
||||
@ -155,12 +162,7 @@ class DaoProduct extends AbstractSqlDao implements BulkDeletable {
|
||||
final Product product,
|
||||
final OpenFoodFactsLanguage language, {
|
||||
required final ProductType productType,
|
||||
}) async =>
|
||||
putAll(
|
||||
<Product>[product],
|
||||
language,
|
||||
productType: productType,
|
||||
);
|
||||
}) async => putAll(<Product>[product], language, productType: productType);
|
||||
|
||||
/// Replaces products in database
|
||||
Future<void> putAll(
|
||||
@ -174,23 +176,18 @@ class DaoProduct extends AbstractSqlDao implements BulkDeletable {
|
||||
product.productType ??= productType;
|
||||
}
|
||||
await localDatabase.database.transaction(
|
||||
(final Transaction transaction) async => _bulkReplaceLoop(
|
||||
transaction,
|
||||
products,
|
||||
language,
|
||||
),
|
||||
(final Transaction transaction) async =>
|
||||
_bulkReplaceLoop(transaction, products, language),
|
||||
);
|
||||
}
|
||||
|
||||
Future<List<String>> getAllKeys() async {
|
||||
final List<String> result = <String>[];
|
||||
final List<Map<String, dynamic>> queryResults =
|
||||
await localDatabase.database.query(
|
||||
_TABLE_PRODUCT,
|
||||
columns: <String>[
|
||||
_TABLE_PRODUCT_COLUMN_BARCODE,
|
||||
],
|
||||
);
|
||||
final List<Map<String, dynamic>> queryResults = await localDatabase.database
|
||||
.query(
|
||||
_TABLE_PRODUCT,
|
||||
columns: <String>[_TABLE_PRODUCT_COLUMN_BARCODE],
|
||||
);
|
||||
if (queryResults.isEmpty) {
|
||||
return result;
|
||||
}
|
||||
@ -271,19 +268,20 @@ class DaoProduct extends AbstractSqlDao implements BulkDeletable {
|
||||
if (!verbose) {
|
||||
return;
|
||||
}
|
||||
final List<Map<String, dynamic>> queryResults =
|
||||
await localDatabase.database.rawQuery(
|
||||
'select'
|
||||
' $_TABLE_PRODUCT_COLUMN_BARCODE'
|
||||
', length($_TABLE_PRODUCT_COLUMN_GZIPPED_JSON) as mylength'
|
||||
' from $_TABLE_PRODUCT',
|
||||
);
|
||||
final List<Map<String, dynamic>> queryResults = await localDatabase.database
|
||||
.rawQuery(
|
||||
'select'
|
||||
' $_TABLE_PRODUCT_COLUMN_BARCODE'
|
||||
', length($_TABLE_PRODUCT_COLUMN_GZIPPED_JSON) as mylength'
|
||||
' from $_TABLE_PRODUCT',
|
||||
);
|
||||
debugPrint('Product by product');
|
||||
debugPrint('barcode;gzipped;string;factor');
|
||||
for (final Map<String, dynamic> row in queryResults) {
|
||||
final String barcode = row[_TABLE_PRODUCT_COLUMN_BARCODE] as String;
|
||||
final int asString =
|
||||
utf8.encode(jsonEncode(map[barcode]!.toJson())).length;
|
||||
final int asString = utf8
|
||||
.encode(jsonEncode(map[barcode]!.toJson()))
|
||||
.length;
|
||||
final int asZipped = row['mylength'] as int;
|
||||
final double factor = (asString * 1.0) / asZipped;
|
||||
debugPrint('$barcode;$asZipped;$asString;$factor');
|
||||
@ -293,11 +291,8 @@ class DaoProduct extends AbstractSqlDao implements BulkDeletable {
|
||||
/// Get the total number of products in the database
|
||||
Future<Map<ProductType, int>> getTotalNoOfProducts() async {
|
||||
final Map<ProductType, int> result = <ProductType, int>{};
|
||||
final List<Map<String, dynamic>> queryResults =
|
||||
await localDatabase.database.query(
|
||||
_TABLE_PRODUCT,
|
||||
columns: _columns,
|
||||
);
|
||||
final List<Map<String, dynamic>> queryResults = await localDatabase.database
|
||||
.query(_TABLE_PRODUCT, columns: _columns);
|
||||
for (final Map<String, dynamic> row in queryResults) {
|
||||
final Product product = _getProductFromQueryResult(row);
|
||||
final ProductType productType = product.productType ?? ProductType.food;
|
||||
@ -349,7 +344,8 @@ class DaoProduct extends AbstractSqlDao implements BulkDeletable {
|
||||
|
||||
const String tableJoin =
|
||||
'p.$_TABLE_PRODUCT_COLUMN_BARCODE = a.${DaoProductLastAccess.COLUMN_BARCODE}';
|
||||
final String languageCondition = ' ('
|
||||
final String languageCondition =
|
||||
' ('
|
||||
'p.$_TABLE_PRODUCT_COLUMN_LANGUAGE is null '
|
||||
"or p.$_TABLE_PRODUCT_COLUMN_LANGUAGE != '${language.offTag}'"
|
||||
') ';
|
||||
@ -385,11 +381,8 @@ class DaoProduct extends AbstractSqlDao implements BulkDeletable {
|
||||
for (final String query in queries) {
|
||||
// optimization: using a cursor, as we don't want all the rows,
|
||||
// and we don't know how many rows we'll need.
|
||||
final QueryCursor queryCursor =
|
||||
await localDatabase.database.rawQueryCursor(
|
||||
query,
|
||||
null,
|
||||
);
|
||||
final QueryCursor queryCursor = await localDatabase.database
|
||||
.rawQueryCursor(query, null);
|
||||
while (await queryCursor.moveNext()) {
|
||||
final Product product = _getProductFromQueryResult(queryCursor.current);
|
||||
final String barcode = product.barcode!;
|
||||
@ -416,7 +409,7 @@ class DaoProduct extends AbstractSqlDao implements BulkDeletable {
|
||||
/// with a language null or different from the current app language", and use
|
||||
/// the same mechanism as "switch language and refresh products accordingly".
|
||||
Future<int> clearAllLanguages() async => localDatabase.database.update(
|
||||
_TABLE_PRODUCT,
|
||||
<String, Object?>{_TABLE_PRODUCT_COLUMN_LANGUAGE: null},
|
||||
);
|
||||
_TABLE_PRODUCT,
|
||||
<String, Object?>{_TABLE_PRODUCT_COLUMN_LANGUAGE: null},
|
||||
);
|
||||
}
|
||||
|
@ -17,11 +17,13 @@ class DaoProductLastAccess extends AbstractSqlDao {
|
||||
final int newVersion,
|
||||
) async {
|
||||
if (oldVersion < 5) {
|
||||
await db.execute('create table $TABLE('
|
||||
// cf. https://www.sqlite.org/lang_conflict.html
|
||||
'$COLUMN_BARCODE TEXT PRIMARY KEY on conflict replace'
|
||||
',$COLUMN_LAST_ACCESS INT NOT NULL'
|
||||
')');
|
||||
await db.execute(
|
||||
'create table $TABLE('
|
||||
// cf. https://www.sqlite.org/lang_conflict.html
|
||||
'$COLUMN_BARCODE TEXT PRIMARY KEY on conflict replace'
|
||||
',$COLUMN_LAST_ACCESS INT NOT NULL'
|
||||
')',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,10 +31,7 @@ class DaoProductLastAccess extends AbstractSqlDao {
|
||||
localDatabase.database.rawInsert(
|
||||
'insert into $TABLE($COLUMN_BARCODE, $COLUMN_LAST_ACCESS) '
|
||||
'values(?, ?)',
|
||||
<Object>[
|
||||
barcode,
|
||||
LocalDatabase.nowInMillis(),
|
||||
],
|
||||
<Object>[barcode, LocalDatabase.nowInMillis()],
|
||||
);
|
||||
|
||||
/// Delete all items from the database
|
||||
|
@ -13,25 +13,17 @@ const int _uselessTotalSizeValue = 0;
|
||||
|
||||
/// An immutable barcode list; e.g. my search yesterday about "Nutella"
|
||||
class _BarcodeList {
|
||||
const _BarcodeList(
|
||||
this.timestamp,
|
||||
this.barcodes,
|
||||
this.totalSize,
|
||||
);
|
||||
const _BarcodeList(this.timestamp, this.barcodes, this.totalSize);
|
||||
|
||||
_BarcodeList.now(final List<String> barcodes)
|
||||
: this(
|
||||
LocalDatabase.nowInMillis(),
|
||||
barcodes,
|
||||
_uselessTotalSizeValue,
|
||||
);
|
||||
: this(LocalDatabase.nowInMillis(), barcodes, _uselessTotalSizeValue);
|
||||
|
||||
_BarcodeList.fromProductList(final ProductList productList)
|
||||
: this(
|
||||
LocalDatabase.nowInMillis(),
|
||||
productList.barcodes,
|
||||
productList.totalSize,
|
||||
);
|
||||
: this(
|
||||
LocalDatabase.nowInMillis(),
|
||||
productList.barcodes,
|
||||
productList.totalSize,
|
||||
);
|
||||
|
||||
/// Freshness indicator: last time the list was updated.
|
||||
///
|
||||
@ -186,10 +178,7 @@ class DaoProductList extends AbstractDao {
|
||||
/// One barcode duplicate is potentially removed:
|
||||
/// * If the barcode was already there, it's moved to the end of the list.
|
||||
/// * If the barcode wasn't there, it's added to the end of the list.
|
||||
Future<void> push(
|
||||
final ProductList productList,
|
||||
final String barcode,
|
||||
) async {
|
||||
Future<void> push(final ProductList productList, final String barcode) async {
|
||||
final _BarcodeList? list = await _get(productList);
|
||||
final List<String> barcodes;
|
||||
if (list == null) {
|
||||
|
@ -23,24 +23,26 @@ class DaoWorkBarcode extends AbstractSqlDao {
|
||||
final int newVersion,
|
||||
) async {
|
||||
if (oldVersion < 3) {
|
||||
await db.execute('create table $_table('
|
||||
'$_columnWork TEXT NOT NULL'
|
||||
',$_columnBarcode TEXT NOT NULL'
|
||||
// cf. https://www.sqlite.org/lang_conflict.html
|
||||
',PRIMARY KEY($_columnWork,$_columnBarcode) on conflict replace'
|
||||
')');
|
||||
await db.execute(
|
||||
'create table $_table('
|
||||
'$_columnWork TEXT NOT NULL'
|
||||
',$_columnBarcode TEXT NOT NULL'
|
||||
// cf. https://www.sqlite.org/lang_conflict.html
|
||||
',PRIMARY KEY($_columnWork,$_columnBarcode) on conflict replace'
|
||||
')',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the number of barcodes for that work.
|
||||
Future<int> getCount(final String work) async {
|
||||
final List<Map<String, dynamic>> queryResults =
|
||||
await localDatabase.database.query(
|
||||
_table,
|
||||
columns: <String>['count(1) as my_count'],
|
||||
where: '$_columnWork = ?',
|
||||
whereArgs: <String>[work],
|
||||
);
|
||||
final List<Map<String, dynamic>> queryResults = await localDatabase.database
|
||||
.query(
|
||||
_table,
|
||||
columns: <String>['count(1) as my_count'],
|
||||
where: '$_columnWork = ?',
|
||||
whereArgs: <String>[work],
|
||||
);
|
||||
for (final Map<String, dynamic> row in queryResults) {
|
||||
return row['my_count'] as int;
|
||||
}
|
||||
@ -53,14 +55,14 @@ class DaoWorkBarcode extends AbstractSqlDao {
|
||||
final int pageSize,
|
||||
) async {
|
||||
final List<String> result = <String>[];
|
||||
final List<Map<String, dynamic>> queryResults =
|
||||
await localDatabase.database.query(
|
||||
_table,
|
||||
columns: <String>[_columnBarcode],
|
||||
where: '$_columnWork = ?',
|
||||
whereArgs: <String>[work],
|
||||
limit: pageSize,
|
||||
);
|
||||
final List<Map<String, dynamic>> queryResults = await localDatabase.database
|
||||
.query(
|
||||
_table,
|
||||
columns: <String>[_columnBarcode],
|
||||
where: '$_columnWork = ?',
|
||||
whereArgs: <String>[work],
|
||||
limit: pageSize,
|
||||
);
|
||||
for (final Map<String, dynamic> row in queryResults) {
|
||||
result.add(row[_columnBarcode] as String);
|
||||
}
|
||||
@ -71,11 +73,10 @@ class DaoWorkBarcode extends AbstractSqlDao {
|
||||
Future<int> putAll(
|
||||
final String work,
|
||||
final Iterable<String> barcodes,
|
||||
) async =>
|
||||
localDatabase.database.transaction(
|
||||
(final Transaction transaction) async =>
|
||||
_bulkInsert(transaction, work, barcodes),
|
||||
);
|
||||
) async => localDatabase.database.transaction(
|
||||
(final Transaction transaction) async =>
|
||||
_bulkInsert(transaction, work, barcodes),
|
||||
);
|
||||
|
||||
/// Returns the number of inserted rows by optimized bulk insert.
|
||||
Future<int> _bulkInsert(
|
||||
@ -117,12 +118,8 @@ class DaoWorkBarcode extends AbstractSqlDao {
|
||||
/// Deletes all barcodes for a given work.
|
||||
///
|
||||
/// Returns the number of rows deleted.
|
||||
Future<int> deleteWork(final String work) async =>
|
||||
localDatabase.database.delete(
|
||||
_table,
|
||||
where: '$_columnWork = ?',
|
||||
whereArgs: <String>[work],
|
||||
);
|
||||
Future<int> deleteWork(final String work) async => localDatabase.database
|
||||
.delete(_table, where: '$_columnWork = ?', whereArgs: <String>[work]);
|
||||
|
||||
/// Deletes all barcodes for a given work.
|
||||
///
|
||||
@ -130,11 +127,10 @@ class DaoWorkBarcode extends AbstractSqlDao {
|
||||
Future<int> deleteBarcodes(
|
||||
final String work,
|
||||
final Iterable<String> barcodes,
|
||||
) async =>
|
||||
localDatabase.database.transaction(
|
||||
(final Transaction transaction) async =>
|
||||
_bulkDelete(transaction, work, barcodes),
|
||||
);
|
||||
) async => localDatabase.database.transaction(
|
||||
(final Transaction transaction) async =>
|
||||
_bulkDelete(transaction, work, barcodes),
|
||||
);
|
||||
|
||||
/// Returns the number of deleted rows by optimized bulk delete.
|
||||
Future<int> _bulkDelete(
|
||||
@ -154,7 +150,8 @@ class DaoWorkBarcode extends AbstractSqlDao {
|
||||
}
|
||||
final int deleted = await databaseExecutor.delete(
|
||||
_table,
|
||||
where: '$_columnWork = ? '
|
||||
where:
|
||||
'$_columnWork = ? '
|
||||
'and $_columnBarcode in(?${',?' * (parameters.length - 2)})',
|
||||
whereArgs: parameters,
|
||||
);
|
||||
|
@ -22,8 +22,8 @@ class TransientFile {
|
||||
this.barcode,
|
||||
this.language, [
|
||||
this.uploadedDate,
|
||||
]) : imageField = productImageData.imageField,
|
||||
url = productImageData.imageUrl;
|
||||
]) : imageField = productImageData.imageField,
|
||||
url = productImageData.imageUrl;
|
||||
|
||||
factory TransientFile.fromProduct(
|
||||
final Product product,
|
||||
@ -60,18 +60,13 @@ class TransientFile {
|
||||
static final Map<String, String> _transientFiles = <String, String>{};
|
||||
|
||||
/// Stores locally [file] as a transient image for [imageField] and [barcode].
|
||||
void putImage(
|
||||
final LocalDatabase localDatabase,
|
||||
final File file,
|
||||
) {
|
||||
void putImage(final LocalDatabase localDatabase, final File file) {
|
||||
_transientFiles[_getImageKey()] = file.path;
|
||||
localDatabase.notifyListeners();
|
||||
}
|
||||
|
||||
/// Removes the current transient image for [imageField] and [barcode].
|
||||
void removeImage(
|
||||
final LocalDatabase localDatabase,
|
||||
) {
|
||||
void removeImage(final LocalDatabase localDatabase) {
|
||||
_transientFiles.remove(_getImageKey());
|
||||
localDatabase.notifyListeners();
|
||||
}
|
||||
@ -93,8 +88,7 @@ class TransientFile {
|
||||
static String _getImageKeyPrefix(
|
||||
final ImageField imageField,
|
||||
final String barcode,
|
||||
) =>
|
||||
'$barcode;$imageField;';
|
||||
) => '$barcode;$imageField;';
|
||||
|
||||
/// Returns a way to display the image, either locally or from the server.
|
||||
ImageProvider? getImageProvider() {
|
||||
|
Reference in New Issue
Block a user