This commit is contained in:
problematicconsumer
2023-12-01 12:56:24 +03:30
parent 9c165e178b
commit ed614988a2
181 changed files with 3092 additions and 2341 deletions

View File

@@ -0,0 +1,59 @@
import 'package:drift/drift.dart';
import 'package:hiddify/core/database/connection/database_connection.dart';
import 'package:hiddify/core/database/converters/duration_converter.dart';
import 'package:hiddify/core/database/schema_versions.dart';
import 'package:hiddify/core/database/tables/database_tables.dart';
import 'package:hiddify/features/geo_asset/data/geo_asset_data_mapper.dart';
import 'package:hiddify/features/geo_asset/model/default_geo_assets.dart';
import 'package:hiddify/features/geo_asset/model/geo_asset_entity.dart';
import 'package:hiddify/features/profile/model/profile_entity.dart';
part 'app_database.g.dart';
@DriftDatabase(tables: [ProfileEntries, GeoAssetEntries])
class AppDatabase extends _$AppDatabase {
AppDatabase({required QueryExecutor connection}) : super(connection);
AppDatabase.connect() : super(openConnection());
@override
int get schemaVersion => 3;
@override
MigrationStrategy get migration {
return MigrationStrategy(
onCreate: (Migrator m) async {
await m.createAll();
await _prePopulateGeoAssets();
},
onUpgrade: stepByStep(
// add type column to profile entries table
// make url column nullable
from1To2: (m, schema) async {
await m.alterTable(
TableMigration(
schema.profileEntries,
columnTransformer: {
schema.profileEntries.type: const Constant<String>("remote"),
},
newColumns: [schema.profileEntries.type],
),
);
},
from2To3: (m, schema) async {
await m.createTable(schema.geoAssetEntries);
await _prePopulateGeoAssets();
},
),
);
}
Future<void> _prePopulateGeoAssets() async {
await transaction(() async {
final geoAssets = defaultGeoAssets.map((e) => e.toEntry());
for (final geoAsset in geoAssets) {
await into(geoAssetEntries).insert(geoAsset);
}
});
}
}

View File

@@ -0,0 +1,14 @@
import 'dart:io';
import 'package:drift/drift.dart';
import 'package:drift/native.dart';
import 'package:hiddify/services/files_editor_service.dart';
import 'package:path/path.dart' as p;
LazyDatabase openConnection() {
return LazyDatabase(() async {
final dbDir = await FilesEditorService.getDatabaseDirectory();
final file = File(p.join(dbDir.path, 'db.sqlite'));
return NativeDatabase.createInBackground(file);
});
}

View 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;
}
}

View File

@@ -0,0 +1,7 @@
import 'package:hiddify/core/database/app_database.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'database_provider.g.dart';
@Riverpod(keepAlive: true)
AppDatabase appDatabase(AppDatabaseRef ref) => AppDatabase.connect();

View File

