Skip to content

Commit

Permalink
#22 - new util: ReadyOrNotMixin
Browse files Browse the repository at this point in the history
  • Loading branch information
turn-a-round committed May 9, 2020
1 parent 33eb7d0 commit 417a996
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 110 deletions.
24 changes: 8 additions & 16 deletions src/sprightly/lib/models/dao.dart
Original file line number Diff line number Diff line change
@@ -1,32 +1,24 @@
library sprightly.dao;

import 'dart:async';

import 'package:package_info/package_info.dart';
import 'package:sprightly/models/constants/enums.dart';
import 'package:sprightly/models/db/database.dart';
import 'package:sprightly/utils/ready_or_not.dart';

String get groupAccountPrefix => 'GroupAccount';

abstract class AppDao {
bool get ready;
Future getReady();
FutureOr getReady();
}

class AppInformation extends AppDao {
bool _initialized = false;
bool _working = false;
Future<PackageInfo> _worker;
class AppInformation with ReadyOrNotMixin<PackageInfo> {
PackageInfo packageInfo;
@override
bool get ready => _initialized;
@override
Future getReady() async {
if (!_initialized && !_working) {
_working = true;
_worker = PackageInfo.fromPlatform();
packageInfo = await _worker;
_initialized = true;
_working = false;
} else if (_working) await _worker;

AppInformation() {
getReadyWorker = PackageInfo.fromPlatform;
}

String get appName => packageInfo.appName;
Expand Down
105 changes: 41 additions & 64 deletions src/sprightly/lib/models/db/database.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'package:sprightly/models/constants/enums.dart';
import 'package:sprightly/models/dao.dart';
import 'package:sprightly/utils/file_provider.dart';
import 'package:sprightly/utils/happy_hash.dart';
import 'package:sprightly/utils/ready_or_not.dart';

part 'database.g.dart';

Expand Down Expand Up @@ -458,13 +459,13 @@ class CustomQuery {
bool get isLoaded => (_query ?? '').isNotEmpty;
}

class SprightlyQueries {
static SprightlyQueries universal = SprightlyQueries();
class SprightlyQueries with ReadyOrNotMixin {
static SprightlyQueries universal = SprightlyQueries._();
SprightlyQueries._() {
getReadyWorker = _getReady;
}
factory SprightlyQueries() => universal;

bool initialized = false;
bool _working = false;

// startup queries
CustomQuery get defaultStartupStatement =>
CustomQuery.fromAsset("defaultStartupStatement.sql");
Expand Down Expand Up @@ -494,34 +495,25 @@ class SprightlyQueries {
// 'https://example.com/some/source/setupMigrationFrom1.sql'),
};

Future _init() async {
if (!initialized && !_working) {
_working = true;
try {
// Required for fetching file from web
await RemoteFileCache.universal.init();

// custom queries
await selectGroupAccountMembers.load();
await selectGroupOnlyMembers.load();
await selectGroupSettlements.load();
await selectGroupTransactions.load();

initialized = true;
} finally {
_working = false;
}
}
Future _getReady() async {
// Required for fetching file from web
await RemoteFileCache.universal.getReady();

// custom queries
await selectGroupAccountMembers.load();
await selectGroupOnlyMembers.load();
await selectGroupSettlements.load();
await selectGroupTransactions.load();
}
}

mixin _GenericDaoMixin<T extends GeneratedDatabase> on DatabaseAccessor<T> {
SprightlyQueries _queries = SprightlyQueries.universal;

bool get ready => _queries.initialized;
bool get _daoMixinReady => _queries.ready;

Future getReady() async {
await _queries._init();
Future _getDaoMixinReady() async {
await _queries.getReady();
await customStatement(await _queries.defaultStartupStatement.load());
}

Expand Down Expand Up @@ -605,26 +597,18 @@ mixin _GenericDaoMixin<T extends GeneratedDatabase> on DatabaseAccessor<T> {
],
)
class SprightlyDao extends DatabaseAccessor<SprightlyDatabase>
with _$SprightlyDaoMixin, _GenericDaoMixin
with _$SprightlyDaoMixin, _GenericDaoMixin, ReadyOrNotMixin
implements SystemDao {
SprightlyDao(SprightlyDatabase _db) : super(_db);
SprightlyDao(SprightlyDatabase _db) : super(_db) {
getReadyWorker = _getReady;
}

bool _initialized = false;
bool _working = false;
@override
bool get ready => super.ready && _initialized;
@override
Future getReady() async {
if (!_initialized && !_working) {
_working = true;
try {
await super.getReady();
_sharedGroupList = await getGroups(GroupType.Shared);
_initialized = true;
} finally {
_working = false;
}
}
bool get ready => super._daoMixinReady && super.ready;

Future _getReady() async {
await super._getDaoMixinReady();
_sharedGroupList = await getGroups(GroupType.Shared);
}

@override
Expand Down Expand Up @@ -1097,30 +1081,23 @@ class SprightlyDao extends DatabaseAccessor<SprightlyDatabase>
],
)
class SprightlySetupDao extends DatabaseAccessor<SprightlySetupDatabase>
with _$SprightlySetupDaoMixin, _GenericDaoMixin
with _$SprightlySetupDaoMixin, _GenericDaoMixin, ReadyOrNotMixin
implements SettingsDao {
SprightlySetupDao(SprightlySetupDatabase _db) : super(_db);
SprightlySetupDao(SprightlySetupDatabase _db) : super(_db) {
getReadyWorker = _getReady;
}

bool _initialized = false;
bool _working = false;
@override
bool get ready => super.ready && _appInformation.ready && _initialized;
@override
Future getReady() async {
if (!_initialized && !_working) {
_working = true;
try {
await super.getReady();
await _appInformation.getReady();
_allAppSettings = await getAppSettings();
_allAppFonts = await getAppFonts();
_allFontCombos = await getFontCombos();
_allColorCombos = await getColorCombos();
_initialized = true;
} finally {
_working = false;
}
}
bool get ready =>
super._daoMixinReady && _appInformation.ready && super.ready;

Future _getReady() async {
await super._getDaoMixinReady();
await _appInformation.getReady();
_allAppSettings = await getAppSettings();
_allAppFonts = await getAppFonts();
_allFontCombos = await getFontCombos();
_allColorCombos = await getColorCombos();
}

@override
Expand Down
57 changes: 27 additions & 30 deletions src/sprightly/lib/utils/file_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import 'package:path_provider/path_provider.dart';
import 'package:sprightly/extensions/file_system_entity_extensions.dart';
import 'package:sprightly/extensions/http_response_extensions.dart';
import 'package:sprightly/utils/formatted_exception.dart';
import 'package:sprightly/utils/ready_or_not.dart';

String get _moduleName => 'file_provider';
int get maxCachedRetentionMins => 7 * 24 * 60; // 7 days
Expand Down Expand Up @@ -274,8 +275,11 @@ FormattedException<T> _formattedException<T extends Exception>(
moduleName: _moduleName,
);

class RemoteFileCache {
static RemoteFileCache universal = RemoteFileCache();
class RemoteFileCache with ReadyOrNotMixin {
static RemoteFileCache universal = RemoteFileCache._();
RemoteFileCache._() {
getReadyWorker = _getReady;
}
factory RemoteFileCache() => universal;

final String _cacheDirectory = '__fileCache';
Expand All @@ -286,35 +290,28 @@ class RemoteFileCache {
DirectoryInfo _directoryInfo;
DirectoryInfo get directoryInfo => _directoryInfo;

bool initialized = false;
@override
bool get ready => _ready && super.ready;
bool _ready = false;
bool _working = false;

Future<void> init() async {
if (!initialized && !_working) {
_working = true;
try {
var cacheDirectory = await getDirectory(_cacheDirectory);
if (await cacheDirectory.exists()) {
var oldFileCache =
await getFileText(p.join(_cacheDirectory, _cacheFile));
if (null != oldFileCache)
_fileCache
..clear()
..addAll(json.decode(oldFileCache));
} else
await cacheDirectory.create(recursive: true);

// non-essential for startup. let it be on its own.
// i.e. not await(ing)
compute(DirectoryInfo.readDirectory, cacheDirectory).then((info) {
_directoryInfo = info;
initialized = true;
}).whenComplete(() => _working = false);
} catch (error) {
_working = false;
rethrow;
}
}
Future _getReady() async {
var cacheDirectory = await getDirectory(_cacheDirectory);
if (await cacheDirectory.exists()) {
var oldFileCache = await getFileText(p.join(_cacheDirectory, _cacheFile));
if (null != oldFileCache)
_fileCache
..clear()
..addAll(json.decode(oldFileCache));
} else
await cacheDirectory.create(recursive: true);

// non-essential for startup. let it be on its own.
// i.e. not await(ing)
compute(DirectoryInfo.readDirectory, cacheDirectory).then((info) {
_directoryInfo = info;
_ready = true;
});
}

/// Fetch the file from the [source] url and store in a the local [_cacheDirectory].
Expand Down Expand Up @@ -463,7 +460,7 @@ class RemoteFileCache {
}

Future<bool> cleanUp() async {
if (initialized && !_working) {
if (ready && !_working) {
_working = true;
return _cleanFileCache().whenComplete(() =>
DirectoryInfo.cleanUp(_DirectoryCleanUp(_directoryInfo, _fileCache))
Expand Down
24 changes: 24 additions & 0 deletions src/sprightly/lib/utils/ready_or_not.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import 'dart:async';

typedef FutureOr<T> ReadyOrNotWorker<T>();

mixin ReadyOrNotMixin<T> {
bool _initialized = false;
bool _working = false;
Future<T> _future;
ReadyOrNotWorker<T> getReadyWorker;

bool get ready => _initialized;
FutureOr getReady() async {
if (!_initialized && !_working) {
_working = true;
try {
_future = getReadyWorker();
await _future;
_initialized = true;
} finally {
_working = false;
}
} else if (_working) await _future;
}
}

0 comments on commit 417a996

Please sign in to comment.