brick_core 1.0.0-nullsafety.1 copy "brick_core: ^1.0.0-nullsafety.1" to clipboard
brick_core: ^1.0.0-nullsafety.1 copied to clipboard

outdated

Interfaces and shared helpers for implementing models, adapters, providers, and repositories in Brick, an intuitive way to work with persistent data in Dart.

example/example.dart

import 'dart:convert';
import 'dart:io';

import 'package:glob/glob.dart';

import 'package:brick_core/core.dart';

abstract class FileModel extends Model {
  String get fileName;

  Future<dynamic> get contents async {
    final contents = await asFile.readAsString();
    if (contents.startsWith('{')) return jsonDecode(contents);
    return contents;
  }

  File get asFile => File(fileName);
}

class User extends FileModel {
  @override
  String get fileName => name;

  final String name;

  User({
    this.name,
  });
}

class FileProvider implements Provider<FileModel> {
  @override
  final FileModelDictionary modelDictionary;
  FileProvider({this.modelDictionary});

  @override
  Future<bool> delete<T extends FileModel>(instance, {query, repository}) async {
    await instance.asFile.delete();
    return true;
  }

  @override
  bool exists<T extends FileModel>({Query query, ModelRepository<FileModel> repository}) => false;

  /// Query.where must always include `filePath`
  @override
  Future<List<T>> get<T extends FileModel>({query, repository}) async {
    final adapter = modelDictionary.adapterFor[T];
    if (query.where != null) {
      final filePath = Where.firstByField('filePath', query.where)?.value;

      final contents = await File('${adapter.directory}/$filePath.json').readAsString();
      return [await adapter.fromFile(contents)];
    }

    final files = Glob('${adapter.directory}/**.${adapter.fileExtension}');
    return Future.wait<T>(files.listSync().map<Future<T>>((file) async {
      final contents = await File(file.path).readAsString();
      return await adapter.fromFile(contents);
    }));
  }

  @override
  Future<T> upsert<T extends FileModel>(instance, {query, repository}) async {
    final adapter = modelDictionary.adapterFor[T];
    final fileContents = await adapter.toFile(instance, provider: this, repository: repository);
    await File(instance.fileName).writeAsString(fileContents);
    return instance;
  }
}

abstract class FileAdapter<_Model extends FileModel> extends Adapter<_Model> {
  /// Folder to store all of these
  String get directory;

  String get fileExtension => '.json';

  String filePath(String fileName) => '$directory/$fileName$fileExtension';

  Future<FileModel> fromFile(
    String data, {
    FileProvider provider,
    ModelRepository<FileModel> repository,
  });
  Future<String> toFile(
    _Model instance, {
    FileProvider provider,
    ModelRepository<FileModel> repository,
  });
}

/// This is generated. As this is an example, `FileProvider` does not
/// have a complimenting build system to generate this adapter. It was handwritten
/// for this example.
class UserAdapter extends FileAdapter<User> {
  @override
  final directory = 'users';

  UserAdapter();

  @override
  Future<User> fromFile(input, {provider, repository}) async {
    final contents = jsonDecode(input);
    return User(name: contents['name']);
  }

  @override
  Future<String> toFile(instance, {provider, repository}) async =>
      jsonEncode({'name': instance.name});
}

class FileModelDictionary extends ModelDictionary<FileModel, FileAdapter> {
  FileModelDictionary(Map<Type, FileAdapter> dictionary) : super(dictionary);
}

final Map<Type, FileAdapter> mappings = {
  User: UserAdapter(),
};
final fileModelDictionary = FileModelDictionary(mappings);

// finally, what the end application sees:
class FileRepository extends SingleProviderRepository<FileModel> {
  FileRepository() : super(FileProvider(modelDictionary: fileModelDictionary));
}

void main() async {
  final repository = FileRepository();

  await repository.upsert<User>(User(name: 'Thomas'));

  final users = await repository.get<User>(query: Query.where('fileName', 'Thomas'));
  await repository.delete<User>(users.first);
}
6
likes
0
pub points
43%
popularity

Publisher

unverified uploader

Interfaces and shared helpers for implementing models, adapters, providers, and repositories in Brick, an intuitive way to work with persistent data in Dart.

Homepage
Repository (GitHub)
View/report issues

License

unknown (LICENSE)

Dependencies

collection

More

Packages that depend on brick_core