initial
This commit is contained in:
1
lib/data/local/dao/dao.dart
Normal file
1
lib/data/local/dao/dao.dart
Normal file
@@ -0,0 +1 @@
|
||||
export 'profiles_dao.dart';
|
||||
83
lib/data/local/dao/profiles_dao.dart
Normal file
83
lib/data/local/dao/profiles_dao.dart
Normal file
@@ -0,0 +1,83 @@
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:hiddify/data/local/data_mappers.dart';
|
||||
import 'package:hiddify/data/local/database.dart';
|
||||
import 'package:hiddify/data/local/tables.dart';
|
||||
import 'package:hiddify/domain/profiles/profiles.dart';
|
||||
import 'package:hiddify/utils/utils.dart';
|
||||
|
||||
part 'profiles_dao.g.dart';
|
||||
|
||||
@DriftAccessor(tables: [ProfileEntries])
|
||||
class ProfilesDao extends DatabaseAccessor<AppDatabase>
|
||||
with _$ProfilesDaoMixin, InfraLogger {
|
||||
ProfilesDao(super.db);
|
||||
|
||||
Future<Profile?> getById(String id) async {
|
||||
return (profileEntries.select()..where((tbl) => tbl.id.equals(id)))
|
||||
.map(ProfileMapper.fromEntry)
|
||||
.getSingleOrNull();
|
||||
}
|
||||
|
||||
Stream<Profile?> watchActiveProfile() {
|
||||
return (profileEntries.select()..where((tbl) => tbl.active.equals(true)))
|
||||
.map(ProfileMapper.fromEntry)
|
||||
.watchSingleOrNull();
|
||||
}
|
||||
|
||||
Stream<int> watchProfileCount() {
|
||||
final count = profileEntries.id.count();
|
||||
return (profileEntries.selectOnly()..addColumns([count]))
|
||||
.map((exp) => exp.read(count)!)
|
||||
.watchSingle();
|
||||
}
|
||||
|
||||
Stream<List<Profile>> watchAll() {
|
||||
return (profileEntries.select()
|
||||
..orderBy(
|
||||
[(tbl) => OrderingTerm.desc(tbl.active)],
|
||||
))
|
||||
.map(ProfileMapper.fromEntry)
|
||||
.watch();
|
||||
}
|
||||
|
||||
Future<void> create(Profile profile) async {
|
||||
await transaction(
|
||||
() async {
|
||||
if (profile.active) {
|
||||
await (update(profileEntries)
|
||||
..where((tbl) => tbl.id.isNotValue(profile.id)))
|
||||
.write(const ProfileEntriesCompanion(active: Value(false)));
|
||||
}
|
||||
await into(profileEntries).insert(profile.toCompanion());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> edit(Profile patch) async {
|
||||
await transaction(
|
||||
() async {
|
||||
await (update(profileEntries)..where((tbl) => tbl.id.equals(patch.id)))
|
||||
.write(patch.toCompanion());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> setAsActive(String id) async {
|
||||
await transaction(
|
||||
() async {
|
||||
await (update(profileEntries)..where((tbl) => tbl.id.isNotValue(id)))
|
||||
.write(const ProfileEntriesCompanion(active: Value(false)));
|
||||
await (update(profileEntries)..where((tbl) => tbl.id.equals(id)))
|
||||
.write(const ProfileEntriesCompanion(active: Value(true)));
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> removeById(String id) async {
|
||||
await transaction(
|
||||
() async {
|
||||
await (delete(profileEntries)..where((tbl) => tbl.id.equals(id))).go();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
37
lib/data/local/data_mappers.dart
Normal file
37
lib/data/local/data_mappers.dart
Normal file
@@ -0,0 +1,37 @@
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:hiddify/data/local/database.dart';
|
||||
import 'package:hiddify/domain/profiles/profiles.dart';
|
||||
|
||||
extension ProfileMapper on Profile {
|
||||
ProfileEntriesCompanion toCompanion() {
|
||||
return ProfileEntriesCompanion.insert(
|
||||
id: id,
|
||||
active: active,
|
||||
name: name,
|
||||
url: url,
|
||||
lastUpdate: lastUpdate,
|
||||
upload: Value(subInfo?.upload),
|
||||
download: Value(subInfo?.download),
|
||||
total: Value(subInfo?.total),
|
||||
expire: Value(subInfo?.expire),
|
||||
updateInterval: Value(updateInterval),
|
||||
);
|
||||
}
|
||||
|
||||
static Profile fromEntry(ProfileEntry entry) {
|
||||
return Profile(
|
||||
id: entry.id,
|
||||
active: entry.active,
|
||||
name: entry.name,
|
||||
url: entry.url,
|
||||
lastUpdate: entry.lastUpdate,
|
||||
updateInterval: entry.updateInterval,
|
||||
subInfo: SubscriptionInfo(
|
||||
upload: entry.upload,
|
||||
download: entry.download,
|
||||
total: entry.total,
|
||||
expire: entry.expire,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
29
lib/data/local/database.dart
Normal file
29
lib/data/local/database.dart
Normal file
@@ -0,0 +1,29 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:drift/native.dart';
|
||||
import 'package:hiddify/data/local/dao/dao.dart';
|
||||
import 'package:hiddify/data/local/tables.dart';
|
||||
import 'package:hiddify/data/local/type_converters.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
|
||||
part 'database.g.dart';
|
||||
|
||||
@DriftDatabase(tables: [ProfileEntries], daos: [ProfilesDao])
|
||||
class AppDatabase extends _$AppDatabase {
|
||||
AppDatabase({required QueryExecutor connection}) : super(connection);
|
||||
|
||||
AppDatabase.connect() : super(_openConnection());
|
||||
|
||||
@override
|
||||
int get schemaVersion => 1;
|
||||
}
|
||||
|
||||
LazyDatabase _openConnection() {
|
||||
return LazyDatabase(() async {
|
||||
final dbFolder = await getApplicationDocumentsDirectory();
|
||||
final file = File(p.join(dbFolder.path, 'db.sqlite'));
|
||||
return NativeDatabase.createInBackground(file);
|
||||
});
|
||||
}
|
||||
20
lib/data/local/tables.dart
Normal file
20
lib/data/local/tables.dart
Normal file
@@ -0,0 +1,20 @@
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:hiddify/data/local/type_converters.dart';
|
||||
|
||||
@DataClassName('ProfileEntry')
|
||||
class ProfileEntries extends Table {
|
||||
TextColumn get id => text()();
|
||||
BoolColumn get active => boolean()();
|
||||
TextColumn get name => text().withLength(min: 1)();
|
||||
TextColumn get url => text()();
|
||||
IntColumn get upload => integer().nullable()();
|
||||
IntColumn get download => integer().nullable()();
|
||||
IntColumn get total => integer().nullable()();
|
||||
DateTimeColumn get expire => dateTime().nullable()();
|
||||
IntColumn get updateInterval =>
|
||||
integer().nullable().map(DurationTypeConverter())();
|
||||
DateTimeColumn get lastUpdate => dateTime()();
|
||||
|
||||
@override
|
||||
Set<Column> get primaryKey => {id};
|
||||
}
|
||||
13
lib/data/local/type_converters.dart
Normal file
13
lib/data/local/type_converters.dart
Normal file
@@ -0,0 +1,13 @@
|
||||
import 'package:drift/drift.dart';
|
||||
|
||||
class DurationTypeConverter extends TypeConverter<Duration, int> {
|
||||
@override
|
||||
Duration fromSql(int fromDb) {
|
||||
return Duration(seconds: fromDb);
|
||||
}
|
||||
|
||||
@override
|
||||
int toSql(Duration value) {
|
||||
return value.inSeconds;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user