🗃️ Local keypair db

This commit is contained in:
LittleSheep 2025-03-03 21:31:41 +08:00
parent 4f47cd2c0c
commit 56711889ab
15 changed files with 1757 additions and 43 deletions

View File

@ -4,4 +4,8 @@ targets:
json_serializable:
options:
explicit_to_json: true
field_rename: snake
field_rename: snake
drift_dev:
options:
databases:
my_database: lib/database/database.dart

View File

@ -0,0 +1 @@
{"_meta":{"description":"This file contains a serialized version of schema entities for drift.","version":"1.2.0"},"options":{"store_date_time_values_as_text":false},"entities":[{"id":0,"references":[],"type":"table","data":{"name":"sn_local_chat_channel","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","dialectAwareDefaultConstraints":{"sqlite":"PRIMARY KEY AUTOINCREMENT"},"default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment"]},{"name":"alias","getter_name":"alias","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"content","getter_name":"content","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const SnChannelConverter()","dart_type_name":"SnChannel"}},{"name":"created_at","getter_name":"createdAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')","default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":false,"constraints":[]}},{"id":1,"references":[],"type":"table","data":{"name":"sn_local_chat_message","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","dialectAwareDefaultConstraints":{"sqlite":"PRIMARY KEY AUTOINCREMENT"},"default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment"]},{"name":"channel_id","getter_name":"channelId","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"content","getter_name":"content","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const SnMessageConverter()","dart_type_name":"SnChatMessage"}},{"name":"created_at","getter_name":"createdAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')","default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":false,"constraints":[]}}]}

View File

@ -0,0 +1 @@
{"_meta":{"description":"This file contains a serialized version of schema entities for drift.","version":"1.2.0"},"options":{"store_date_time_values_as_text":false},"entities":[{"id":0,"references":[],"type":"table","data":{"name":"sn_local_chat_channel","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","dialectAwareDefaultConstraints":{"sqlite":"PRIMARY KEY AUTOINCREMENT"},"default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment"]},{"name":"alias","getter_name":"alias","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"content","getter_name":"content","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const SnChannelConverter()","dart_type_name":"SnChannel"}},{"name":"created_at","getter_name":"createdAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')","default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":false,"constraints":[]}},{"id":1,"references":[],"type":"table","data":{"name":"sn_local_chat_message","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","dialectAwareDefaultConstraints":{"sqlite":"PRIMARY KEY AUTOINCREMENT"},"default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment"]},{"name":"channel_id","getter_name":"channelId","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"content","getter_name":"content","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const SnMessageConverter()","dart_type_name":"SnChatMessage"}},{"name":"created_at","getter_name":"createdAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')","default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":false,"constraints":[]}},{"id":2,"references":[],"type":"table","data":{"name":"sn_local_key_pair","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"account_id","getter_name":"accountId","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"public_key","getter_name":"publicKey","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"private_key","getter_name":"privateKey","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":false,"constraints":[]}}]}

View File

@ -2,16 +2,18 @@ import 'package:drift/drift.dart';
import 'package:drift_flutter/drift_flutter.dart';
import 'package:path_provider/path_provider.dart';
import 'package:surface/database/chat.dart';
import 'package:surface/database/database.steps.dart';
import 'package:surface/database/keypair.dart';
import 'package:surface/types/chat.dart';
part 'database.g.dart';
@DriftDatabase(tables: [SnLocalChatChannel, SnLocalChatMessage])
@DriftDatabase(tables: [SnLocalChatChannel, SnLocalChatMessage, SnLocalKeyPair])
class AppDatabase extends _$AppDatabase {
AppDatabase() : super(_openConnection());
AppDatabase([QueryExecutor? e]) : super(e ?? _openConnection());
@override
int get schemaVersion => 1;
int get schemaVersion => 2;
static QueryExecutor _openConnection() {
return driftDatabase(
@ -25,4 +27,13 @@ class AppDatabase extends _$AppDatabase {
),
);
}
@override
MigrationStrategy get migration {
return MigrationStrategy(
onUpgrade: stepByStep(from1To2: (m, schema) async {
// Nothing else to do here
}),
);
}
}

View File

@ -0,0 +1,154 @@
// dart format width=80
import 'package:drift/internal/versioned_schema.dart' as i0;
import 'package:drift/drift.dart' as i1;
import 'package:drift/drift.dart'; // ignore_for_file: type=lint,unused_import
// GENERATED BY drift_dev, DO NOT MODIFY.
final class Schema2 extends i0.VersionedSchema {
Schema2({required super.database}) : super(version: 2);
@override
late final List<i1.DatabaseSchemaEntity> entities = [
snLocalChatChannel,
snLocalChatMessage,
snLocalKeyPair,
];
late final Shape0 snLocalChatChannel = Shape0(
source: i0.VersionedTable(
entityName: 'sn_local_chat_channel',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_1,
_column_2,
_column_3,
],
attachedDatabase: database,
),
alias: null);
late final Shape1 snLocalChatMessage = Shape1(
source: i0.VersionedTable(
entityName: 'sn_local_chat_message',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_4,
_column_2,
_column_3,
],
attachedDatabase: database,
),
alias: null);
late final Shape2 snLocalKeyPair = Shape2(
source: i0.VersionedTable(
entityName: 'sn_local_key_pair',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_5,
_column_6,
_column_7,
_column_8,
],
attachedDatabase: database,
),
alias: null);
}
class Shape0 extends i0.VersionedTable {
Shape0({required super.source, required super.alias}) : super.aliased();
i1.GeneratedColumn<int> get id =>
columnsByName['id']! as i1.GeneratedColumn<int>;
i1.GeneratedColumn<String> get alias =>
columnsByName['alias']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get content =>
columnsByName['content']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<DateTime> get createdAt =>
columnsByName['created_at']! as i1.GeneratedColumn<DateTime>;
}
i1.GeneratedColumn<int> _column_0(String aliasedName) =>
i1.GeneratedColumn<int>('id', aliasedName, false,
hasAutoIncrement: true,
type: i1.DriftSqlType.int,
defaultConstraints:
i1.GeneratedColumn.constraintIsAlways('PRIMARY KEY AUTOINCREMENT'));
i1.GeneratedColumn<String> _column_1(String aliasedName) =>
i1.GeneratedColumn<String>('alias', aliasedName, false,
type: i1.DriftSqlType.string);
i1.GeneratedColumn<String> _column_2(String aliasedName) =>
i1.GeneratedColumn<String>('content', aliasedName, false,
type: i1.DriftSqlType.string);
i1.GeneratedColumn<DateTime> _column_3(String aliasedName) =>
i1.GeneratedColumn<DateTime>('created_at', aliasedName, false,
type: i1.DriftSqlType.dateTime,
defaultValue: const CustomExpression(
'CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER)'));
class Shape1 extends i0.VersionedTable {
Shape1({required super.source, required super.alias}) : super.aliased();
i1.GeneratedColumn<int> get id =>
columnsByName['id']! as i1.GeneratedColumn<int>;
i1.GeneratedColumn<int> get channelId =>
columnsByName['channel_id']! as i1.GeneratedColumn<int>;
i1.GeneratedColumn<String> get content =>
columnsByName['content']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<DateTime> get createdAt =>
columnsByName['created_at']! as i1.GeneratedColumn<DateTime>;
}
i1.GeneratedColumn<int> _column_4(String aliasedName) =>
i1.GeneratedColumn<int>('channel_id', aliasedName, false,
type: i1.DriftSqlType.int);
class Shape2 extends i0.VersionedTable {
Shape2({required super.source, required super.alias}) : super.aliased();
i1.GeneratedColumn<String> get id =>
columnsByName['id']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<int> get accountId =>
columnsByName['account_id']! as i1.GeneratedColumn<int>;
i1.GeneratedColumn<String> get publicKey =>
columnsByName['public_key']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get privateKey =>
columnsByName['private_key']! as i1.GeneratedColumn<String>;
}
i1.GeneratedColumn<String> _column_5(String aliasedName) =>
i1.GeneratedColumn<String>('id', aliasedName, false,
type: i1.DriftSqlType.string);
i1.GeneratedColumn<int> _column_6(String aliasedName) =>
i1.GeneratedColumn<int>('account_id', aliasedName, false,
type: i1.DriftSqlType.int);
i1.GeneratedColumn<String> _column_7(String aliasedName) =>
i1.GeneratedColumn<String>('public_key', aliasedName, false,
type: i1.DriftSqlType.string);
i1.GeneratedColumn<String> _column_8(String aliasedName) =>
i1.GeneratedColumn<String>('private_key', aliasedName, true,
type: i1.DriftSqlType.string);
i0.MigrationStepWithVersion migrationSteps({
required Future<void> Function(i1.Migrator m, Schema2 schema) from1To2,
}) {
return (currentVersion, database) async {
switch (currentVersion) {
case 1:
final schema = Schema2(database: database);
final migrator = i1.Migrator(database, schema);
await from1To2(migrator, schema);
return 2;
default:
throw ArgumentError.value('Unknown migration from $currentVersion');
}
};
}
i1.OnUpgrade stepByStep({
required Future<void> Function(i1.Migrator m, Schema2 schema) from1To2,
}) =>
i0.VersionedSchema.stepByStepHelper(
step: migrationSteps(
from1To2: from1To2,
));

