• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

jcmellado / dartis / 53

pending completion
53

Pull #25

travis-ci

web-flow
- Fixed coverage configuration
Pull Request #25: Release 0.4.0

2 of 2 new or added lines in 1 file covered. (100.0%)

1238 of 1434 relevant lines covered (86.33%)

1.41 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.57
/lib/src/commands/geo.dart
1
// Copyright (c) 2018, Juan Mellado. All rights reserved. Use of this source
2
// is governed by a MIT-style license that can be found in the LICENSE file.
3

4
import 'dart:async' show Future;
5

6
import '../command.dart';
7
import '../protocol.dart';
8

9
/// A convenient shared mapper for the GEOPOS command.
10
const GeoPositionMapper geoPositionMapper = GeoPositionMapper();
11

12
/// A convenient shared mapper for the GEORADIUS family commands.
13
const GeoRadiusStoreMapper geoRadiusStoreMapper = GeoRadiusStoreMapper();
14

15
/// Redis geo commands.
16
abstract class GeoCommands<K, V> {
17
  /// Adds one or more geospatial items in the geospatial index represented
18
  /// by the sorted set stored at [key].
19
  ///
20
  /// Returns the number of elements added to the sorted set.
21
  ///
22
  /// See https://redis.io/commands/geoadd
23
  Future<int> geoadd(K key,
24
      {GeoItem<V> item, Iterable<GeoItem<V>> items = const []});
25

26
  /// Returns the distance between two members in the geospatial index
27
  /// represented by the sorted set stored at [key].
28
  ///
29
  /// See https://redis.io/commands/geodist
30
  Future<double> geodist(K key, V member1, V member2, {GeoUnit unit});
31

32
  /// Returns members of a geospatial index represented by the sorted set
33
  /// stored at [key] as standard geohash strings.
34
  ///
35
  /// See https://redis.io/commands/geohash
36
  Future<List<String>> geohash(K key,
37
      {V member, Iterable<V> members = const []});
38

39
  /// Returns the positions (longitude, latitude) of all the specified members
40
  /// of the geospatial index represented by the sorted set stored at [key].
41
  ///
42
  /// See https://redis.io/commands/geopos
43
  Future<List<GeoPosition>> geopos(K key,
44
      {V member, Iterable<V> members = const []});
45

46
  /// Queries a geospatial index represented by the sorted set stored at [key]
47
  /// to fetch members matching a given maximum distance from a point.
48
  ///
49
  /// See [georadiusStore].
50
  ///
51
  /// See https://redis.io/commands/georadius
52
  Future<List<GeoradiusResult<V>>> georadius(
53
      K key, double longitude, double latitude, double radius, GeoUnit unit,
54
      {bool withCoord = false,
55
      bool withDist = false,
56
      bool withHash = false,
57
      int count,
58
      GeoOrder order});
59

60
  /// Queries a geospatial index represented by the sorted set stored at [key]
61
  /// to fetch members matching a given maximum distance from a point and
62
  /// stores the result.
63
  ///
64
  /// See [georadius].
65
  ///
66
  /// See https://redis.io/commands/georadius
67
  Future<int> georadiusStore(
68
      K key, double longitude, double latitude, double radius, GeoUnit unit,
69
      {int count, GeoOrder order, K storeKey, K storeDistKey});
70

71
  /// Queries a geospatial index represented by the sorted set stored at [key]
72
  /// to fetch members matching a given maximum distance from a member.
73
  ///
74
  /// See [georadiusbymemberStore].
75
  ///
76
  /// See https://redis.io/commands/georadiusbymember
77
  Future<List<GeoradiusResult<V>>> georadiusbymember(
78
      K key, V member, double radius, GeoUnit unit,
79
      {bool withCoord = false,
80
      bool withDist = false,
81
      bool withHash = false,
82
      int count,
83
      GeoOrder order});
84

85
  /// Queries a geospatial index represented by the sorted set stored at [key]
86
  /// to fetch members matching a given maximum distance from a member and
87
  /// stores the result.
88
  ///
89
  /// See [georadiusbymember].
90
  ///
91
  /// See https://redis.io/commands/georadiusbymember
92
  Future<int> georadiusbymemberStore(
93
      K key, V member, double radius, GeoUnit unit,
94
      {int count, GeoOrder order, K storeKey, K storeDistKey});
95
}
96

97
/// Metric units.
98
class GeoUnit {
99
  /// The name of the unit.
100
  final String name;
101

102
  const GeoUnit._(this.name);
×
103

104
  /// Meter.
105
  static const GeoUnit meter = GeoUnit._(r'm');
106

107
  /// Kilometer.
108
  static const GeoUnit kilometer = GeoUnit._(r'km');
109

110
  /// Mile.
111
  static const GeoUnit mile = GeoUnit._(r'mi');
112

113
  /// Feet.
114
  static const GeoUnit feet = GeoUnit._(r'ft');
115

116
  @override
1✔
117
  String toString() => 'GeoUnit: $name';
2✔
118
}
119

120
/// Orders.
121
class GeoOrder {
122
  /// The name of the order.
123
  final String name;
124

125
  const GeoOrder._(this.name);
×
126

127
  /// Ascending.
128
  static const GeoOrder ascending = GeoOrder._(r'ASC');
129

130
  /// Descending.
131
  static const GeoOrder descending = GeoOrder._(r'DESC');
132

133
  @override
1✔
134
  String toString() => 'GeoOrder: $name';
2✔
135
}
136

