feat(crud) : new package for crud operations

This commit is contained in:
Hugo Pointcheval 2022-04-20 22:57:14 +02:00
parent e3776259df
commit b38fea130f
22 changed files with 1022 additions and 0 deletions

10
packages/wyatt_crud_bloc/.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
# Files and directories created by pub.
.dart_tool/
.packages
# Conventional directory for build outputs.
build/
# Omit committing pubspec.lock for library packages; see
# https://dart.dev/guides/libraries/private-files#pubspeclock.
pubspec.lock

View File

@ -0,0 +1,3 @@
## 1.0.0
- Initial version.

View File

@ -0,0 +1,39 @@
<!--
This README describes the package. If you publish this package to pub.dev,
this README's contents appear on the landing page for your package.
For information about how to write a good package README, see the guide for
[writing package pages](https://dart.dev/guides/libraries/writing-package-pages).
For general information about developing packages, see the Dart guide for
[creating packages](https://dart.dev/guides/libraries/create-library-packages)
and the Flutter guide for
[developing packages and plugins](https://flutter.dev/developing-packages).
-->
TODO: Put a short description of the package here that helps potential users
know whether this package might be useful for them.
## Features
TODO: List what your package can do. Maybe include images, gifs, or videos.
## Getting started
TODO: List prerequisites and provide or point to information on how to
start using the package.
## Usage
TODO: Include short and useful examples for package users. Add longer examples
to `/example` folder.
```dart
const like = 'sample';
```
## Additional information
TODO: Tell users more about the package: where to find more information, how to
contribute to the package, how to file issues, what response they can expect
from the package authors, and more.

View File

@ -0,0 +1 @@
include: package:wyatt_analysis/analysis_options.flutter.yaml

View File

@ -0,0 +1,18 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
export 'crud_builder.dart';
export 'crud_stream_builder.dart';

View File

@ -0,0 +1,53 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:wyatt_crud_bloc/src/crud/cubit/crud_cubit.dart';
import 'package:wyatt_crud_bloc/src/models/model.dart';
class CrudBuilder<T extends Model<Object?, T>> extends StatelessWidget {
const CrudBuilder({
Key? key,
this.onIdle,
required this.onLoading,
required this.onError,
required this.onSuccess,
}) : super(key: key);
final Widget Function(BuildContext, CrudState<T>)? onIdle;
final Widget Function(BuildContext, CrudState<T>) onLoading;
final Widget Function(BuildContext, CrudState<T>) onError;
final Widget Function(BuildContext, CrudState<T>) onSuccess;
@override
Widget build(BuildContext context) {
return BlocBuilder<CrudCubit<T>, CrudState<T>>(
builder: (context, state) {
switch (state.status) {
case CrudStatus.idle:
return onIdle?.call(context, state) ?? onError.call(context, state);
case CrudStatus.loading:
return onLoading.call(context, state);
case CrudStatus.failure:
return onError.call(context, state);
case CrudStatus.success:
return onSuccess.call(context, state);
}
},
);
}
}

View File

@ -0,0 +1,55 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:wyatt_crud_bloc/src/crud/cubit/crud_cubit.dart';
import 'package:wyatt_crud_bloc/src/models/model.dart';
class CrudStreamBuilder<T extends Model<Object?, T>> extends StatelessWidget {
const CrudStreamBuilder({
Key? key,
required this.onLoading,
required this.onError,
required this.onStream,
}) : super(key: key);
final Widget Function(BuildContext, List<T?>) onStream;
final Widget Function(BuildContext, CrudState<T>) onLoading;
final Widget Function(BuildContext, CrudState<T>) onError;
@override
Widget build(BuildContext context) {
return BlocBuilder<CrudCubit<T>, CrudState<T>>(
builder: (context, state) {
if (state.stream != null) {
return StreamBuilder<List<T?>>(
stream: state.stream,
builder: (context, snapshot) {
if (snapshot.hasData) {
return onStream(context, snapshot.data!);
} else {
return onLoading(context, state);
}
},
);
} else {
return onError(context, state);
}
},
);
}
}

View File

@ -0,0 +1,18 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
export 'builder/builder.dart';
export 'cubit/crud_cubit.dart';

View File

@ -0,0 +1,219 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:wyatt_crud_bloc/src/models/model.dart';
import 'package:wyatt_crud_bloc/src/models/queries/queries_interface.dart';
import 'package:wyatt_crud_bloc/src/repositories/crud_repository_interface.dart';
part 'crud_state.dart';
class CrudCubit<T extends Model<Object?, T>> extends Cubit<CrudState<T>> {
final CrudRepositoryInterface<T> _crudRepository;
// ignore: prefer_const_constructors
CrudCubit(this._crudRepository) : super(CrudState());
// Here we can't use `const` because we need the generic type T
void reset() {
// ignore: prefer_const_constructors
emit(CrudState());
// Same here, because of `const` we can't use T generic type
}
Future<void> create(Model object, {String? id}) async {
emit(state.copyWith(status: CrudStatus.loading));
try {
await _crudRepository.create(object, id: id);
final data = state.data..addAll([object].cast<T>());
emit(
state.copyWith(
data: data,
status: CrudStatus.success,
),
);
} catch (e) {
// TODO(hpcl): implement Exception
emit(
state.copyWith(
status: CrudStatus.failure,
errorMessage: e.toString(),
),
);
}
}
Future<void> delete(String id) async {
emit(state.copyWith(status: CrudStatus.loading));
try {
await _crudRepository.delete(id);
final data = state.data
..removeWhere((element) => element!.id != null && element.id == id);
emit(
state.copyWith(
data: data,
status: CrudStatus.success,
),
);
} catch (e) {
emit(
state.copyWith(
status: CrudStatus.failure,
errorMessage: e.toString(),
),
);
}
}
Future<void> deleteAll() async {
emit(state.copyWith(status: CrudStatus.loading));
try {
await _crudRepository.deleteAll();
emit(
state.copyWith(
data: [],
status: CrudStatus.success,
),
);
} catch (e) {
emit(
state.copyWith(
status: CrudStatus.failure,
errorMessage: e.toString(),
),
);
}
}
Future<void> get(String id) async {
emit(state.copyWith(status: CrudStatus.loading));
try {
final data = await _crudRepository.get(id);
emit(
state.copyWith(
data: [data].cast<T>(),
status: CrudStatus.success,
),
);
} catch (e) {
emit(
state.copyWith(
status: CrudStatus.failure,
errorMessage: e.toString(),
),
);
}
}
Future<void> getAll() async {
emit(state.copyWith(status: CrudStatus.loading));
try {
final data = await _crudRepository.getAll();
emit(
state.copyWith(
data: data.cast<T>(),
status: CrudStatus.success,
),
);
} catch (e) {
emit(
state.copyWith(
status: CrudStatus.failure,
errorMessage: e.toString(),
),
);
}
}
Future<void> query(List<QueryInterface> conditions) async {
emit(state.copyWith(status: CrudStatus.loading));
try {
final data = await _crudRepository.query(conditions);
emit(
state.copyWith(
data: data.cast<T>(),
status: CrudStatus.success,
),
);
} catch (e) {
emit(
state.copyWith(
status: CrudStatus.failure,
errorMessage: e.toString(),
),
);
}
}
Future<void> streamOf({String? id}) async {
emit(state.copyWith(status: CrudStatus.loading));
try {
final Stream<List<T?>> data = _crudRepository.stream(id: id);
emit(
state.copyWith(
stream: data,
status: CrudStatus.success,
),
);
} catch (e) {
emit(
state.copyWith(
status: CrudStatus.failure,
errorMessage: e.toString(),
),
);
}
}
Future<void> update(
String id, {
Model? object,
Map<String, dynamic>? raw,
}) async {
emit(state.copyWith(status: CrudStatus.loading));
try {
await _crudRepository.update(
id,
object: object,
raw: raw,
);
emit(state.copyWith(status: CrudStatus.success));
} catch (e) {
emit(
state.copyWith(
status: CrudStatus.failure,
errorMessage: e.toString(),
),
);
}
}
Future<void> updateAll(Map<String, Object?> raw) async {
emit(state.copyWith(status: CrudStatus.loading));
try {
await _crudRepository.updateAll(raw);
emit(state.copyWith(status: CrudStatus.success));
} catch (e) {
emit(
state.copyWith(
status: CrudStatus.failure,
errorMessage: e.toString(),
),
);
}
}
}

View File

@ -0,0 +1,60 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
part of 'crud_cubit.dart';
enum CrudStatus {
idle,
loading,
success,
failure,
}
class CrudState<T> extends Equatable {
final CrudStatus status;
final List<T?> data;
final Stream<List<T?>>? stream;
final String? errorMessage;
const CrudState({
this.status = CrudStatus.idle,
this.data = const [],
this.stream,
this.errorMessage,
});
@override
List<Object?> get props => [status, data];
CrudState<T> copyWith({
CrudStatus? status,
List<T?>? data,
Stream<List<T?>>? stream,
String? errorMessage,
}) {
return CrudState<T>(
status: status ?? this.status,
data: data ?? this.data,
stream: stream ?? this.stream,
errorMessage: errorMessage ?? this.errorMessage,
);
}
@override
String toString() =>
// ignore: lines_longer_than_80_chars
'CrudState(status: $status, data: $data, stream: ${stream != null ? 'listening' : 'null'}, errorMessage: $errorMessage)';
}

View File

@ -0,0 +1,21 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
abstract class Model<O, T> {
String? get id;
Map<String, Object> toMap();
T? from(O? object);
}

View File

@ -0,0 +1,18 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
export 'model.dart';
export 'queries/queries.dart';

View File

@ -0,0 +1,18 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
export 'queries_firestore.dart';
export 'queries_interface.dart';

View File

@ -0,0 +1,88 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:wyatt_crud_bloc/src/models/queries/queries_interface.dart';
class QueryParserFirestore implements QueryParserInterface {
@override
Query parser(QueryInterface condition, Object query) {
query as Query;
if (condition is WhereQueryInterface) {
switch (condition.type) {
case WhereQueryType.isEqualTo:
return query.where(condition.field, isEqualTo: condition.value);
case WhereQueryType.isNotEqualTo:
return query.where(condition.field, isNotEqualTo: condition.value);
case WhereQueryType.isLessThan:
return query.where(condition.field, isLessThan: condition.value);
case WhereQueryType.isLessThanOrEqualTo:
return query.where(
condition.field,
isLessThanOrEqualTo: condition.value,
);
case WhereQueryType.isGreaterThan:
return query.where(condition.field, isGreaterThan: condition.value);
case WhereQueryType.isGreaterThanOrEqualTo:
return query.where(
condition.field,
isGreaterThanOrEqualTo: condition.value,
);
case WhereQueryType.arrayContains:
return query.where(condition.field, arrayContains: condition.value);
case WhereQueryType.arrayContainsAny:
return query.where(
condition.field,
arrayContainsAny: condition.value as List<Object>,
);
case WhereQueryType.whereIn:
return query.where(
condition.field,
whereIn: condition.value as List<Object>,
);
case WhereQueryType.whereNotIn:
return query.where(
condition.field,
whereNotIn: condition.value as List<Object>,
);
case WhereQueryType.isNull:
return query.where(condition.field, isNull: condition.value as bool);
}
} else if (condition is LimitQueryInterface) {
return query.limit(condition.limit);
} else if (condition is OrderByQueryInterface) {
return query.orderBy(
condition.field,
descending: !condition.ascending,
);
}
return query;
}
}
class WhereQueryFirestore extends WhereQueryInterface {
WhereQueryFirestore(WhereQueryType type, String field, Object value)
: super(type, field, value);
}
class LimitQueryFirestore extends LimitQueryInterface {
LimitQueryFirestore(int limit) : super(limit);
}
class OrderByQueryFirestore extends OrderByQueryInterface {
OrderByQueryFirestore(String field, {bool ascending = true})
: super(field, ascending: ascending);
}

View File

@ -0,0 +1,57 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// ignore: one_member_abstracts
abstract class QueryParserInterface {
Object parser(QueryInterface condition, Object query);
}
abstract class QueryInterface {}
enum WhereQueryType {
isEqualTo,
isNotEqualTo,
isLessThan,
isLessThanOrEqualTo,
isGreaterThan,
isGreaterThanOrEqualTo,
arrayContains,
arrayContainsAny,
whereIn,
whereNotIn,
isNull,
}
abstract class WhereQueryInterface extends QueryInterface {
final WhereQueryType type;
final String field;
final Object value;
WhereQueryInterface(this.type, this.field, this.value);
}
abstract class LimitQueryInterface extends QueryInterface {
final int limit;
LimitQueryInterface(this.limit);
}
abstract class OrderByQueryInterface extends QueryInterface {
final String field;
final bool ascending;
OrderByQueryInterface(this.field, {this.ascending = true});
}

View File

@ -0,0 +1,102 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:firebase_database/firebase_database.dart';
import 'package:wyatt_crud_bloc/src/models/model.dart';
import 'package:wyatt_crud_bloc/src/models/queries/queries_interface.dart';
import 'package:wyatt_crud_bloc/src/repositories/crud_repository_interface.dart';
class CrudRepositoryFirebaseDatabase<T> implements CrudRepositoryInterface<T> {
final FirebaseDatabase _firebaseDatabase;
final Model<Object, T> _parser;
late DatabaseReference _rootReference;
CrudRepositoryFirebaseDatabase(
String root,
Model<Object, T> parser, {
FirebaseDatabase? firebaseDatabase,
}) : _firebaseDatabase = firebaseDatabase ?? FirebaseDatabase.instance,
_parser = parser {
_rootReference = _firebaseDatabase.ref(root);
}
@override
Future<void> create(Model object, {String? id}) {
DatabaseReference _reference = _rootReference;
if (id != null) {
_reference = _reference.child(id);
}
return _reference.set(object.toMap());
}
@override
Future<void> delete(String id) {
final DatabaseReference _reference = _rootReference.child(id);
return _reference.remove();
}
@override
Future<void> deleteAll() {
return _rootReference.remove();
}
@override
Future<T?> get(String id) async {
final DatabaseEvent _event = await _rootReference.child(id).once();
return _parser.from(_event.snapshot.value);
}
@override
Future<List<T?>> getAll() async {
final DatabaseEvent _event = await _rootReference.once();
final List<T?> _objects = [];
_event.snapshot.children.map((e) => _objects.add(_parser.from(e.value)));
return _objects;
}
@override
Future<List<T?>> query(List<QueryInterface> conditions) {
// TODO(hpcl): implement query
throw UnimplementedError();
}
@override
Stream<List<T?>> stream({String? id, List<QueryInterface>? conditions}) {
DatabaseReference _reference = _rootReference;
if (id != null) {
_reference = _reference.child(id);
}
return _reference.onValue.map((e) {
final List<T?> _objects = [];
e.snapshot.children.map((e) => _objects.add(_parser.from(e.value)));
return _objects;
});
}
@override
Future<void> update(String id, {Model? object, Map<String, dynamic>? raw}) {
// TODO(hpcl): implement update
throw UnimplementedError();
}
@override
Future<void> updateAll(Map<String, Object?> raw) {
// TODO(hpcl): implement updateAll
throw UnimplementedError();
}
}

View File

@ -0,0 +1,146 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:wyatt_crud_bloc/src/models/model.dart';
import 'package:wyatt_crud_bloc/src/models/queries/queries_firestore.dart';
import 'package:wyatt_crud_bloc/src/models/queries/queries_interface.dart';
import 'package:wyatt_crud_bloc/src/repositories/crud_repository_interface.dart';
class CrudRepositoryFirestore<T> implements CrudRepositoryInterface<T> {
final FirebaseFirestore _firestore;
final Model<DocumentSnapshot, T> _parser;
late CollectionReference _collectionReference;
CrudRepositoryFirestore(
String collection,
Model<DocumentSnapshot, T> parser, {
FirebaseFirestore? firestore,
}) : _firestore = firestore ?? FirebaseFirestore.instance,
_parser = parser {
_collectionReference = _firestore.collection(collection);
}
@override
Future<void> create(Model object, {String? id}) {
if (id != null) {
return _collectionReference.doc(id).set(object.toMap());
} else {
return _collectionReference.add(object.toMap());
}
}
@override
Future<void> delete(String id) {
return _collectionReference.doc(id).delete();
}
@override
Future<void> deleteAll() async {
final _batch = _firestore.batch();
final QuerySnapshot snapshots = await _collectionReference.get();
for (final DocumentSnapshot snapshot in snapshots.docs) {
_batch.delete(snapshot.reference);
}
return _batch.commit();
}
@override
Future<T?> get(String id) async {
final DocumentSnapshot snapshot = await _collectionReference.doc(id).get();
return _parser.from(snapshot);
}
@override
Future<List<T?>> getAll() async {
final QuerySnapshot snapshots = await _collectionReference.get();
return snapshots.docs.map(_parser.from).toList();
}
@override
Future<List<T?>> query(List<QueryInterface> conditions) async {
Query query = _collectionReference;
for (final condition in conditions) {
query = QueryParserFirestore().parser(condition, query);
}
final QuerySnapshot snapshots = await query.get();
return snapshots.docs.map(_parser.from).toList();
}
@override
Stream<List<T?>> stream({
String? id,
List<QueryInterface>? conditions,
bool includeMetadataChanges = false,
}) {
if (id != null) {
return _collectionReference
.doc(id)
.snapshots(
includeMetadataChanges: includeMetadataChanges,
)
.map<List<T?>>(
(DocumentSnapshot snapshot) => [_parser.from(snapshot)],
);
} else {
if (conditions != null) {
Query query = _collectionReference;
for (final condition in conditions) {
query = QueryParserFirestore().parser(condition, query);
}
return query
.snapshots(
includeMetadataChanges: includeMetadataChanges,
)
.map((querySnapshot) {
return querySnapshot.docs.map(_parser.from).toList();
});
} else {
return _collectionReference
.snapshots(
includeMetadataChanges: includeMetadataChanges,
)
.map((querySnapshot) {
return querySnapshot.docs.map(_parser.from).toList();
});
}
}
}
@override
Future<void> update(String id, {Model? object, Map<String, Object?>? raw}) {
if (object != null) {
return _collectionReference.doc(id).update(object.toMap());
} else {
if (raw != null) {
return _collectionReference.doc(id).update(raw);
} else {
throw Exception('You must provide an object or a raw map');
}
}
}
@override
Future<void> updateAll(Map<String, Object?> raw) async {
final _batch = _firestore.batch();
final QuerySnapshot snapshots = await _collectionReference.get();
for (final DocumentSnapshot snapshot in snapshots.docs) {
_batch.update(snapshot.reference, raw);
}
return _batch.commit();
}
}

View File

@ -0,0 +1,30 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:wyatt_crud_bloc/src/models/model.dart';
import 'package:wyatt_crud_bloc/src/models/queries/queries_interface.dart';
abstract class CrudRepositoryInterface<T> {
Future<void> create(Model object, {String? id});
Future<void> delete(String id);
Future<void> deleteAll();
Future<T?> get(String id);
Future<List<T?>> getAll();
Future<List<T?>> query(List<QueryInterface> conditions);
Stream<List<T?>> stream({String? id, List<QueryInterface>? conditions});
Future<void> update(String id, {Model? object, Map<String, dynamic>? raw});
Future<void> updateAll(Map<String, Object?> raw);
}

View File

@ -0,0 +1,18 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
export 'crud_repository_firestore.dart';
export 'crud_repository_interface.dart';

View File

@ -0,0 +1,21 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
library wyatt_crud_bloc;
export 'src/crud/crud.dart';
export 'src/models/models.dart';
export 'src/repositories/repositories.dart';

View File

@ -0,0 +1,27 @@
name: wyatt_crud_bloc
description: Create/Read/Update/Delete BLoC for Flutter
repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_crud_bloc
version: 0.0.2
environment:
sdk: '>=2.16.2 <3.0.0'
flutter: ">=1.17.0"
dependencies:
flutter:
sdk: flutter
flutter_bloc: ^8.0.1
equatable: ^2.0.3
cloud_firestore: ^3.1.12
firebase_database: ^9.0.11
dev_dependencies:
flutter_test:
sdk: flutter
bloc_test: ^9.0.3
wyatt_analysis:
git:
url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages
ref: wyatt_analysis-v2.0.0
path: packages/wyatt_analysis