import 'dart:convert'; import 'package:pocketbase/pocketbase.dart'; import 'package:uae_stat/config/api_config.dart'; abstract class PocketBaseService { static const _host = apiUrl; static final _pb = PocketBase(_host); static PocketBase get client => _pb; static final users = _pb.collection('users'); } /// must assign [T] as entity, which must have /// [jsonEncode] and [jsonDecode] methods. In /// pocketbase, records must be stored in one /// column: data as type json. [V] is entity id /// type class PbCollection { PbCollection( this.collectionIdOrName, { required this.fromJson, this.isNestedInJsonData = true, }); final String collectionIdOrName; final T Function(dynamic json) fromJson; final bool isNestedInJsonData; Map? _entityIdToModelId; RecordService get _collection => PocketBaseService._pb.collection( collectionIdOrName, ); Future> getAll([ Map? filter, ]) async { final modelList = await _collection.getFullList( filter: filter?.entries .map( (e) => isNestedInJsonData ? 'data.${e.key}=${e.value}' : '${e.key} = "${e.value}"', ) .join(' '), ); final entityList = modelList.map( (model) { final source = isNestedInJsonData ? model.data['data'] : model.data; if (!isNestedInJsonData) source['id'] = model.id; final entity = fromJson(source); _entityIdToModelId ??= {}; _entityIdToModelId![entity] = model.id; return entity; }, ).toList(); return entityList; } Future get([ Map filter = const {}, ]) { final filterString = filter.isEmpty ? '' : filter.entries .map( (e) => isNestedInJsonData ? 'data.${e.key}=${jsonEncode(e.value)}' : '${e.key} = ${jsonEncode(e.value)}', ) .join(' '); return _collection .getFirstListItem( filterString, ) .then( (value) => fromJson(value.data['data']), ); } Future delete( T entity, ) => _collection.delete( _entityIdToModelId![entity]!, ); Future write(T e) => _collection.create( body: isNestedInJsonData ? {'data': e} : jsonDecode( jsonEncode(e), ), ); }