1 module uim.mongo.bson;
2 
3 import uim.mongo;
4 
5 @safe:
6 	class DBSON {
7 		this() {}
8 		this(string[string] values) {
9 			_bson = Bson.emptyObject;
10 			foreach(k, v; values) { _bson[k] = v; }
11 		}
12 
13 		private Bson _bson;
14 
15 		bool isEmpty() { return (_bson.type == Bson.Type.undefined); }
16 		bool isUndefined() { return (_bson.type == Bson.Type.undefined); }
17 		bool isArray() { return (_bson.type == Bson.Type.array); }
18 		bool isBinData() { return (_bson.type == Bson.Type.binData); }
19 		bool isBool() { return (_bson.type == Bson.Type.bool_); }
20 		// TODO
21 
22 		O and(this O)(string[string] values) { 
23 			if (isEmpty) _bson = Bson.emptyObject;
24 			foreach(k, v; values) _bson[k] = v; 
25 			return cast(O)this;
26 		}
27 		unittest {	
28 			assert(BSON.and(["a":"b", "c":"d"]) == `{"c":"d","a":"b"}`);			
29 		}
30 
31 		O or(this O)(string[string][] values) {
32 			DBSON[] bsons; bsons.length = values.length;
33 			foreach(i, v; values) bsons[i] = BSON(v);
34 			this.or(bsons); 
35 			return cast(O)this;
36 		}
37 		O or(this O)(DBSON[] values) { 
38 			Bson[] bsons; bsons.length = values.length;
39 			size_t pre = 0;
40 			if (!isEmpty) {
41 				bsons.length = values.length+1;
42 				bsons[0] = _bson;
43 				pre = 1;
44 			}
45 			foreach(i, v; values) bsons[i+pre] = v.toBson;
46 			_bson = Bson(["$or": Bson(bsons)]); 
47 			return cast(O)this; }
48 		unittest {	
49 			assert(BSON.or([["a":"b"], ["c":"d"]]) == `{"$or":[{"a":"b"},{"c":"d"}]}`);
50 			assert(BSON(["a":"b"]).or([["c":"d"]]) == `{"$or":[{"a":"b"},{"c":"d"}]}`);
51 		}
52 
53 		bool opEquals(string txt) { return (toString == txt); }
54 		Bson toBson() {
55 			return _bson;
56 		}
57 		override string toString() {
58 			return _bson.toString;
59 		}
60 	}
61 	auto BSON() { return new DBSON(); }
62 	auto BSON(string[string] values) { return new DBSON(values); }
63 
64 // Create Bson Object 
65 auto BsonArray() { return Bson.emptyArray; }
66 
67 // Create Bson Object 
68 auto BsonObj() { return Bson.emptyObject; }
69 
70 // Create Bson Object of Associative Array
71 auto toBSON(V)(V[string] vals) {
72 	auto result = BsonObj;
73 	foreach(k, v; vals) result[k] = v;
74 	return result;
75 }
76 unittest {
77 	assert(["a":"b", "c":"d"].toBSON.toString == `{"c":"d","a":"b"}`, "Error in toBSON");
78 }
79 
80 // AND operator 	
81 Bson bAND(V)(V[string] conditions) {	
82 	return bObject(conditions);
83 }
84 Bson and(V)(Bson obj, V[string] conditions) {
85 	foreach(k, v; conditions) obj[k] = v;
86 	return obj;
87 }
88 unittest {	
89 	assert(["a":"b", "c":"d"].toBSON.and(["x":"y"]).toString == `{"c":"d","a":"b","x":"y"}`, "Error in and");
90 }
91 
92 // OR Operator
93 Bson or(string[string][] values) {
94 	Bson[] conditions;
95 	foreach(val; values) conditions~=val.toBSON;
96 	return or(conditions);
97 }
98 Bson or(Bson[] conditions) { return Bson(["$or": Bson(conditions)]); }
99 
100 unittest {
101 /*	writeln(or([["a":"b"].toBSON, ["c":"d"].toBSON]));
102 	writeln(or[["a":"b"].toBSON, ["c":"d", "x":"y"].toBSON]));
103 	writeln(BSON.or([["a":"b"], ["c":"d"]]));
104 	writeln(BSON.or([["a":"b"], ["c":"d"]]).and(["x":"y"]));
105 	writeln(BSON.or([["a":"b"], ["c":"d"]]).and(["x":"y"]));*/
106 }
107 
108 // EQ Equal operator
109 Bson bEQ(V)(string field, V value) { return Bson([field: Bson(["$eq":Bson(V)])]); }
110 
111 // GT Greater Equal operator
112 Bson bGT(V)(string field, V value) { return Bson([field: Bson(["$gt":Bson(V)])]); }
113 
114 // GT Greater then operator
115 Bson bGE(V)(string field, V value) { return Bson([field: Bson(["$gte":Bson(V)])]); }
116 
117 // LT Less then operator
118 Bson bLT(V)(string field, V value) { return Bson([field: Bson(["$lt":Bson(V)])]); }
119 
120 // LE Less equal operator
121 Bson bLE(V)(string field, V value) { return Bson([field: Bson(["$lte":Bson(V)])]); }
122 
123 // NE NOT Equal operator
124 Bson bNE(V)(string field, V value) { return Bson([field: Bson(["$ne":Bson(V)])]); }
125 
126 Bson bArray(V)(V[] values) {
127 	Bson[] results;
128 	foreach(v; values) results ~= Bson(v);
129 	return Bson(results);
130 }
131 Bson mIN(V)(string field, V[] values) { return Bson([field: Bson(["$in":_array(values)])]); }
132 Bson mNI(V)(string field, V[] values) { return Bson([field: Bson(["$nin":_array(values)])]); }
133 
134 Bson bSET(Bson[string] values) { 
135 	auto obj = Bson.emptyObject;
136 	foreach(k, v; values) obj[k] = v;
137 	return bSET(obj);
138 }
139 Bson bSET(Bson obj) { return Bson(["$set": obj]); }
140 
141 Bson bUNSET(string[] fields) {
142 	auto obj = Bson.emptyObject;
143 	foreach(field; fields) obj[field] = "";
144 	return bUNSET(obj);
145 }
146 Bson bUNSET( Bson obj) { return Bson(["$unset": obj]);}
147 
148 Bson bINC(size_t[string] values) { 
149 	auto obj = Bson.emptyObject;
150 	foreach(k, v; values) obj[k] = v;
151 	return _inc(obj);
152 }
153 Bson _inc(Bson obj) { return Bson(["$set": obj]); }
154 
155 Bson _mul(double[string] values) { 
156 	auto obj = Bson.emptyObject;
157 	foreach(k, v; values) obj[k] = v;
158 	return _mul(obj);
159 }
160 Bson _mul(Bson obj) { return Bson(["$mul": obj]); }
161 
162 unittest {
163 
164 }