mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 11:18:41 +00:00
improve media download handling in case of an error
This commit is contained in:
parent
fc7cb16271
commit
02045e8fc0
12 changed files with 3945 additions and 433 deletions
1
drift_schemas/twonly_database/drift_schema_v16.json
Normal file
1
drift_schemas/twonly_database/drift_schema_v16.json
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -1,43 +0,0 @@
|
|||
import 'dart:convert';
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:twonly/src/database/tables/media_download_table.dart';
|
||||
import 'package:twonly/src/database/twonly_database.dart';
|
||||
import 'package:twonly/src/utils/log.dart';
|
||||
|
||||
part 'media_downloads_dao.g.dart';
|
||||
|
||||
@DriftAccessor(tables: [MediaDownloads])
|
||||
class MediaDownloadsDao extends DatabaseAccessor<TwonlyDatabase>
|
||||
with _$MediaDownloadsDaoMixin {
|
||||
MediaDownloadsDao(super.db);
|
||||
|
||||
Future<void> updateMediaDownload(
|
||||
int messageId, MediaDownloadsCompanion updatedValues) {
|
||||
return (update(mediaDownloads)..where((c) => c.messageId.equals(messageId)))
|
||||
.write(updatedValues);
|
||||
}
|
||||
|
||||
Future<int?> insertMediaDownload(MediaDownloadsCompanion values) async {
|
||||
try {
|
||||
return await into(mediaDownloads).insert(values);
|
||||
} catch (e) {
|
||||
Log.error('Error while inserting media upload: $e');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> deleteMediaDownload(int messageId) {
|
||||
return (delete(mediaDownloads)..where((t) => t.messageId.equals(messageId)))
|
||||
.go();
|
||||
}
|
||||
|
||||
SingleOrNullSelectable<MediaDownload> getMediaDownloadById(int messageId) {
|
||||
return select(mediaDownloads)..where((t) => t.messageId.equals(messageId));
|
||||
}
|
||||
|
||||
SingleOrNullSelectable<MediaDownload> getMediaDownloadByDownloadToken(
|
||||
List<int> downloadToken) {
|
||||
return select(mediaDownloads)
|
||||
..where((t) => t.downloadToken.equals(json.encode(downloadToken)));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'media_downloads_dao.dart';
|
||||
|
||||
// ignore_for_file: type=lint
|
||||
mixin _$MediaDownloadsDaoMixin on DatabaseAccessor<TwonlyDatabase> {
|
||||
$MediaDownloadsTable get mediaDownloads => attachedDatabase.mediaDownloads;
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
import 'package:drift/drift.dart';
|
||||
import 'package:twonly/src/database/tables/media_uploads_table.dart';
|
||||
|
||||
@DataClassName('MediaDownload')
|
||||
class MediaDownloads extends Table {
|
||||
IntColumn get messageId => integer()();
|
||||
TextColumn get downloadToken => text().map(IntListTypeConverter())();
|
||||
}
|
||||
|
|
@ -3,13 +3,11 @@ import 'package:drift_flutter/drift_flutter.dart'
|
|||
show DriftNativeOptions, driftDatabase;
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:twonly/src/database/daos/contacts_dao.dart';
|
||||
import 'package:twonly/src/database/daos/media_downloads_dao.dart';
|
||||
import 'package:twonly/src/database/daos/media_uploads_dao.dart';
|
||||
import 'package:twonly/src/database/daos/message_retransmissions.dao.dart';
|
||||
import 'package:twonly/src/database/daos/messages_dao.dart';
|
||||
import 'package:twonly/src/database/daos/signal_dao.dart';
|
||||
import 'package:twonly/src/database/tables/contacts_table.dart';
|
||||
import 'package:twonly/src/database/tables/media_download_table.dart';
|
||||
import 'package:twonly/src/database/tables/media_uploads_table.dart';
|
||||
import 'package:twonly/src/database/tables/message_retransmissions.dart';
|
||||
import 'package:twonly/src/database/tables/messages_table.dart';
|
||||
|
|
@ -29,7 +27,6 @@ part 'twonly_database.g.dart';
|
|||
Contacts,
|
||||
Messages,
|
||||
MediaUploads,
|
||||
MediaDownloads,
|
||||
SignalIdentityKeyStores,
|
||||
SignalPreKeyStores,
|
||||
SignalSenderKeyStores,
|
||||
|
|
@ -41,7 +38,6 @@ part 'twonly_database.g.dart';
|
|||
MessagesDao,
|
||||
ContactsDao,
|
||||
MediaUploadsDao,
|
||||
MediaDownloadsDao,
|
||||
SignalDao,
|
||||
MessageRetransmissionDao
|
||||
])
|
||||
|
|
@ -54,7 +50,7 @@ class TwonlyDatabase extends _$TwonlyDatabase {
|
|||
TwonlyDatabase.forTesting(DatabaseConnection super.connection);
|
||||
|
||||
@override
|
||||
int get schemaVersion => 15;
|
||||
int get schemaVersion => 16;
|
||||
|
||||
static QueryExecutor _openConnection() {
|
||||
return driftDatabase(
|
||||
|
|
@ -91,7 +87,7 @@ class TwonlyDatabase extends _$TwonlyDatabase {
|
|||
));
|
||||
},
|
||||
from4To5: (m, schema) async {
|
||||
await m.createTable(mediaDownloads);
|
||||
await m.createTable(schema.mediaDownloads);
|
||||
await m.addColumn(schema.messages, schema.messages.mediaDownloadId);
|
||||
await m.addColumn(schema.messages, schema.messages.mediaUploadId);
|
||||
},
|
||||
|
|
@ -140,6 +136,9 @@ class TwonlyDatabase extends _$TwonlyDatabase {
|
|||
await m.addColumn(
|
||||
schema.messages, schema.messages.mediaRetransmissionState);
|
||||
},
|
||||
from15To16: (m, schema) async {
|
||||
await m.deleteTable('media_downloads');
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
@ -164,7 +163,6 @@ class TwonlyDatabase extends _$TwonlyDatabase {
|
|||
Future<void> deleteDataForTwonlySafe() async {
|
||||
await delete(messages).go();
|
||||
await delete(messageRetransmissions).go();
|
||||
await delete(mediaDownloads).go();
|
||||
await delete(mediaUploads).go();
|
||||
await update(contacts).write(
|
||||
const ContactsCompanion(
|
||||
|
|
|
|||
|
|
@ -2341,206 +2341,6 @@ class MediaUploadsCompanion extends UpdateCompanion<MediaUpload> {
|
|||
}
|
||||
}
|
||||
|
||||
class $MediaDownloadsTable extends MediaDownloads
|
||||
with TableInfo<$MediaDownloadsTable, MediaDownload> {
|
||||
@override
|
||||
final GeneratedDatabase attachedDatabase;
|
||||
final String? _alias;
|
||||
$MediaDownloadsTable(this.attachedDatabase, [this._alias]);
|
||||
static const VerificationMeta _messageIdMeta =
|
||||
const VerificationMeta('messageId');
|
||||
@override
|
||||
late final GeneratedColumn<int> messageId = GeneratedColumn<int>(
|
||||
'message_id', aliasedName, false,
|
||||
type: DriftSqlType.int, requiredDuringInsert: true);
|
||||
@override
|
||||
late final GeneratedColumnWithTypeConverter<List<int>, String> downloadToken =
|
||||
GeneratedColumn<String>('download_token', aliasedName, false,
|
||||
type: DriftSqlType.string, requiredDuringInsert: true)
|
||||
.withConverter<List<int>>(
|
||||
$MediaDownloadsTable.$converterdownloadToken);
|
||||
@override
|
||||
List<GeneratedColumn> get $columns => [messageId, downloadToken];
|
||||
@override
|
||||
String get aliasedName => _alias ?? actualTableName;
|
||||
@override
|
||||
String get actualTableName => $name;
|
||||
static const String $name = 'media_downloads';
|
||||
@override
|
||||
VerificationContext validateIntegrity(Insertable<MediaDownload> instance,
|
||||
{bool isInserting = false}) {
|
||||
final context = VerificationContext();
|
||||
final data = instance.toColumns(true);
|
||||
if (data.containsKey('message_id')) {
|
||||
context.handle(_messageIdMeta,
|
||||
messageId.isAcceptableOrUnknown(data['message_id']!, _messageIdMeta));
|
||||
} else if (isInserting) {
|
||||
context.missing(_messageIdMeta);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => const {};
|
||||
@override
|
||||
MediaDownload map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
|
||||
return MediaDownload(
|
||||
messageId: attachedDatabase.typeMapping
|
||||
.read(DriftSqlType.int, data['${effectivePrefix}message_id'])!,
|
||||
downloadToken: $MediaDownloadsTable.$converterdownloadToken.fromSql(
|
||||
attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.string, data['${effectivePrefix}download_token'])!),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
$MediaDownloadsTable createAlias(String alias) {
|
||||
return $MediaDownloadsTable(attachedDatabase, alias);
|
||||
}
|
||||
|
||||
static TypeConverter<List<int>, String> $converterdownloadToken =
|
||||
IntListTypeConverter();
|
||||
}
|
||||
|
||||
class MediaDownload extends DataClass implements Insertable<MediaDownload> {
|
||||
final int messageId;
|
||||
final List<int> downloadToken;
|
||||
const MediaDownload({required this.messageId, required this.downloadToken});
|
||||
@override
|
||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||
final map = <String, Expression>{};
|
||||
map['message_id'] = Variable<int>(messageId);
|
||||
{
|
||||
map['download_token'] = Variable<String>(
|
||||
$MediaDownloadsTable.$converterdownloadToken.toSql(downloadToken));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
MediaDownloadsCompanion toCompanion(bool nullToAbsent) {
|
||||
return MediaDownloadsCompanion(
|
||||
messageId: Value(messageId),
|
||||
downloadToken: Value(downloadToken),
|
||||
);
|
||||
}
|
||||
|
||||
factory MediaDownload.fromJson(Map<String, dynamic> json,
|
||||
{ValueSerializer? serializer}) {
|
||||
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||
return MediaDownload(
|
||||
messageId: serializer.fromJson<int>(json['messageId']),
|
||||
downloadToken: serializer.fromJson<List<int>>(json['downloadToken']),
|
||||
);
|
||||
}
|
||||
@override
|
||||
Map<String, dynamic> toJson({ValueSerializer? serializer}) {
|
||||
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||
return <String, dynamic>{
|
||||
'messageId': serializer.toJson<int>(messageId),
|
||||
'downloadToken': serializer.toJson<List<int>>(downloadToken),
|
||||
};
|
||||
}
|
||||
|
||||
MediaDownload copyWith({int? messageId, List<int>? downloadToken}) =>
|
||||
MediaDownload(
|
||||
messageId: messageId ?? this.messageId,
|
||||
downloadToken: downloadToken ?? this.downloadToken,
|
||||
);
|
||||
MediaDownload copyWithCompanion(MediaDownloadsCompanion data) {
|
||||
return MediaDownload(
|
||||
messageId: data.messageId.present ? data.messageId.value : this.messageId,
|
||||
downloadToken: data.downloadToken.present
|
||||
? data.downloadToken.value
|
||||
: this.downloadToken,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return (StringBuffer('MediaDownload(')
|
||||
..write('messageId: $messageId, ')
|
||||
..write('downloadToken: $downloadToken')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(messageId, downloadToken);
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
(other is MediaDownload &&
|
||||
other.messageId == this.messageId &&
|
||||
other.downloadToken == this.downloadToken);
|
||||
}
|
||||
|
||||
class MediaDownloadsCompanion extends UpdateCompanion<MediaDownload> {
|
||||
final Value<int> messageId;
|
||||
final Value<List<int>> downloadToken;
|
||||
final Value<int> rowid;
|
||||
const MediaDownloadsCompanion({
|
||||
this.messageId = const Value.absent(),
|
||||
this.downloadToken = const Value.absent(),
|
||||
this.rowid = const Value.absent(),
|
||||
});
|
||||
MediaDownloadsCompanion.insert({
|
||||
required int messageId,
|
||||
required List<int> downloadToken,
|
||||
this.rowid = const Value.absent(),
|
||||
}) : messageId = Value(messageId),
|
||||
downloadToken = Value(downloadToken);
|
||||
static Insertable<MediaDownload> custom({
|
||||
Expression<int>? messageId,
|
||||
Expression<String>? downloadToken,
|
||||
Expression<int>? rowid,
|
||||
}) {
|
||||
return RawValuesInsertable({
|
||||
if (messageId != null) 'message_id': messageId,
|
||||
if (downloadToken != null) 'download_token': downloadToken,
|
||||
if (rowid != null) 'rowid': rowid,
|
||||
});
|
||||
}
|
||||
|
||||
MediaDownloadsCompanion copyWith(
|
||||
{Value<int>? messageId,
|
||||
Value<List<int>>? downloadToken,
|
||||
Value<int>? rowid}) {
|
||||
return MediaDownloadsCompanion(
|
||||
messageId: messageId ?? this.messageId,
|
||||
downloadToken: downloadToken ?? this.downloadToken,
|
||||
rowid: rowid ?? this.rowid,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||
final map = <String, Expression>{};
|
||||
if (messageId.present) {
|
||||
map['message_id'] = Variable<int>(messageId.value);
|
||||
}
|
||||
if (downloadToken.present) {
|
||||
map['download_token'] = Variable<String>($MediaDownloadsTable
|
||||
.$converterdownloadToken
|
||||
.toSql(downloadToken.value));
|
||||
}
|
||||
if (rowid.present) {
|
||||
map['rowid'] = Variable<int>(rowid.value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return (StringBuffer('MediaDownloadsCompanion(')
|
||||
..write('messageId: $messageId, ')
|
||||
..write('downloadToken: $downloadToken, ')
|
||||
..write('rowid: $rowid')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
class $SignalIdentityKeyStoresTable extends SignalIdentityKeyStores
|
||||
with TableInfo<$SignalIdentityKeyStoresTable, SignalIdentityKeyStore> {
|
||||
@override
|
||||
|
|
@ -4568,7 +4368,6 @@ abstract class _$TwonlyDatabase extends GeneratedDatabase {
|
|||
late final $ContactsTable contacts = $ContactsTable(this);
|
||||
late final $MessagesTable messages = $MessagesTable(this);
|
||||
late final $MediaUploadsTable mediaUploads = $MediaUploadsTable(this);
|
||||
late final $MediaDownloadsTable mediaDownloads = $MediaDownloadsTable(this);
|
||||
late final $SignalIdentityKeyStoresTable signalIdentityKeyStores =
|
||||
$SignalIdentityKeyStoresTable(this);
|
||||
late final $SignalPreKeyStoresTable signalPreKeyStores =
|
||||
|
|
@ -4587,8 +4386,6 @@ abstract class _$TwonlyDatabase extends GeneratedDatabase {
|
|||
late final ContactsDao contactsDao = ContactsDao(this as TwonlyDatabase);
|
||||
late final MediaUploadsDao mediaUploadsDao =
|
||||
MediaUploadsDao(this as TwonlyDatabase);
|
||||
late final MediaDownloadsDao mediaDownloadsDao =
|
||||
MediaDownloadsDao(this as TwonlyDatabase);
|
||||
late final SignalDao signalDao = SignalDao(this as TwonlyDatabase);
|
||||
late final MessageRetransmissionDao messageRetransmissionDao =
|
||||
MessageRetransmissionDao(this as TwonlyDatabase);
|
||||
|
|
@ -4600,7 +4397,6 @@ abstract class _$TwonlyDatabase extends GeneratedDatabase {
|
|||
contacts,
|
||||
messages,
|
||||
mediaUploads,
|
||||
mediaDownloads,
|
||||
signalIdentityKeyStores,
|
||||
signalPreKeyStores,
|
||||
signalSenderKeyStores,
|
||||
|
|
@ -5999,139 +5795,6 @@ typedef $$MediaUploadsTableProcessedTableManager = ProcessedTableManager<
|
|||
),
|
||||
MediaUpload,
|
||||
PrefetchHooks Function()>;
|
||||
typedef $$MediaDownloadsTableCreateCompanionBuilder = MediaDownloadsCompanion
|
||||
Function({
|
||||
required int messageId,
|
||||
required List<int> downloadToken,
|
||||
Value<int> rowid,
|
||||
});
|
||||
typedef $$MediaDownloadsTableUpdateCompanionBuilder = MediaDownloadsCompanion
|
||||
Function({
|
||||
Value<int> messageId,
|
||||
Value<List<int>> downloadToken,
|
||||
Value<int> rowid,
|
||||
});
|
||||
|
||||
class $$MediaDownloadsTableFilterComposer
|
||||
extends Composer<_$TwonlyDatabase, $MediaDownloadsTable> {
|
||||
$$MediaDownloadsTableFilterComposer({
|
||||
required super.$db,
|
||||
required super.$table,
|
||||
super.joinBuilder,
|
||||
super.$addJoinBuilderToRootComposer,
|
||||
super.$removeJoinBuilderFromRootComposer,
|
||||
});
|
||||
ColumnFilters<int> get messageId => $composableBuilder(
|
||||
column: $table.messageId, builder: (column) => ColumnFilters(column));
|
||||
|
||||
ColumnWithTypeConverterFilters<List<int>, List<int>, String>
|
||||
get downloadToken => $composableBuilder(
|
||||
column: $table.downloadToken,
|
||||
builder: (column) => ColumnWithTypeConverterFilters(column));
|
||||
}
|
||||
|
||||
class $$MediaDownloadsTableOrderingComposer
|
||||
extends Composer<_$TwonlyDatabase, $MediaDownloadsTable> {
|
||||
$$MediaDownloadsTableOrderingComposer({
|
||||
required super.$db,
|
||||
required super.$table,
|
||||
super.joinBuilder,
|
||||
super.$addJoinBuilderToRootComposer,
|
||||
super.$removeJoinBuilderFromRootComposer,
|
||||
});
|
||||
ColumnOrderings<int> get messageId => $composableBuilder(
|
||||
column: $table.messageId, builder: (column) => ColumnOrderings(column));
|
||||
|
||||
ColumnOrderings<String> get downloadToken => $composableBuilder(
|
||||
column: $table.downloadToken,
|
||||
builder: (column) => ColumnOrderings(column));
|
||||
}
|
||||
|
||||
class $$MediaDownloadsTableAnnotationComposer
|
||||
extends Composer<_$TwonlyDatabase, $MediaDownloadsTable> {
|
||||
$$MediaDownloadsTableAnnotationComposer({
|
||||
required super.$db,
|
||||
required super.$table,
|
||||
super.joinBuilder,
|
||||
super.$addJoinBuilderToRootComposer,
|
||||
super.$removeJoinBuilderFromRootComposer,
|
||||
});
|
||||
GeneratedColumn<int> get messageId =>
|
||||
$composableBuilder(column: $table.messageId, builder: (column) => column);
|
||||
|
||||
GeneratedColumnWithTypeConverter<List<int>, String> get downloadToken =>
|
||||
$composableBuilder(
|
||||
column: $table.downloadToken, builder: (column) => column);
|
||||
}
|
||||
|
||||
class $$MediaDownloadsTableTableManager extends RootTableManager<
|
||||
_$TwonlyDatabase,
|
||||
$MediaDownloadsTable,
|
||||
MediaDownload,
|
||||
$$MediaDownloadsTableFilterComposer,
|
||||
$$MediaDownloadsTableOrderingComposer,
|
||||
$$MediaDownloadsTableAnnotationComposer,
|
||||
$$MediaDownloadsTableCreateCompanionBuilder,
|
||||
$$MediaDownloadsTableUpdateCompanionBuilder,
|
||||
(
|
||||
MediaDownload,
|
||||
BaseReferences<_$TwonlyDatabase, $MediaDownloadsTable, MediaDownload>
|
||||
),
|
||||
MediaDownload,
|
||||
PrefetchHooks Function()> {
|
||||
$$MediaDownloadsTableTableManager(
|
||||
_$TwonlyDatabase db, $MediaDownloadsTable table)
|
||||
: super(TableManagerState(
|
||||
db: db,
|
||||
table: table,
|
||||
createFilteringComposer: () =>
|
||||
$$MediaDownloadsTableFilterComposer($db: db, $table: table),
|
||||
createOrderingComposer: () =>
|
||||
$$MediaDownloadsTableOrderingComposer($db: db, $table: table),
|
||||
createComputedFieldComposer: () =>
|
||||
$$MediaDownloadsTableAnnotationComposer($db: db, $table: table),
|
||||
updateCompanionCallback: ({
|
||||
Value<int> messageId = const Value.absent(),
|
||||
Value<List<int>> downloadToken = const Value.absent(),
|
||||
Value<int> rowid = const Value.absent(),
|
||||
}) =>
|
||||
MediaDownloadsCompanion(
|
||||
messageId: messageId,
|
||||
downloadToken: downloadToken,
|
||||
rowid: rowid,
|
||||
),
|
||||
createCompanionCallback: ({
|
||||
required int messageId,
|
||||
required List<int> downloadToken,
|
||||
Value<int> rowid = const Value.absent(),
|
||||
}) =>
|
||||
MediaDownloadsCompanion.insert(
|
||||
messageId: messageId,
|
||||
downloadToken: downloadToken,
|
||||
rowid: rowid,
|
||||
),
|
||||
withReferenceMapper: (p0) => p0
|
||||
.map((e) => (e.readTable(table), BaseReferences(db, table, e)))
|
||||
.toList(),
|
||||
prefetchHooksCallback: null,
|
||||
));
|
||||
}
|
||||
|
||||
typedef $$MediaDownloadsTableProcessedTableManager = ProcessedTableManager<
|
||||
_$TwonlyDatabase,
|
||||
$MediaDownloadsTable,
|
||||
MediaDownload,
|
||||
$$MediaDownloadsTableFilterComposer,
|
||||
$$MediaDownloadsTableOrderingComposer,
|
||||
$$MediaDownloadsTableAnnotationComposer,
|
||||
$$MediaDownloadsTableCreateCompanionBuilder,
|
||||
$$MediaDownloadsTableUpdateCompanionBuilder,
|
||||
(
|
||||
MediaDownload,
|
||||
BaseReferences<_$TwonlyDatabase, $MediaDownloadsTable, MediaDownload>
|
||||
),
|
||||
MediaDownload,
|
||||
PrefetchHooks Function()>;
|
||||
typedef $$SignalIdentityKeyStoresTableCreateCompanionBuilder
|
||||
= SignalIdentityKeyStoresCompanion Function({
|
||||
required int deviceId,
|
||||
|
|
@ -7481,8 +7144,6 @@ class $TwonlyDatabaseManager {
|
|||
$$MessagesTableTableManager(_db, _db.messages);
|
||||
$$MediaUploadsTableTableManager get mediaUploads =>
|
||||
$$MediaUploadsTableTableManager(_db, _db.mediaUploads);
|
||||
$$MediaDownloadsTableTableManager get mediaDownloads =>
|
||||
$$MediaDownloadsTableTableManager(_db, _db.mediaDownloads);
|
||||
$$SignalIdentityKeyStoresTableTableManager get signalIdentityKeyStores =>
|
||||
$$SignalIdentityKeyStoresTableTableManager(
|
||||
_db, _db.signalIdentityKeyStores);
|
||||
|
|
|
|||
|
|
@ -3497,6 +3497,222 @@ class Shape20 extends i0.VersionedTable {
|
|||
columnsByName['encryption_data']! as i1.GeneratedColumn<String>;
|
||||
}
|
||||
|
||||
final class Schema16 extends i0.VersionedSchema {
|
||||
Schema16({required super.database}) : super(version: 16);
|
||||
@override
|
||||
late final List<i1.DatabaseSchemaEntity> entities = [
|
||||
contacts,
|
||||
messages,
|
||||
mediaUploads,
|
||||
signalIdentityKeyStores,
|
||||
signalPreKeyStores,
|
||||
signalSenderKeyStores,
|
||||
signalSessionStores,
|
||||
signalContactPreKeys,
|
||||
signalContactSignedPreKeys,
|
||||
messageRetransmissions,
|
||||
];
|
||||
late final Shape13 contacts = Shape13(
|
||||
source: i0.VersionedTable(
|
||||
entityName: 'contacts',
|
||||
withoutRowId: false,
|
||||
isStrict: false,
|
||||
tableConstraints: [
|
||||
'PRIMARY KEY(user_id)',
|
||||
],
|
||||
columns: [
|
||||
_column_0,
|
||||
_column_1,
|
||||
_column_2,
|
||||
_column_3,
|
||||
_column_4,
|
||||
_column_5,
|
||||
_column_6,
|
||||
_column_7,
|
||||
_column_8,
|
||||
_column_9,
|
||||
_column_39,
|
||||
_column_53,
|
||||
_column_57,
|
||||
_column_54,
|
||||
_column_40,
|
||||
_column_10,
|
||||
_column_11,
|
||||
_column_12,
|
||||
_column_13,
|
||||
_column_14,
|
||||
_column_55,
|
||||
_column_15,
|
||||
_column_16,
|
||||
],
|
||||
attachedDatabase: database,
|
||||
),
|
||||
alias: null);
|
||||
late final Shape19 messages = Shape19(
|
||||
source: i0.VersionedTable(
|
||||
entityName: 'messages',
|
||||
withoutRowId: false,
|
||||
isStrict: false,
|
||||
tableConstraints: [],
|
||||
columns: [
|
||||
_column_17,
|
||||
_column_18,
|
||||
_column_19,
|
||||
_column_48,
|
||||
_column_49,
|
||||
_column_20,
|
||||
_column_21,
|
||||
_column_22,
|
||||
_column_52,
|
||||
_column_23,
|
||||
_column_24,
|
||||
_column_25,
|
||||
_column_70,
|
||||
_column_26,
|
||||
_column_27,
|
||||
_column_28,
|
||||
_column_29,
|
||||
_column_30,
|
||||
],
|
||||
attachedDatabase: database,
|
||||
),
|
||||
alias: null);
|
||||
late final Shape20 mediaUploads = Shape20(
|
||||
source: i0.VersionedTable(
|
||||
entityName: 'media_uploads',
|
||||
withoutRowId: false,
|
||||
isStrict: false,
|
||||
tableConstraints: [],
|
||||
columns: [
|
||||
_column_41,
|
||||
_column_42,
|
||||
_column_56,
|
||||
_column_44,
|
||||
_column_45,
|
||||
],
|
||||
attachedDatabase: database,
|
||||
),
|
||||
alias: null);
|
||||
late final Shape2 signalIdentityKeyStores = Shape2(
|
||||
source: i0.VersionedTable(
|
||||
entityName: 'signal_identity_key_stores',
|
||||
withoutRowId: false,
|
||||
isStrict: false,
|
||||
tableConstraints: [
|
||||
'PRIMARY KEY(device_id, name)',
|
||||
],
|
||||
columns: [
|
||||
_column_31,
|
||||
_column_32,
|
||||
_column_33,
|
||||
_column_10,
|
||||
],
|
||||
attachedDatabase: database,
|
||||
),
|
||||
alias: null);
|
||||
late final Shape3 signalPreKeyStores = Shape3(
|
||||
source: i0.VersionedTable(
|
||||
entityName: 'signal_pre_key_stores',
|
||||
withoutRowId: false,
|
||||
isStrict: false,
|
||||
tableConstraints: [
|
||||
'PRIMARY KEY(pre_key_id)',
|
||||
],
|
||||
columns: [
|
||||
_column_34,
|
||||
_column_35,
|
||||
_column_10,
|
||||
],
|
||||
attachedDatabase: database,
|
||||
),
|
||||
alias: null);
|
||||
late final Shape4 signalSenderKeyStores = Shape4(
|
||||
source: i0.VersionedTable(
|
||||
entityName: 'signal_sender_key_stores',
|
||||
withoutRowId: false,
|
||||
isStrict: false,
|
||||
tableConstraints: [
|
||||
'PRIMARY KEY(sender_key_name)',
|
||||
],
|
||||
columns: [
|
||||
_column_36,
|
||||
_column_37,
|
||||
],
|
||||
attachedDatabase: database,
|
||||
),
|
||||
alias: null);
|
||||
late final Shape5 signalSessionStores = Shape5(
|
||||
source: i0.VersionedTable(
|
||||
entityName: 'signal_session_stores',
|
||||
withoutRowId: false,
|
||||
isStrict: false,
|
||||
tableConstraints: [
|
||||
'PRIMARY KEY(device_id, name)',
|
||||
],
|
||||
columns: [
|
||||
_column_31,
|
||||
_column_32,
|
||||
_column_38,
|
||||
_column_10,
|
||||
],
|
||||
attachedDatabase: database,
|
||||
),
|
||||
alias: null);
|
||||
late final Shape14 signalContactPreKeys = Shape14(
|
||||
source: i0.VersionedTable(
|
||||
entityName: 'signal_contact_pre_keys',
|
||||
withoutRowId: false,
|
||||
isStrict: false,
|
||||
tableConstraints: [
|
||||
'PRIMARY KEY(contact_id, pre_key_id)',
|
||||
],
|
||||
columns: [
|
||||
_column_58,
|
||||
_column_34,
|
||||
_column_35,
|
||||
_column_10,
|
||||
],
|
||||
attachedDatabase: database,
|
||||
),
|
||||
alias: null);
|
||||
late final Shape15 signalContactSignedPreKeys = Shape15(
|
||||
source: i0.VersionedTable(
|
||||
entityName: 'signal_contact_signed_pre_keys',
|
||||
withoutRowId: false,
|
||||
isStrict: false,
|
||||
tableConstraints: [
|
||||
'PRIMARY KEY(contact_id)',
|
||||
],
|
||||
columns: [
|
||||
_column_58,
|
||||
_column_59,
|
||||
_column_60,
|
||||
_column_61,
|
||||
_column_10,
|
||||
],
|
||||
attachedDatabase: database,
|
||||
),
|
||||
alias: null);
|
||||
late final Shape18 messageRetransmissions = Shape18(
|
||||
source: i0.VersionedTable(
|
||||
entityName: 'message_retransmissions',
|
||||
withoutRowId: false,
|
||||
isStrict: false,
|
||||
tableConstraints: [],
|
||||
columns: [
|
||||
_column_62,
|
||||
_column_63,
|
||||
_column_64,
|
||||
_column_65,
|
||||
_column_66,
|
||||
_column_69,
|
||||
_column_67,
|
||||
],
|
||||
attachedDatabase: database,
|
||||
),
|
||||
alias: null);
|
||||
}
|
||||
|
||||
i0.MigrationStepWithVersion migrationSteps({
|
||||
required Future<void> Function(i1.Migrator m, Schema2 schema) from1To2,
|
||||
required Future<void> Function(i1.Migrator m, Schema3 schema) from2To3,
|
||||
|
|
@ -3512,6 +3728,7 @@ i0.MigrationStepWithVersion migrationSteps({
|
|||
required Future<void> Function(i1.Migrator m, Schema13 schema) from12To13,
|
||||
required Future<void> Function(i1.Migrator m, Schema14 schema) from13To14,
|
||||
required Future<void> Function(i1.Migrator m, Schema15 schema) from14To15,
|
||||
required Future<void> Function(i1.Migrator m, Schema16 schema) from15To16,
|
||||
}) {
|
||||
return (currentVersion, database) async {
|
||||
switch (currentVersion) {
|
||||
|
|
@ -3585,6 +3802,11 @@ i0.MigrationStepWithVersion migrationSteps({
|
|||
final migrator = i1.Migrator(database, schema);
|
||||
await from14To15(migrator, schema);
|
||||
return 15;
|
||||
case 15:
|
||||
final schema = Schema16(database: database);
|
||||
final migrator = i1.Migrator(database, schema);
|
||||
await from15To16(migrator, schema);
|
||||
return 16;
|
||||
default:
|
||||
throw ArgumentError.value('Unknown migration from $currentVersion');
|
||||
}
|
||||
|
|
@ -3606,6 +3828,7 @@ i1.OnUpgrade stepByStep({
|
|||
required Future<void> Function(i1.Migrator m, Schema13 schema) from12To13,
|
||||
required Future<void> Function(i1.Migrator m, Schema14 schema) from13To14,
|
||||
required Future<void> Function(i1.Migrator m, Schema15 schema) from14To15,
|
||||
required Future<void> Function(i1.Migrator m, Schema16 schema) from15To16,
|
||||
}) =>
|
||||
i0.VersionedSchema.stepByStepHelper(
|
||||
step: migrationSteps(
|
||||
|
|
@ -3623,4 +3846,5 @@ i1.OnUpgrade stepByStep({
|
|||
from12To13: from12To13,
|
||||
from13To14: from13To14,
|
||||
from14To15: from14To15,
|
||||
from15To16: from15To16,
|
||||
));
|
||||
|
|
|
|||
|
|
@ -120,32 +120,34 @@ Future<void> handleDownloadStatusUpdateInternal(
|
|||
Mutex protectDownload = Mutex();
|
||||
|
||||
Future<void> startDownloadMedia(Message message, bool force) async {
|
||||
if (message.contentJson == null) return;
|
||||
|
||||
final content = MessageContent.fromJson(
|
||||
message.kind, jsonDecode(message.contentJson!) as Map);
|
||||
|
||||
if (content is! MediaMessageContent) return;
|
||||
if (content.downloadToken == null) return;
|
||||
|
||||
var media = await twonlyDB.mediaDownloadsDao
|
||||
.getMediaDownloadById(message.messageId)
|
||||
.getSingleOrNull();
|
||||
if (media == null) {
|
||||
await twonlyDB.mediaDownloadsDao.insertMediaDownload(
|
||||
MediaDownloadsCompanion(
|
||||
messageId: Value(message.messageId),
|
||||
downloadToken: Value(content.downloadToken!),
|
||||
),
|
||||
);
|
||||
media = await twonlyDB.mediaDownloadsDao
|
||||
.getMediaDownloadById(message.messageId)
|
||||
.getSingleOrNull();
|
||||
Log.info(
|
||||
'Download blocked for ${message.messageId} because of network state.');
|
||||
if (message.contentJson == null) {
|
||||
Log.error('Content of ${message.messageId} not found.');
|
||||
await handleMediaError(message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (media == null) return;
|
||||
final content = MessageContent.fromJson(
|
||||
message.kind,
|
||||
jsonDecode(message.contentJson!) as Map,
|
||||
);
|
||||
|
||||
if (content is! MediaMessageContent) {
|
||||
Log.error('Content of ${message.messageId} is not media file.');
|
||||
await handleMediaError(message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (content.downloadToken == null) {
|
||||
Log.error('Download token not defined for ${message.messageId}.');
|
||||
await handleMediaError(message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!force && !await isAllowedToDownload(content.isVideo)) {
|
||||
Log.warn(
|
||||
'Download blocked for ${message.messageId} because of network state.');
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -185,10 +187,10 @@ Future<void> startDownloadMedia(Message message, bool force) async {
|
|||
try {
|
||||
final task = DownloadTask(
|
||||
url: apiUrl,
|
||||
taskId: 'download_${media.messageId}',
|
||||
taskId: 'download_${message.messageId}',
|
||||
directory: 'media/received/',
|
||||
baseDirectory: BaseDirectory.applicationSupport,
|
||||
filename: '${media.messageId}.encrypted',
|
||||
filename: '${message.messageId}.encrypted',
|
||||
priority: 0,
|
||||
retries: 10,
|
||||
);
|
||||
|
|
@ -198,7 +200,7 @@ Future<void> startDownloadMedia(Message message, bool force) async {
|
|||
);
|
||||
|
||||
try {
|
||||
await downloadFileFast(media.messageId, apiUrl);
|
||||
await downloadFileFast(message.messageId, apiUrl);
|
||||
} catch (e) {
|
||||
Log.error('Fast download failed: $e');
|
||||
await FileDownloader().enqueue(task);
|
||||
|
|
|
|||
|
|
@ -555,8 +555,9 @@ Future<void> handleMediaUpload(MediaUpload media) async {
|
|||
timestamp: media.metadata!.messageSendAt,
|
||||
);
|
||||
|
||||
final plaintextContent =
|
||||
Uint8List.fromList(gzip.encode(utf8.encode(jsonEncode(msg.toJson()))));
|
||||
final plaintextContent = Uint8List.fromList(
|
||||
gzip.encode(utf8.encode(jsonEncode(msg.toJson()))),
|
||||
);
|
||||
|
||||
final contact = await twonlyDB.contactsDao
|
||||
.getContactByUserId(message.contactId)
|
||||
|
|
|
|||
|
|
@ -398,9 +398,12 @@ Future<client.Response> handleNewMessage(int fromUserId, Uint8List body) async {
|
|||
);
|
||||
|
||||
if (messageId == null) {
|
||||
Log.error('could not insert message into db');
|
||||
return client.Response()..error = ErrorCode.InternalError;
|
||||
}
|
||||
|
||||
Log.info('Inserted a new message with id: $messageId');
|
||||
|
||||
if (message.kind == MessageKind.media) {
|
||||
await twonlyDB.contactsDao.incFlameCounter(
|
||||
fromUserId,
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import 'schema_v12.dart' as v12;
|
|||
import 'schema_v13.dart' as v13;
|
||||
import 'schema_v14.dart' as v14;
|
||||
import 'schema_v15.dart' as v15;
|
||||
import 'schema_v16.dart' as v16;
|
||||
|
||||
class GeneratedHelper implements SchemaInstantiationHelper {
|
||||
@override
|
||||
|
|
@ -53,6 +54,8 @@ class GeneratedHelper implements SchemaInstantiationHelper {
|
|||
return v14.DatabaseAtV14(db);
|
||||
case 15:
|
||||
return v15.DatabaseAtV15(db);
|
||||
case 16:
|
||||
return v16.DatabaseAtV16(db);
|
||||
default:
|
||||
throw MissingSchemaException(version, versions);
|
||||
}
|
||||
|
|
@ -73,6 +76,7 @@ class GeneratedHelper implements SchemaInstantiationHelper {
|
|||
12,
|
||||
13,
|
||||
14,
|
||||
15
|
||||
15,
|
||||
16
|
||||
];
|
||||
}
|
||||
|
|
|
|||
3677
test/drift/twonly_database/generated/schema_v16.dart
Normal file
3677
test/drift/twonly_database/generated/schema_v16.dart
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue