2using System.Collections;
3using System.Collections.Generic;
7using System.Threading.Tasks;
26 public const string Namespace =
"http://waher.se/Schema/Export.xsd";
28 private readonly XmlWriterSettings settings;
29 private readonly SemaphoreSlim semaphore =
new SemaphoreSlim(1);
30 private StreamWriter file;
31 private DateTime lastEvent = DateTime.MinValue;
32 private XmlWriter output;
33 private TextWriter textOutput;
35 private readonly
string fileName;
36 private string lastFileName =
null;
37 private readonly
string transform =
null;
38 private readonly
int deleteAfterDays;
79 : this(
FileName, string.Empty, DeleteAfterDays)
126 this.deleteAfterDays = DeleteAfterDays;
128 this.settings =
new XmlWriterSettings()
131 ConformanceLevel = ConformanceLevel.Document,
132 Encoding = Encoding.UTF8,
135 NewLineChars =
"\r\n",
136 NewLineHandling = NewLineHandling.Replace,
137 NewLineOnAttributes =
false,
138 OmitXmlDeclaration =
false,
139 WriteEndDocumentOnClose =
true,
143 string FolderName = Path.GetDirectoryName(
FileName);
145 if (!
string.IsNullOrEmpty(FolderName) && !Directory.Exists(FolderName))
148 Directory.CreateDirectory(FolderName);
158 this.textOutput = Output;
160 this.fileName =
null;
161 this.transform =
null;
162 this.deleteAfterDays = 0;
164 this.settings =
new XmlWriterSettings()
167 ConformanceLevel = ConformanceLevel.Document,
168 Encoding = Encoding.UTF8,
171 NewLineChars =
"\r\n",
172 NewLineHandling = NewLineHandling.Replace,
173 NewLineOnAttributes =
false,
174 OmitXmlDeclaration =
false,
175 WriteEndDocumentOnClose =
true,
179 this.output = XmlWriter.Create(this.textOutput, this.settings);
180 this.output.WriteStartDocument();
181 this.output.WriteStartElement(
"LedgerExport",
Namespace);
210 public static string GetFileName(
string TemplateFileName, DateTime TP)
212 return TemplateFileName.
213 Replace(
"%YEAR%", TP.Year.ToString(
"D4")).
214 Replace(
"%MONTH%", TP.Month.ToString(
"D2")).
215 Replace(
"%DAY%", TP.Day.ToString(
"D2")).
216 Replace(
"%HOUR%", TP.Hour.ToString(
"D2")).
217 Replace(
"%MINUTE%", TP.Minute.ToString(
"D2")).
218 Replace(
"%SECOND%", TP.Second.ToString(
"D2"));
241 while (File.Exists(s));
250 private async Task BeforeWrite()
252 if (this.fileName is
null)
255 DateTime TP = DateTime.Now;
259 if (!(this.lastFileName is
null) && this.lastFileName == s && !(this.file is
null) && this.file.BaseStream.CanWrite)
264 if (!(this.output is
null))
266 await this.output.WriteEndElementAsync();
267 await this.output.WriteEndDocumentAsync();
268 await this.output.FlushAsync();
271 this.file?.Dispose();
277 await this.DisposeOutput();
293 this.file = File.CreateText(s2);
294 this.lastFileName = s;
295 this.output = XmlWriter.Create(this.file, this.settings);
304 await this.output.WriteStartDocumentAsync();
306 if (!
string.IsNullOrEmpty(this.transform))
308 if (File.Exists(
this.transform))
314 await this.output.WriteProcessingInstructionAsync(
"xml-stylesheet",
"type=\"text/xsl\" href=\"data:text/xsl;base64," +
315 Convert.ToBase64String(XsltBin) +
"\"");
319 await this.output.WriteProcessingInstructionAsync(
"xml-stylesheet",
"type=\"text/xsl\" href=\"" + this.transform +
"\"");
323 await this.output.WriteProcessingInstructionAsync(
"xml-stylesheet",
"type=\"text/xsl\" href=\"" + this.transform +
"\"");
326 await this.output.WriteStartElementAsync(
string.Empty,
"LedgerExport",
Namespace);
327 await this.output.FlushAsync();
329 if (this.deleteAfterDays > 0 && this.deleteAfterDays <
int.MaxValue)
331 string FolderName = Path.GetDirectoryName(s);
333 if (!
string.IsNullOrEmpty(FolderName))
335 string[] Files = Directory.GetFiles(FolderName,
"*.*");
339 if ((DateTime.Now - File.GetLastWriteTime(
FileName)).TotalDays >=
this.deleteAfterDays)
345 catch (IOException ex)
362 private async Task DisposeOutput()
364 if (!(this.output is
null))
366 await this.output.FlushAsync();
367 this.output.Dispose();
371 this.file?.Dispose();
374 this.textOutput?.Flush();
375 this.textOutput =
null;
380 #region ILedgerProvider
388 return Task.CompletedTask;
398 this.running =
false;
400 if (!(this.output is
null))
402 await this.output.WriteEndElementAsync();
403 await this.output.WriteEndDocumentAsync();
415 if (!(this.output is
null))
416 await this.output.FlushAsync();
418 if (!(this.file is
null))
419 await this.file.FlushAsync();
421 if (!(this.textOutput is
null))
422 await this.textOutput.FlushAsync();
431 return this.OutputEntry(
"New", Object);
440 return this.OutputEntry(
"Update", Object);
449 return this.OutputEntry(
"Delete", Object);
452 private async Task OutputEntry(
string Method,
object Object)
458 DateTime Timestamp = DateTime.UtcNow;
460 await this.semaphore.WaitAsync();
465 await this.BeforeWrite();
467 if (!(this.output is
null))
469 await this.output.WriteStartElementAsync(
string.Empty, Method,
Namespace);
470 await this.output.WriteAttributeStringAsync(
string.Empty,
"timestamp",
string.Empty,
XML.
Encode(Timestamp));
471 await this.output.WriteAttributeStringAsync(
string.Empty,
"collection",
string.Empty, Obj.
CollectionName);
472 await this.output.WriteAttributeStringAsync(
string.Empty,
"type",
string.Empty, Obj.
TypeName);
473 await this.output.WriteAttributeStringAsync(
string.Empty,
"id",
string.Empty, Obj.
ObjectId.ToString());
475 foreach (KeyValuePair<string, object> P
in Obj.
Properties)
478 await this.output.WriteEndElementAsync();
479 await this.output.FlushAsync();
486 await this.DisposeOutput();
496 this.semaphore.Release();
509 if (PropertyValue is
null)
511 await Output.WriteStartElementAsync(
string.Empty,
"Null",
Namespace);
512 if (!(PropertyName is
null))
513 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
514 await Output.WriteEndElementAsync();
516 else if (PropertyValue is Enum)
518 await Output.WriteStartElementAsync(
string.Empty,
"En",
Namespace);
519 if (!(PropertyName is
null))
520 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
521 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, PropertyValue.ToString());
522 await Output.WriteEndElementAsync();
526 switch (Type.GetTypeCode(PropertyValue.GetType()))
528 case TypeCode.Boolean:
529 await Output.WriteStartElementAsync(
string.Empty,
"Bl",
Namespace);
530 if (!(PropertyName is
null))
531 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
532 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty,
CommonTypes.
Encode((
bool)PropertyValue));
533 await Output.WriteEndElementAsync();
537 await Output.WriteStartElementAsync(
string.Empty,
"B",
Namespace);
538 if (!(PropertyName is
null))
539 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
540 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, PropertyValue.ToString());
541 await Output.WriteEndElementAsync();
545 await Output.WriteStartElementAsync(
string.Empty,
"Ch",
Namespace);
546 if (!(PropertyName is
null))
547 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
548 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, PropertyValue.ToString());
549 await Output.WriteEndElementAsync();
552 case TypeCode.DateTime:
553 await Output.WriteStartElementAsync(
string.Empty,
"DT",
Namespace);
554 if (!(PropertyName is
null))
555 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
556 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty,
XML.
Encode((DateTime)PropertyValue));
557 await Output.WriteEndElementAsync();
560 case TypeCode.Decimal:
561 await Output.WriteStartElementAsync(
string.Empty,
"Dc",
Namespace);
562 if (!(PropertyName is
null))
563 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
564 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty,
CommonTypes.
Encode((decimal)PropertyValue));
565 await Output.WriteEndElementAsync();
568 case TypeCode.Double:
569 await Output.WriteStartElementAsync(
string.Empty,
"Db",
Namespace);
570 if (!(PropertyName is
null))
571 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
572 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty,
CommonTypes.
Encode((
double)PropertyValue));
573 await Output.WriteEndElementAsync();
577 await Output.WriteStartElementAsync(
string.Empty,
"I2",
Namespace);
578 if (!(PropertyName is
null))
579 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
580 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, PropertyValue.ToString());
581 await Output.WriteEndElementAsync();
585 await Output.WriteStartElementAsync(
string.Empty,
"I4",
Namespace);
586 if (!(PropertyName is
null))
587 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
588 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, PropertyValue.ToString());
589 await Output.WriteEndElementAsync();
593 await Output.WriteStartElementAsync(
string.Empty,
"I8",
Namespace);
594 if (!(PropertyName is
null))
595 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
596 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, PropertyValue.ToString());
597 await Output.WriteEndElementAsync();
601 await Output.WriteStartElementAsync(
string.Empty,
"I1",
Namespace);
602 if (!(PropertyName is
null))
603 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
604 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, PropertyValue.ToString());
605 await Output.WriteEndElementAsync();
608 case TypeCode.Single:
609 await Output.WriteStartElementAsync(
string.Empty,
"Fl",
Namespace);
610 if (!(PropertyName is
null))
611 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
612 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty,
CommonTypes.
Encode((
float)PropertyValue));
613 await Output.WriteEndElementAsync();
616 case TypeCode.String:
617 string s = PropertyValue.ToString();
620 XmlConvert.VerifyXmlChars(s);
621 await Output.WriteStartElementAsync(
string.Empty,
"S",
Namespace);
622 if (!(PropertyName is
null))
623 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
624 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, s);
625 await Output.WriteEndElementAsync();
629 byte[] Bin = System.Text.Encoding.UTF8.GetBytes(s);
630 s = Convert.ToBase64String(Bin);
631 await Output.WriteStartElementAsync(
string.Empty,
"S64",
Namespace);
632 if (!(PropertyName is
null))
633 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
634 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, s);
635 await Output.WriteEndElementAsync();
639 case TypeCode.UInt16:
640 await Output.WriteStartElementAsync(
string.Empty,
"U2",
Namespace);
641 if (!(PropertyName is
null))
642 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
643 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, PropertyValue.ToString());
644 await Output.WriteEndElementAsync();
647 case TypeCode.UInt32:
648 await Output.WriteStartElementAsync(
string.Empty,
"U4",
Namespace);
649 if (!(PropertyName is
null))
650 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
651 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, PropertyValue.ToString());
652 await Output.WriteEndElementAsync();
655 case TypeCode.UInt64:
656 await Output.WriteStartElementAsync(
string.Empty,
"U8",
Namespace);
657 if (!(PropertyName is
null))
658 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
659 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, PropertyValue.ToString());
660 await Output.WriteEndElementAsync();
665 await Output.WriteStartElementAsync(
string.Empty,
"Null",
Namespace);
666 if (!(PropertyName is
null))
667 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
668 await Output.WriteEndElementAsync();
671 case TypeCode.Object:
672 if (PropertyValue is TimeSpan)
674 await Output.WriteStartElementAsync(
string.Empty,
"TS",
Namespace);
675 if (!(PropertyName is
null))
676 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
677 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, PropertyValue.ToString());
678 await Output.WriteEndElementAsync();
680 else if (PropertyValue is DateTimeOffset DTO)
682 await Output.WriteStartElementAsync(
string.Empty,
"DTO",
Namespace);
683 if (!(PropertyName is
null))
684 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
685 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty,
XML.
Encode(DTO));
686 await Output.WriteEndElementAsync();
693 XmlConvert.VerifyXmlChars(s);
694 await Output.WriteStartElementAsync(
string.Empty,
"CIS",
Namespace);
695 if (!(PropertyName is
null))
696 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
697 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, s);
698 await Output.WriteEndElementAsync();
702 byte[] Bin = System.Text.Encoding.UTF8.GetBytes(s);
703 s = Convert.ToBase64String(Bin);
704 await Output.WriteStartElementAsync(
string.Empty,
"CIS64",
Namespace);
705 if (!(PropertyName is
null))
706 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
707 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, s);
708 await Output.WriteEndElementAsync();
711 else if (PropertyValue is
byte[] Bin)
713 await Output.WriteStartElementAsync(
string.Empty,
"Bin",
Namespace);
714 if (!(PropertyName is
null))
715 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
733 if (i == 0 && j == c)
740 Array.Copy(Bin, i, Buf, 0, j);
742 await Output.WriteElementStringAsync(
string.Empty,
"Chunk",
Namespace, Convert.ToBase64String(Buf, 0, j));
746 await Output.WriteEndElementAsync();
748 else if (PropertyValue is Guid)
750 await Output.WriteStartElementAsync(
string.Empty,
"ID",
Namespace);
751 if (!(PropertyName is
null))
752 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
753 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, PropertyValue.ToString());
754 await Output.WriteEndElementAsync();
756 else if (PropertyValue is Array A)
758 await Output.WriteStartElementAsync(
string.Empty,
"Array",
Namespace);
759 if (!(PropertyName is
null))
760 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
761 await Output.WriteAttributeStringAsync(
string.Empty,
"elementType",
string.Empty, PropertyValue.GetType().GetElementType().FullName);
763 foreach (
object Obj
in A)
766 await Output.WriteEndElementAsync();
770 await Output.WriteStartElementAsync(
string.Empty,
"Obj",
Namespace);
771 if (!(PropertyName is
null))
772 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
773 await Output.WriteAttributeStringAsync(
string.Empty,
"type",
string.Empty, Obj.TypeName);
775 foreach (KeyValuePair<string, object> P
in Obj)
778 await Output.WriteEndElementAsync();
781 throw new Exception(
"Unhandled property value type: " + PropertyValue.GetType().FullName);
785 throw new Exception(
"Unhandled property value type: " + PropertyValue.GetType().FullName);
799 DateTime Timestamp = DateTime.UtcNow;
801 await this.semaphore.WaitAsync();
806 await this.BeforeWrite();
808 if (!(this.output is
null))
810 await this.output.WriteStartElementAsync(
string.Empty,
"Clear",
Namespace);
811 await this.output.WriteAttributeStringAsync(
string.Empty,
"timestamp",
string.Empty,
XML.
Encode(Timestamp));
812 await this.output.WriteAttributeStringAsync(
string.Empty,
"collection",
string.Empty, Collection);
813 await this.output.WriteEndElementAsync();
814 await this.output.FlushAsync();
821 await this.DisposeOutput();
831 this.semaphore.Release();
842 if (!(this.externalEvents is
null) && this.externalEvents != ExternalEvents)
843 throw new Exception(
"An interface for external events has already been registered.");
845 this.externalEvents = ExternalEvents;
855 if (!(this.externalEvents is
null) && this.externalEvents != ExternalEvents)
856 throw new Exception(
"The registered interface for external events differs from the one presented.");
858 this.externalEvents =
null;
884 object IEnumerator.Current =>
null;
885 public void Dispose() { }
886 public bool MoveNext() =>
false;
887 public Task<bool> MoveNextAsync() => Task.FromResult(
false);
888 public void Reset() { }
897 return Task.FromResult(
new string[0]);
909 return Task.FromResult(
true);
922 return Task.FromResult(
true);
927 #region ILedgerExport
929 private readonly LinkedList<KeyValuePair<string, object>> blockMetaData =
new LinkedList<KeyValuePair<string, object>>();
930 private string writtenCollection =
null;
931 private string writtenBlockId =
null;
932 private string currentCollection =
null;
933 private string currentBlockId =
null;
934 private string currentEntryObjectId =
null;
935 private string currentEntryObjectType =
null;
937 private DateTimeOffset currentEntryTimestamp = DateTimeOffset.MinValue;
938 private Dictionary<string, object> currentEntryProperties =
null;
946 this.currentCollection =
null;
968 this.currentCollection = CollectionName;
969 return Task.FromResult(
true);
978 if (!(this.writtenCollection is
null))
980 await this.output.WriteEndElementAsync();
981 this.writtenCollection =
null;
984 this.currentCollection =
null;
995 this.currentBlockId = BlockID;
996 return Task.FromResult(
true);
1007 this.blockMetaData.AddLast(
new KeyValuePair<string, object>(Key, Value));
1008 return Task.FromResult(
true);
1017 if (!(this.writtenBlockId is
null))
1019 await this.output.WriteEndElementAsync();
1020 this.writtenBlockId =
null;
1021 this.blockMetaData.Clear();
1024 this.currentBlockId =
null;
1039 this.currentEntryObjectId = ObjectId;
1040 this.currentEntryObjectType = TypeName;
1042 this.currentEntryTimestamp = EntryTimestamp;
1044 if (this.currentEntryProperties is
null)
1045 this.currentEntryProperties =
new Dictionary<string, object>();
1047 this.currentEntryProperties.Clear();
1049 return Task.FromResult(
true);
1061 await this.semaphore.WaitAsync();
1066 await this.BeforeWrite();
1068 if (!(this.output is
null))
1070 await this.WritePendingInfoLocked();
1072 await this.output.WriteStartElementAsync(
string.Empty, this.currentEntryType.ToString(),
Namespace);
1073 await this.output.WriteAttributeStringAsync(
string.Empty,
"timestamp",
string.Empty,
XML.
Encode(
this.currentEntryTimestamp));
1074 await this.output.WriteAttributeStringAsync(
string.Empty,
"type",
string.Empty, this.currentEntryObjectType);
1075 await this.output.WriteAttributeStringAsync(
string.Empty,
"id",
string.Empty, this.currentEntryObjectId);
1077 foreach (KeyValuePair<string, object> P
in this.currentEntryProperties)
1080 await this.output.WriteEndElementAsync();
1081 await this.output.FlushAsync();
1088 await this.DisposeOutput();
1098 this.semaphore.Release();
1104 private async Task WritePendingInfoLocked()
1106 if (!(this.currentBlockId is
null) &&
1107 !(this.writtenBlockId is
null) &&
1108 this.currentBlockId != this.writtenBlockId)
1110 await this.output.WriteEndElementAsync();
1111 this.writtenBlockId =
null;
1112 this.blockMetaData.Clear();
1115 if (!(this.currentCollection is
null) &&
1116 !(this.writtenCollection is
null) &&
1117 this.currentCollection != this.writtenCollection)
1119 await this.output.WriteEndElementAsync();
1120 this.writtenCollection =
null;
1123 if (this.writtenCollection is
null)
1125 await this.output.WriteStartElementAsync(
string.Empty,
"Collection",
Namespace);
1126 await this.output.WriteAttributeStringAsync(
string.Empty,
"name",
string.Empty, this.currentCollection);
1127 this.writtenCollection = this.currentCollection;
1130 if (this.writtenBlockId is
null)
1132 await this.output.WriteStartElementAsync(
string.Empty,
"Block",
Namespace);
1133 await this.output.WriteAttributeStringAsync(
string.Empty,
"id",
string.Empty, this.currentBlockId);
1134 this.writtenBlockId = this.currentBlockId;
1136 if (!(this.blockMetaData.First is
null))
1138 foreach (KeyValuePair<string, object> P
in this.blockMetaData)
1153 await this.semaphore.WaitAsync();
1158 await this.BeforeWrite();
1160 if (!(this.output is
null))
1162 await this.WritePendingInfoLocked();
1164 await this.output.WriteStartElementAsync(
string.Empty,
"Clear",
Namespace);
1165 await this.output.WriteAttributeStringAsync(
string.Empty,
"timestamp",
string.Empty,
XML.
Encode(EntryTimestamp));
1166 await this.output.WriteEndElementAsync();
1167 await this.output.FlushAsync();
1174 await this.DisposeOutput();
1184 this.semaphore.Release();
1198 this.currentEntryProperties[PropertyName] = PropertyValue;
1199 return Task.FromResult(
true);
1212 await this.semaphore.WaitAsync();
1217 await this.BeforeWrite();
1219 if (!(this.output is
null))
1221 await this.WritePendingInfoLocked();
1223 await this.output.WriteCommentAsync(Message);
1224 await this.output.FlushAsync();
1231 await this.DisposeOutput();
1241 this.semaphore.Release();
Helps with parsing of commong data types.
static string Encode(bool x)
Encodes a Boolean for use in XML and other formats.
Static class managing loading of resources stored as embedded resources or in content files.
static async Task< byte[]> ReadAllBytesAsync(string FileName)
Reads a binary file asynchronously.
Helps with common XML-related tasks.
static string Encode(string s)
Encodes a string for use in XML.
Static class managing the application event log. Applications and services log events on this static ...
static void Exception(Exception Exception, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, params KeyValuePair< string, object >[] Tags)
Logs an exception. Event type will be determined by the severity of the exception.
static void Error(string Message, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, string StackTrace, params KeyValuePair< string, object >[] Tags)
Logs an error event.
static void Informational(string Message, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, string StackTrace, params KeyValuePair< string, object >[] Tags)
Logs an informational event.
Represents a case-insensitive string.
Static interface for database persistence. In order to work, a database provider has to be assigned t...
static Task< GenericObject > Generalize(object Object)
Creates a generalized representation of an object.
Contains basic ledger export restrictions.
Generic object. Contains a sequence of properties.
IEnumerable< KeyValuePair< string, object > > Properties
Current set of properties.
string TypeName
Type name.
string CollectionName
Collection name.
Simple ledger that records anything that happens in the database to XML files in the program data fol...
async Task< bool > CollectionCleared(DateTimeOffset EntryTimestamp)
Is called when the collection has been cleared.
XmlFileLedger(string FileName, string Transform, int DeleteAfterDays)
Simple ledger that records anything that happens in the database to XML files in the program data fol...
Task< bool > Export(ILedgerExport Output, LedgerExportRestriction Restriction)
Performs an export of the entire ledger.
Task< string[]> GetCollections()
Gets an array of available collections.
async Task Stop()
Called when processing ends.
Task< ILedgerEnumerator< T > > GetEnumerator< T >()
Gets an eumerator for objects of type T .
Task< bool > Export(ILedgerExport Output, LedgerExportRestriction Restriction, ProfilerThread Thread)
Performs an export of the entire ledger.
string Transform
Transform to use.
async Task ClearedCollection(string Collection)
Clears a collection in the ledger.
void Unregister(ILedgerExternalEvents ExternalEvents)
Unregisters a recipient of external events.
XmlFileLedger(TextWriter Output)
Simple ledger that records anything that happens in the database to a text output stream.
async Task< bool > EndBlock()
Is called when a block in a collection is finished.
Task DeletedEntry(object Object)
Deletes an entry in the ledger.
void Register(ILedgerExternalEvents ExternalEvents)
Registers a recipient of external events.
string FileName
File Name.
XmlFileLedger(string FileName, string Transform)
Simple ledger that records anything that happens in the database to XML files in the program data fol...
Task< bool > StartEntry(string ObjectId, string TypeName, EntryType EntryType, DateTimeOffset EntryTimestamp)
Is called when an entry is started.
Task< bool > StartCollection(string CollectionName)
Is called when a collection is started.
Task< ILedgerEnumerator< object > > GetEnumerator(string CollectionName)
Gets an eumerator for objects in a collection.
async Task Flush()
Persists any pending changes.
Task< bool > ReportException(Exception Exception)
Is called when an exception has occurred.
Task< bool > StartBlock(string BlockID)
Is called when a block in a collection is started.
async Task< bool > EndEntry()
Is called when an entry is finished.
static void MakeUnique(ref string FileName)
Makes a file name unique.
DateTime LastEvent
Timestamp of Last event
static string GetFileName(string TemplateFileName, DateTime TP)
Gets the name of a file, given a file name template.
XmlFileLedger(string FileName, int DeleteAfterDays)
Simple ledger that records anything that happens in the database to XML files in the program data fol...
const string Namespace
http://waher.se/Schema/Export.xsd
Task Start()
Called when processing starts.
XmlFileLedger(string FileName)
Simple ledger that records anything that happens in the database to XML files in the program data fol...
static async Task ReportProperty(XmlWriter Output, string PropertyName, object PropertyValue, string Namespace)
Serializes a property to XML.
async Task< bool > EndLedger()
Is called when export of ledger is finished.
Task NewEntry(object Object)
Adds an entry to the ledger.
async Task< bool > StartLedger()
Is called when export of ledger is started.
Task< bool > BlockMetaData(string Key, object Value)
Reports block meta-data.
Task< bool > ReportProperty(string PropertyName, object PropertyValue)
Is called when a property is reported.
async Task< bool > EndCollection()
Is called when a collection is finished.
Task UpdatedEntry(object Object)
Updates an entry in the ledger.
async Task< bool > ReportError(string Message)
Is called when an error is reported.
Class that keeps track of events and timing for one thread.
Interface for ledger entries.
Enumerator of ledger entries
Interface for proxy for reporting changes to the ledger from external sources.
Interface for ledger providers that can be plugged into the static Ledger class.
Interface for ledger exports.
delegate string ToString(IElement Element)
Delegate for callback methods that convert an element value to a string.
EntryType
Ledger entry type.