@@ -0,0 +1,231 @@
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 _S2 extends i0.VersionedSchema {
_S2({required super.database}) : super(version: 2);
@override
late final List<i1.DatabaseSchemaEntity> entities = [
profileEntries,
];
late final Shape0 profileEntries = Shape0(
source: i0.VersionedTable(
entityName: 'profile_entries',
withoutRowId: false,
isStrict: false,
tableConstraints: [
'PRIMARY KEY(id)',
],
columns: [
_column_0,
_column_1,
_column_2,
_column_3,
_column_4,
_column_5,
_column_6,
_column_7,
_column_8,
_column_9,
_column_10,
_column_11,
_column_12,
],
attachedDatabase: database,
),
alias: null);
}
class Shape0 extends i0.VersionedTable {
Shape0({required super.source, required super.alias}) : super.aliased();
i1.GeneratedColumn<String> get id =>
columnsByName['id']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get type =>
columnsByName['type']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<bool> get active =>
columnsByName['active']! as i1.GeneratedColumn<bool>;
i1.GeneratedColumn<String> get name =>
columnsByName['name']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get url =>
columnsByName['url']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<DateTime> get lastUpdate =>
columnsByName['last_update']! as i1.GeneratedColumn<DateTime>;
i1.GeneratedColumn<int> get updateInterval =>
columnsByName['update_interval']! as i1.GeneratedColumn<int>;
i1.GeneratedColumn<int> get upload =>
columnsByName['upload']! as i1.GeneratedColumn<int>;
i1.GeneratedColumn<int> get download =>
columnsByName['download']! as i1.GeneratedColumn<int>;
i1.GeneratedColumn<int> get total =>
columnsByName['total']! as i1.GeneratedColumn<int>;
i1.GeneratedColumn<DateTime> get expire =>
columnsByName['expire']! as i1.GeneratedColumn<DateTime>;
i1.GeneratedColumn<String> get webPageUrl =>
columnsByName['web_page_url']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get supportUrl =>
columnsByName['support_url']! as i1.GeneratedColumn<String>;
}
i1.GeneratedColumn<String> _column_0(String aliasedName) =>
i1.GeneratedColumn<String>('id', aliasedName, false,
type: i1.DriftSqlType.string);
i1.GeneratedColumn<String> _column_1(String aliasedName) =>
i1.GeneratedColumn<String>('type', aliasedName, false,
type: i1.DriftSqlType.string);
i1.GeneratedColumn<bool> _column_2(String aliasedName) =>
i1.GeneratedColumn<bool>('active', aliasedName, false,
type: i1.DriftSqlType.bool,
defaultConstraints: i1.GeneratedColumn.constraintIsAlways(
'CHECK ("active" IN (0, 1))'));
i1.GeneratedColumn<String> _column_3(String aliasedName) =>
i1.GeneratedColumn<String>('name', aliasedName, false,
additionalChecks: i1.GeneratedColumn.checkTextLength(
minTextLength: 1,
),
type: i1.DriftSqlType.string);
i1.GeneratedColumn<String> _column_4(String aliasedName) =>
i1.GeneratedColumn<String>('url', aliasedName, true,
type: i1.DriftSqlType.string);
i1.GeneratedColumn<DateTime> _column_5(String aliasedName) =>
i1.GeneratedColumn<DateTime>('last_update', aliasedName, false,
type: i1.DriftSqlType.dateTime);
i1.GeneratedColumn<int> _column_6(String aliasedName) =>
i1.GeneratedColumn<int>('update_interval', aliasedName, true,
type: i1.DriftSqlType.int);
i1.GeneratedColumn<int> _column_7(String aliasedName) =>
i1.GeneratedColumn<int>('upload', aliasedName, true,
type: i1.DriftSqlType.int);
i1.GeneratedColumn<int> _column_8(String aliasedName) =>
i1.GeneratedColumn<int>('download', aliasedName, true,
type: i1.DriftSqlType.int);
i1.GeneratedColumn<int> _column_9(String aliasedName) =>
i1.GeneratedColumn<int>('total', aliasedName, true,
type: i1.DriftSqlType.int);
i1.GeneratedColumn<DateTime> _column_10(String aliasedName) =>
i1.GeneratedColumn<DateTime>('expire', aliasedName, true,
type: i1.DriftSqlType.dateTime);
i1.GeneratedColumn<String> _column_11(String aliasedName) =>
i1.GeneratedColumn<String>('web_page_url', aliasedName, true,
type: i1.DriftSqlType.string);
i1.GeneratedColumn<String> _column_12(String aliasedName) =>
i1.GeneratedColumn<String>('support_url', aliasedName, true,
type: i1.DriftSqlType.string);
final class _S3 extends i0.VersionedSchema {
_S3({required super.database}) : super(version: 3);
@override
late final List<i1.DatabaseSchemaEntity> entities = [
profileEntries,
geoAssetEntries,
];
late final Shape0 profileEntries = Shape0(
source: i0.VersionedTable(
entityName: 'profile_entries',
withoutRowId: false,
isStrict: false,
tableConstraints: [
'PRIMARY KEY(id)',
],
columns: [
_column_0,
_column_1,
_column_2,
_column_3,
_column_4,
_column_5,
_column_6,
_column_7,
_column_8,
_column_9,
_column_10,
_column_11,
_column_12,
],
attachedDatabase: database,
),
alias: null);
late final Shape1 geoAssetEntries = Shape1(
source: i0.VersionedTable(
entityName: 'geo_asset_entries',
withoutRowId: false,
isStrict: false,
tableConstraints: [
'PRIMARY KEY(id)',
'UNIQUE(name, provider_name)',
],
columns: [
_column_0,
_column_1,
_column_2,
_column_3,
_column_13,
_column_14,
_column_15,
],
attachedDatabase: database,
),
alias: null);
}
class Shape1 extends i0.VersionedTable {
Shape1({required super.source, required super.alias}) : super.aliased();
i1.GeneratedColumn<String> get id =>
columnsByName['id']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get type =>
columnsByName['type']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<bool> get active =>
columnsByName['active']! as i1.GeneratedColumn<bool>;
i1.GeneratedColumn<String> get name =>
columnsByName['name']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get providerName =>
columnsByName['provider_name']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get version =>
columnsByName['version']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<DateTime> get lastCheck =>
columnsByName['last_check']! as i1.GeneratedColumn<DateTime>;
}
i1.GeneratedColumn<String> _column_13(String aliasedName) =>
i1.GeneratedColumn<String>('provider_name', aliasedName, false,
additionalChecks: i1.GeneratedColumn.checkTextLength(
minTextLength: 1,
),
type: i1.DriftSqlType.string);
i1.GeneratedColumn<String> _column_14(String aliasedName) =>
i1.GeneratedColumn<String>('version', aliasedName, true,
type: i1.DriftSqlType.string);
i1.GeneratedColumn<DateTime> _column_15(String aliasedName) =>
i1.GeneratedColumn<DateTime>('last_check', aliasedName, true,
type: i1.DriftSqlType.dateTime);
i0.MigrationStepWithVersion migrationSteps({
required Future<void> Function(i1.Migrator m, _S2 schema) from1To2,
required Future<void> Function(i1.Migrator m, _S3 schema) from2To3,
}) {
return (currentVersion, database) async {
switch (currentVersion) {
case 1:
final schema = _S2(database: database);
final migrator = i1.Migrator(database, schema);
await from1To2(migrator, schema);
return 2;
case 2:
final schema = _S3(database: database);
final migrator = i1.Migrator(database, schema);
await from2To3(migrator, schema);
return 3;
default:
throw ArgumentError.value('Unknown migration from $currentVersion');
}
};
}
i1.OnUpgrade stepByStep({
required Future<void> Function(i1.Migrator m, _S2 schema) from1To2,
required Future<void> Function(i1.Migrator m, _S3 schema) from2To3,
}) =>
i0.VersionedSchema.stepByStepHelper(
step: migrationSteps(
from1To2: from1To2,
from2To3: from2To3,
));