39
lib/database/keypair.dart Normal file
View File

@ -0,0 +1,39 @@
import 'dart:convert';
import 'package:drift/drift.dart';
import 'package:surface/types/keypair.dart';
class SnKeyPairConverter extends TypeConverter<SnKeyPair, String>
with JsonTypeConverter2<SnKeyPair, String, Map<String, Object?>> {
const SnKeyPairConverter();
@override
SnKeyPair fromSql(String fromDb) {
return fromJson(jsonDecode(fromDb) as Map<String, dynamic>);
}
@override
String toSql(SnKeyPair value) {
return jsonEncode(toJson(value));
}
@override
SnKeyPair fromJson(Map<String, Object?> json) {
return SnKeyPair.fromJson(json);
}
@override
Map<String, Object?> toJson(SnKeyPair value) {
return value.toJson();
}
}
class SnLocalKeyPair extends Table {
TextColumn get id => text()();
IntColumn get accountId => integer()();
TextColumn get publicKey => text()();
TextColumn get privateKey => text().nullable()();
}

View File

@ -138,6 +138,7 @@ class _ProfileEditScreenState extends State<ProfileEditScreen> {
rawBytes = await image.readAsBytes();
}
if (!mounted) return;
final attach = context.read<SnAttachmentProvider>();
try {

View File

@ -68,16 +68,19 @@ class _AccountPublisherEditScreenState extends State<AccountPublisherEditScreen>
setState(() => _isBusy = true);
try {
await sn.client.put('/cgi/co/publishers/${widget.name}', data: {
'avatar': _avatar,
'banner': _banner,
'nick': _nickController.text,
'name': _nameController.text,
'description': _descriptionController.text,
});
await sn.client.put(
'/cgi/co/publishers/${widget.name}',
data: {
'avatar': _avatar,
'banner': _banner,
'nick': _nickController.text,
'name': _nameController.text,
'description': _descriptionController.text,
},
);
if (mounted) Navigator.pop(context, true);
} catch (err) {
if(mounted) context.showErrorDialog(err);
if (mounted) context.showErrorDialog(err);
} finally {
setState(() => _isBusy = false);
}
@ -114,21 +117,21 @@ class _AccountPublisherEditScreenState extends State<AccountPublisherEditScreen>
if (!skipCrop) {
final ImageProvider imageProvider = kIsWeb ? NetworkImage(image.path) : FileImage(File(image.path));
final aspectRatios =
place == 'banner' ? [CropAspectRatio(width: 16, height: 7)] : [CropAspectRatio(width: 1, height: 1)];
place == 'banner' ? [CropAspectRatio(width: 16, height: 7)] : [CropAspectRatio(width: 1, height: 1)];
final result =
(!kIsWeb && (Platform.isIOS || Platform.isMacOS))
? await showCupertinoImageCropper(
// ignore: use_build_context_synchronously
context,
allowedAspectRatios: aspectRatios,
imageProvider: imageProvider,
)
: await showMaterialImageCropper(
// ignore: use_build_context_synchronously
context,
allowedAspectRatios: aspectRatios,
imageProvider: imageProvider,
);
(!kIsWeb && (Platform.isIOS || Platform.isMacOS))
? await showCupertinoImageCropper(
// ignore: use_build_context_synchronously
context,
allowedAspectRatios: aspectRatios,
imageProvider: imageProvider,
)
: await showMaterialImageCropper(
// ignore: use_build_context_synchronously
context,
allowedAspectRatios: aspectRatios,
imageProvider: imageProvider,
);
if (result == null) return;
@ -141,6 +144,7 @@ class _AccountPublisherEditScreenState extends State<AccountPublisherEditScreen>
rawBytes = await image.readAsBytes();
}
if (!mounted) return;
final attach = context.read<SnAttachmentProvider>();
try {
@ -187,10 +191,7 @@ class _AccountPublisherEditScreenState extends State<AccountPublisherEditScreen>
final sn = context.read<SnNetworkProvider>();
return AppScaffold(
appBar: AppBar(
leading: PageBackButton(),
title: Text('screenAccountPublisherEdit').tr(),
),
appBar: AppBar(leading: PageBackButton(), title: Text('screenAccountPublisherEdit').tr()),
body: SingleChildScrollView(
child: Column(
children: [
@ -208,12 +209,10 @@ class _AccountPublisherEditScreenState extends State<AccountPublisherEditScreen>
aspectRatio: 16 / 9,
child: Container(
color: Theme.of(context).colorScheme.surfaceContainerHigh,
child: _banner != null
? AutoResizeUniversalImage(
sn.getAttachmentUrl(_banner!),
fit: BoxFit.cover,
)
: const SizedBox.shrink(),
child:
_banner != null
? AutoResizeUniversalImage(sn.getAttachmentUrl(_banner!), fit: BoxFit.cover)
: const SizedBox.shrink(),
),
),
),
@ -251,9 +250,7 @@ class _AccountPublisherEditScreenState extends State<AccountPublisherEditScreen>
const Gap(4),
TextField(
controller: _nickController,
decoration: InputDecoration(
labelText: 'fieldNickname'.tr(),
),
decoration: InputDecoration(labelText: 'fieldNickname'.tr()),
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
),
const Gap(4),
@ -261,9 +258,7 @@ class _AccountPublisherEditScreenState extends State<AccountPublisherEditScreen>
controller: _descriptionController,
maxLines: null,
minLines: 3,
decoration: InputDecoration(
labelText: 'fieldDescription'.tr(),
),
decoration: InputDecoration(labelText: 'fieldDescription'.tr()),
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
),
const Gap(12),
@ -284,7 +279,7 @@ class _AccountPublisherEditScreenState extends State<AccountPublisherEditScreen>
icon: const Icon(Symbols.save),
),
],
)
),
],
).padding(horizontal: 24, vertical: 12),
),

16
lib/types/keypair.dart Normal file
View File

@ -0,0 +1,16 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'keypair.freezed.dart';
part 'keypair.g.dart';
@freezed
abstract class SnKeyPair with _$SnKeyPair {
const factory SnKeyPair({
required String id,
required int accountId,
required String publicKey,
String? privateKey,
}) = _SnKeyPair;
factory SnKeyPair.fromJson(Map<String, Object?> json) => _$SnKeyPairFromJson(json);
}

