Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
Database.cs
1using System;
2using System.Collections.Generic;
3using System.Text;
4using System.Threading.Tasks;
5using System.Xml;
6using Waher.Events;
11
12namespace Waher.Persistence
13{
18 public static class Database
19 {
20 private static readonly Dictionary<string, Dictionary<string, FlagSource>> toRepair = new Dictionary<string, Dictionary<string, FlagSource>>();
21 private static IDatabaseProvider provider = null;
22 private static bool locked = false;
23
31 public static void Register(IDatabaseProvider DatabaseProvider)
32 {
33 Register(DatabaseProvider, true);
34 }
35
44 public static void Register(IDatabaseProvider DatabaseProvider, bool Lock)
45 {
46 if (!(provider is null) && locked)
47 throw new Exception("A database provider is already registered.");
48
49 provider = DatabaseProvider;
50 locked = Lock;
51 }
52
57 {
58 get
59 {
60 if (!(provider is null))
61 return provider;
62 else
63 throw new Exception("A database provider has not been registered.");
64 }
65 }
66
67 internal static IDatabaseProvider Stop()
68 {
69 IDatabaseProvider Result = provider;
70 provider = new NullDatabaseProvider();
71 locked = false;
72 return Result;
73 }
74
78 public static bool HasProvider
79 {
80 get => !(provider is null) && (!(provider is NullDatabaseProvider) || locked);
81 }
82
86 public static bool Locked
87 {
88 get { return locked; }
89 }
90
95 public async static Task Insert(object Object)
96 {
97 await Provider.Insert(Object);
98 RaiseInserted(Object);
99 }
100
101 private static void RaiseInserted(object Object)
102 {
104 if (!(h is null))
105 {
106 try
107 {
108 h(Provider, new ObjectEventArgs(Object));
109 }
110 catch (Exception)
111 {
112 // Ignore
113 }
114 }
115 }
116
117 private static void RaiseInserted(IEnumerable<object> Objects)
118 {
119 foreach (object Object in Objects)
120 RaiseInserted(Object);
121 }
122
126 public static event ObjectEventHandler ObjectInserted = null;
127
132 public async static Task Insert(params object[] Objects)
133 {
134 if (Objects.Length == 1)
135 await Provider.Insert(Objects[0]);
136 else
137 await Provider.Insert(Objects);
138
139 RaiseInserted(Objects);
140 }
141
146 public async static Task Insert(IEnumerable<object> Objects)
147 {
148 await Provider.Insert(Objects);
149 RaiseInserted(Objects);
150 }
151
156 public static async Task InsertLazy(object Object)
157 {
158 await Provider.InsertLazy(Object, RaiseInserted);
159 }
160
165 public static async Task InsertLazy(params object[] Objects)
166 {
167 if (Objects.Length == 1)
168 await Provider.InsertLazy(Objects[0], RaiseInserted);
169 else
170 await Provider.InsertLazy(Objects, RaiseInserted);
171 }
172
177 public static async Task InsertLazy(IEnumerable<object> Objects)
178 {
179 await Provider.InsertLazy(Objects, RaiseInserted);
180 }
181
189 public static Task<IEnumerable<T>> Find<T>(params string[] SortOrder)
190 where T : class
191 {
192 return Provider.Find<T>(0, int.MaxValue, SortOrder);
193 }
194
203 public static Task<IEnumerable<T>> Find<T>(Filter Filter, params string[] SortOrder)
204 where T : class
205 {
206 return Provider.Find<T>(0, int.MaxValue, Filter, SortOrder);
207 }
208
218 public static Task<IEnumerable<T>> Find<T>(int Offset, int MaxCount, params string[] SortOrder)
219 where T : class
220 {
221 return Provider.Find<T>(Offset, MaxCount, SortOrder);
222 }
223
234 public static Task<IEnumerable<T>> Find<T>(int Offset, int MaxCount, Filter Filter, params string[] SortOrder)
235 where T : class
236 {
237 return Provider.Find<T>(Offset, MaxCount, Filter, SortOrder);
238 }
239
247 public static Task<IEnumerable<object>> Find(string Collection, params string[] SortOrder)
248 {
249 return Provider.Find(Collection, 0, int.MaxValue, SortOrder);
250 }
251
260 public static Task<IEnumerable<object>> Find(string Collection, Filter Filter, params string[] SortOrder)
261 {
262 return Provider.Find(Collection, 0, int.MaxValue, Filter, SortOrder);
263 }
264
274 public static Task<IEnumerable<object>> Find(string Collection, int Offset, int MaxCount, params string[] SortOrder)
275 {
276 return Provider.Find(Collection, Offset, MaxCount, SortOrder);
277 }
278
289 public static Task<IEnumerable<object>> Find(string Collection, int Offset, int MaxCount, Filter Filter, params string[] SortOrder)
290 {
291 return Provider.Find(Collection, Offset, MaxCount, Filter, SortOrder);
292 }
293
302 public static Task<IEnumerable<T>> Find<T>(string Collection, string[] SortOrder) // Note: No params, to avoid confusion with Find<T>(params SortOrder)
303 where T : class
304 {
305 return Provider.Find<T>(Collection, 0, int.MaxValue, null, SortOrder);
306 }
307
317 public static Task<IEnumerable<T>> Find<T>(string Collection, Filter Filter, params string[] SortOrder)
318 where T : class
319 {
320 return Provider.Find<T>(Collection, 0, int.MaxValue, Filter, SortOrder);
321 }
322
333 public static Task<IEnumerable<T>> Find<T>(string Collection, int Offset, int MaxCount, params string[] SortOrder)
334 where T : class
335 {
336 return Provider.Find<T>(Collection, Offset, MaxCount, null, SortOrder);
337 }
338
350 public static Task<IEnumerable<T>> Find<T>(string Collection, int Offset, int MaxCount, Filter Filter, params string[] SortOrder)
351 where T : class
352 {
353 return Provider.Find<T>(Collection, Offset, MaxCount, Filter, SortOrder);
354 }
355
364 public static Task<IPage<T>> FindFirst<T>(int PageSize, params string[] SortOrder)
365 where T : class
366 {
367 return Provider.FindFirst<T>(PageSize, SortOrder);
368 }
369
379 public static Task<IPage<T>> FindFirst<T>(int PageSize, Filter Filter, params string[] SortOrder)
380 where T : class
381 {
382 return Provider.FindFirst<T>(PageSize, Filter, SortOrder);
383 }
384
385
394 public static Task<IPage<object>> FindFirst(string Collection, int PageSize, params string[] SortOrder)
395 {
396 return Provider.FindFirst(Collection, PageSize, SortOrder);
397 }
398
408 public static Task<IPage<object>> FindFirst(string Collection, int PageSize, Filter Filter, params string[] SortOrder)
409 {
410 return Provider.FindFirst(Collection, PageSize, Filter, SortOrder);
411 }
412
423 public static Task<IPage<T>> FindFirst<T>(string Collection, int PageSize, Filter Filter, params string[] SortOrder)
424 where T : class
425 {
426 return Provider.FindFirst<T>(Collection, PageSize, Filter, SortOrder);
427 }
428
435 public static Task<IPage<T>> FindNext<T>(IPage<T> Page)
436 where T : class
437 {
438 return Provider.FindNext(Page);
439 }
440
446 public static Task<IPage<object>> FindNext(IPage<object> Page)
447 {
448 return Provider.FindNext(Page);
449 }
450
461 public static async Task<PaginatedEnumerator<T>> Enumerate<T>(int PageSize, params string[] SortOrder)
462 where T : class
463 {
464 return new PaginatedEnumerator<T>(await FindFirst<T>(PageSize, SortOrder));
465 }
466
476 public static async Task<PaginatedEnumerator<T>> Enumerate<T>(int PageSize, Filter Filter, params string[] SortOrder)
477 where T : class
478 {
479 return new PaginatedEnumerator<T>(await FindFirst<T>(PageSize, Filter, SortOrder));
480 }
481
482
491 public static async Task<PaginatedEnumerator<object>> Enumerate(string Collection, int PageSize, params string[] SortOrder)
492 {
493 return new PaginatedEnumerator<object>(await FindFirst(Collection, PageSize, SortOrder));
494 }
495
505 public static async Task<PaginatedEnumerator<object>> Enumerate(string Collection, int PageSize, Filter Filter, params string[] SortOrder)
506 {
507 return new PaginatedEnumerator<object>(await FindFirst(Collection, PageSize, Filter, SortOrder));
508 }
509
520 public static async Task<PaginatedEnumerator<T>> Enumerate<T>(string Collection, int PageSize, Filter Filter, params string[] SortOrder)
521 where T : class
522 {
523 return new PaginatedEnumerator<T>(await FindFirst<T>(Collection, PageSize, Filter, SortOrder));
524 }
525
534 public async static Task<T> FindFirstDeleteRest<T>(params string[] SortOrder)
535 where T : class
536 {
537 return await FirstDeleteRest(await Provider.Find<T>(0, int.MaxValue, SortOrder));
538 }
539
540 private static async Task<T> FirstDeleteRest<T>(IEnumerable<T> Set)
541 where T : class
542 {
543 T Result = default;
544 bool First = true;
545
546 foreach (T Obj in Set)
547 {
548 if (First)
549 {
550 First = false;
551 Result = Obj;
552 }
553 else
554 {
555 try
556 {
557 await Delete(Obj);
558 }
559 catch (KeyNotFoundException)
560 {
561 // TODO: Inconsistency should flag collection for repairing
562 }
563 }
564 }
565
566 return Result;
567 }
568
578 public static async Task<T> FindFirstDeleteRest<T>(Filter Filter, params string[] SortOrder)
579 where T : class
580 {
581 return await FirstDeleteRest(await Provider.Find<T>(0, int.MaxValue, Filter, SortOrder));
582 }
583
592 public async static Task<T> FindFirstIgnoreRest<T>(params string[] SortOrder)
593 where T : class
594 {
595 return FirstIgnoreRest(await Provider.Find<T>(0, 1, SortOrder));
596 }
597
598 private static T FirstIgnoreRest<T>(IEnumerable<T> Set)
599 where T : class
600 {
601 foreach (T Obj in Set)
602 return Obj;
603
604 return default;
605 }
606
616 public static async Task<T> FindFirstIgnoreRest<T>(Filter Filter, params string[] SortOrder)
617 where T : class
618 {
619 return FirstIgnoreRest(await Provider.Find<T>(0, 1, Filter, SortOrder));
620 }
621
626 public async static Task Update(object Object)
627 {
628 await Provider.Update(Object);
629 RaiseUpdated(Object);
630 }
631
632 private static void RaiseUpdated(object Object)
633 {
635 if (!(h is null))
636 {
637 try
638 {
639 h(Provider, new ObjectEventArgs(Object));
640 }
641 catch (Exception)
642 {
643 // Ignore
644 }
645 }
646 }
647
648 private static void RaiseUpdated(IEnumerable<object> Objects)
649 {
650 foreach (object Object in Objects)
651 RaiseUpdated(Object);
652 }
653
657 public static event ObjectEventHandler ObjectUpdated = null;
658
663 public async static Task Update(params object[] Objects)
664 {
665 if (Objects.Length == 1)
666 await Provider.Update(Objects[0]);
667 else
668 await Provider.Update(Objects);
669
670 RaiseUpdated(Objects);
671 }
672
677 public async static Task Update(IEnumerable<object> Objects)
678 {
679 await Provider.Update(Objects);
680 RaiseUpdated(Objects);
681 }
682
687 public async static Task UpdateLazy(object Object)
688 {
689 await Provider.UpdateLazy(Object, RaiseUpdated);
690 }
691
696 public async static Task UpdateLazy(params object[] Objects)
697 {
698 if (Objects.Length == 1)
699 await Provider.UpdateLazy(Objects[0], RaiseUpdated);
700 else
701 await Provider.UpdateLazy(Objects, RaiseUpdated);
702 }
703
708 public async static Task UpdateLazy(IEnumerable<object> Objects)
709 {
710 await Provider.UpdateLazy(Objects, RaiseUpdated);
711 }
712
717 public async static Task Delete(object Object)
718 {
719 await Provider.Delete(Object);
720 RaiseDeleted(Object);
721 }
722
726 public static event ObjectEventHandler ObjectDeleted = null;
727
732 public async static Task Delete(params object[] Objects)
733 {
734 if (Objects.Length == 1)
735 await Provider.Delete(Objects[0]);
736 else
737 await Provider.Delete(Objects);
738
739 RaiseDeleted(Objects);
740 }
741
746 public async static Task Delete(IEnumerable<object> Objects)
747 {
748 await Provider.Delete(Objects);
749 RaiseDeleted(Objects);
750 }
751
756 public async static Task DeleteLazy(object Object)
757 {
758 await Provider.DeleteLazy(Object, RaiseDeleted);
759 }
760
765 public async static Task DeleteLazy(params object[] Objects)
766 {
767 if (Objects.Length == 1)
768 await Provider.DeleteLazy(Objects[0], RaiseDeleted);
769 else
770 await Provider.DeleteLazy(Objects, RaiseDeleted);
771 }
772
777 public async static Task DeleteLazy(IEnumerable<object> Objects)
778 {
779 await Provider.DeleteLazy(Objects, RaiseDeleted);
780 }
781
782 private static void RaiseDeleted(object Object)
783 {
785 if (!(h is null))
786 {
787 try
788 {
789 h(Provider, new ObjectEventArgs(Object));
790 }
791 catch (Exception)
792 {
793 // Ignore
794 }
795 }
796 }
797
798 private static void RaiseDeleted(IEnumerable<object> Objects)
799 {
800 foreach (object Object in Objects)
801 RaiseDeleted(Object);
802 }
803
811 public static Task<IEnumerable<T>> FindDelete<T>(params string[] SortOrder)
812 where T : class
813 {
814 return FindDelete<T>(0, int.MaxValue, SortOrder);
815 }
816
826 public static async Task<IEnumerable<T>> FindDelete<T>(int Offset, int MaxCount, params string[] SortOrder)
827 where T : class
828 {
829 IEnumerable<T> Result = await Provider.FindDelete<T>(Offset, MaxCount, SortOrder);
830
831 foreach (T Object in Result)
832 RaiseDeleted(Object);
833
834 return Result;
835 }
836
845 public static Task<IEnumerable<T>> FindDelete<T>(Filter Filter, params string[] SortOrder)
846 where T : class
847 {
848 return FindDelete<T>(0, int.MaxValue, Filter, SortOrder);
849 }
850
861 public static async Task<IEnumerable<T>> FindDelete<T>(int Offset, int MaxCount, Filter Filter, params string[] SortOrder)
862 where T : class
863 {
864 IEnumerable<T> Result = await Provider.FindDelete<T>(Offset, MaxCount, Filter, SortOrder);
865
866 foreach (T Object in Result)
867 RaiseDeleted(Object);
868
869 return Result;
870 }
871
879 public static Task<IEnumerable<object>> FindDelete(string Collection, params string[] SortOrder)
880 {
881 return FindDelete(Collection, 0, int.MaxValue, SortOrder);
882 }
883
893 public static async Task<IEnumerable<object>> FindDelete(string Collection, int Offset, int MaxCount, params string[] SortOrder)
894 {
895 IEnumerable<object> Result = await Provider.FindDelete(Collection, Offset, MaxCount, SortOrder);
896
897 foreach (object Object in Result)
898 RaiseDeleted(Object);
899
900 return Result;
901 }
902
911 public static Task<IEnumerable<object>> FindDelete(string Collection, Filter Filter, params string[] SortOrder)
912 {
913 return FindDelete(Collection, 0, int.MaxValue, Filter, SortOrder);
914 }
915
926 public static async Task<IEnumerable<object>> FindDelete(string Collection, int Offset, int MaxCount, Filter Filter, params string[] SortOrder)
927 {
928 IEnumerable<object> Result = await Provider.FindDelete(Collection, Offset, MaxCount, Filter, SortOrder);
929
930 foreach (object Object in Result)
931 RaiseDeleted(Object);
932
933 return Result;
934 }
935
943 public static Task DeleteLazy<T>(params string[] SortOrder)
944 where T : class
945 {
946 return DeleteLazy<T>(0, int.MaxValue, SortOrder);
947 }
948
958 public static Task DeleteLazy<T>(int Offset, int MaxCount, params string[] SortOrder)
959 where T : class
960 {
961 return Provider.DeleteLazy<T>(Offset, MaxCount, SortOrder, RaiseDeleted);
962 }
963
972 public static Task DeleteLazy<T>(Filter Filter, params string[] SortOrder)
973 where T : class
974 {
975 return DeleteLazy<T>(0, int.MaxValue, Filter, SortOrder);
976 }
977
988 public static Task DeleteLazy<T>(int Offset, int MaxCount, Filter Filter, params string[] SortOrder)
989 where T : class
990 {
991 return Provider.DeleteLazy<T>(Offset, MaxCount, Filter, SortOrder, RaiseDeleted);
992 }
993
1001 public static Task DeleteLazy(string Collection, params string[] SortOrder)
1002 {
1003 return DeleteLazy(Collection, 0, int.MaxValue, SortOrder);
1004 }
1005
1015 public static Task DeleteLazy(string Collection, int Offset, int MaxCount, params string[] SortOrder)
1016 {
1017 return Provider.DeleteLazy(Collection, Offset, MaxCount, SortOrder, RaiseDeleted);
1018 }
1019
1028 public static Task DeleteLazy(string Collection, Filter Filter, params string[] SortOrder)
1029 {
1030 return DeleteLazy(Collection, 0, int.MaxValue, Filter, SortOrder);
1031 }
1032
1043 public static Task DeleteLazy(string Collection, int Offset, int MaxCount, Filter Filter, params string[] SortOrder)
1044 {
1045 return Provider.DeleteLazy(Collection, Offset, MaxCount, Filter, SortOrder, RaiseDeleted);
1046 }
1047
1054 public static Task<T> TryLoadObject<T>(object ObjectId)
1055 where T : class
1056 {
1057 return Provider.TryLoadObject<T>(ObjectId);
1058 }
1059
1067 public static Task<T> TryLoadObject<T>(string CollectionName, object ObjectId)
1068 where T : class
1069 {
1070 return Provider.TryLoadObject<T>(CollectionName, ObjectId);
1071 }
1072
1079 public static Task<object> TryLoadObject(string CollectionName, object ObjectId)
1080 {
1081 return Provider.TryLoadObject(CollectionName, ObjectId);
1082 }
1083
1090 public static async Task<T> LoadObject<T>(object ObjectId)
1091 where T : class
1092 {
1093 T Result = await Provider.TryLoadObject<T>(ObjectId)
1094 ?? throw new KeyNotFoundException("Object not found.");
1095
1096 return Result;
1097 }
1098
1106 public async static Task<T> LoadObject<T>(string CollectionName, object ObjectId)
1107 where T : class
1108 {
1109 T Result = await Provider.TryLoadObject<T>(CollectionName, ObjectId)
1110 ?? throw new KeyNotFoundException("Object not found.");
1111
1112 return Result;
1113 }
1114
1121 public static async Task<object> LoadObject(string CollectionName, object ObjectId)
1122 {
1123 object Result = await Provider.TryLoadObject(CollectionName, ObjectId)
1124 ?? throw new KeyNotFoundException("Object not found.");
1125
1126 return Result;
1127 }
1128
1134 public static Task<bool> Export(IDatabaseExport Output)
1135 {
1136 return Export(Output, null);
1137 }
1138
1145 public static Task<bool> Export(IDatabaseExport Output, string[] CollectionNames)
1146 {
1147 return Provider.Export(Output, CollectionNames);
1148 }
1149
1157 public static Task<bool> Export(IDatabaseExport Output, string[] CollectionNames, ProfilerThread Thread)
1158 {
1159 return Provider.Export(Output, CollectionNames, Thread);
1160 }
1161
1168 public static Task Iterate<T>(IDatabaseIteration<T> Recipient)
1169 where T : class
1170 {
1171 return Iterate(Recipient, null);
1172 }
1173
1181 public static Task Iterate<T>(IDatabaseIteration<T> Recipient, string[] CollectionNames)
1182 where T : class
1183 {
1184 return Provider.Iterate(Recipient, CollectionNames);
1185 }
1186
1195 public static Task Iterate<T>(IDatabaseIteration<T> Recipient, string[] CollectionNames, ProfilerThread Thread)
1196 where T : class
1197 {
1198 return Provider.Iterate(Recipient, CollectionNames, Thread);
1199 }
1200
1206 public async static Task Clear(string CollectionName)
1207 {
1208 await Provider.Clear(CollectionName);
1209
1211 if (!(h is null))
1212 {
1213 try
1214 {
1215 await h(Provider, new CollectionEventArgs(CollectionName));
1216 }
1217 catch (Exception)
1218 {
1219 // Ignore
1220 }
1221 }
1222 }
1223
1227 public static event CollectionEventHandler CollectionCleared = null;
1228
1237 public static Task<string[]> Analyze(XmlWriter Output, string XsltPath, string ProgramDataFolder, bool ExportData)
1238 {
1239 return Provider.Analyze(Output, XsltPath, ProgramDataFolder, ExportData);
1240 }
1241
1251 public static Task<string[]> Analyze(XmlWriter Output, string XsltPath, string ProgramDataFolder, bool ExportData,
1252 ProfilerThread Thread)
1253 {
1254 return Provider.Analyze(Output, XsltPath, ProgramDataFolder, ExportData, Thread);
1255 }
1256
1265 public static Task<string[]> Repair(XmlWriter Output, string XsltPath, string ProgramDataFolder, bool ExportData)
1266 {
1267 return Repair(Output, XsltPath, ProgramDataFolder, ExportData, null);
1268 }
1269
1279 public async static Task<string[]> Repair(XmlWriter Output, string XsltPath, string ProgramDataFolder, bool ExportData,
1280 ProfilerThread Thread)
1281 {
1282 KeyValuePair<string, Dictionary<string, FlagSource>>[] Flagged = GetFlaggedCollections();
1283
1284 string[] Result = await Provider.Repair(Output, XsltPath, ProgramDataFolder, ExportData, Thread);
1285
1286 if (Result.Length > 0)
1287 RaiseRepaired(Result, Flagged);
1288
1289 return Result;
1290 }
1291
1292 private static void RaiseRepaired(string[] Collections, KeyValuePair<string, Dictionary<string, FlagSource>>[] Flagged)
1293 {
1294 FlagSource[] FlaggedCollection;
1296
1297 if (!(h is null))
1298 {
1299 foreach (string Collection in Collections)
1300 {
1301 FlaggedCollection = null;
1302
1303 if (!(Flagged is null))
1304 {
1305 foreach (KeyValuePair<string, Dictionary<string, FlagSource>> Rec in Flagged)
1306 {
1307 if (Rec.Key == Collection)
1308 {
1309 FlaggedCollection = new FlagSource[Rec.Value.Count];
1310 Rec.Value.Values.CopyTo(FlaggedCollection, 0);
1311 break;
1312 }
1313 }
1314 }
1315
1316 try
1317 {
1318 h(Provider, new CollectionRepairedEventArgs(Collection, FlaggedCollection));
1319 }
1320 catch (Exception)
1321 {
1322 // Ignore
1323 }
1324 }
1325 }
1326 }
1327
1332
1342 public static Task<string[]> Analyze(XmlWriter Output, string XsltPath, string ProgramDataFolder, bool ExportData,
1343 bool Repair)
1344 {
1345 return Analyze(Output, XsltPath, ProgramDataFolder, ExportData, Repair, null);
1346 }
1347
1358 public async static Task<string[]> Analyze(XmlWriter Output, string XsltPath, string ProgramDataFolder, bool ExportData,
1359 bool Repair, ProfilerThread Thread)
1360 {
1361 KeyValuePair<string, Dictionary<string, FlagSource>>[] Flagged = GetFlaggedCollections();
1362
1363 string[] Result = await Provider.Analyze(Output, XsltPath, ProgramDataFolder, ExportData, Repair, Thread);
1364
1365 if (Repair && Result.Length > 0)
1366 RaiseRepaired(Result, Flagged);
1367
1368 return Result;
1369 }
1370
1371 private static KeyValuePair<string, Dictionary<string, FlagSource>>[] GetFlaggedCollections()
1372 {
1373 KeyValuePair<string, Dictionary<string, FlagSource>>[] Flagged;
1374 int i;
1375
1376 lock (toRepair)
1377 {
1378 Flagged = new KeyValuePair<string, Dictionary<string, FlagSource>>[toRepair.Count];
1379 i = 0;
1380
1381 foreach (KeyValuePair<string, Dictionary<string, FlagSource>> P in toRepair)
1382 Flagged[i++] = P;
1383
1384 toRepair.Clear();
1385 }
1386
1387 return Flagged;
1388 }
1389
1394 public static string[] GetFlaggedCollectionNames()
1395 {
1396 string[] Result;
1397
1398 lock (toRepair)
1399 {
1400 Result = new string[toRepair.Count];
1401 toRepair.Keys.CopyTo(Result, 0);
1402 }
1403
1404 return Result;
1405 }
1406
1411 public static void BeginRepair(string Collection)
1412 {
1413 lock (toRepair)
1414 {
1415 toRepair[Collection] = null;
1416 }
1417 }
1418
1423 public static void EndRepair(string Collection)
1424 {
1425 lock (toRepair)
1426 {
1427 toRepair.Remove(Collection);
1428 }
1429 }
1430
1436 public static Exception FlagForRepair(string Collection, string Reason)
1437 {
1438 InconsistencyException Result = new InconsistencyException(Collection, Reason);
1439 string StackTrace = Log.CleanStackTrace(Environment.StackTrace);
1440 string Key = Reason + " | " + StackTrace;
1441
1442 lock (toRepair)
1443 {
1444 if (toRepair.TryGetValue(Collection, out Dictionary<string, FlagSource> PerStackTrace))
1445 {
1446 if (!(PerStackTrace is null))
1447 {
1448 if (PerStackTrace.TryGetValue(Key, out FlagSource FlagSource))
1449 FlagSource.Count++;
1450 else
1451 PerStackTrace[Key] = new FlagSource(Reason, StackTrace, 1);
1452 }
1453 }
1454 else
1455 toRepair[Collection] = new Dictionary<string, FlagSource>() { { Key, new FlagSource(Reason, StackTrace, 1) } };
1456 }
1457
1458 return Result;
1459 }
1460
1467 public static Task AddIndex(string CollectionName, string[] FieldNames)
1468 {
1469 return Provider.AddIndex(CollectionName, FieldNames);
1470 }
1471
1478 public static Task RemoveIndex(string CollectionName, string[] FieldNames)
1479 {
1480 return Provider.RemoveIndex(CollectionName, FieldNames);
1481 }
1482
1486 public static Task StartBulk()
1487 {
1488 return Provider.StartBulk();
1489 }
1490
1494 public static Task EndBulk()
1495 {
1496 return Provider.EndBulk();
1497 }
1498
1504 public static string[] ToStringArray(this CaseInsensitiveString[] A)
1505 {
1506 if (A is null)
1507 return null;
1508
1509 int i, c = A.Length;
1510 string[] B = new string[c];
1511
1512 for (i = 0; i < c; i++)
1513 B[i] = A[i].Value;
1514
1515 return B;
1516 }
1517
1524 {
1525 if (A is null)
1526 return null;
1527
1528 int i, c = A.Length;
1530
1531 for (i = 0; i < c; i++)
1532 B[i] = A[i];
1533
1534 return B;
1535 }
1536
1542 public static Task<IPersistentDictionary> GetDictionary(string Collection)
1543 {
1544 return Provider.GetDictionary(Collection);
1545 }
1546
1551 public static Task<string[]> GetDictionaries()
1552 {
1553 return Provider.GetDictionaries();
1554 }
1555
1560 public static Task<string[]> GetCollections()
1561 {
1562 return Provider.GetCollections();
1563 }
1564
1570 public static Task<string> GetCollection(Type Type)
1571 {
1572 return Provider.GetCollection(Type);
1573 }
1574
1580 public static Task<string> GetCollection(Object Object)
1581 {
1582 return Provider.GetCollection(Object);
1583 }
1584
1592 public static Task<bool> IsLabel(string Collection, string Label)
1593 {
1594 return Provider.IsLabel(Collection, Label);
1595 }
1596
1601 public static Task<string[]> GetLabels(string Collection)
1602 {
1603 return Provider.GetLabels(Collection);
1604 }
1605
1611 public static Task<object> TryGetObjectId(object Object)
1612 {
1613 return Provider.TryGetObjectId(Object);
1614 }
1615
1620 public static Task DropCollection(string CollectionName)
1621 {
1622 return Provider.DropCollection(CollectionName);
1623 }
1624
1631 public static string WildcardToRegex(string s, string Wildcard)
1632 {
1633 string[] Parts = s.Split(new string[] { Wildcard }, StringSplitOptions.None);
1634 StringBuilder RegEx = new StringBuilder();
1635 bool First = true;
1636 int i, j, c;
1637
1638 foreach (string Part in Parts)
1639 {
1640 if (First)
1641 First = false;
1642 else
1643 RegEx.Append(".*");
1644
1645 i = 0;
1646 c = Part.Length;
1647 while (i < c)
1648 {
1649 j = Part.IndexOfAny(regexSpecialCharaters, i);
1650 if (j < i)
1651 {
1652 RegEx.Append(Part.Substring(i));
1653 i = c;
1654 }
1655 else
1656 {
1657 if (j > i)
1658 RegEx.Append(Part.Substring(i, j - i));
1659
1660 RegEx.Append('\\');
1661 RegEx.Append(Part[j]);
1662
1663 i = j + 1;
1664 }
1665 }
1666 }
1667
1668 return RegEx.ToString();
1669 }
1670
1671 private static readonly char[] regexSpecialCharaters = new char[] { '\\', '^', '$', '{', '}', '[', ']', '(', ')', '.', '*', '+', '?', '|', '<', '>', '-', '&' };
1672
1678 public static Task<GenericObject> Generalize(object Object)
1679 {
1680 return Provider.Generalize(Object);
1681 }
1682
1688 public static Task<object> Specialize(GenericObject Object)
1689 {
1690 return Provider.Specialize(Object);
1691 }
1692
1697 public static string[] GetExcludedCollections()
1698 {
1700 }
1701
1702 }
1703}
Static class managing the application event log. Applications and services log events on this static ...
Definition: Log.cs:13
static string CleanStackTrace(string StackTrace)
Cleans a Stack Trace string, removing entries from the asynchronous execution model,...
Definition: Log.cs:184
Represents a case-insensitive string.
int Length
Gets the number of characters in the current CaseInsensitiveString object.
Event arguments for collection events.
Event arguments for collection repaired events.
Static interface for database persistence. In order to work, a database provider has to be assigned t...
Definition: Database.cs:19
static Task< string[]> GetDictionaries()
Gets an array of available dictionary collections.
Definition: Database.cs:1551
static Task< IEnumerable< object > > FindDelete(string Collection, params string[] SortOrder)
Finds objects in a given collection and deletes them in the same atomic operation.
Definition: Database.cs:879
static Task< string[]> Analyze(XmlWriter Output, string XsltPath, string ProgramDataFolder, bool ExportData, ProfilerThread Thread)
Analyzes the database and exports findings to XML.
Definition: Database.cs:1251
static Task< T > TryLoadObject< T >(object ObjectId)
Tries to load an object given its Object ID ObjectId and its class type T .
Definition: Database.cs:1054
static ObjectEventHandler ObjectUpdated
Event raised when an object has been updated.
Definition: Database.cs:657
static Task< string > GetCollection(Object Object)
Gets the collection corresponding to a given object.
Definition: Database.cs:1580
static Task< IEnumerable< T > > Find< T >(params string[] SortOrder)
Finds objects of a given class T .
Definition: Database.cs:189
static Task DeleteLazy(string Collection, Filter Filter, params string[] SortOrder)
Finds objects in a given collection and deletes them in the same atomic operation.
Definition: Database.cs:1028
static Task< IPage< T > > FindNext< T >(IPage< T > Page)
Finds the next page of objects of a given class T .
Definition: Database.cs:435
static Task< bool > Export(IDatabaseExport Output, string[] CollectionNames)
Performs an export of the database.
Definition: Database.cs:1145
static async Task< IEnumerable< object > > FindDelete(string Collection, int Offset, int MaxCount, params string[] SortOrder)
Finds objects in a given collection and deletes them in the same atomic operation.
Definition: Database.cs:893
static Task DeleteLazy(string Collection, params string[] SortOrder)
Finds objects in a given collection and deletes them in the same atomic operation.
Definition: Database.cs:1001
static async Task DeleteLazy(object Object)
Deletes an object in the database, if unlocked. If locked, object will be deleted at next opportunity...
Definition: Database.cs:756
static Task RemoveIndex(string CollectionName, string[] FieldNames)
Removes an index from a collection, if one exist.
Definition: Database.cs:1478
static Task< IPersistentDictionary > GetDictionary(string Collection)
Gets a persistent dictionary containing objects in a collection.
Definition: Database.cs:1542
static async Task< string[]> Analyze(XmlWriter Output, string XsltPath, string ProgramDataFolder, bool ExportData, bool Repair, ProfilerThread Thread)
Analyzes the database and exports findings to XML.
Definition: Database.cs:1358
static Task DeleteLazy< T >(params string[] SortOrder)
Finds objects of a given class T and deletes them in the same atomic operation.
Definition: Database.cs:943
static Task< IEnumerable< object > > Find(string Collection, Filter Filter, params string[] SortOrder)
Finds objects in a given collection.
Definition: Database.cs:260
static Task< IEnumerable< T > > FindDelete< T >(params string[] SortOrder)
Finds objects of a given class T and deletes them in the same atomic operation.
Definition: Database.cs:811
static void EndRepair(string Collection)
Is called when reparation of a collection is ended.
Definition: Database.cs:1423
static Task EndBulk()
Ends bulk-processing of data. Must be called once for every call to StartBulk.
Definition: Database.cs:1494
static bool HasProvider
If a database provider is registered.
Definition: Database.cs:79
static Task< string[]> Analyze(XmlWriter Output, string XsltPath, string ProgramDataFolder, bool ExportData)
Analyzes the database and exports findings to XML.
Definition: Database.cs:1237
static Task< string[]> Repair(XmlWriter Output, string XsltPath, string ProgramDataFolder, bool ExportData)
Analyzes the database and repairs it if necessary. Results are exported to XML.
Definition: Database.cs:1265
static CaseInsensitiveString[] ToCaseInsensitiveStringArray(this string[] A)
Converts a case insensitive string array to a normal string array.
Definition: Database.cs:1523
static async Task< T > FindFirstIgnoreRest< T >(params string[] SortOrder)
Finds the first object of a given class T and ignores the rest.
Definition: Database.cs:592
static Task Iterate< T >(IDatabaseIteration< T > Recipient)
Performs an iteration of contents of the entire database.
Definition: Database.cs:1168
static Task< bool > IsLabel(string Collection, string Label)
Checks if a string is a label in a given collection.
Definition: Database.cs:1592
static string[] GetExcludedCollections()
Gets an array of collections that should be excluded from backups.
Definition: Database.cs:1697
static Task< object > TryGetObjectId(object Object)
Tries to get the Object ID of an object, if it exists.
Definition: Database.cs:1611
static async Task InsertLazy(object Object)
Inserts an object into the database, if unlocked. If locked, object will be inserted at next opportun...
Definition: Database.cs:156
static void Register(IDatabaseProvider DatabaseProvider)
Registers a database provider for use from the static Database class, throughout the lifetime of the ...
Definition: Database.cs:31
static Task DeleteLazy(string Collection, int Offset, int MaxCount, Filter Filter, params string[] SortOrder)
Finds objects in a given collection and deletes them in the same atomic operation.
Definition: Database.cs:1043
static IDatabaseProvider Provider
Registered database provider.
Definition: Database.cs:57
static Task< IPage< object > > FindNext(IPage< object > Page)
Finds the next page of objects in a given collection.
Definition: Database.cs:446
static async Task Update(params object[] Objects)
Updates a collection of objects in the database.
Definition: Database.cs:663
static Task< IEnumerable< object > > Find(string Collection, int Offset, int MaxCount, Filter Filter, params string[] SortOrder)
Finds objects in a given collection.
Definition: Database.cs:289
static async Task Update(IEnumerable< object > Objects)
Updates a collection of objects in the database.
Definition: Database.cs:677
static Task DeleteLazy(string Collection, int Offset, int MaxCount, params string[] SortOrder)
Finds objects in a given collection and deletes them in the same atomic operation.
Definition: Database.cs:1015
static Task AddIndex(string CollectionName, string[] FieldNames)
Adds an index to a collection, if one does not already exist.
Definition: Database.cs:1467
static string WildcardToRegex(string s, string Wildcard)
Converts a wildcard string to a regular expression string.
Definition: Database.cs:1631
static Task< string[]> GetCollections()
Gets an array of available collections.
Definition: Database.cs:1560
static Task< bool > Export(IDatabaseExport Output)
Performs an export of the database.
Definition: Database.cs:1134
static Exception FlagForRepair(string Collection, string Reason)
Flags a collection for repairing.
Definition: Database.cs:1436
static Task< IPage< object > > FindFirst(string Collection, int PageSize, params string[] SortOrder)
Finds the first page of objects in a given collection.
Definition: Database.cs:394
static ObjectEventHandler ObjectDeleted
Event raised when an object has been deleted.
Definition: Database.cs:726
static Task StartBulk()
Starts bulk-proccessing of data. Must be followed by a call to EndBulk.
Definition: Database.cs:1486
static async Task Delete(IEnumerable< object > Objects)
Deletes a collection of objects in the database.
Definition: Database.cs:746
static void BeginRepair(string Collection)
Is called when reparation of a collection is begin.
Definition: Database.cs:1411
static Task< IEnumerable< object > > Find(string Collection, int Offset, int MaxCount, params string[] SortOrder)
Finds objects in a given collection.
Definition: Database.cs:274
static async Task< PaginatedEnumerator< T > > Enumerate< T >(int PageSize, params string[] SortOrder)
Enumerates objects of a given class T available in the database, by retrieving items from the databa...
Definition: Database.cs:461
static async Task UpdateLazy(object Object)
Updates an object in the database, if unlocked. If locked, object will be updated at next opportunity...
Definition: Database.cs:687
static async Task UpdateLazy(IEnumerable< object > Objects)
Updates a collection of objects in the database, if unlocked. If locked, objects will be updated at n...
Definition: Database.cs:708
static CollectionEventHandler CollectionCleared
Event raised when a collection has been cleared.
Definition: Database.cs:1227
static bool Locked
If the datbase provider has been locked for the rest of the run-time of the application.
Definition: Database.cs:87
static Task< bool > Export(IDatabaseExport Output, string[] CollectionNames, ProfilerThread Thread)
Performs an export of the database.
Definition: Database.cs:1157
static Task< string[]> Analyze(XmlWriter Output, string XsltPath, string ProgramDataFolder, bool ExportData, bool Repair)
Analyzes the database and exports findings to XML.
Definition: Database.cs:1342
static string[] ToStringArray(this CaseInsensitiveString[] A)
Converts a case insensitive string array to a normal string array.
Definition: Database.cs:1504
static async Task Update(object Object)
Updates an object in the database.
Definition: Database.cs:626
static Task< GenericObject > Generalize(object Object)
Creates a generalized representation of an object.
Definition: Database.cs:1678
static Task< string > GetCollection(Type Type)
Gets the collection corresponding to a given type.
Definition: Database.cs:1570
static async Task Delete(object Object)
Deletes an object in the database.
Definition: Database.cs:717
static async Task< T > LoadObject< T >(object ObjectId)
Loads an object given its Object ID ObjectId and its base type T .
Definition: Database.cs:1090
static async Task< object > LoadObject(string CollectionName, object ObjectId)
Loads an object given its Object ID ObjectId and its collection name CollectionName .
Definition: Database.cs:1121
static Task< string[]> GetLabels(string Collection)
Gets an array of available labels for a collection.
Definition: Database.cs:1601
static async Task Insert(params object[] Objects)
Inserts a set of objects into the default collection of the database.
Definition: Database.cs:132
static string[] GetFlaggedCollectionNames()
Gets the names of the collections that have been flagged as possibly corrupt.
Definition: Database.cs:1394
static async Task< PaginatedEnumerator< object > > Enumerate(string Collection, int PageSize, Filter Filter, params string[] SortOrder)
Finds the first page of objects in a given collection.
Definition: Database.cs:505
static Task< object > Specialize(GenericObject Object)
Creates a specialized representation of a generic object.
Definition: Database.cs:1688
static async Task DeleteLazy(params object[] Objects)
Deletes a collection of objects in the database, if unlocked. If locked, objects will be deleted at n...
Definition: Database.cs:765
static async Task< IEnumerable< object > > FindDelete(string Collection, int Offset, int MaxCount, Filter Filter, params string[] SortOrder)
Finds objects in a given collection and deletes them in the same atomic operation.
Definition: Database.cs:926
static async Task< string[]> Repair(XmlWriter Output, string XsltPath, string ProgramDataFolder, bool ExportData, ProfilerThread Thread)
Analyzes the database and repairs it if necessary. Results are exported to XML.
Definition: Database.cs:1279
static ObjectEventHandler ObjectInserted
Event raised when an object has been inserted.
Definition: Database.cs:126
static Task< IEnumerable< object > > Find(string Collection, params string[] SortOrder)
Finds objects in a given collection.
Definition: Database.cs:247
static Task< IEnumerable< object > > FindDelete(string Collection, Filter Filter, params string[] SortOrder)
Finds objects in a given collection and deletes them in the same atomic operation.
Definition: Database.cs:911
static async Task Insert(object Object)
Inserts an object into the default collection of the database.
Definition: Database.cs:95
static async Task UpdateLazy(params object[] Objects)
Updates a collection of objects in the database, if unlocked. If locked, objects will be updated at n...
Definition: Database.cs:696
static CollectionRepairedEventHandler CollectionRepaired
Event raised when a collection has been repaired.
Definition: Database.cs:1331
static Task< object > TryLoadObject(string CollectionName, object ObjectId)
Tries to load an object given its Object ID ObjectId and its collection name CollectionName .
Definition: Database.cs:1079
static async Task< T > FindFirstDeleteRest< T >(params string[] SortOrder)
Finds the first object of a given class T and deletes the rest.
Definition: Database.cs:534
static async Task InsertLazy(params object[] Objects)
Inserts an object into the database, if unlocked. If locked, object will be inserted at next opportun...
Definition: Database.cs:165
static async Task Insert(IEnumerable< object > Objects)
Inserts a set of objects into the default collection of the database.
Definition: Database.cs:146
static void Register(IDatabaseProvider DatabaseProvider, bool Lock)
Registers a database provider for use from the static Database class, throughout the lifetime of the ...
Definition: Database.cs:44
static async Task DeleteLazy(IEnumerable< object > Objects)
Deletes a collection of objects in the database, if unlocked. If locked, objects will be deleted at n...
Definition: Database.cs:777
static Task DropCollection(string CollectionName)
Drops a collection, if it exist.
Definition: Database.cs:1620
static Task< IPage< object > > FindFirst(string Collection, int PageSize, Filter Filter, params string[] SortOrder)
Finds the first page of objects in a given collection.
Definition: Database.cs:408
static async Task Delete(params object[] Objects)
Deletes a collection of objects in the database.
Definition: Database.cs:732
static Task< IPage< T > > FindFirst< T >(int PageSize, params string[] SortOrder)
Finds the first page of objects of a given class T .
Definition: Database.cs:364
static async Task< PaginatedEnumerator< object > > Enumerate(string Collection, int PageSize, params string[] SortOrder)
Finds the first page of objects in a given collection.
Definition: Database.cs:491
static async Task InsertLazy(IEnumerable< object > Objects)
Inserts an object into the database, if unlocked. If locked, object will be inserted at next opportun...
Definition: Database.cs:177
static async Task Clear(string CollectionName)
Clears a collection of all objects.
Definition: Database.cs:1206
Database inconsistency exception. Raised when an inconsistency in the database has been found.
Base class for all filter classes.
Definition: Filter.cs:15
Source of code flagging a collection for repair.
Definition: FlagSource.cs:9
int Count
Number of times the collection has been flagged from this source.
Definition: FlagSource.cs:41
Event arguments for database object events.
Generic object. Contains a sequence of properties.
Class that keeps track of events and timing for one thread.
Interface for database providers that can be plugged into the static Database class.
Task Update(object Object)
Updates an object in the database.
Task InsertLazy(object Object, ObjectCallback Callback)
Inserts an object into the database, if unlocked. If locked, object will be inserted at next opportun...
Task< string[]> Repair(XmlWriter Output, string XsltPath, string ProgramDataFolder, bool ExportData)
Analyzes the database and repairs it if necessary. Results are exported to XML.
Task< object > TryLoadObject(string CollectionName, object ObjectId)
Tries to load an object given its Object ID ObjectId and its collection name CollectionName .
Task< IPage< object > > FindFirst(string Collection, int PageSize, params string[] SortOrder)
Finds the first page of objects in a given collection.
Task< object > TryGetObjectId(object Object)
Tries to get the Object ID of an object, if it exists.
Task AddIndex(string CollectionName, string[] FieldNames)
Adds an index to a collection, if one does not already exist.
Task Delete(object Object)
Deletes an object in the database.
Task< object > Specialize(GenericObject Object)
Creates a specialized representation of a generic object.
Task< IEnumerable< object > > Find(string Collection, int Offset, int MaxCount, params string[] SortOrder)
Finds objects in a given collection.
Task< bool > IsLabel(string Collection, string Label)
Checks if a string is a label in a given collection.
Task< string[]> GetLabels(string Collection)
Gets an array of available labels for a collection.
Task< string > GetCollection(Type Type)
Gets the collection corresponding to a given type.
Task< bool > Export(IDatabaseExport Output, string[] CollectionNames)
Performs an export of the database.
Task< string[]> GetCollections()
Gets an array of available collections.
Task Clear(string CollectionName)
Clears a collection of all objects.
Task< string[]> GetDictionaries()
Gets an array of available dictionary collections.
Task EndBulk()
Ends bulk-processing of data. Must be called once for every call to StartBulk.
Task UpdateLazy(object Object, ObjectCallback Callback)
Updates an object in the database, if unlocked. If locked, object will be updated at next opportunity...
Task< GenericObject > Generalize(object Object)
Creates a generalized representation of an object.
Task Insert(object Object)
Inserts an object into the database.
Task DeleteLazy(object Object, ObjectCallback Callback)
Deletes an object in the database, if unlocked. If locked, object will be deleted at next opportunity...
Task< IPersistentDictionary > GetDictionary(string Collection)
Gets a persistent dictionary containing objects in a collection.
Task< string[]> Analyze(XmlWriter Output, string XsltPath, string ProgramDataFolder, bool ExportData)
Analyzes the database and exports findings to XML.
string[] GetExcludedCollections()
Gets an array of collections that should be excluded from backups.
Task< IEnumerable< object > > FindDelete(string Collection, int Offset, int MaxCount, params string[] SortOrder)
Finds objects in a given collection and deletes them in the same atomic operation.
Task DropCollection(string CollectionName)
Drops a collection, if it exist.
Task RemoveIndex(string CollectionName, string[] FieldNames)
Removes an index from a collection, if one exist.
Task< IPage< object > > FindNext(IPage< object > Page)
Finds the next page of objects in a given collection.
Task StartBulk()
Starts bulk-proccessing of data. Must be followed by a call to EndBulk.
Interface for paginated results.
Definition: IPage.cs:11
Interface for iterations of database contents.
delegate void ObjectEventHandler(object Sender, ObjectEventArgs e)
Event handler for object events.
delegate Task CollectionEventHandler(object Sender, CollectionEventArgs e)
Event handler for collection events.
delegate Task CollectionRepairedEventHandler(object Sender, CollectionRepairedEventArgs e)
Event handler for collection repaired events.