1 module tinyredis.collections.set; 2 3 import tinyredis : Redis, Response; 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 Redis conn; 18 string name; 19 } 20 21 this(Redis conn, string name) 22 { 23 this.conn = conn; 24 this.name = name; 25 } 26 27 auto smembers() 28 { 29 return conn.send("SMEMBERS", name); 30 } 31 32 @property int scard() 33 { 34 return conn.send!int("SCARD", name); 35 } 36 alias count = scard; 37 38 39 int srem(const(char[])[] values...) 40 { 41 return conn.send!int("SREM", name, values); 42 } 43 44 int del() 45 { 46 return conn.send!int("DEL", name); 47 } 48 49 // OutputRange 50 int put(in char[] value) 51 { 52 return conn.send!int("SADD", name, value); 53 } 54 55 int put(const(char[])[] values) 56 { 57 int count; 58 foreach(value; values) 59 count += put(value); 60 return count; 61 } 62 63 void opAssign(const(char[]) value) 64 { 65 del(); 66 put(value); 67 } 68 69 void opAssign(const(char[])[] values) 70 { 71 del(); 72 put(values); 73 } 74 75 void opOpAssign(string op : "~")(in char[] value) { 76 put(value); 77 } 78 79 void opOpAssign(string op : "-")(in char[] value) { 80 srem(value); 81 } 82 83 void opOpAssign(string op : "~")(const(char[])[] values) { 84 foreach(value; values) 85 put(value); 86 } 87 88 void opOpAssign(string op : "-")(const(char[])[] values) { 89 foreach(value; values) 90 srem(value); 91 } 92 } 93 94 unittest { 95 import std.range : isOutputRange; 96 97 static assert(isOutputRange!(Set, string)); 98 99 // Start a redis server on 127.0.0.1:6379 100 auto conn = new Redis("localhost", 6379); 101 auto set = new Set(conn, "tinyRedisUnitTestSet"); 102 103 set = ["banana", "apple", "orange"]; // data can be assigned using opAssign 104 set.put("grapes"); //the put() function appends a value 105 106 assert(set.scard == 4); // runs the SCARD command, presents a proper count of the set on the server 107 assert(set.count == 4); // count is an alias for SCARD command 108 109 //opAssign resets the data 110 set = ["guava", "pear"]; 111 assert(set.scard == 2); 112 113 set ~= "banana"; // implements opOpAssign so ~= appends data 114 set ~= "apple"; 115 set ~= ["orange", "mango"]; 116 set ~= "apple"; //DUPLICATE! 117 assert(set.count == 6); 118 119 set -= "mango"; //Not mango season! 120 assert(set.count == 5); 121 122 import std.algorithm : canFind; 123 foreach(fruit; set.smembers()) 124 assert(["guava", "pear", "banana", "apple", "orange"].canFind(fruit.toString)); 125 }