View File

@ -0,0 +1,213 @@
// dart format width=80
// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
part of 'keypair.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$SnKeyPair {
String get id;
int get accountId;
String get publicKey;
String? get privateKey;
/// Create a copy of SnKeyPair
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$SnKeyPairCopyWith<SnKeyPair> get copyWith =>
_$SnKeyPairCopyWithImpl<SnKeyPair>(this as SnKeyPair, _$identity);
/// Serializes this SnKeyPair to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is SnKeyPair &&
(identical(other.id, id) || other.id == id) &&
(identical(other.accountId, accountId) ||
other.accountId == accountId) &&
(identical(other.publicKey, publicKey) ||
other.publicKey == publicKey) &&
(identical(other.privateKey, privateKey) ||
other.privateKey == privateKey));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode =>
Object.hash(runtimeType, id, accountId, publicKey, privateKey);
@override
String toString() {
return 'SnKeyPair(id: $id, accountId: $accountId, publicKey: $publicKey, privateKey: $privateKey)';
}
}
/// @nodoc
abstract mixin class $SnKeyPairCopyWith<$Res> {
factory $SnKeyPairCopyWith(SnKeyPair value, $Res Function(SnKeyPair) _then) =
_$SnKeyPairCopyWithImpl;
@useResult
$Res call({String id, int accountId, String publicKey, String? privateKey});
}
/// @nodoc
class _$SnKeyPairCopyWithImpl<$Res> implements $SnKeyPairCopyWith<$Res> {
_$SnKeyPairCopyWithImpl(this._self, this._then);
final SnKeyPair _self;
final $Res Function(SnKeyPair) _then;
/// Create a copy of SnKeyPair
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? id = null,
Object? accountId = null,
Object? publicKey = null,
Object? privateKey = freezed,
}) {
return _then(_self.copyWith(
id: null == id
? _self.id
: id // ignore: cast_nullable_to_non_nullable
as String,
accountId: null == accountId
? _self.accountId
: accountId // ignore: cast_nullable_to_non_nullable
as int,
publicKey: null == publicKey
? _self.publicKey
: publicKey // ignore: cast_nullable_to_non_nullable
as String,
privateKey: freezed == privateKey
? _self.privateKey
: privateKey // ignore: cast_nullable_to_non_nullable
as String?,
));
}
}
/// @nodoc
@JsonSerializable()
class _SnKeyPair implements SnKeyPair {
const _SnKeyPair(
{required this.id,
required this.accountId,
required this.publicKey,
this.privateKey});
factory _SnKeyPair.fromJson(Map<String, dynamic> json) =>
_$SnKeyPairFromJson(json);
@override
final String id;
@override
final int accountId;
@override
final String publicKey;
@override
final String? privateKey;
/// Create a copy of SnKeyPair
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$SnKeyPairCopyWith<_SnKeyPair> get copyWith =>
__$SnKeyPairCopyWithImpl<_SnKeyPair>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$SnKeyPairToJson(
this,
);
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _SnKeyPair &&
(identical(other.id, id) || other.id == id) &&
(identical(other.accountId, accountId) ||
other.accountId == accountId) &&
(identical(other.publicKey, publicKey) ||
other.publicKey == publicKey) &&
(identical(other.privateKey, privateKey) ||
other.privateKey == privateKey));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode =>
Object.hash(runtimeType, id, accountId, publicKey, privateKey);
@override
String toString() {
return 'SnKeyPair(id: $id, accountId: $accountId, publicKey: $publicKey, privateKey: $privateKey)';
}
}
/// @nodoc
abstract mixin class _$SnKeyPairCopyWith<$Res>
implements $SnKeyPairCopyWith<$Res> {
factory _$SnKeyPairCopyWith(
_SnKeyPair value, $Res Function(_SnKeyPair) _then) =
__$SnKeyPairCopyWithImpl;
@override
@useResult
$Res call({String id, int accountId, String publicKey, String? privateKey});
}
/// @nodoc
class __$SnKeyPairCopyWithImpl<$Res> implements _$SnKeyPairCopyWith<$Res> {
__$SnKeyPairCopyWithImpl(this._self, this._then);
final _SnKeyPair _self;
final $Res Function(_SnKeyPair) _then;
/// Create a copy of SnKeyPair
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$Res call({
Object? id = null,
Object? accountId = null,
Object? publicKey = null,
Object? privateKey = freezed,
}) {
return _then(_SnKeyPair(
id: null == id
? _self.id
: id // ignore: cast_nullable_to_non_nullable
as String,
accountId: null == accountId
? _self.accountId
: accountId // ignore: cast_nullable_to_non_nullable
as int,
publicKey: null == publicKey
? _self.publicKey
: publicKey // ignore: cast_nullable_to_non_nullable
as String,
privateKey: freezed == privateKey
? _self.privateKey
: privateKey // ignore: cast_nullable_to_non_nullable
as String?,
));
}
}
// dart format on

22
lib/types/keypair.g.dart Normal file
View File

@ -0,0 +1,22 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'keypair.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_SnKeyPair _$SnKeyPairFromJson(Map<String, dynamic> json) => _SnKeyPair(
id: json['id'] as String,
accountId: (json['account_id'] as num).toInt(),
publicKey: json['public_key'] as String,
privateKey: json['private_key'] as String?,
);
Map<String, dynamic> _$SnKeyPairToJson(_SnKeyPair instance) =>
<String, dynamic>{
'id': instance.id,
'account_id': instance.accountId,
'public_key': instance.publicKey,
'private_key': instance.privateKey,
};

View File

@ -0,0 +1,23 @@
// dart format width=80
// GENERATED CODE, DO NOT EDIT BY HAND.
// ignore_for_file: type=lint
import 'package:drift/drift.dart';
import 'package:drift/internal/migrations.dart';
import 'schema_v1.dart' as v1;
import 'schema_v2.dart' as v2;
class GeneratedHelper implements SchemaInstantiationHelper {
@override
GeneratedDatabase databaseForVersion(QueryExecutor db, int version) {
switch (version) {
case 1:
return v1.DatabaseAtV1(db);
case 2:
return v2.DatabaseAtV2(db);
default:
throw MissingSchemaException(version, versions);
}
}
static const versions = const [1, 2];
}

View File