View File

@@ -0,0 +1,160 @@
{
"_meta": {
"description": "This file contains a serialized version of schema entities for drift.",
"version": "1.1.0"
},
"options": {
"store_date_time_values_as_text": true
},
"entities": [
{
"id": 0,
"references": [],
"type": "table",
"data": {
"name": "profile_entries",
"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": "active",
"getter_name": "active",
"moor_type": "bool",
"nullable": false,
"customConstraints": null,
"defaultConstraints": "CHECK (\"active\" IN (0, 1))",
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "name",
"getter_name": "name",
"moor_type": "string",
"nullable": false,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": [
{
"allowed-lengths": {
"min": 1,
"max": null
}
}
]
},
{
"name": "url",
"getter_name": "url",
"moor_type": "string",
"nullable": false,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "last_update",
"getter_name": "lastUpdate",
"moor_type": "dateTime",
"nullable": false,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "update_interval",
"getter_name": "updateInterval",
"moor_type": "int",
"nullable": true,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": [],
"type_converter": {
"dart_expr": "DurationTypeConverter()",
"dart_type_name": "Duration"
}
},
{
"name": "upload",
"getter_name": "upload",
"moor_type": "int",
"nullable": true,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "download",
"getter_name": "download",
"moor_type": "int",
"nullable": true,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "total",
"getter_name": "total",
"moor_type": "int",
"nullable": true,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "expire",
"getter_name": "expire",
"moor_type": "dateTime",
"nullable": true,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "web_page_url",
"getter_name": "webPageUrl",
"moor_type": "string",
"nullable": true,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "support_url",
"getter_name": "supportUrl",
"moor_type": "string",
"nullable": true,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
}
],
"is_virtual": false,
"without_rowid": false,
"constraints": [],
"explicit_pk": [
"id"
]
}
}
]
}

