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(), }; }