@ -0,0 +1,462 @@
// dart format width=80
// GENERATED CODE, DO NOT EDIT BY HAND.
// ignore_for_file: type=lint
import 'package:drift/drift.dart';
class SnLocalChatChannel extends Table
with TableInfo<SnLocalChatChannel, SnLocalChatChannelData> {
@override
final GeneratedDatabase attachedDatabase;
final String? _alias;
SnLocalChatChannel(this.attachedDatabase, [this._alias]);
late final GeneratedColumn<int> id = GeneratedColumn<int>(
'id', aliasedName, false,
hasAutoIncrement: true,
type: DriftSqlType.int,
requiredDuringInsert: false,
defaultConstraints:
GeneratedColumn.constraintIsAlways('PRIMARY KEY AUTOINCREMENT'));
late final GeneratedColumn<String> alias = GeneratedColumn<String>(
'alias', aliasedName, false,
type: DriftSqlType.string, requiredDuringInsert: true);
late final GeneratedColumn<String> content = GeneratedColumn<String>(
'content', aliasedName, false,
type: DriftSqlType.string, requiredDuringInsert: true);
late final GeneratedColumn<DateTime> createdAt = GeneratedColumn<DateTime>(
'created_at', aliasedName, false,
type: DriftSqlType.dateTime,
requiredDuringInsert: false,
defaultValue: const CustomExpression(
'CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER)'));
@override
List<GeneratedColumn> get $columns => [id, alias, content, createdAt];
@override
String get aliasedName => _alias ?? actualTableName;
@override
String get actualTableName => $name;
static const String $name = 'sn_local_chat_channel';
@override
Set<GeneratedColumn> get $primaryKey => {id};
@override
SnLocalChatChannelData map(Map<String, dynamic> data, {String? tablePrefix}) {
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return SnLocalChatChannelData(
id: attachedDatabase.typeMapping
.read(DriftSqlType.int, data['${effectivePrefix}id'])!,
alias: attachedDatabase.typeMapping
.read(DriftSqlType.string, data['${effectivePrefix}alias'])!,
content: attachedDatabase.typeMapping
.read(DriftSqlType.string, data['${effectivePrefix}content'])!,
createdAt: attachedDatabase.typeMapping
.read(DriftSqlType.dateTime, data['${effectivePrefix}created_at'])!,
);
}
@override
SnLocalChatChannel createAlias(String alias) {
return SnLocalChatChannel(attachedDatabase, alias);
}
}
class SnLocalChatChannelData extends DataClass
implements Insertable<SnLocalChatChannelData> {
final int id;
final String alias;
final String content;
final DateTime createdAt;
const SnLocalChatChannelData(
{required this.id,
required this.alias,
required this.content,
required this.createdAt});
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
map['id'] = Variable<int>(id);
map['alias'] = Variable<String>(alias);
map['content'] = Variable<String>(content);
map['created_at'] = Variable<DateTime>(createdAt);
return map;
}
SnLocalChatChannelCompanion toCompanion(bool nullToAbsent) {
return SnLocalChatChannelCompanion(
id: Value(id),
alias: Value(alias),
content: Value(content),
createdAt: Value(createdAt),
);
}
factory SnLocalChatChannelData.fromJson(Map<String, dynamic> json,
{ValueSerializer? serializer}) {
serializer ??= driftRuntimeOptions.defaultSerializer;
return SnLocalChatChannelData(
id: serializer.fromJson<int>(json['id']),
alias: serializer.fromJson<String>(json['alias']),
content: serializer.fromJson<String>(json['content']),
createdAt: serializer.fromJson<DateTime>(json['createdAt']),
);
}
@override
Map<String, dynamic> toJson({ValueSerializer? serializer}) {
serializer ??= driftRuntimeOptions.defaultSerializer;
return <String, dynamic>{
'id': serializer.toJson<int>(id),
'alias': serializer.toJson<String>(alias),
'content': serializer.toJson<String>(content),
'createdAt': serializer.toJson<DateTime>(createdAt),
};
}
SnLocalChatChannelData copyWith(
{int? id, String? alias, String? content, DateTime? createdAt}) =>
SnLocalChatChannelData(
id: id ?? this.id,
alias: alias ?? this.alias,
content: content ?? this.content,
createdAt: createdAt ?? this.createdAt,
);
SnLocalChatChannelData copyWithCompanion(SnLocalChatChannelCompanion data) {
return SnLocalChatChannelData(
id: data.id.present ? data.id.value : this.id,
alias: data.alias.present ? data.alias.value : this.alias,
content: data.content.present ? data.content.value : this.content,
createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt,
);
}
@override
String toString() {
return (StringBuffer('SnLocalChatChannelData(')
..write('id: $id, ')
..write('alias: $alias, ')
..write('content: $content, ')
..write('createdAt: $createdAt')
..write(')'))
.toString();
}
@override
int get hashCode => Object.hash(id, alias, content, createdAt);
@override
bool operator ==(Object other) =>
identical(this, other) ||
(other is SnLocalChatChannelData &&
other.id == this.id &&
other.alias == this.alias &&
other.content == this.content &&
other.createdAt == this.createdAt);
}
class SnLocalChatChannelCompanion
extends UpdateCompanion<SnLocalChatChannelData> {
final Value<int> id;
final Value<String> alias;
final Value<String> content;
final Value<DateTime> createdAt;
const SnLocalChatChannelCompanion({
this.id = const Value.absent(),
this.alias = const Value.absent(),
this.content = const Value.absent(),
this.createdAt = const Value.absent(),
});
SnLocalChatChannelCompanion.insert({
this.id = const Value.absent(),
required String alias,
required String content,
this.createdAt = const Value.absent(),
}) : alias = Value(alias),
content = Value(content);
static Insertable<SnLocalChatChannelData> custom({
Expression<int>? id,
Expression<String>? alias,
Expression<String>? content,
Expression<DateTime>? createdAt,
}) {
return RawValuesInsertable({
if (id != null) 'id': id,
if (alias != null) 'alias': alias,
if (content != null) 'content': content,
if (createdAt != null) 'created_at': createdAt,
});
}
SnLocalChatChannelCompanion copyWith(
{Value<int>? id,
Value<String>? alias,
Value<String>? content,
Value<DateTime>? createdAt}) {
return SnLocalChatChannelCompanion(
id: id ?? this.id,
alias: alias ?? this.alias,
content: content ?? this.content,
createdAt: createdAt ?? this.createdAt,
);
}
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
if (id.present) {
map['id'] = Variable<int>(id.value);
}
if (alias.present) {
map['alias'] = Variable<String>(alias.value);
}
if (content.present) {
map['content'] = Variable<String>(content.value);
}
if (createdAt.present) {
map['created_at'] = Variable<DateTime>(createdAt.value);
}
return map;
}
@override
String toString() {
return (StringBuffer('SnLocalChatChannelCompanion(')
..write('id: $id, ')
..write('alias: $alias, ')
..write('content: $content, ')
..write('createdAt: $createdAt')
..write(')'))
.toString();
}
}
class SnLocalChatMessage extends Table
with TableInfo<SnLocalChatMessage, SnLocalChatMessageData> {
@override
final GeneratedDatabase attachedDatabase;
final String? _alias;
SnLocalChatMessage(this.attachedDatabase, [this._alias]);
late final GeneratedColumn<int> id = GeneratedColumn<int>(
'id', aliasedName, false,
hasAutoIncrement: true,
type: DriftSqlType.int,
requiredDuringInsert: false,
defaultConstraints:
GeneratedColumn.constraintIsAlways('PRIMARY KEY AUTOINCREMENT'));
late final GeneratedColumn<int> channelId = GeneratedColumn<int>(
'channel_id', aliasedName, false,
type: DriftSqlType.int, requiredDuringInsert: true);
late final GeneratedColumn<String> content = GeneratedColumn<String>(
'content', aliasedName, false,
type: DriftSqlType.string, requiredDuringInsert: true);
late final GeneratedColumn<DateTime> createdAt = GeneratedColumn<DateTime>(
'created_at', aliasedName, false,
type: DriftSqlType.dateTime,
requiredDuringInsert: false,
defaultValue: const CustomExpression(
'CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER)'));
@override
List<GeneratedColumn> get $columns => [id, channelId, content, createdAt];
@override
String get aliasedName => _alias ?? actualTableName;
@override
String get actualTableName => $name;
static const String $name = 'sn_local_chat_message';
@override
Set<GeneratedColumn> get $primaryKey => {id};
@override
SnLocalChatMessageData map(Map<String, dynamic> data, {String? tablePrefix}) {
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return SnLocalChatMessageData(
id: attachedDatabase.typeMapping
.read(DriftSqlType.int, data['${effectivePrefix}id'])!,
channelId: attachedDatabase.typeMapping
.read(DriftSqlType.int, data['${effectivePrefix}channel_id'])!,
content: attachedDatabase.typeMapping
.read(DriftSqlType.string, data['${effectivePrefix}content'])!,
createdAt: attachedDatabase.typeMapping
.read(DriftSqlType.dateTime, data['${effectivePrefix}created_at'])!,
);
}
@override
SnLocalChatMessage createAlias(String alias) {
return SnLocalChatMessage(attachedDatabase, alias);
}
}
class SnLocalChatMessageData extends DataClass
implements Insertable<SnLocalChatMessageData> {
final int id;
final int channelId;
final String content;
final DateTime createdAt;
const SnLocalChatMessageData(
{required this.id,
required this.channelId,
required this.content,
required this.createdAt});
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
map['id'] = Variable<int>(id);
map['channel_id'] = Variable<int>(channelId);
map['content'] = Variable<String>(content);
map['created_at'] = Variable<DateTime>(createdAt);
return map;
}
SnLocalChatMessageCompanion toCompanion(bool nullToAbsent) {
return SnLocalChatMessageCompanion(
id: Value(id),
channelId: Value(channelId),
content: Value(content),
createdAt: Value(createdAt),
);
}
factory SnLocalChatMessageData.fromJson(Map<String, dynamic> json,
{ValueSerializer? serializer}) {
serializer ??= driftRuntimeOptions.defaultSerializer;
return SnLocalChatMessageData(
id: serializer.fromJson<int>(json['id']),
channelId: serializer.fromJson<int>(json['channelId']),
content: serializer.fromJson<String>(json['content']),
createdAt: serializer.fromJson<DateTime>(json['createdAt']),
);
}
@override
Map<String, dynamic> toJson({ValueSerializer? serializer}) {
serializer ??= driftRuntimeOptions.defaultSerializer;
return <String, dynamic>{
'id': serializer.toJson<int>(id),
'channelId': serializer.toJson<int>(channelId),
'content': serializer.toJson<String>(content),
'createdAt': serializer.toJson<DateTime>(createdAt),
};
}
SnLocalChatMessageData copyWith(
{int? id, int? channelId, String? content, DateTime? createdAt}) =>
SnLocalChatMessageData(
id: id ?? this.id,
channelId: channelId ?? this.channelId,
content: content ?? this.content,
createdAt: createdAt ?? this.createdAt,
);
SnLocalChatMessageData copyWithCompanion(SnLocalChatMessageCompanion data) {
return SnLocalChatMessageData(
id: data.id.present ? data.id.value : this.id,
channelId: data.channelId.present ? data.channelId.value : this.channelId,
content: data.content.present ? data.content.value : this.content,
createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt,
);
}
@override
String toString() {
return (StringBuffer('SnLocalChatMessageData(')
..write('id: $id, ')
..write('channelId: $channelId, ')
..write('content: $content, ')
..write('createdAt: $createdAt')
..write(')'))
.toString();
}
@override
int get hashCode => Object.hash(id, channelId, content, createdAt);
@override
bool operator ==(Object other) =>
identical(this, other) ||
(other is SnLocalChatMessageData &&
other.id == this.id &&
other.channelId == this.channelId &&
other.content == this.content &&
other.createdAt == this.createdAt);
}
class SnLocalChatMessageCompanion
extends UpdateCompanion<SnLocalChatMessageData> {
final Value<int> id;
final Value<int> channelId;
final Value<String> content;
final Value<DateTime> createdAt;
const SnLocalChatMessageCompanion({
this.id = const Value.absent(),
this.channelId = const Value.absent(),
this.content = const Value.absent(),
this.createdAt = const Value.absent(),
});
SnLocalChatMessageCompanion.insert({
this.id = const Value.absent(),
required int channelId,
required String content,
this.createdAt = const Value.absent(),
}) : channelId = Value(channelId),
content = Value(content);
static Insertable<SnLocalChatMessageData> custom({
Expression<int>? id,
Expression<int>? channelId,
Expression<String>? content,
Expression<DateTime>? createdAt,
}) {
return RawValuesInsertable({
if (id != null) 'id': id,
if (channelId != null) 'channel_id': channelId,
if (content != null) 'content': content,
if (createdAt != null) 'created_at': createdAt,
});
}
SnLocalChatMessageCompanion copyWith(
{Value<int>? id,
Value<int>? channelId,
Value<String>? content,
Value<DateTime>? createdAt}) {
return SnLocalChatMessageCompanion(
id: id ?? this.id,
channelId: channelId ?? this.channelId,
content: content ?? this.content,
createdAt: createdAt ?? this.createdAt,
);
}
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
if (id.present) {
map['id'] = Variable<int>(id.value);
}
if (channelId.present) {
map['channel_id'] = Variable<int>(channelId.value);
}
if (content.present) {
map['content'] = Variable<String>(content.value);
}
if (createdAt.present) {
map['created_at'] = Variable<DateTime>(createdAt.value);
}
return map;
}
@override
String toString() {
return (StringBuffer('SnLocalChatMessageCompanion(')
..write('id: $id, ')
..write('channelId: $channelId, ')
..write('content: $content, ')
..write('createdAt: $createdAt')
..write(')'))
.toString();
}
}
class DatabaseAtV1 extends GeneratedDatabase {
DatabaseAtV1(QueryExecutor e) : super(e);
late final SnLocalChatChannel snLocalChatChannel = SnLocalChatChannel(this);
late final SnLocalChatMessage snLocalChatMessage = SnLocalChatMessage(this);
@override
Iterable<TableInfo<Table, Object?>> get allTables =>
allSchemaEntities.whereType<TableInfo<Table, Object?>>();
@override
List<DatabaseSchemaEntity> get allSchemaEntities =>
[snLocalChatChannel, snLocalChatMessage];
@override
int get schemaVersion => 1;
}