View File

@@ -0,0 +1,174 @@
{
"_meta": {
"description": "This file contains a serialized version of schema entities for drift.",
"version": "1.1.0"
},
"options": {
"store_date_time_values_as_text": true
},
"entities": [
{
"id": 0,
"references": [],
"type": "table",
"data": {
"name": "profile_entries",
"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": "type",
"getter_name": "type",
"moor_type": "string",
"nullable": false,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": [],
"type_converter": {
"dart_expr": "const EnumNameConverter<ProfileType>(ProfileType.values)",
"dart_type_name": "ProfileType"
}
},
{
"name": "active",
"getter_name": "active",
"moor_type": "bool",
"nullable": false,
"customConstraints": null,
"defaultConstraints": "CHECK (\"active\" IN (0, 1))",
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "name",
"getter_name": "name",
"moor_type": "string",
"nullable": false,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": [
{
"allowed-lengths": {
"min": 1,
"max": null
}
}
]
},
{
"name": "url",
"getter_name": "url",
"moor_type": "string",
"nullable": true,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "last_update",
"getter_name": "lastUpdate",
"moor_type": "dateTime",
"nullable": false,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "update_interval",
"getter_name": "updateInterval",
"moor_type": "int",
"nullable": true,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": [],
"type_converter": {
"dart_expr": "DurationTypeConverter()",
"dart_type_name": "Duration"
}
},
{
"name": "upload",
"getter_name": "upload",
"moor_type": "int",
"nullable": true,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "download",
"getter_name": "download",
"moor_type": "int",
"nullable": true,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "total",
"getter_name": "total",
"moor_type": "int",
"nullable": true,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "expire",
"getter_name": "expire",
"moor_type": "dateTime",
"nullable": true,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "web_page_url",
"getter_name": "webPageUrl",
"moor_type": "string",
"nullable": true,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "support_url",
"getter_name": "supportUrl",
"moor_type": "string",
"nullable": true,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
}
],
"is_virtual": false,
"without_rowid": false,
"constraints": [],
"explicit_pk": [
"id"
]
}
}
]
}

View File

