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;
36 private readonly
string transform =
null;
37 private readonly
int deleteAfterDays;
78 : this(
FileName, string.Empty, DeleteAfterDays)
125 this.deleteAfterDays = DeleteAfterDays;
127 this.settings =
new XmlWriterSettings()
130 ConformanceLevel = ConformanceLevel.Document,
131 Encoding = Encoding.UTF8,
134 NewLineChars =
"\r\n",
135 NewLineHandling = NewLineHandling.Replace,
136 NewLineOnAttributes =
false,
137 OmitXmlDeclaration =
false,
138 WriteEndDocumentOnClose =
true,
142 string FolderName = Path.GetDirectoryName(
FileName);
144 if (!
string.IsNullOrEmpty(FolderName) && !Directory.Exists(FolderName))
147 Directory.CreateDirectory(FolderName);
157 this.textOutput = Output;
159 this.fileSequence =
null;
160 this.transform =
null;
161 this.deleteAfterDays = 0;
163 this.settings =
new XmlWriterSettings()
166 ConformanceLevel = ConformanceLevel.Document,
167 Encoding = Encoding.UTF8,
170 NewLineChars =
"\r\n",
171 NewLineHandling = NewLineHandling.Replace,
172 NewLineOnAttributes =
false,
173 OmitXmlDeclaration =
false,
174 WriteEndDocumentOnClose =
true,
178 this.output = XmlWriter.Create(this.textOutput, this.settings);
179 this.output.WriteStartDocument();
180 this.output.WriteStartElement(
"LedgerExport",
Namespace);
191 public string FileName => this.fileSequence.FileNamePattern;
206 private async Task BeforeWrite()
208 if (this.fileSequence is
null)
211 if (!this.fileSequence.TryGetNewFileName(out
string s))
216 if (!(this.output is
null))
218 await this.output.WriteEndElementAsync();
219 await this.output.WriteEndDocumentAsync();
220 await this.output.FlushAsync();
223 this.file?.Dispose();
229 await this.DisposeOutput();
242 this.file = File.CreateText(s);
243 this.output = XmlWriter.Create(this.file, this.settings);
252 await this.output.WriteStartDocumentAsync();
254 if (!
string.IsNullOrEmpty(this.transform))
256 if (File.Exists(
this.transform))
260 byte[] XsltBin = await Runtime.IO.Files.ReadAllBytesAsync(this.transform);
262 await this.output.WriteProcessingInstructionAsync(
"xml-stylesheet",
"type=\"text/xsl\" href=\"data:text/xsl;base64," +
263 Convert.ToBase64String(XsltBin) +
"\"");
267 await this.output.WriteProcessingInstructionAsync(
"xml-stylesheet",
"type=\"text/xsl\" href=\"" + this.transform +
"\"");
271 await this.output.WriteProcessingInstructionAsync(
"xml-stylesheet",
"type=\"text/xsl\" href=\"" + this.transform +
"\"");
274 await this.output.WriteStartElementAsync(
string.Empty,
"LedgerExport",
Namespace);
275 await this.output.FlushAsync();
277 if (this.deleteAfterDays > 0 && this.deleteAfterDays <
int.MaxValue)
279 string FolderName = Path.GetDirectoryName(s);
281 if (!
string.IsNullOrEmpty(FolderName))
282 Files.
DeleteOldFiles(FolderName, TimeSpan.FromDays(
this.deleteAfterDays), SearchOption.AllDirectories,
true);
289 private async Task DisposeOutput()
291 if (!(this.output is
null))
293 await this.output.FlushAsync();
294 this.output.Dispose();
298 this.file?.Dispose();
301 this.textOutput?.Flush();
302 this.textOutput =
null;
307 #region ILedgerProvider
315 return Task.CompletedTask;
325 this.running =
false;
327 if (!(this.output is
null))
329 await this.output.WriteEndElementAsync();
330 await this.output.WriteEndDocumentAsync();
336 this.output?.Dispose();
345 if (!(this.output is
null))
346 await this.output.FlushAsync();
348 if (!(this.file is
null))
349 await this.file.FlushAsync();
351 if (!(this.textOutput is
null))
352 await this.textOutput.FlushAsync();
361 return this.OutputEntry(
"New", Object);
370 return this.OutputEntry(
"Update", Object);
379 return this.OutputEntry(
"Delete", Object);
382 private async Task OutputEntry(
string Method,
object Object)
388 DateTime Timestamp = DateTime.UtcNow;
389 this.lastEvent = Timestamp;
391 await this.semaphore.WaitAsync();
396 await this.BeforeWrite();
398 if (!(this.output is
null))
400 await this.output.WriteStartElementAsync(
string.Empty, Method,
Namespace);
401 await this.output.WriteAttributeStringAsync(
string.Empty,
"timestamp",
string.Empty,
XML.
Encode(Timestamp));
402 await this.output.WriteAttributeStringAsync(
string.Empty,
"collection",
string.Empty, Obj.
CollectionName);
403 await this.output.WriteAttributeStringAsync(
string.Empty,
"type",
string.Empty, Obj.
TypeName);
404 await this.output.WriteAttributeStringAsync(
string.Empty,
"id",
string.Empty, Obj.
ObjectId.ToString());
406 foreach (KeyValuePair<string, object> P
in Obj.
Properties)
409 await this.output.WriteEndElementAsync();
410 await this.output.FlushAsync();
417 await this.DisposeOutput();
427 this.semaphore.Release();
440 if (PropertyValue is
null)
442 await Output.WriteStartElementAsync(
string.Empty,
"Null",
Namespace);
443 if (!(PropertyName is
null))
444 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
445 await Output.WriteEndElementAsync();
447 else if (PropertyValue is Enum)
449 await Output.WriteStartElementAsync(
string.Empty,
"En",
Namespace);
450 if (!(PropertyName is
null))
451 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
452 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, PropertyValue.ToString());
453 await Output.WriteEndElementAsync();
457 switch (Type.GetTypeCode(PropertyValue.GetType()))
459 case TypeCode.Boolean:
460 await Output.WriteStartElementAsync(
string.Empty,
"Bl",
Namespace);
461 if (!(PropertyName is
null))
462 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
463 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty,
CommonTypes.
Encode((
bool)PropertyValue));
464 await Output.WriteEndElementAsync();
468 await Output.WriteStartElementAsync(
string.Empty,
"B",
Namespace);
469 if (!(PropertyName is
null))
470 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
471 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, PropertyValue.ToString());
472 await Output.WriteEndElementAsync();
476 await Output.WriteStartElementAsync(
string.Empty,
"Ch",
Namespace);
477 if (!(PropertyName is
null))
478 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
479 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, PropertyValue.ToString());
480 await Output.WriteEndElementAsync();
483 case TypeCode.DateTime:
484 await Output.WriteStartElementAsync(
string.Empty,
"DT",
Namespace);
485 if (!(PropertyName is
null))
486 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
487 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty,
XML.
Encode((DateTime)PropertyValue));
488 await Output.WriteEndElementAsync();
491 case TypeCode.Decimal:
492 await Output.WriteStartElementAsync(
string.Empty,
"Dc",
Namespace);
493 if (!(PropertyName is
null))
494 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
495 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty,
CommonTypes.
Encode((decimal)PropertyValue));
496 await Output.WriteEndElementAsync();
499 case TypeCode.Double:
500 await Output.WriteStartElementAsync(
string.Empty,
"Db",
Namespace);
501 if (!(PropertyName is
null))
502 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
503 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty,
CommonTypes.
Encode((
double)PropertyValue));
504 await Output.WriteEndElementAsync();
508 await Output.WriteStartElementAsync(
string.Empty,
"I2",
Namespace);
509 if (!(PropertyName is
null))
510 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
511 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, PropertyValue.ToString());
512 await Output.WriteEndElementAsync();
516 await Output.WriteStartElementAsync(
string.Empty,
"I4",
Namespace);
517 if (!(PropertyName is
null))
518 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
519 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, PropertyValue.ToString());
520 await Output.WriteEndElementAsync();
524 await Output.WriteStartElementAsync(
string.Empty,
"I8",
Namespace);
525 if (!(PropertyName is
null))
526 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
527 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, PropertyValue.ToString());
528 await Output.WriteEndElementAsync();
532 await Output.WriteStartElementAsync(
string.Empty,
"I1",
Namespace);
533 if (!(PropertyName is
null))
534 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
535 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, PropertyValue.ToString());
536 await Output.WriteEndElementAsync();
539 case TypeCode.Single:
540 await Output.WriteStartElementAsync(
string.Empty,
"Fl",
Namespace);
541 if (!(PropertyName is
null))
542 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
543 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty,
CommonTypes.
Encode((
float)PropertyValue));
544 await Output.WriteEndElementAsync();
547 case TypeCode.String:
548 string s = PropertyValue.ToString();
551 XmlConvert.VerifyXmlChars(s);
552 await Output.WriteStartElementAsync(
string.Empty,
"S",
Namespace);
553 if (!(PropertyName is
null))
554 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
555 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, s);
556 await Output.WriteEndElementAsync();
560 byte[] Bin =
System.Text.Encoding.UTF8.GetBytes(s);
561 s = Convert.ToBase64String(Bin);
562 await Output.WriteStartElementAsync(
string.Empty,
"S64",
Namespace);
563 if (!(PropertyName is
null))
564 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
565 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, s);
566 await Output.WriteEndElementAsync();
570 case TypeCode.UInt16:
571 await Output.WriteStartElementAsync(
string.Empty,
"U2",
Namespace);
572 if (!(PropertyName is
null))
573 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
574 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, PropertyValue.ToString());
575 await Output.WriteEndElementAsync();
578 case TypeCode.UInt32:
579 await Output.WriteStartElementAsync(
string.Empty,
"U4",
Namespace);
580 if (!(PropertyName is
null))
581 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
582 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, PropertyValue.ToString());
583 await Output.WriteEndElementAsync();
586 case TypeCode.UInt64:
587 await Output.WriteStartElementAsync(
string.Empty,
"U8",
Namespace);
588 if (!(PropertyName is
null))
589 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
590 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, PropertyValue.ToString());
591 await Output.WriteEndElementAsync();
596 await Output.WriteStartElementAsync(
string.Empty,
"Null",
Namespace);
597 if (!(PropertyName is
null))
598 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
599 await Output.WriteEndElementAsync();
602 case TypeCode.Object:
603 if (PropertyValue is TimeSpan)
605 await Output.WriteStartElementAsync(
string.Empty,
"TS",
Namespace);
606 if (!(PropertyName is
null))
607 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
608 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, PropertyValue.ToString());
609 await Output.WriteEndElementAsync();
611 else if (PropertyValue is DateTimeOffset DTO)
613 await Output.WriteStartElementAsync(
string.Empty,
"DTO",
Namespace);
614 if (!(PropertyName is
null))
615 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
616 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty,
XML.
Encode(DTO));
617 await Output.WriteEndElementAsync();
624 XmlConvert.VerifyXmlChars(s);
625 await Output.WriteStartElementAsync(
string.Empty,
"CIS",
Namespace);
626 if (!(PropertyName is
null))
627 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
628 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, s);
629 await Output.WriteEndElementAsync();
633 byte[] Bin =
System.Text.Encoding.UTF8.GetBytes(s);
634 s = Convert.ToBase64String(Bin);
635 await Output.WriteStartElementAsync(
string.Empty,
"CIS64",
Namespace);
636 if (!(PropertyName is
null))
637 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
638 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, s);
639 await Output.WriteEndElementAsync();
642 else if (PropertyValue is
byte[] Bin)
644 await Output.WriteStartElementAsync(
string.Empty,
"Bin",
Namespace);
645 if (!(PropertyName is
null))
646 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
664 if (i == 0 && j == c)
671 Buffer.BlockCopy(Bin, i, Buf, 0, j);
673 await Output.WriteElementStringAsync(
string.Empty,
"Chunk",
Namespace, Convert.ToBase64String(Buf, 0, j));
677 await Output.WriteEndElementAsync();
679 else if (PropertyValue is Guid)
681 await Output.WriteStartElementAsync(
string.Empty,
"ID",
Namespace);
682 if (!(PropertyName is
null))
683 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
684 await Output.WriteAttributeStringAsync(
string.Empty,
"v",
string.Empty, PropertyValue.ToString());
685 await Output.WriteEndElementAsync();
687 else if (PropertyValue is Array A)
689 await Output.WriteStartElementAsync(
string.Empty,
"Array",
Namespace);
690 if (!(PropertyName is
null))
691 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
692 await Output.WriteAttributeStringAsync(
string.Empty,
"elementType",
string.Empty, PropertyValue.GetType().GetElementType().FullName);
694 foreach (
object Obj
in A)
697 await Output.WriteEndElementAsync();
701 await Output.WriteStartElementAsync(
string.Empty,
"Obj",
Namespace);
702 if (!(PropertyName is
null))
703 await Output.WriteAttributeStringAsync(
string.Empty,
"n",
string.Empty, PropertyName);
704 await Output.WriteAttributeStringAsync(
string.Empty,
"type",
string.Empty, Obj.TypeName);
706 foreach (KeyValuePair<string, object> P
in Obj)
709 await Output.WriteEndElementAsync();
712 throw new Exception(
"Unhandled property value type: " + PropertyValue.GetType().FullName);
716 throw new Exception(
"Unhandled property value type: " + PropertyValue.GetType().FullName);
730 DateTime Timestamp = DateTime.UtcNow;
732 await this.semaphore.WaitAsync();
737 await this.BeforeWrite();
739 if (!(this.output is
null))
741 await this.output.WriteStartElementAsync(
string.Empty,
"Clear",
Namespace);
742 await this.output.WriteAttributeStringAsync(
string.Empty,
"timestamp",
string.Empty,
XML.
Encode(Timestamp));
743 await this.output.WriteAttributeStringAsync(
string.Empty,
"collection",
string.Empty, Collection);
744 await this.output.WriteEndElementAsync();
745 await this.output.FlushAsync();
752 await this.DisposeOutput();
762 this.semaphore.Release();
773 if (!(this.externalEvents is
null) && this.externalEvents != ExternalEvents)
774 throw new Exception(
"An interface for external events has already been registered.");
776 this.externalEvents = ExternalEvents;
786 if (!(this.externalEvents is
null) && this.externalEvents != ExternalEvents)
787 throw new Exception(
"The registered interface for external events differs from the one presented.");
789 this.externalEvents =
null;
815 object IEnumerator.Current =>
null;
816 public void Dispose() { }
817 public bool MoveNext() =>
false;
818 public Task<bool> MoveNextAsync() => Task.FromResult(
false);
819 public void Reset() { }
828 return Task.FromResult(Array.Empty<
string>());
840 return Task.FromResult(
true);
853 return Task.FromResult(
true);
858 #region ILedgerExport
860 private readonly LinkedList<KeyValuePair<string, object>> blockMetaData =
new LinkedList<KeyValuePair<string, object>>();
861 private string writtenCollection =
null;
862 private string writtenBlockId =
null;
863 private string currentCollection =
null;
864 private string currentBlockId =
null;
865 private string currentEntryObjectId =
null;
866 private string currentEntryObjectType =
null;
868 private DateTimeOffset currentEntryTimestamp = DateTimeOffset.MinValue;
869 private Dictionary<string, object> currentEntryProperties =
null;
878 this.currentCollection =
null;
900 this.currentCollection = CollectionName;
901 return Task.FromResult(
true);
910 if (!(this.writtenCollection is
null))
912 await this.output.WriteEndElementAsync();
913 this.writtenCollection =
null;
916 this.currentCollection =
null;
927 this.currentBlockId = BlockID;
928 return Task.FromResult(
true);
939 this.blockMetaData.AddLast(
new KeyValuePair<string, object>(Key, Value));
940 return Task.FromResult(
true);
949 if (!(this.writtenBlockId is
null))
951 await this.output.WriteEndElementAsync();
952 this.writtenBlockId =
null;
953 this.blockMetaData.Clear();
956 this.currentBlockId =
null;
971 this.currentEntryObjectId = ObjectId;
972 this.currentEntryObjectType = TypeName;
974 this.currentEntryTimestamp = EntryTimestamp;
976 if (this.currentEntryProperties is
null)
977 this.currentEntryProperties =
new Dictionary<string, object>();
979 this.currentEntryProperties.Clear();
981 return Task.FromResult(
true);
993 await this.semaphore.WaitAsync();
998 await this.BeforeWrite();
1000 if (!(this.output is
null))
1002 await this.WritePendingInfoLocked();
1004 await this.output.WriteStartElementAsync(
string.Empty, this.currentEntryType.ToString(),
Namespace);
1005 await this.output.WriteAttributeStringAsync(
string.Empty,
"timestamp",
string.Empty,
XML.
Encode(
this.currentEntryTimestamp));
1006 await this.output.WriteAttributeStringAsync(
string.Empty,
"type",
string.Empty, this.currentEntryObjectType);
1007 await this.output.WriteAttributeStringAsync(
string.Empty,
"id",
string.Empty, this.currentEntryObjectId);
1009 foreach (KeyValuePair<string, object> P
in this.currentEntryProperties)
1012 await this.output.WriteEndElementAsync();
1013 await this.output.FlushAsync();
1020 await this.DisposeOutput();
1030 this.semaphore.Release();
1036 private async Task WritePendingInfoLocked()
1038 if (!(this.currentBlockId is
null) &&
1039 !(this.writtenBlockId is
null) &&
1040 this.currentBlockId != this.writtenBlockId)
1042 await this.output.WriteEndElementAsync();
1043 this.writtenBlockId =
null;
1044 this.blockMetaData.Clear();
1047 if (!(this.currentCollection is
null) &&
1048 !(this.writtenCollection is
null) &&
1049 this.currentCollection != this.writtenCollection)
1051 await this.output.WriteEndElementAsync();
1052 this.writtenCollection =
null;
1055 if (this.writtenCollection is
null)
1057 await this.output.WriteStartElementAsync(
string.Empty,
"Collection",
Namespace);
1058 await this.output.WriteAttributeStringAsync(
string.Empty,
"name",
string.Empty, this.currentCollection);
1059 this.writtenCollection = this.currentCollection;
1062 if (this.writtenBlockId is
null)
1064 await this.output.WriteStartElementAsync(
string.Empty,
"Block",
Namespace);
1065 await this.output.WriteAttributeStringAsync(
string.Empty,
"id",
string.Empty, this.currentBlockId);
1066 this.writtenBlockId = this.currentBlockId;
1068 if (!(this.blockMetaData.First is
null))
1070 foreach (KeyValuePair<string, object> P
in this.blockMetaData)
1085 await this.semaphore.WaitAsync();
1090 await this.BeforeWrite();
1092 if (!(this.output is
null))
1094 await this.WritePendingInfoLocked();
1096 await this.output.WriteStartElementAsync(
string.Empty,
"Clear",
Namespace);
1097 await this.output.WriteAttributeStringAsync(
string.Empty,
"timestamp",
string.Empty,
XML.
Encode(EntryTimestamp));
1098 await this.output.WriteEndElementAsync();
1099 await this.output.FlushAsync();
1106 await this.DisposeOutput();
1116 this.semaphore.Release();
1130 this.currentEntryProperties[PropertyName] = PropertyValue;
1131 return Task.FromResult(
true);
1144 await this.semaphore.WaitAsync();
1149 await this.BeforeWrite();
1151 if (!(this.output is
null))
1153 await this.WritePendingInfoLocked();
1155 await this.output.WriteCommentAsync(Message);
1156 await this.output.FlushAsync();
1163 await this.DisposeOutput();
1173 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.
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 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.
DateTime LastEvent
Timestamp of Last event
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(ILedgerProvider Provider)
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 generates a sequence of file names, based on the system time.
static void DeleteOldFiles(string FolderName, TimeSpan MaxAge)
Deletes old files.
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.
EntryType
Ledger entry type.