1 module vibe.db.redis.sessionstore; 2 3 import vibe.data.json; 4 import vibe.db.redis.redis; 5 import vibe.http.session; 6 import core.time; 7 import std.typecons : Nullable; 8 import std.variant; 9 10 11 final class RedisSessionStore : SessionStore { 12 private { 13 RedisDatabase m_db; 14 Duration m_expirationTime = Duration.max; 15 } 16 17 /** Constructs a new Redis session store. 18 19 Params: 20 host = Host name of the Redis instance to connect to 21 database = Database number to select on the server 22 port = Optional port number to use when connecting to the server 23 */ 24 this(string host, long database, ushort port = RedisClient.defaultPort) 25 { 26 m_db = connectRedis(host, port).getDatabase(database); 27 } 28 29 /** The duration without access after which a session expires. 30 */ 31 @property Duration expirationTime() const { return m_expirationTime; } 32 /// ditto 33 @property void expirationTime(Duration dur) { m_expirationTime = dur; } 34 35 @property SessionStorageType storageType() const { return SessionStorageType.json; } 36 37 Session create() 38 { 39 auto s = createSessionInstance(); 40 m_db.hset(s.id, "__SESS", true); // set place holder to avoid create empty hash 41 assert(m_db.exists(s.id)); 42 if (m_expirationTime != Duration.max) 43 m_db.expire(s.id, m_expirationTime); 44 return s; 45 } 46 47 Session open(string id) 48 { 49 if (m_db.exists(id)) 50 { 51 auto s = createSessionInstance(id); 52 if (m_expirationTime != Duration.max) 53 m_db.expire(s.id, m_expirationTime); 54 return s; 55 } 56 return Session.init; 57 } 58 59 void set(string id, string name, Variant value) 60 @trusted { 61 m_db.hset(id, name, value.get!Json.toString()); 62 } 63 64 Variant get(string id, string name, lazy Variant defaultVal) 65 @trusted { 66 auto v = m_db.hget!(Nullable!string)(id, name); 67 return v.isNull ? defaultVal : Variant(parseJsonString(v.get)); 68 } 69 70 bool isKeySet(string id, string key) 71 { 72 return m_db.hexists(id, key); 73 } 74 75 void remove(string id, string key) 76 { 77 m_db.hdel(id, key); 78 } 79 80 void destroy(string id) 81 { 82 m_db.del(id); 83 } 84 85 int delegate(int delegate(ref string key, ref Variant value)) iterateSession(string id) 86 { 87 assert(false, "Not available for RedisSessionStore"); 88 } 89 90 int iterateSession(string id, scope int delegate(string key) @safe del) 91 { 92 auto res = m_db.hkeys(id); 93 while (!res.empty) { 94 auto key = res.front; 95 res.popFront(); 96 if (auto ret = del(key)) 97 return ret; 98 } 99 return 0; 100 } 101 }