View File

@ -0,0 +1,697 @@
// dart format width=80
// GENERATED CODE, DO NOT EDIT BY HAND.
// ignore_for_file: type=lint
import 'package:drift/drift.dart';
class SnLocalChatChannel extends Table
with TableInfo<SnLocalChatChannel, SnLocalChatChannelData> {
@override
final GeneratedDatabase attachedDatabase;
final String? _alias;
SnLocalChatChannel(this.attachedDatabase, [this._alias]);
late final GeneratedColumn<int> id = GeneratedColumn<int>(
'id', aliasedName, false,
hasAutoIncrement: true,
type: DriftSqlType.int,
requiredDuringInsert: false,
defaultConstraints:
GeneratedColumn.constraintIsAlways('PRIMARY KEY AUTOINCREMENT'));
late final GeneratedColumn<String> alias = GeneratedColumn<String>(
'alias', aliasedName, false,
type: DriftSqlType.string, requiredDuringInsert: true);
late final GeneratedColumn<String> content = GeneratedColumn<String>(
'content', aliasedName, false,
type: DriftSqlType.string, requiredDuringInsert: true);
late final GeneratedColumn<DateTime> createdAt = GeneratedColumn<DateTime>(
'created_at', aliasedName, false,
type: DriftSqlType.dateTime,
requiredDuringInsert: false,
defaultValue: const CustomExpression(
'CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER)'));
@override
List<GeneratedColumn> get $columns => [id, alias, content, createdAt];
@override
String get aliasedName => _alias ?? actualTableName;
@override
String get actualTableName => $name;
static const String $name = 'sn_local_chat_channel';
@override
Set<GeneratedColumn> get $primaryKey => {id};
@override
SnLocalChatChannelData map(Map<String, dynamic> data, {String? tablePrefix}) {
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return SnLocalChatChannelData(
id: attachedDatabase.typeMapping
.read(DriftSqlType.int, data['${effectivePrefix}id'])!,
alias: attachedDatabase.typeMapping
.read(DriftSqlType.string, data['${effectivePrefix}alias'])!,
content: attachedDatabase.typeMapping
.read(DriftSqlType.string, data['${effectivePrefix}content'])!,
createdAt: attachedDatabase.typeMapping
.read(DriftSqlType.dateTime, data['${effectivePrefix}created_at'])!,
);
}
@override
SnLocalChatChannel createAlias(String alias) {
return SnLocalChatChannel(attachedDatabase, alias);
}
}
class SnLocalChatChannelData extends DataClass
implements Insertable<SnLocalChatChannelData> {
final int id;
final String alias;
final String content;
final DateTime createdAt;
const SnLocalChatChannelData(
{required this.id,
required this.alias,
required this.content,
required this.createdAt});
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
map['id'] = Variable<int>(id);
map['alias'] = Variable<String>(alias);
map['content'] = Variable<String>(content);
map['created_at'] = Variable<DateTime>(createdAt);
return map;
}
SnLocalChatChannelCompanion toCompanion(bool nullToAbsent) {
return SnLocalChatChannelCompanion(
id: Value(id),
alias: Value(alias),
content: Value(content),
createdAt: Value(createdAt),
);
}
factory SnLocalChatChannelData.fromJson(Map<String, dynamic> json,
{ValueSerializer? serializer}) {
serializer ??= driftRuntimeOptions.defaultSerializer;
return SnLocalChatChannelData(
id: serializer.fromJson<int>(json['id']),
alias: serializer.fromJson<String>(json['alias']),
content: serializer.fromJson<String>(json['content']),
createdAt: serializer.fromJson<DateTime>(json['createdAt']),
);
}
@override
Map<String, dynamic> toJson({ValueSerializer? serializer}) {
serializer ??= driftRuntimeOptions.defaultSerializer;
return <String, dynamic>{
'id': serializer.toJson<int>(id),
'alias': serializer.toJson<String>(alias),
'content': serializer.toJson<String>(content),
'createdAt': serializer.toJson<DateTime>(createdAt),
};
}
SnLocalChatChannelData copyWith(
{int? id, String? alias, String? content, DateTime? createdAt}) =>
SnLocalChatChannelData(
id: id ?? this.id,
alias: alias ?? this.alias,
content: content ?? this.content,
createdAt: createdAt ?? this.createdAt,
);
SnLocalChatChannelData copyWithCompanion(SnLocalChatChannelCompanion data) {
return SnLocalChatChannelData(
id: data.id.present ? data.id.value : this.id,
alias: data.alias.present ? data.alias.value : this.alias,
content: data.content.present ? data.content.value : this.content,
createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt,
);
}
@override
String toString() {
return (StringBuffer('SnLocalChatChannelData(')
..write('id: $id, ')
..write('alias: $alias, ')
..write('content: $content, ')
..write('createdAt: $createdAt')
..write(')'))
.toString();
}
@override
int get hashCode => Object.hash(id, alias, content, createdAt);
@override
bool operator ==(Object other) =>
identical(this, other) ||
(other is SnLocalChatChannelData &&
other.id == this.id &&
other.alias == this.alias &&
other.content == this.content &&
other.createdAt == this.createdAt);
}
class SnLocalChatChannelCompanion
extends UpdateCompanion<SnLocalChatChannelData> {
final Value<int> id;
final Value<String> alias;
final Value<String> content;
final Value<DateTime> createdAt;
const SnLocalChatChannelCompanion({
this.id = const Value.absent(),
this.alias = const Value.absent(),
this.content = const Value.absent(),
this.createdAt = const Value.absent(),
});
SnLocalChatChannelCompanion.insert({
this.id = const Value.absent(),
required String alias,
required String content,
this.createdAt = const Value.absent(),
}) : alias = Value(alias),
content = Value(content);
static Insertable<SnLocalChatChannelData> custom({
Expression<int>? id,
Expression<String>? alias,
Expression<String>? content,
Expression<DateTime>? createdAt,
}) {
return RawValuesInsertable({
if (id != null) 'id': id,
if (alias != null) 'alias': alias,
if (content != null) 'content': content,
if (createdAt != null) 'created_at': createdAt,
});
}
SnLocalChatChannelCompanion copyWith(
{Value<int>? id,
Value<String>? alias,
Value<String>? content,
Value<DateTime>? createdAt}) {
return SnLocalChatChannelCompanion(
id: id ?? this.id,
alias: alias ?? this.alias,
content: content ?? this.content,
createdAt: createdAt ?? this.createdAt,
);
}
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
if (id.present) {
map['id'] = Variable<int>(id.value);
}
if (alias.present) {
map['alias'] = Variable<String>(alias.value);
}
if (content.present) {
map['content'] = Variable<String>(content.value);
}
if (createdAt.present) {
map['created_at'] = Variable<DateTime>(createdAt.value);
}
return map;
}
@override
String toString() {
return (StringBuffer('SnLocalChatChannelCompanion(')
..write('id: $id, ')
..write('alias: $alias, ')
..write('content: $content, ')
..write('createdAt: $createdAt')
..write(')'))
.toString();
}
}
class SnLocalChatMessage extends Table
with TableInfo<SnLocalChatMessage, SnLocalChatMessageData> {
@override
final GeneratedDatabase attachedDatabase;
final String? _alias;
SnLocalChatMessage(this.attachedDatabase, [this._alias]);
late final GeneratedColumn<int> id = GeneratedColumn<int>(
'id', aliasedName, false,
hasAutoIncrement: true,
type: DriftSqlType.int,
requiredDuringInsert: false,
defaultConstraints:
GeneratedColumn.constraintIsAlways('PRIMARY KEY AUTOINCREMENT'));
late final GeneratedColumn<int> channelId = GeneratedColumn<int>(
'channel_id', aliasedName, false,
type: DriftSqlType.int, requiredDuringInsert: true);
late final GeneratedColumn<String> content = GeneratedColumn<String>(
'content', aliasedName, false,
type: DriftSqlType.string, requiredDuringInsert: true);
late final GeneratedColumn<DateTime> createdAt = GeneratedColumn<DateTime>(
'created_at', aliasedName, false,
type: DriftSqlType.dateTime,
requiredDuringInsert: false,
defaultValue: const CustomExpression(
'CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER)'));
@override
List<GeneratedColumn> get $columns => [id, channelId, content, createdAt];
@override
String get aliasedName => _alias ?? actualTableName;
@override
String get actualTableName => $name;
static const String $name = 'sn_local_chat_message';
@override
Set<GeneratedColumn> get $primaryKey => {id};
@override
SnLocalChatMessageData map(Map<String, dynamic> data, {String? tablePrefix}) {
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return SnLocalChatMessageData(
id: attachedDatabase.typeMapping
.read(DriftSqlType.int, data['${effectivePrefix}id'])!,
channelId: attachedDatabase.typeMapping
.read(DriftSqlType.int, data['${effectivePrefix}channel_id'])!,
content: attachedDatabase.typeMapping
.read(DriftSqlType.string, data['${effectivePrefix}content'])!,
createdAt: attachedDatabase.typeMapping
.read(DriftSqlType.dateTime, data['${effectivePrefix}created_at'])!,
);
}
@override
SnLocalChatMessage createAlias(String alias) {
return SnLocalChatMessage(attachedDatabase, alias);
}
}
class SnLocalChatMessageData extends DataClass
implements Insertable<SnLocalChatMessageData> {
final int id;
final int channelId;
final String content;
final DateTime createdAt;
const SnLocalChatMessageData(
{required this.id,
required this.channelId,
required this.content,
required this.createdAt});
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
map['id'] = Variable<int>(id);
map['channel_id'] = Variable<int>(channelId);
map['content'] = Variable<String>(content);
map['created_at'] = Variable<DateTime>(createdAt);
return map;
}
SnLocalChatMessageCompanion toCompanion(bool nullToAbsent) {
return SnLocalChatMessageCompanion(
id: Value(id),
channelId: Value(channelId),
content: Value(content),
createdAt: Value(createdAt),
);
}
factory SnLocalChatMessageData.fromJson(Map<String, dynamic> json,
{ValueSerializer? serializer}) {
serializer ??= driftRuntimeOptions.defaultSerializer;
return SnLocalChatMessageData(
id: serializer.fromJson<int>(json['id']),
channelId: serializer.fromJson<int>(json['channelId']),
content: serializer.fromJson<String>(json['content']),
createdAt: serializer.fromJson<DateTime>(json['createdAt']),
);
}
@override
Map<String, dynamic> toJson({ValueSerializer? serializer}) {
serializer ??= driftRuntimeOptions.defaultSerializer;
return <String, dynamic>{
'id': serializer.toJson<int>(id),
'channelId': serializer.toJson<int>(channelId),
'content': serializer.toJson<String>(content),
'createdAt': serializer.toJson<DateTime>(createdAt),
};
}
SnLocalChatMessageData copyWith(
{int? id, int? channelId, String? content, DateTime? createdAt}) =>
SnLocalChatMessageData(
id: id ?? this.id,
channelId: channelId ?? this.channelId,
content: content ?? this.content,
createdAt: createdAt ?? this.createdAt,
);
SnLocalChatMessageData copyWithCompanion(SnLocalChatMessageCompanion data) {
return SnLocalChatMessageData(
id: data.id.present ? data.id.value : this.id,
channelId: data.channelId.present ? data.channelId.value : this.channelId,
content: data.content.present ? data.content.value : this.content,
createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt,
);
}
@override
String toString() {
return (StringBuffer('SnLocalChatMessageData(')
..write('id: $id, ')
..write('channelId: $channelId, ')
..write('content: $content, ')
..write('createdAt: $createdAt')
..write(')'))
.toString();
}
@override
int get hashCode => Object.hash(id, channelId, content, createdAt);
@override
bool operator ==(Object other) =>
identical(this, other) ||
(other is SnLocalChatMessageData &&
other.id == this.id &&
other.channelId == this.channelId &&
other.content == this.content &&
other.createdAt == this.createdAt);
}
class SnLocalChatMessageCompanion
extends UpdateCompanion<SnLocalChatMessageData> {
final Value<int> id;
final Value<int> channelId;
final Value<String> content;
final Value<DateTime> createdAt;
const SnLocalChatMessageCompanion({
this.id = const Value.absent(),
this.channelId = const Value.absent(),
this.content = const Value.absent(),
this.createdAt = const Value.absent(),
});
SnLocalChatMessageCompanion.insert({
this.id = const Value.absent(),
required int channelId,
required String content,
this.createdAt = const Value.absent(),
}) : channelId = Value(channelId),
content = Value(content);
static Insertable<SnLocalChatMessageData> custom({
Expression<int>? id,
Expression<int>? channelId,
Expression<String>? content,
Expression<DateTime>? createdAt,
}) {
return RawValuesInsertable({
if (id != null) 'id': id,
if (channelId != null) 'channel_id': channelId,
if (content != null) 'content': content,
if (createdAt != null) 'created_at': createdAt,
});
}
SnLocalChatMessageCompanion copyWith(
{Value<int>? id,
Value<int>? channelId,
Value<String>? content,
Value<DateTime>? createdAt}) {
return SnLocalChatMessageCompanion(
id: id ?? this.id,
channelId: channelId ?? this.channelId,
content: content ?? this.content,
createdAt: createdAt ?? this.createdAt,
);
}
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
if (id.present) {
map['id'] = Variable<int>(id.value);
}
if (channelId.present) {
map['channel_id'] = Variable<int>(channelId.value);
}
if (content.present) {
map['content'] = Variable<String>(content.value);
}
if (createdAt.present) {
map['created_at'] = Variable<DateTime>(createdAt.value);
}
return map;
}
@override
String toString() {
return (StringBuffer('SnLocalChatMessageCompanion(')
..write('id: $id, ')
..write('channelId: $channelId, ')
..write('content: $content, ')
..write('createdAt: $createdAt')
..write(')'))
.toString();
}
}
class SnLocalKeyPair extends Table
with TableInfo<SnLocalKeyPair, SnLocalKeyPairData> {
@override
final GeneratedDatabase attachedDatabase;
final String? _alias;
SnLocalKeyPair(this.attachedDatabase, [this._alias]);
late final GeneratedColumn<String> id = GeneratedColumn<String>(
'id', aliasedName, false,
type: DriftSqlType.string, requiredDuringInsert: true);
late final GeneratedColumn<int> accountId = GeneratedColumn<int>(
'account_id', aliasedName, false,
type: DriftSqlType.int, requiredDuringInsert: true);
late final GeneratedColumn<String> publicKey = GeneratedColumn<String>(
'public_key', aliasedName, false,
type: DriftSqlType.string, requiredDuringInsert: true);
late final GeneratedColumn<String> privateKey = GeneratedColumn<String>(
'private_key', aliasedName, true,
type: DriftSqlType.string, requiredDuringInsert: false);
@override
List<GeneratedColumn> get $columns => [id, accountId, publicKey, privateKey];
@override
String get aliasedName => _alias ?? actualTableName;
@override
String get actualTableName => $name;
static const String $name = 'sn_local_key_pair';
@override
Set<GeneratedColumn> get $primaryKey => const {};
@override
SnLocalKeyPairData map(Map<String, dynamic> data, {String? tablePrefix}) {
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return SnLocalKeyPairData(
id: attachedDatabase.typeMapping
.read(DriftSqlType.string, data['${effectivePrefix}id'])!,
accountId: attachedDatabase.typeMapping
.read(DriftSqlType.int, data['${effectivePrefix}account_id'])!,
publicKey: attachedDatabase.typeMapping
.read(DriftSqlType.string, data['${effectivePrefix}public_key'])!,
privateKey: attachedDatabase.typeMapping
.read(DriftSqlType.string, data['${effectivePrefix}private_key']),
);
}
@override
SnLocalKeyPair createAlias(String alias) {
return SnLocalKeyPair(attachedDatabase, alias);
}
}
class SnLocalKeyPairData extends DataClass
implements Insertable<SnLocalKeyPairData> {
final String id;
final int accountId;
final String publicKey;
final String? privateKey;
const SnLocalKeyPairData(
{required this.id,
required this.accountId,
required this.publicKey,
this.privateKey});
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
map['id'] = Variable<String>(id);
map['account_id'] = Variable<int>(accountId);
map['public_key'] = Variable<String>(publicKey);
if (!nullToAbsent || privateKey != null) {
map['private_key'] = Variable<String>(privateKey);
}
return map;
}
SnLocalKeyPairCompanion toCompanion(bool nullToAbsent) {
return SnLocalKeyPairCompanion(
id: Value(id),
accountId: Value(accountId),
publicKey: Value(publicKey),
privateKey: privateKey == null && nullToAbsent
? const Value.absent()
: Value(privateKey),
);
}
factory SnLocalKeyPairData.fromJson(Map<String, dynamic> json,
{ValueSerializer? serializer}) {
serializer ??= driftRuntimeOptions.defaultSerializer;
return SnLocalKeyPairData(
id: serializer.fromJson<String>(json['id']),
accountId: serializer.fromJson<int>(json['accountId']),
publicKey: serializer.fromJson<String>(json['publicKey']),
privateKey: serializer.fromJson<String?>(json['privateKey']),
);
}
@override
Map<String, dynamic> toJson({ValueSerializer? serializer}) {
serializer ??= driftRuntimeOptions.defaultSerializer;
return <String, dynamic>{
'id': serializer.toJson<String>(id),
'accountId': serializer.toJson<int>(accountId),
'publicKey': serializer.toJson<String>(publicKey),
'privateKey': serializer.toJson<String?>(privateKey),
};
}
SnLocalKeyPairData copyWith(
{String? id,
int? accountId,
String? publicKey,
Value<String?> privateKey = const Value.absent()}) =>
SnLocalKeyPairData(
id: id ?? this.id,
accountId: accountId ?? this.accountId,
publicKey: publicKey ?? this.publicKey,
privateKey: privateKey.present ? privateKey.value : this.privateKey,
);
SnLocalKeyPairData copyWithCompanion(SnLocalKeyPairCompanion data) {
return SnLocalKeyPairData(
id: data.id.present ? data.id.value : this.id,
accountId: data.accountId.present ? data.accountId.value : this.accountId,
publicKey: data.publicKey.present ? data.publicKey.value : this.publicKey,
privateKey:
data.privateKey.present ? data.privateKey.value : this.privateKey,
);
}
@override
String toString() {
return (StringBuffer('SnLocalKeyPairData(')
..write('id: $id, ')
..write('accountId: $accountId, ')
..write('publicKey: $publicKey, ')
..write('privateKey: $privateKey')
..write(')'))
.toString();
}
@override
int get hashCode => Object.hash(id, accountId, publicKey, privateKey);
@override
bool operator ==(Object other) =>
identical(this, other) ||
(other is SnLocalKeyPairData &&
other.id == this.id &&
other.accountId == this.accountId &&
other.publicKey == this.publicKey &&
other.privateKey == this.privateKey);
}
class SnLocalKeyPairCompanion extends UpdateCompanion<SnLocalKeyPairData> {
final Value<String> id;
final Value<int> accountId;
final Value<String> publicKey;
final Value<String?> privateKey;
final Value<int> rowid;
const SnLocalKeyPairCompanion({
this.id = const Value.absent(),
this.accountId = const Value.absent(),
this.publicKey = const Value.absent(),
this.privateKey = const Value.absent(),
this.rowid = const Value.absent(),
});
SnLocalKeyPairCompanion.insert({
required String id,
required int accountId,
required String publicKey,
this.privateKey = const Value.absent(),
this.rowid = const Value.absent(),
}) : id = Value(id),
accountId = Value(accountId),
publicKey = Value(publicKey);
static Insertable<SnLocalKeyPairData> custom({
Expression<String>? id,
Expression<int>? accountId,
Expression<String>? publicKey,
Expression<String>? privateKey,
Expression<int>? rowid,
}) {
return RawValuesInsertable({
if (id != null) 'id': id,
if (accountId != null) 'account_id': accountId,
if (publicKey != null) 'public_key': publicKey,
if (privateKey != null) 'private_key': privateKey,
if (rowid != null) 'rowid': rowid,
});
}
SnLocalKeyPairCompanion copyWith(
{Value<String>? id,
Value<int>? accountId,
Value<String>? publicKey,
Value<String?>? privateKey,
Value<int>? rowid}) {
return SnLocalKeyPairCompanion(
id: id ?? this.id,
accountId: accountId ?? this.accountId,
publicKey: publicKey ?? this.publicKey,
privateKey: privateKey ?? this.privateKey,
rowid: rowid ?? this.rowid,
);
}
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
if (id.present) {
map['id'] = Variable<String>(id.value);
}
if (accountId.present) {
map['account_id'] = Variable<int>(accountId.value);
}
if (publicKey.present) {
map['public_key'] = Variable<String>(publicKey.value);
}
if (privateKey.present) {
map['private_key'] = Variable<String>(privateKey.value);
}
if (rowid.present) {
map['rowid'] = Variable<int>(rowid.value);
}
return map;
}
@override
String toString() {
return (StringBuffer('SnLocalKeyPairCompanion(')
..write('id: $id, ')
..write('accountId: $accountId, ')
..write('publicKey: $publicKey, ')
..write('privateKey: $privateKey, ')
..write('rowid: $rowid')
..write(')'))
.toString();
}
}
class DatabaseAtV2 extends GeneratedDatabase {
DatabaseAtV2(QueryExecutor e) : super(e);
late final SnLocalChatChannel snLocalChatChannel = SnLocalChatChannel(this);
late final SnLocalChatMessage snLocalChatMessage = SnLocalChatMessage(this);
late final SnLocalKeyPair snLocalKeyPair = SnLocalKeyPair(this);
@override
Iterable<TableInfo<Table, Object?>> get allTables =>
allSchemaEntities.whereType<TableInfo<Table, Object?>>();
@override
List<DatabaseSchemaEntity> get allSchemaEntities =>
[snLocalChatChannel, snLocalChatMessage, snLocalKeyPair];
@override
int get schemaVersion => 2;
}

