1
- using NUnit . Framework ;
1
+ using System . Collections . Generic ;
2
+ using System . Linq ;
3
+ using NUnit . Framework ;
2
4
using ServiceStack . Text ;
3
5
4
6
namespace ServiceStack . Redis . Tests
@@ -80,5 +82,149 @@ public void Can_call_Cached_Lua_even_after_script_is_flushed()
80
82
Assert . That ( r . Children . Count , Is . EqualTo ( 10 ) ) ;
81
83
}
82
84
}
85
+
86
+ private const string KeyAttributesScript = @"
87
+ local limit = tonumber(ARGV[2])
88
+ local pattern = ARGV[1]
89
+ local cursor = 0
90
+ local len = 0
91
+ local keys = {}
92
+
93
+ repeat
94
+ local r = redis.call('scan', cursor, 'MATCH', pattern, 'COUNT', limit)
95
+ cursor = tonumber(r[1])
96
+ for k,v in ipairs(r[2]) do
97
+ table.insert(keys, v)
98
+ len = len + 1
99
+ if len == limit then break end
100
+ end
101
+ until cursor == 0 or len == limit
102
+
103
+ local keyAttrs = {}
104
+ for i,key in ipairs(keys) do
105
+ local type = redis.call('type', key)['ok']
106
+ local pttl = redis.call('pttl', key)
107
+ local size = 0
108
+ if type == 'string' then
109
+ size = redis.call('strlen', key)
110
+ elseif type == 'list' then
111
+ size = redis.call('llen', key)
112
+ elseif type == 'set' then
113
+ size = redis.call('scard', key)
114
+ elseif type == 'zset' then
115
+ size = redis.call('zcard', key)
116
+ elseif type == 'hash' then
117
+ size = redis.call('hlen', key)
118
+ end
119
+
120
+ local attrs = {['id'] = key, ['type'] = type, ['ttl'] = pttl, ['size'] = size}
121
+
122
+ table.insert(keyAttrs, attrs)
123
+ end
124
+
125
+ return cjson.encode(keyAttrs)" ;
126
+
127
+ [ Test ]
128
+ public void Can_call_script_with_complex_response ( )
129
+ {
130
+ using ( var redis = new RedisClient ( ) )
131
+ {
132
+ var r = redis . ExecCachedLua ( KeyAttributesScript , sha1 =>
133
+ redis . ExecLuaShaAsString ( sha1 , "key:*" , "10" ) ) ;
134
+
135
+ r . Print ( ) ;
136
+
137
+ var results = r . FromJson < List < SearchResult > > ( ) ;
138
+
139
+ Assert . That ( results . Count , Is . EqualTo ( 10 ) ) ;
140
+
141
+ var result = results [ 0 ] ;
142
+ Assert . That ( result . Id . StartsWith ( "key:" ) ) ;
143
+ Assert . That ( result . Type , Is . EqualTo ( "string" ) ) ;
144
+ Assert . That ( result . Size , Is . GreaterThan ( "value:" . Length ) ) ;
145
+ Assert . That ( result . Ttl , Is . EqualTo ( - 1 ) ) ;
146
+ }
147
+ }
148
+
149
+ public class SearchResult
150
+ {
151
+ public string Id { get ; set ; }
152
+ public string Type { get ; set ; }
153
+ public long Ttl { get ; set ; }
154
+ public long Size { get ; set ; }
155
+ }
156
+
157
+ [ Test ]
158
+ public void Can_merge_multiple_SearchResults ( )
159
+ {
160
+ var Redis = new RedisClient ( ) ;
161
+ var limit = 10 ;
162
+ var query = "key:*" ;
163
+
164
+ var keys = Redis . ScanAllKeys ( pattern : query , pageSize : limit )
165
+ . Take ( limit ) . ToList ( ) ;
166
+
167
+ var keyTypes = new Dictionary < string , string > ( ) ;
168
+ var keyTtls = new Dictionary < string , long > ( ) ;
169
+ var keySizes = new Dictionary < string , long > ( ) ;
170
+
171
+ if ( keys . Count > 0 )
172
+ {
173
+ using ( var pipeline = Redis . CreatePipeline ( ) )
174
+ {
175
+ keys . Each ( key =>
176
+ pipeline . QueueCommand ( r => r . Type ( key ) , x => keyTypes [ key ] = x ) ) ;
177
+
178
+ keys . Each ( key =>
179
+ pipeline . QueueCommand ( r => ( ( RedisNativeClient ) r ) . PTtl ( key ) , x => keyTtls [ key ] = x ) ) ;
180
+
181
+ pipeline . Flush ( ) ;
182
+ }
183
+
184
+ using ( var pipeline = Redis . CreatePipeline ( ) )
185
+ {
186
+ foreach ( var entry in keyTypes )
187
+ {
188
+ var key = entry . Key ;
189
+ switch ( entry . Value )
190
+ {
191
+ case "string" :
192
+ pipeline . QueueCommand ( r => r . GetStringCount ( key ) , x => keySizes [ key ] = x ) ;
193
+ break ;
194
+ case "list" :
195
+ pipeline . QueueCommand ( r => r . GetListCount ( key ) , x => keySizes [ key ] = x ) ;
196
+ break ;
197
+ case "set" :
198
+ pipeline . QueueCommand ( r => r . GetSetCount ( key ) , x => keySizes [ key ] = x ) ;
199
+ break ;
200
+ case "zset" :
201
+ pipeline . QueueCommand ( r => r . GetSortedSetCount ( key ) , x => keySizes [ key ] = x ) ;
202
+ break ;
203
+ case "hash" :
204
+ pipeline . QueueCommand ( r => r . GetHashCount ( key ) , x => keySizes [ key ] = x ) ;
205
+ break ;
206
+ }
207
+ }
208
+
209
+ pipeline . Flush ( ) ;
210
+ }
211
+ }
212
+
213
+ var results = keys . Map ( x => new SearchResult
214
+ {
215
+ Id = x ,
216
+ Type = keyTypes . GetValueOrDefault ( x ) ,
217
+ Ttl = keyTtls . GetValueOrDefault ( x ) ,
218
+ Size = keySizes . GetValueOrDefault ( x ) ,
219
+ } ) ;
220
+
221
+ Assert . That ( results . Count , Is . EqualTo ( limit ) ) ;
222
+
223
+ var result = results [ 0 ] ;
224
+ Assert . That ( result . Id . StartsWith ( "key:" ) ) ;
225
+ Assert . That ( result . Type , Is . EqualTo ( "string" ) ) ;
226
+ Assert . That ( result . Size , Is . GreaterThan ( "value:" . Length ) ) ;
227
+ Assert . That ( result . Ttl , Is . EqualTo ( - 1 ) ) ;
228
+ }
83
229
}
84
230
}
0 commit comments