|
8 | 8 |
|
9 | 9 | namespace Meteor |
10 | 10 | { |
11 | | - public interface ICollection : System.Collections.ICollection |
12 | | - { |
13 | | - /// <summary> |
14 | | - /// Add a record before another record in order. |
15 | | - /// </summary> |
16 | | - /// <param name="id">Record ID.</param> |
17 | | - /// <param name="before">The ID of the record to insert before.</param> |
18 | | - /// <param name="record">The record.</param> |
19 | | - void AddedBefore (string id, string before, object record); |
20 | | - |
21 | | - /// <summary> |
22 | | - /// Add the serialized message to the collection. |
23 | | - /// </summary> |
24 | | - /// <param name="addedMessage">Added message.</param> |
25 | | - void Added (string addedMessage); |
26 | | - |
27 | | - /// <summary> |
28 | | - /// Add the record to the collection. |
29 | | - /// </summary> |
30 | | - /// <param name="record">Record.</param> |
31 | | - void Added (object record); |
32 | | - |
33 | | - /// <summary> |
34 | | - /// Add the record to the collection with the specified ID |
35 | | - /// </summary> |
36 | | - /// <param name="id">Identifier.</param> |
37 | | - /// <param name="record">Record.</param> |
38 | | - void Added (string id, object record); |
39 | | - |
40 | | - /// <summary> |
41 | | - /// Notify the collection that a record has changed. |
42 | | - /// </summary> |
43 | | - /// <param name="id">Record ID.</param> |
44 | | - /// <param name="cleared">Fields that are now undefined.</param> |
45 | | - /// <param name="fields">New values for fields of record.</param> |
46 | | - void Changed (string id, string[] cleared, IDictionary fields); |
47 | | - |
48 | | - /// <summary> |
49 | | - /// Move a record before another record. |
50 | | - /// </summary> |
51 | | - /// <param name="id">ID of record.</param> |
52 | | - /// <param name="before">ID of record to move before.</param> |
53 | | - void MovedBefore (string id, string before); |
54 | | - |
55 | | - /// <summary> |
56 | | - /// Remove a record. |
57 | | - /// </summary> |
58 | | - /// <param name="id">Identifier.</param> |
59 | | - void Removed (string id); |
60 | | - |
61 | | - /// <summary> |
62 | | - /// Collection name. |
63 | | - /// </summary> |
64 | | - /// <value>The name.</value> |
65 | | - string Name { |
66 | | - get; |
67 | | - } |
68 | | - |
69 | | - /// <summary> |
70 | | - /// Record type. |
71 | | - /// </summary> |
72 | | - /// <value>The type of the collection.</value> |
73 | | - Type CollectionType { get; } |
74 | | - } |
75 | | - |
76 | 11 | public class TemporaryCollection : Hashtable, Meteor.ICollection |
77 | 12 | { |
78 | 13 | public TemporaryCollection () : base () |
@@ -169,38 +104,105 @@ protected Collection () : base () |
169 | 104 | { |
170 | 105 | } |
171 | 106 |
|
| 107 | + /// <summary> |
| 108 | + /// Creates a new Mongo-style collection. |
| 109 | + /// Throws an exception if a collection with the given name already exists. If you want a way to get an |
| 110 | + /// existing collection instance if it already exists, use Collection<TRecordType>.Create(name) |
| 111 | + /// </summary> |
| 112 | + /// <param name="name">Name. If null, returns a local-only collection.</param> |
| 113 | + public Collection (string name) : base () |
| 114 | + { |
| 115 | + var doesCollectionAlreadyExist = LiveData.Instance.Collections.Contains (name); |
| 116 | + var isNameEmpty = string.IsNullOrEmpty (name); |
| 117 | + var isCollectionTemporary = LiveData.Instance.Collections [name] as TemporaryCollection != null; |
| 118 | + if (!isNameEmpty |
| 119 | + && doesCollectionAlreadyExist |
| 120 | + && !isCollectionTemporary) { |
| 121 | + throw new ArgumentException (string.Format ("A collection with name {0} already exists", name)); |
| 122 | + } |
| 123 | + |
| 124 | + Collection<TRecordType>.Create (name, instance: this); |
| 125 | + } |
| 126 | + |
| 127 | + public Cursor<TRecordType> Find (Func<TRecordType, bool> selector = null) |
| 128 | + { |
| 129 | + return new Cursor<TRecordType> (collection: this, selector: selector); |
| 130 | + } |
| 131 | + |
| 132 | + public Cursor<TRecordType> Find (string id) |
| 133 | + { |
| 134 | + return new Cursor<TRecordType> (collection: this, id: id); |
| 135 | + } |
| 136 | + |
| 137 | + public Cursor<TRecordType> Find (IEnumerable<string> ids) |
| 138 | + { |
| 139 | + return new Cursor<TRecordType> (collection: this, ids: ids); |
| 140 | + } |
| 141 | + |
| 142 | + public TRecordType FindOne (string id) |
| 143 | + { |
| 144 | + return this [id]; |
| 145 | + } |
| 146 | + |
| 147 | + public TRecordType FindOne (Func<TRecordType, bool> selector = null) |
| 148 | + { |
| 149 | + selector = selector ?? delegate(TRecordType arg) { |
| 150 | + return true; |
| 151 | + }; |
| 152 | + |
| 153 | + foreach (var record in this) { |
| 154 | + if (selector (record)) { |
| 155 | + return record; |
| 156 | + } |
| 157 | + } |
| 158 | + return null; |
| 159 | + } |
| 160 | + |
172 | 161 | public static Collection<TRecordType> Create (string name) |
173 | 162 | { |
| 163 | + return Create (name, new Collection<TRecordType> ()); |
| 164 | + } |
| 165 | + |
| 166 | + protected static Collection<TRecordType> Create (string name, Collection<TRecordType> instance) |
| 167 | + { |
| 168 | + instance = instance ?? new Collection<TRecordType> (); |
174 | 169 | if (string.IsNullOrEmpty (name)) { |
175 | | - return new Collection<TRecordType> (); |
| 170 | + return instance; |
176 | 171 | } |
177 | 172 |
|
178 | 173 | // Check if we already have this collection defined, otherwise make it |
179 | 174 | if (!LiveData.Instance.Collections.Contains (name)) { |
180 | | - LiveData.Instance.Collections.Add (new Collection<TRecordType> () { name = name } as ICollection); |
| 175 | + instance.name = name; |
| 176 | + LiveData.Instance.Collections.Add (instance as ICollection); |
181 | 177 | } |
182 | 178 |
|
183 | 179 | var collection = LiveData.Instance.Collections [name] as Collection<TRecordType>; |
184 | 180 |
|
185 | 181 | // The collection may already exist, but it may be of the wrong type |
186 | 182 | if (collection == null) { |
187 | 183 | // Convert the collection to the requested type |
188 | | - var oldCollection = LiveData.Instance.Collections [name]; |
189 | | - var typedCollection = new Collection<TRecordType> (); |
190 | | - typedCollection.name = name; |
191 | | - foreach (DictionaryEntry doc in oldCollection) { |
192 | | - var value = doc.Value.Coerce<TRecordType> (); |
193 | | - value._id = (string)doc.Key; |
194 | | - typedCollection.Add (value); |
195 | | - } |
196 | | - |
197 | | - LiveData.Instance.Collections.Remove (name); |
198 | | - LiveData.Instance.Collections.Add (typedCollection); |
199 | | - collection = typedCollection; |
| 184 | + collection = Convert (name, instance); |
200 | 185 | } |
| 186 | + |
201 | 187 | return collection; |
202 | 188 | } |
203 | 189 |
|
| 190 | + protected static Collection<TRecordType> Convert (string name, Collection<TRecordType> instance) |
| 191 | + { |
| 192 | + var oldCollection = LiveData.Instance.Collections [name]; |
| 193 | + var typedCollection = instance ?? new Collection<TRecordType> (); |
| 194 | + typedCollection.name = name; |
| 195 | + foreach (DictionaryEntry doc in oldCollection) { |
| 196 | + var value = doc.Value.Coerce<TRecordType> (); |
| 197 | + value._id = (string)doc.Key; |
| 198 | + typedCollection.Add (value); |
| 199 | + } |
| 200 | + |
| 201 | + LiveData.Instance.Collections.Remove (name); |
| 202 | + LiveData.Instance.Collections.Add (typedCollection); |
| 203 | + return typedCollection; |
| 204 | + } |
| 205 | + |
204 | 206 | protected override string GetKeyForItem (TRecordType item) |
205 | 207 | { |
206 | 208 | return item._id; |
|
0 commit comments