Skip to content

Commit

Permalink
Merge pull request #19 from olmps/architecture-updates
Browse files Browse the repository at this point in the history
Architecture updates
  • Loading branch information
matuella authored Apr 2, 2021
2 parents 470730d + 0f34dea commit 02afa7d
Show file tree
Hide file tree
Showing 29 changed files with 444 additions and 414 deletions.
Binary file removed .resources/00arch_overview.png
Binary file not shown.
Binary file added .resources/00arch_overview_simple.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .resources/01arch_overview_complex.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
219 changes: 150 additions & 69 deletions ARCHITECTURE.md

Large diffs are not rendered by default.

9 changes: 7 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
Releases here should only be made whenever there is a build available for them in the respective stores (even if it's
a beta or production release, they must be documented here).

## Unreleased
## [Unreleased]

> Android build: ?
> iOS build: ?
> iOS build: ?
## [0.1.0-dev.1] - 2021-04-01

Initial release, defines core architecture.
The application is unusable on this version.
20 changes: 12 additions & 8 deletions lib/application/view-models/app_vm.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import 'package:flutter/foundation.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:memo/data/database_repository.dart';
import 'package:memo/data/sembast_database.dart' as sembast_db;
import 'package:memo/data/repositories/deck_repository.dart';
import 'package:memo/domain/services/deck_services.dart';
import 'package:memo/data/gateways/document_database_gateway.dart';
import 'package:memo/data/gateways/sembast_database.dart' as sembast_db;
import 'package:sembast/sembast.dart';

/// Manages all app asynchronous dependencies
Expand Down Expand Up @@ -41,14 +43,16 @@ class AppVMImpl extends AppVM {
//
// All of these needs a late initialization due to runtime dependencies, which we will only know after some async
// initialization.
final dbRepo = DatabaseRepositoryImpl(dependencies[0] as Database);
// final exampleServices = HabitsServicesImpl(dbRepo: dbRepo);
// return AppState(exampleServices: exampleServices);
value = AsyncValue.data(AppState());

final dbRepo = SembastGateway(dependencies[0] as Database);
final decksRepo = DeckRepositoryImpl(dbRepo);
final deckServices = DeckServicesImpl(decksRepo);

value = AsyncValue.data(AppState(deckServices: deckServices));
}
}

class AppState {
// const AppState({required this.exampleServices});
// final ExampleServices exampleServices;
const AppState({required this.deckServices});
final DeckServices deckServices;
}
157 changes: 0 additions & 157 deletions lib/data/database_repository.dart

This file was deleted.

90 changes: 90 additions & 0 deletions lib/data/gateways/document_database_gateway.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import 'dart:async';
import 'package:sembast/sembast.dart';

/// Handles the local persistence to the database
abstract class DocumentDatabaseGateway {
/// Adds an [object] to the [store], using a [id]
///
/// If there is already an object with the same [id], the default behavior is to merge all of its fields.
/// [shouldMerge] should be `false` if pre-existing fields should not be merged.
Future<void> put({
required String id,
required Map<String, dynamic> object,
required String store,
bool shouldMerge = true,
});

/// Deletes the value with [id] from the [store]
Future<void> remove({required String id, required String store});

/// Retrieves an object with [id] from the [store]
///
/// Returns `null` if the key doesn't exist
Future<Map<String, dynamic>?> get({required String id, required String store});

/// Retrieves all objects within [store]
Future<List<Map<String, dynamic>>> getAll({required String store});

/// Retrieves a stream of all the [store] objects, triggered whenever any update occurs to this [store]
Future<Stream<List<Map<String, dynamic>>>> listenAll({required String store});
}

//
// DocumentDatabaseGateway implementation using `sembast`
//
class SembastGateway implements DocumentDatabaseGateway {
SembastGateway(this._db);

// `sembast` database instance
final Database _db;

@override
Future<void> put({
required String id,
required Map<String, dynamic> object,
required String store,
bool shouldMerge = true,
}) async {
final storeMap = stringMapStoreFactory.store(store);

await storeMap.record(id).put(_db, object, merge: shouldMerge);
}

@override
Future<void> remove({required String id, required String store}) async {
final storeMap = stringMapStoreFactory.store(store);
await storeMap.record(id).delete(_db);
}

@override
Future<Map<String, dynamic>?> get({required String id, required String store}) async {
final storeMap = stringMapStoreFactory.store(store);
return storeMap.record(id).get(_db);
}

@override
Future<List<Map<String, dynamic>>> getAll({
required String store,
}) async {
final storeMap = stringMapStoreFactory.store(store);

final allRecords = await storeMap.find(_db);
return allRecords.map((record) => record.value).toList();
}

@override
Future<Stream<List<Map<String, dynamic>>>> listenAll({required String store}) async {
final storeMap = stringMapStoreFactory.store(store);

return storeMap.query().onSnapshots(_db).transform(snapshotTransformer);
}

/// Transforms a list of `sembast` snapshot records into a list of objects
final snapshotTransformer =
StreamTransformer<List<RecordSnapshot<String, Map<String, Object?>>>, List<Map<String, Object?>>>.fromHandlers(
handleData: (snapshots, sink) {
final transformedRecords = snapshots.map((record) => record.value).toList();
sink.add(transformedRecords);
},
);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';
import 'package:sembast/sembast.dart';
Expand Down
21 changes: 21 additions & 0 deletions lib/data/repositories/deck_repository.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import 'package:memo/domain/models/deck.dart';
import 'package:memo/data/serializers/deck_serializer.dart';
import 'package:memo/data/gateways/document_database_gateway.dart';

abstract class DeckRepository {
Future<List<Deck>> getAllDecks();
}

class DeckRepositoryImpl implements DeckRepository {
DeckRepositoryImpl(this._db);

final DocumentDatabaseGateway _db;
final _deckSerializer = DeckSerializer();
final _deckStore = 'decks';

@override
Future<List<Deck>> getAllDecks() async {
final rawDecks = await _db.getAll(store: _deckStore);
return rawDecks.map(_deckSerializer.from).toList();
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import 'package:memo/core/faults/errors/serialization_error.dart';
import 'package:memo/data/database_repository.dart';
import 'package:memo/data/serializers/serializer.dart';
import 'package:memo/domain/enums/card_block_type.dart';
import 'package:memo/domain/models/card_block.dart';

class CardBlockSerializer implements JsonSerializer<CardBlock> {
class CardBlockSerializer implements Serializer<CardBlock, Map<String, dynamic>> {
@override
CardBlock fromMap(Map<String, dynamic> json) {
CardBlock from(Map<String, dynamic> json) {
final rawType = json['type'] as String;
final type = _typeFromRaw(rawType);

Expand All @@ -15,7 +15,7 @@ class CardBlockSerializer implements JsonSerializer<CardBlock> {
}

@override
Map<String, dynamic> mapOf(CardBlock block) => <String, dynamic>{
Map<String, dynamic> to(CardBlock block) => <String, dynamic>{
'type': block.type.raw,
'rawContents': block.rawContents,
};
Expand Down
Loading

0 comments on commit 02afa7d

Please sign in to comment.