1 module redis.collections.set; 2 3 public import redis; 4 5 /** 6 Set 7 A class that represents a SET structure in redis. 8 Allows you to query and manipulate the set using methods. 9 Implements OutputRange. 10 11 NOTE: Operations are done on the server side as much as possible, to reflect the true state of 12 the collection. 13 */ 14 class Set 15 { 16 private : 17 string name; 18 Redis conn; 19 20 public : 21 22 this(Redis conn, string name) 23 { 24 this.conn = conn; 25 this.name = name; 26 } 27 28 Response smembers() 29 { 30 return conn.send("SMEMBERS", name); 31 } 32 33 int scard() 34 { 35 return conn.send!(int)("SCARD", name); 36 } 37 alias count = scard; 38 39 40 bool srem(const(char[]) value) 41 { 42 return conn.send!(bool)("SREM", name, value); 43 } 44 45 void del() 46 { 47 conn.send("DEL", name); 48 } 49 50 // OutputRange 51 void put(const(char[]) value) 52 { 53 conn.send("SADD", name, value); 54 } 55 56 void put(const(char[])[] values) 57 { 58 foreach(value; values) 59 conn.send("SADD", name, value); 60 } 61 62 void opAssign(const(char[]) value) 63 { 64 del(); 65 put(value); 66 } 67 68 void opAssign(const(char[])[] values) 69 { 70 del(); 71 put(values); 72 } 73 74 void opOpAssign(string op)(const(char[]) value) 75 { 76 static if (op == "~") 77 put(value); 78 else static if (op == "-") 79 srem(value); 80 else 81 static assert(0, "Operator "~op~" not implemented"); 82 } 83 84 void opOpAssign(string op)(const(char[])[] values) 85 { 86 static if (op == "~") 87 foreach(value; values) 88 put(value); 89 else static if (op == "-") 90 foreach(value; values) 91 srem(value); 92 else 93 static assert(0, "Operator "~op~" not implemented"); 94 } 95 96 } 97 98 unittest { 99 100 import std.range : isOutputRange; 101 assert(isOutputRange!(Set, string)); 102 103 // Start a redis server on 127.0.0.1:6379 104 auto conn = new Redis("localhost", 6379); 105 auto set = new Set(conn, "tinyRedisUnitTestSet"); 106 107 set = ["banana", "apple", "orange"]; // data can be assigned using opAssign 108 set.put("grapes"); //the put() function appends a value 109 110 assert(set.scard() == 4); // runs the SCARD command, presents a proper count of the set on the server 111 assert(set.count() == 4); // count is an alias for SCARD command 112 113 //opAssign resets the data 114 set = ["guava", "pear"]; 115 assert(set.scard() == 2); 116 117 set ~= "banana"; // implements opOpAssign so ~= appends data 118 set ~= "apple"; 119 set ~= ["orange", "mango"]; 120 set ~= "apple"; //DUPLICATE! 121 assert(set.count() == 6); 122 123 set -= "mango"; //Not mango season! 124 assert(set.count() == 5); 125 126 import std.algorithm : canFind; 127 foreach(fruit; set.smembers()) 128 assert(["guava", "pear", "banana", "apple", "orange"].canFind(fruit.toString)); 129 130 }