@@ -0,0 +1,286 @@
{
"_meta": {
"description": "This file contains a serialized version of schema entities for drift.",
"version": "1.1.0"
},
"options": {
"store_date_time_values_as_text": true
},
"entities": [
{
"id": 0,
"references": [],
"type": "table",
"data": {
"name": "profile_entries",
"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": "type",
"getter_name": "type",
"moor_type": "string",
"nullable": false,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": [],
"type_converter": {
"dart_expr": "const EnumNameConverter<ProfileType>(ProfileType.values)",
"dart_type_name": "ProfileType"
}
},
{
"name": "active",
"getter_name": "active",
"moor_type": "bool",
"nullable": false,
"customConstraints": null,
"defaultConstraints": "CHECK (\"active\" IN (0, 1))",
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "name",
"getter_name": "name",
"moor_type": "string",
"nullable": false,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": [
{
"allowed-lengths": {
"min": 1,
"max": null
}
}
]
},
{
"name": "url",
"getter_name": "url",
"moor_type": "string",
"nullable": true,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "last_update",
"getter_name": "lastUpdate",
"moor_type": "dateTime",
"nullable": false,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "update_interval",
"getter_name": "updateInterval",
"moor_type": "int",
"nullable": true,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": [],
"type_converter": {
"dart_expr": "DurationTypeConverter()",
"dart_type_name": "Duration"
}
},
{
"name": "upload",
"getter_name": "upload",
"moor_type": "int",
"nullable": true,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "download",
"getter_name": "download",
"moor_type": "int",
"nullable": true,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "total",
"getter_name": "total",
"moor_type": "int",
"nullable": true,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "expire",
"getter_name": "expire",
"moor_type": "dateTime",
"nullable": true,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "web_page_url",
"getter_name": "webPageUrl",
"moor_type": "string",
"nullable": true,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "support_url",
"getter_name": "supportUrl",
"moor_type": "string",
"nullable": true,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
}
],
"is_virtual": false,
"without_rowid": false,
"constraints": [],
"explicit_pk": [
"id"
]
}
},
{
"id": 1,
"references": [],
"type": "table",
"data": {
"name": "geo_asset_entries",
"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": "type",
"getter_name": "type",
"moor_type": "string",
"nullable": false,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": [],
"type_converter": {
"dart_expr": "const EnumNameConverter<GeoAssetType>(GeoAssetType.values)",
"dart_type_name": "GeoAssetType"
}
},
{
"name": "active",
"getter_name": "active",
"moor_type": "bool",
"nullable": false,
"customConstraints": null,
"defaultConstraints": "CHECK (\"active\" IN (0, 1))",
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "name",
"getter_name": "name",
"moor_type": "string",
"nullable": false,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": [
{
"allowed-lengths": {
"min": 1,
"max": null
}
}
]
},
{
"name": "provider_name",
"getter_name": "providerName",
"moor_type": "string",
"nullable": false,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": [
{
"allowed-lengths": {
"min": 1,
"max": null
}
}
]
},
{
"name": "version",
"getter_name": "version",
"moor_type": "string",
"nullable": true,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
},
{
"name": "last_check",
"getter_name": "lastCheck",
"moor_type": "dateTime",
"nullable": true,
"customConstraints": null,
"default_dart": null,
"default_client_dart": null,
"dsl_features": []
}
],
"is_virtual": false,
"without_rowid": false,
"constraints": [],
"explicit_pk": [
"id"
],
"unique_keys": [
[
"name",
"provider_name"
]
]
}
}
]
}

View File

@@ -0,0 +1,44 @@
import 'package:drift/drift.dart';
import 'package:hiddify/core/database/converters/duration_converter.dart';
import 'package:hiddify/features/geo_asset/model/geo_asset_entity.dart';
import 'package:hiddify/features/profile/model/profile_entity.dart';
@DataClassName('ProfileEntry')
class ProfileEntries extends Table {
TextColumn get id => text()();
TextColumn get type => textEnum<ProfileType>()();
BoolColumn get active => boolean()();
TextColumn get name => text().withLength(min: 1)();
TextColumn get url => text().nullable()();
DateTimeColumn get lastUpdate => dateTime()();
IntColumn get updateInterval =>
integer().nullable().map(DurationTypeConverter())();
IntColumn get upload => integer().nullable()();
IntColumn get download => integer().nullable()();
IntColumn get total => integer().nullable()();
DateTimeColumn get expire => dateTime().nullable()();
TextColumn get webPageUrl => text().nullable()();
TextColumn get supportUrl => text().nullable()();
@override
Set<Column> get primaryKey => {id};
}
@DataClassName('GeoAssetEntry')
class GeoAssetEntries extends Table {
TextColumn get id => text()();
TextColumn get type => textEnum<GeoAssetType>()();
BoolColumn get active => boolean()();
TextColumn get name => text().withLength(min: 1)();
TextColumn get providerName => text().withLength(min: 1)();
TextColumn get version => text().nullable()();
DateTimeColumn get lastCheck => dateTime().nullable()();
@override
Set<Column> get primaryKey => {id};
@override
List<Set<Column>> get uniqueKeys => [
{name, providerName},
];
}