diff --git a/src/documentation/xml-autogenerated/microsoft-update-partition.xml b/src/documentation/xml-autogenerated/microsoft-update-partition.xml
index 5a7ba53f..a1078362 100644
--- a/src/documentation/xml-autogenerated/microsoft-update-partition.xml
+++ b/src/documentation/xml-autogenerated/microsoft-update-partition.xml
@@ -1718,6 +1718,11 @@
Get the category or update description
+
+
+ Get the category or update creation date
+
+
Gets the list of files (content) for update
@@ -2000,6 +2005,11 @@
Get the package description
+
+
+ Get the package creation date
+
+
Gets the list of files (content) for a package
diff --git a/src/microsoft-update-partition/Metadata/Parsers/UpdateParser.cs b/src/microsoft-update-partition/Metadata/Parsers/UpdateParser.cs
index 62ed01f4..2d70db69 100644
--- a/src/microsoft-update-partition/Metadata/Parsers/UpdateParser.cs
+++ b/src/microsoft-update-partition/Metadata/Parsers/UpdateParser.cs
@@ -26,7 +26,23 @@ public static string GetDescription(XPathNavigator metadataNavigator, XmlNamespa
}
}
- public static string GetTitle(XPathNavigator metadataNavigator, XmlNamespaceManager namespaceManager)
+ public static string GetCreationDate(XPathNavigator metadataNavigator, XmlNamespaceManager namespaceManager)
+ {
+ XPathExpression updateTypeQuery = metadataNavigator.Compile("upd:Update/upd:Properties/@CreationDate");
+ updateTypeQuery.SetContext(namespaceManager);
+
+ var result = metadataNavigator.Evaluate(updateTypeQuery) as XPathNodeIterator;
+
+ if (result.Count == 0)
+ {
+ throw new Exception("Invalid XML");
+ }
+
+ result.MoveNext();
+ return result.Current.Value;
+ }
+
+ public static string GetTitle(XPathNavigator metadataNavigator, XmlNamespaceManager namespaceManager)
{
XPathExpression titleQuery = metadataNavigator.Compile("upd:Update/upd:LocalizedPropertiesCollection/upd:LocalizedProperties[upd:Language='en']/upd:Title");
titleQuery.SetContext(namespaceManager);
diff --git a/src/microsoft-update-partition/Metadata/UpdateBase.cs b/src/microsoft-update-partition/Metadata/UpdateBase.cs
index 23af3ae6..95d95e69 100644
--- a/src/microsoft-update-partition/Metadata/UpdateBase.cs
+++ b/src/microsoft-update-partition/Metadata/UpdateBase.cs
@@ -164,26 +164,68 @@ public string Description
{
get
{
- if (_MetadataLoaded)
+ if (_DescriptionLoaded)
{
return _Description;
}
- else
- {
- LoadNonIndexedMetadataBase();
- return _Description;
- }
- }
+ else if (_FastLookupSource != null)
+ {
+ _FastLookupSource.TrySimpleKeyLookup(_Id, Storage.Index.AvailableIndexes.DescriptionsIndexName, out string description);
+ return description;
+ }
+ else if (_MetadataSource != null)
+ {
+ LoadNonIndexedMetadataBase();
+ _DescriptionLoaded = true;
+ return _Description;
+ }
+ else
+ {
+ return null;
+ }
+ }
}
- private string _Description = null;
-
- ///
- /// Gets the list of files (content) for update
- ///
- ///
- /// List of content files
- ///
- public IEnumerable Files
+ private bool _DescriptionLoaded;
+ private string _Description = null;
+
+ ///
+ /// Get the category or update creation date
+ ///
+ public string CreationDate
+ {
+ get
+ {
+ if (_CreationDateLoaded)
+ {
+ return _CreationDate;
+ }
+ else if (_FastLookupSource != null)
+ {
+ _FastLookupSource.TrySimpleKeyLookup(_Id, Storage.Index.AvailableIndexes.CreationDatesIndexName, out string creationdate);
+ return creationdate;
+ }
+ else if (_MetadataSource != null)
+ {
+ LoadNonIndexedMetadataBase();
+ _CreationDateLoaded = true;
+ return _CreationDate;
+ }
+ else
+ {
+ return null;
+ }
+ }
+ }
+ private bool _CreationDateLoaded;
+ private string _CreationDate = null;
+
+ ///
+ /// Gets the list of files (content) for update
+ ///
+ ///
+ /// List of content files
+ ///
+ public IEnumerable Files
{
get
{
@@ -464,6 +506,11 @@ internal MicrosoftUpdatePackage(MicrosoftUpdatePackageIdentity id, XPathNavigato
_TitleLoaded = true;
_Description = UpdateParser.GetDescription(metadataNavigator, namespaceManager);
+ _DescriptionLoaded = true;
+
+ _CreationDate = UpdateParser.GetCreationDate(metadataNavigator, namespaceManager);
+ _CreationDateLoaded = true;
+
_MetadataLoaded = true;
_Prerequisites = PrerequisiteParser.FromXml(metadataNavigator, namespaceManager);
@@ -585,7 +632,8 @@ internal void LoadNonIndexedMetadataBase()
manager.AddNamespace("wsi", "http://schemas.microsoft.com/msus/2002/12/UpdateHandlers/WindowsSetup");
_Description = UpdateParser.GetDescription(navigator, manager);
- _Title = UpdateParser.GetTitle(navigator, manager);
+ _CreationDate = UpdateParser.GetCreationDate(navigator, manager);
+ _Title = UpdateParser.GetTitle(navigator, manager);
LoadNonIndexedMetadata(navigator, manager);
}
diff --git a/src/microsoft-update-partition/PackageGraph/ObjectModel/IPackage.cs b/src/microsoft-update-partition/PackageGraph/ObjectModel/IPackage.cs
index 7bf9d0dd..368b88e1 100644
--- a/src/microsoft-update-partition/PackageGraph/ObjectModel/IPackage.cs
+++ b/src/microsoft-update-partition/PackageGraph/ObjectModel/IPackage.cs
@@ -26,6 +26,11 @@ public interface IPackage
///
string Description { get; }
+ ///
+ /// Get the package creation date
+ ///
+ string CreationDate { get; }
+
///
/// Gets the list of files (content) for a package
///
diff --git a/src/microsoft-update-partition/PackageGraph/Partitions/PartitionRegistration.cs b/src/microsoft-update-partition/PackageGraph/Partitions/PartitionRegistration.cs
index 0c4834f8..ecdc7d06 100644
--- a/src/microsoft-update-partition/PackageGraph/Partitions/PartitionRegistration.cs
+++ b/src/microsoft-update-partition/PackageGraph/Partitions/PartitionRegistration.cs
@@ -1,18 +1,18 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
using Microsoft.PackageGraph.MicrosoftUpdate;
-using Microsoft.PackageGraph.ObjectModel;
-using Microsoft.PackageGraph.Storage.Index;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Microsoft.PackageGraph.Partitions
-{
- class PartitionRegistration
- {
+using Microsoft.PackageGraph.ObjectModel;
+using Microsoft.PackageGraph.Storage.Index;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Microsoft.PackageGraph.Partitions
+{
+ class PartitionRegistration
+ {
internal static Dictionary KnownPartitionsIndex =
- new()
+ new()
{
{
"",
@@ -20,7 +20,7 @@ class PartitionRegistration
{
Factory = null,
HasExternalContentFileMetadata = false,
- Indexes = new List() { TitlesIndex.TitlesIndexDefinition },
+ Indexes = new List() { TitlesIndex.TitlesIndexDefinition, DescriptionsIndex.DescriptionsIndexDefinition, CreationDatesIndex.CreationDatesIndexDefinition },
HandlesIdentities = false,
}
},
@@ -45,59 +45,59 @@ class PartitionRegistration
}
}
}
- };
-
- public static void RegisterPartition(PartitionDefinition partitionDefinition)
- {
- lock(KnownPartitionsIndex)
- {
- KnownPartitionsIndex.Add(partitionDefinition.Name, partitionDefinition);
- }
- }
-
- public static bool TryGetPartition(string partitionName, out PartitionDefinition partitionDefinition)
- {
- lock(KnownPartitionsIndex)
- {
- return KnownPartitionsIndex.TryGetValue(partitionName, out partitionDefinition);
- }
- }
-
- public static bool TryGetPartitionFromPackage(IPackage package, out PartitionDefinition partitionDefinition)
- {
- lock (KnownPartitionsIndex)
- {
- return KnownPartitionsIndex.TryGetValue(package.Id.Partition, out partitionDefinition);
- }
- }
-
- public static bool TryGetPartitionFromPackageId(IPackageIdentity packageId, out PartitionDefinition partitionDefinition)
- {
- lock (KnownPartitionsIndex)
- {
- return KnownPartitionsIndex.TryGetValue(packageId.Partition, out partitionDefinition);
- }
- }
-
- public static List GetAllPartitions()
- {
- lock (KnownPartitionsIndex)
- {
- return KnownPartitionsIndex.Values.ToList();
- }
- }
-
- public static IPackage TryCreatePackageFromUri(string sourceUri)
- {
- foreach(var partition in KnownPartitionsIndex.Values)
- {
- if (partition.Factory.CanCreatePackageFromSource(sourceUri))
- {
- return partition.Factory.FromSource(sourceUri);
- }
- }
-
- return null;
- }
- }
-}
+ };
+
+ public static void RegisterPartition(PartitionDefinition partitionDefinition)
+ {
+ lock(KnownPartitionsIndex)
+ {
+ KnownPartitionsIndex.Add(partitionDefinition.Name, partitionDefinition);
+ }
+ }
+
+ public static bool TryGetPartition(string partitionName, out PartitionDefinition partitionDefinition)
+ {
+ lock(KnownPartitionsIndex)
+ {
+ return KnownPartitionsIndex.TryGetValue(partitionName, out partitionDefinition);
+ }
+ }
+
+ public static bool TryGetPartitionFromPackage(IPackage package, out PartitionDefinition partitionDefinition)
+ {
+ lock (KnownPartitionsIndex)
+ {
+ return KnownPartitionsIndex.TryGetValue(package.Id.Partition, out partitionDefinition);
+ }
+ }
+
+ public static bool TryGetPartitionFromPackageId(IPackageIdentity packageId, out PartitionDefinition partitionDefinition)
+ {
+ lock (KnownPartitionsIndex)
+ {
+ return KnownPartitionsIndex.TryGetValue(packageId.Partition, out partitionDefinition);
+ }
+ }
+
+ public static List GetAllPartitions()
+ {
+ lock (KnownPartitionsIndex)
+ {
+ return KnownPartitionsIndex.Values.ToList();
+ }
+ }
+
+ public static IPackage TryCreatePackageFromUri(string sourceUri)
+ {
+ foreach(var partition in KnownPartitionsIndex.Values)
+ {
+ if (partition.Factory.CanCreatePackageFromSource(sourceUri))
+ {
+ return partition.Factory.FromSource(sourceUri);
+ }
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/src/microsoft-update-partition/PackageGraph/Storage/Index/CreationDatesIndex.cs b/src/microsoft-update-partition/PackageGraph/Storage/Index/CreationDatesIndex.cs
new file mode 100644
index 00000000..7c50e38a
--- /dev/null
+++ b/src/microsoft-update-partition/PackageGraph/Storage/Index/CreationDatesIndex.cs
@@ -0,0 +1,33 @@
+using Microsoft.PackageGraph.ObjectModel;
+
+namespace Microsoft.PackageGraph.Storage.Index
+{
+ class CreationDatesIndex : SimpleIndex, ISimpleMetadataIndex
+ {
+ internal static readonly IndexDefinition CreationDatesIndexDefinition =
+ new()
+ {
+ Name = AvailableIndexes.CreationDatesIndexName,
+ PartitionName = null,
+ Version = CreationDatesIndex.CurrentVersion,
+ Factory = new InternalIndexFactory(),
+ Tag = "stream"
+ };
+
+ public override IndexDefinition Definition => CreationDatesIndexDefinition;
+
+ public CreationDatesIndex(IIndexContainer container) : base(container, AvailableIndexes.CreationDatesIndexName)
+ {
+ }
+
+ public override void IndexPackage(IPackage package, int packageIndex)
+ {
+ Add(packageIndex, package.CreationDate);
+ }
+
+ public new bool TryGet(int packageIndex, out string creationDate)
+ {
+ return base.TryGet(packageIndex, out creationDate);
+ }
+ }
+}
diff --git a/src/microsoft-update-partition/PackageGraph/Storage/Index/DescriptionsIndex.cs b/src/microsoft-update-partition/PackageGraph/Storage/Index/DescriptionsIndex.cs
new file mode 100644
index 00000000..d1bd5e15
--- /dev/null
+++ b/src/microsoft-update-partition/PackageGraph/Storage/Index/DescriptionsIndex.cs
@@ -0,0 +1,33 @@
+using Microsoft.PackageGraph.ObjectModel;
+
+namespace Microsoft.PackageGraph.Storage.Index
+{
+ class DescriptionsIndex : SimpleIndex, ISimpleMetadataIndex
+ {
+ internal static readonly IndexDefinition DescriptionsIndexDefinition =
+ new()
+ {
+ Name = AvailableIndexes.DescriptionsIndexName,
+ PartitionName = null,
+ Version = DescriptionsIndex.CurrentVersion,
+ Factory = new InternalIndexFactory(),
+ Tag = "stream"
+ };
+
+ public override IndexDefinition Definition => DescriptionsIndexDefinition;
+
+ public DescriptionsIndex(IIndexContainer container) : base(container, AvailableIndexes.TitlesIndexName)
+ {
+ }
+
+ public override void IndexPackage(IPackage package, int packageIndex)
+ {
+ Add(packageIndex, package.Description);
+ }
+
+ public new bool TryGet(int packageIndex, out string description)
+ {
+ return base.TryGet(packageIndex, out description);
+ }
+ }
+}
diff --git a/src/microsoft-update-partition/PackageGraph/Storage/Index/IndexTypes.cs b/src/microsoft-update-partition/PackageGraph/Storage/Index/IndexTypes.cs
index e63ca78e..8ba55f42 100644
--- a/src/microsoft-update-partition/PackageGraph/Storage/Index/IndexTypes.cs
+++ b/src/microsoft-update-partition/PackageGraph/Storage/Index/IndexTypes.cs
@@ -8,6 +8,8 @@ namespace Microsoft.PackageGraph.Storage.Index
abstract class AvailableIndexes
{
public const string TitlesIndexName = "titles";
+ public const string DescriptionsIndexName = "descriptions";
+ public const string CreationDatesIndexName = "creationDates";
}
class InternalIndexFactory : IIndexFactory
@@ -17,6 +19,8 @@ public IIndex CreateIndex(IndexDefinition definition, IIndexContainer container)
return definition.Name switch
{
AvailableIndexes.TitlesIndexName => new TitlesIndex(container),
+ AvailableIndexes.DescriptionsIndexName => new DescriptionsIndex(container),
+ AvailableIndexes.CreationDatesIndexName => new CreationDatesIndex(container),
_ => throw new NotImplementedException(),
};
}