platform/packages/redis/lib/src/redis_service.dart

105 lines
3.5 KiB
Dart
Raw Normal View History

2018-10-21 12:29:42 +00:00
import 'dart:async';
import 'dart:convert';
import 'package:angel_framework/angel_framework.dart';
2018-10-21 16:41:23 +00:00
import 'package:resp_client/resp_client.dart';
2018-10-21 12:29:42 +00:00
import 'package:resp_client/resp_commands.dart';
2018-10-21 17:04:21 +00:00
/// An Angel service that reads and writes JSON within a Redis store.
2018-10-21 12:29:42 +00:00
class RedisService extends Service<String, Map<String, dynamic>> {
2021-06-20 12:37:20 +00:00
final RespCommandsTier2 respCommands;
2018-10-21 12:29:42 +00:00
/// 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.
2021-06-20 12:37:20 +00:00
final String? prefix;
2018-10-21 12:29:42 +00:00
RedisService(this.respCommands, {this.prefix});
2021-06-20 12:37:20 +00:00
String? _applyPrefix(String? id) => prefix == null ? id : '$prefix:$id';
2018-10-21 12:29:42 +00:00
2018-10-21 17:26:56 +00:00
@override
Future<List<Map<String, dynamic>>> index(
2021-06-20 12:37:20 +00:00
[Map<String, dynamic>? params]) async {
2018-10-21 17:26:56 +00:00
var result =
2021-06-20 12:37:20 +00:00
//await respCommands.client.writeArrayOfBulk(['KEYS', _applyPrefix('*')]);
await respCommands.tier1.tier0.execute(['KEYS', _applyPrefix('*')]);
2018-10-21 17:26:56 +00:00
var keys = result.payload.map((RespType s) => s.payload) as Iterable;
if (keys.isEmpty) return [];
2021-06-20 12:37:20 +00:00
//result = await respCommands.client.writeArrayOfBulk(['MGET']..addAll(keys));
result = await respCommands.tier1.tier0.execute(['MGET', ...keys]);
if (result.isArray) {
return (result as List<RespType>)
.map<Map<String, dynamic>>((RespType s) =>
json.decode(s.payload as String) as Map<String, dynamic>)
.toList();
} else {
// TODO: To be reviewed for handling none array objects
return [json.decode(result.payload as String) as Map<String, dynamic>];
}
2018-10-21 17:26:56 +00:00
}
2018-10-21 12:29:42 +00:00
@override
Future<Map<String, dynamic>> read(String id,
2021-06-20 12:37:20 +00:00
[Map<String, dynamic>? params]) async {
var value = await respCommands.get(_applyPrefix(id)!);
2018-10-21 12:29:42 +00:00
if (value == null) {
2021-06-20 12:37:20 +00:00
throw AngelHttpException.notFound(message: 'No record found for ID $id');
2018-10-21 12:29:42 +00:00
} else {
2021-06-20 12:37:20 +00:00
return json.decode(value) as Map<String, dynamic>;
2018-10-21 12:29:42 +00:00
}
}
2018-10-21 16:23:08 +00:00
@override
2021-06-20 12:37:20 +00:00
Future<Map<String, dynamic>> create(Map<String, dynamic>? data,
[Map<String, dynamic>? params]) async {
String? id;
if (data!['id'] != null) {
id = data['id'] as String?;
} else {
var keyVar = await respCommands.tier1.tier0
.execute(['INCR', _applyPrefix('angel_redis:id')]);
2018-10-21 16:26:53 +00:00
id = keyVar.payload.toString();
2021-06-20 12:37:20 +00:00
data = Map<String, dynamic>.from(data)..['id'] = id;
2018-10-21 16:23:08 +00:00
}
2021-06-20 12:37:20 +00:00
await respCommands.set(_applyPrefix(id)!, json.encode(data));
2018-10-21 16:23:08 +00:00
return data;
}
2018-10-21 17:04:21 +00:00
@override
2021-06-20 12:37:20 +00:00
Future<Map<String, dynamic>> modify(String id, Map<String, dynamic>? data,
[Map<String, dynamic>? params]) async {
var input = await (read(id));
input.addAll(data!);
2018-10-21 17:04:21 +00:00
return await update(id, input, params);
}
2018-10-21 12:29:42 +00:00
@override
2021-06-20 12:37:20 +00:00
Future<Map<String, dynamic>> update(String id, Map<String, dynamic>? data,
[Map<String, dynamic>? params]) async {
data = Map<String, dynamic>.from(data!)..['id'] = id;
await respCommands.set(_applyPrefix(id)!, json.encode(data));
2018-10-21 12:29:42 +00:00
return data;
}
@override
Future<Map<String, dynamic>> remove(String id,
2021-06-20 12:37:20 +00:00
[Map<String, dynamic>? params]) async {
var client = respCommands.tier1.tier0;
await client.execute(['MULTI']);
await client.execute(['GET', _applyPrefix(id)]);
await client.execute(['DEL', _applyPrefix(id)]);
var result = await client.execute(['EXEC']);
2018-10-21 16:41:23 +00:00
var str = result.payload[0] as RespBulkString;
2018-10-21 16:45:09 +00:00
2021-06-20 12:37:20 +00:00
if (str.payload == null) {
throw AngelHttpException.notFound(message: 'No record found for ID $id');
} else {
return json.decode(str.payload!) as Map<String, dynamic>;
}
2018-10-21 12:29:42 +00:00
}
}