1 module hunt.cache.adapter.RedisAdapter;
2 
3 import hunt.cache.adapter.Adapter;
4 import hunt.cache.CacheOptions;
5 import hunt.cache.Nullable;
6 import hunt.cache.Store;
7 
8 import hunt.logging;
9 import hunt.redis;
10 
11 import std.array;
12 import std.conv;
13 import std.range;
14 import std.string;
15 
16 class RedisAdapter : Adapter
17 {
18     this(RedisPoolOptions config)
19     {
20         defalutPoolConfig = config;
21     }
22 
23     Nullable!V get(V) (string key)
24     {
25         version(HUNT_CACHE_DEBUG) trace("key: ", key);
26 
27         Redis _redis = redis();
28         scope(exit) _redis.close();
29         // synchronized(this)
30         {   
31             try {
32                 string data = _redis.get(key);
33                 if(data.empty) return Nullable!V();
34                 return DeserializeToObject!V(cast(byte[])data);
35             } catch(Throwable ex) {
36                 warning(ex.msg);
37                 version(HUNT_DEBUG) warning(ex);
38             }
39             return Nullable!V();
40         }
41     }
42 
43     Nullable!V[string] getAll(V) (string[] keys)
44     {
45         Redis _redis = redis();
46         scope(exit) _redis.close();
47         // synchronized(this)
48         {
49             Nullable!V[string] mapv;
50             if( keys.length == 0)
51                 return mapv;
52 
53             List!(string) r = _redis.mget(keys);
54 
55             foreach(i, v ; r)
56             {
57                 mapv[keys[i]] = DeserializeToObject!V(cast(byte[])v);
58             }
59 
60             return mapv;
61         }
62     }
63 
64     bool hasKey(string key)
65     {
66         Redis _redis = redis();
67         scope(exit) _redis.close();
68         // synchronized(this)
69         {
70             return _redis.exists(key);
71         }
72     }
73 
74     void set(V) (string key,  V v, uint expired)
75     {
76         version(HUNT_DEBUG) trace("key: ", key);
77 
78         Redis _redis = redis();
79         scope(exit) _redis.close();
80 
81         // synchronized(this)
82         {
83             if( expired == 0)
84                 _redis.set(key, cast(string)SerializeToByte(v));
85             else
86                 _redis.setex(key, expired, cast(string)SerializeToByte(v));
87         }
88     }
89 
90     bool setIfAbsent(V) (string key,  V v)
91     {
92         Redis _redis = redis();
93         scope(exit) _redis.close();
94         // synchronized(this)
95         {
96             return _redis.setnx(key, cast(string)SerializeToByte(v)) == 1;        
97         }
98     }
99 
100     void set(V) (V[string] maps, uint expired)
101     {
102         if(maps.length == 0)
103             return;
104         Redis _redis = redis();
105         scope(exit) _redis.close();
106 
107         // synchronized(this)
108         {
109 
110             if(expired == 0)
111             {
112                 _redis.mset(maps);
113             }
114             else
115             {
116                 foreach( k, v ; maps)
117                 {
118                     _redis.set(k, expired, cast(string)SerializeToByte(v));
119                 }
120             }
121         }
122     }
123 
124     bool remove(string key)
125     {
126         Redis _redis = redis();
127         scope(exit) _redis.close();
128 
129         // synchronized(this)
130         {
131             return _redis.del(key) > 0;
132         }
133     }
134 
135     void remove(string[] keys)
136     {
137         if( keys.length == 0)
138             return ;
139 
140         Redis _redis = redis();
141         scope(exit) _redis.close();
142 
143         foreach(key ; keys){
144             _redis.del(key);
145         }
146    
147     }
148 
149     void clear()
150     {
151         Redis _redis = redis();
152         scope(exit) _redis.close();
153         _redis.flushAll();
154 
155         // synchronized(this)
156         // {
157         //     _redis.flushAll();
158         // }
159     }
160 
161 protected:
162     // Redis _redis;
163     Redis redis() {
164         return defaultRedisPool().borrow();
165     }
166 }