View File

@ -0,0 +1,75 @@
// dart format width=80
// ignore_for_file: unused_local_variable, unused_import
import 'package:drift/drift.dart';
import 'package:drift_dev/api/migrations_native.dart';
import 'package:surface/database/database.dart';
import 'package:flutter_test/flutter_test.dart';
import 'generated/schema.dart';
import 'generated/schema_v1.dart' as v1;
import 'generated/schema_v2.dart' as v2;
void main() {
driftRuntimeOptions.dontWarnAboutMultipleDatabases = true;
late SchemaVerifier verifier;
setUpAll(() {
verifier = SchemaVerifier(GeneratedHelper());
});
group('simple database migrations', () {
// These simple tests verify all possible schema updates with a simple (no
// data) migration. This is a quick way to ensure that written database
// migrations properly alter the schema.
const versions = GeneratedHelper.versions;
for (final (i, fromVersion) in versions.indexed) {
group('from $fromVersion', () {
for (final toVersion in versions.skip(i + 1)) {
test('to $toVersion', () async {
final schema = await verifier.schemaAt(fromVersion);
final db = AppDatabase(schema.newConnection());
await verifier.migrateAndValidate(db, toVersion);
await db.close();
});
}
});
}
});
// The following template shows how to write tests ensuring your migrations
// preserve existing data.
// Testing this can be useful for migrations that change existing columns
// (e.g. by alterating their type or constraints). Migrations that only add
// tables or columns typically don't need these advanced tests. For more
// information, see https://drift.simonbinder.eu/migrations/tests/#verifying-data-integrity
// TODO: This generated template shows how these tests could be written. Adopt
// it to your own needs when testing migrations with data integrity.
test('migration from v1 to v2 does not corrupt data', () async {
// Add data to insert into the old database, and the expected rows after the
// migration.
// TODO: Fill these lists
final oldSnLocalChatChannelData = <v1.SnLocalChatChannelData>[];
final expectedNewSnLocalChatChannelData = <v2.SnLocalChatChannelData>[];
final oldSnLocalChatMessageData = <v1.SnLocalChatMessageData>[];
final expectedNewSnLocalChatMessageData = <v2.SnLocalChatMessageData>[];
await verifier.testWithDataIntegrity(
oldVersion: 1,
newVersion: 2,
createOld: v1.DatabaseAtV1.new,
createNew: v2.DatabaseAtV2.new,
openTestedDatabase: AppDatabase.new,
createItems: (batch, oldDb) {
batch.insertAll(oldDb.snLocalChatChannel, oldSnLocalChatChannelData);
batch.insertAll(oldDb.snLocalChatMessage, oldSnLocalChatMessageData);
},
validateItems: (newDb) async {
expect(expectedNewSnLocalChatChannelData,
await newDb.select(newDb.snLocalChatChannel).get());
expect(expectedNewSnLocalChatMessageData,
await newDb.select(newDb.snLocalChatMessage).get());
},
);
});
}