import 'dart:async'; import 'dart:convert'; import 'package:angel_framework/angel_framework.dart'; import 'package:resp_client/resp_client.dart'; import 'package:resp_client/resp_commands.dart'; /// An Angel service that reads and writes JSON within a Redis store. class RedisService extends Service> { final RespCommands respCommands; /// An optional string prefixed to keys before they are inserted into Redis. /// /// Consider using this if you are using several different Redis collections /// within a single application. final String prefix; RedisService(this.respCommands, {this.prefix}); String _applyPrefix(String id) => prefix == null ? id : '$prefix:$id'; @override Future>> index( [Map params]) async { var result = await respCommands.client.writeArrayOfBulk(['KEYS', _applyPrefix('*')]); var keys = result.payload.map((RespType s) => s.payload) as Iterable; if (keys.isEmpty) return []; result = await respCommands.client.writeArrayOfBulk(['MGET']..addAll(keys)); return result.payload .map>( (RespType s) => json.decode(s.payload) as Map) .toList(); } @override Future> read(String id, [Map params]) async { var value = await respCommands.get(_applyPrefix(id)); if (value == null) { throw new AngelHttpException.notFound( message: 'No record found for ID $id'); } else { return json.decode(value); } } @override Future> create(Map data, [Map params]) async { String id; if (data['id'] != null) id = data['id'] as String; else { var keyVar = await respCommands.client .writeArrayOfBulk(['INCR', _applyPrefix('angel_redis:id')]); id = keyVar.payload.toString(); data = new Map.from(data)..['id'] = id; } await respCommands.set(_applyPrefix(id), json.encode(data)); return data; } @override Future> modify(String id, Map data, [Map params]) async { var input = await read(id); input.addAll(data); return await update(id, input, params); } @override Future> update(String id, Map data, [Map params]) async { data = new Map.from(data)..['id'] = id; await respCommands.set(_applyPrefix(id), json.encode(data)); return data; } @override Future> remove(String id, [Map params]) async { var client = respCommands.client; await client.writeArrayOfBulk(['MULTI']); await client.writeArrayOfBulk(['GET', _applyPrefix(id)]); await client.writeArrayOfBulk(['DEL', _applyPrefix(id)]); var result = await client.writeArrayOfBulk(['EXEC']); var str = result.payload[0] as RespBulkString; if (str.payload == null) throw new AngelHttpException.notFound( message: 'No record found for ID $id'); else return json.decode(str.payload); } }