137
/// A geospatial position represented by its longitude and latitude.
138
class GeoPosition {
139
  /// The longitude.
140
  final double longitude;
141

142
  /// The latitude.
143
  final double latitude;
144

145
  /// Creates a [GeoPosition] instance.
146
  const GeoPosition(this.longitude, this.latitude);
1✔
147

148
  @override
1✔
149
  String toString() =>
150
      'GeoPosition: {longitude=$longitude, latitude=$latitude}';
3✔
151
}
152

153
/// A item to be added with the GEOADD command.
154
class GeoItem<V> {
155
  /// The position.
156
  final GeoPosition position;
157

158
  /// The member.
159
  final V member;
160

161
  /// Creates a [GeoItem] instance.
162
  const GeoItem(this.position, this.member);
×
163

164
  @override
1✔
165
  String toString() => 'GeoItem<$V>: {position=$position, member=$member}';
3✔
166
}
167

168
/// A result from the GEORADIUS command.
169
class GeoradiusResult<V> {
170
  /// The member.
171
  final V member;
172

173
  /// The distance.
174
  final double distance;
175

176
  /// The hash.
177
  final int hash;
178

179
  /// The position.
180
  final GeoPosition position;
181

182
  /// Creates a [GeoradiusResult] instance.
183
  const GeoradiusResult(this.member, {this.distance, this.hash, this.position});
1✔
184

185
  @override
1✔
186
  String toString() => '''GeoradiusResult<$V>: {member=$member,'''
1✔
187
      ''' distance=$distance, hash=$hash, position=$position}''';
3✔
188
}
189

190
/// A mapper to be used with the GEOPOS command.
191
class GeoPositionMapper implements Mapper<List<GeoPosition>> {
192
  /// Creates a [GeoPositionMapper] instance.
193
  const GeoPositionMapper();
×
194

195
  @override
1✔
196
  List<GeoPosition> map(covariant ArrayReply reply, RedisCodec codec) =>
197
      reply.array
1✔
198
          // ignore: avoid_as
199
          .map((value) => _mapPosition(value as ArrayReply, codec))
3✔
200
          .toList();
1✔
201

202
  /// Maps a [reply] to `null` or a [GeoPosition] instance.
203
  GeoPosition _mapPosition(ArrayReply reply, RedisCodec codec) {
1✔
204
    final array = reply.array;
1✔
205

206
    if (array == null) {
207
      return null;
208
    }
209

210
    final longitude = codec.decode<double>(array[0]);
2✔
211
    final latitude = codec.decode<double>(array[1]);
2✔
212

213
    return GeoPosition(longitude, latitude);
1✔
214
  }
215
}
216

217
/// A mapper to be used with the GEORADIUS family commands.
218
class GeoRadiusMapper<V> implements Mapper<List<GeoradiusResult<V>>> {
219
  /// Return the distance of the returned items from the specified center.
220
  final bool withCoord;
221

222
  /// Return the longitude,latitude coordinates of the returned items.
223
  final bool withDist;
224

225
  /// Return the raw geohash-encoded sorted set score of the returned items.
226
  final bool withHash;
227

228
  /// Creates a [GeoRadiusMapper] instance.
229
  const GeoRadiusMapper(
1✔
230
      {this.withCoord = false, this.withDist = false, this.withHash = false});
231

232
  @override
1✔
233
  List<GeoradiusResult<V>> map(covariant ArrayReply reply, RedisCodec codec) {
234
    final results = <GeoradiusResult<V>>[];
1✔
235

236
    for (final reply in reply.array) {
2✔
237
      if (withCoord || withDist || withHash) {
3✔
238
        // ignore: avoid_as
239
        final result = _mapResult(reply as ArrayReply, codec);
1✔
240
        results.add(result);
1✔
241
      } else {
242
        final member = codec.decode<V>(reply);
1✔
243
        results.add(GeoradiusResult<V>(member));
2✔
244
      }
245
    }
246

247
    return results;
248
  }
249

250
  /// Maps a [reply] to a [GeoradiusResult] instance.
251
  GeoradiusResult<V> _mapResult(ArrayReply reply, RedisCodec codec) {
1✔
252
    final array = reply.array;
1✔
253
    var index = 0;
254

255
    final member = codec.decode<V>(array[index++]);
3✔
256

257
    double distance;
258
    if (withDist) {
1✔
259
      distance = codec.decode<double>(array[index++]);
3✔
260
    }
261

262
    int hash;
263
    if (withHash) {
1✔
264
      hash = codec.decode<int>(array[index++]);
3✔
265
    }
266

267
    GeoPosition position;
268
    if (withCoord) {
1✔
269
      // ignore: avoid_as
270
      position = _mapPosition(array[index++] as ArrayReply, codec);
3✔
271
    }
272

273
    return GeoradiusResult<V>(member,
1✔
274
        distance: distance, hash: hash, position: position);
275
  }
276

277
  /// Maps a [reply] to a [GeoPosition] instance.
278
  GeoPosition _mapPosition(ArrayReply reply, RedisCodec codec) {
1✔
279
    final longitude = codec.decode<double>(reply.array[0]);
3✔
280
    final latitude = codec.decode<double>(reply.array[1]);
3✔
281

282
    return GeoPosition(longitude, latitude);
1✔
283
  }
284
}
285

286
/// A mapper to be used with the GEORADIUS family commands.
287
class GeoRadiusStoreMapper implements Mapper<int> {
288
  /// Creates a [GeoRadiusStoreMapper] instance.
289
  const GeoRadiusStoreMapper();
×
290

291
  @override
1✔
292
  int map(Reply reply, RedisCodec codec) {
293
    if (reply is ArrayReply) {
1✔
294
      return 0;
295
    }
296

297
    return codec.decode<int>(reply);
1✔
298
  }
299
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2023 Coveralls, Inc