Skip to content

Instantly share code, notes, and snippets.

@AndyButland
Created May 21, 2023 13:12
Show Gist options
  • Save AndyButland/9962f46202b981de275d3f71c066f26d to your computer and use it in GitHub Desktop.
Save AndyButland/9962f46202b981de275d3f71c066f26d to your computer and use it in GitHub Desktop.
private static void ApplyFilter(SearchOptions options, PackageSearchQuery query)
{
var filter = new StringBuilder();
bool isFiltered = false;
// If category provided, return packages that match on the category Id.
if (query.CategoryId.HasValue)
{
filter.AppendFormat("{0} eq '{1}'", $"{nameof(PackageModel.Category)}/{nameof(PackageModel.Category.Id)}", query.CategoryId.Value);
isFiltered = true;
}
// If tags provided, return packages that match all tags.
if (query.Tags is not null && query.Tags.Any())
{
foreach (var tag in query.Tags)
{
AddFilterAggregateClause(filter, isFiltered);
filter.AppendFormat("{0}/any(s: s eq '{1}')", nameof(PackageModel.Tags), tag);
isFiltered = true;
}
}
// If PackageType provided, return only packages matching that type.
if (query.PackageType.HasValue)
{
AddFilterAggregateClause(filter, isFiltered);
filter.AppendFormat("{0} eq '{1}'", nameof(PackageModel.PackageType), query.PackageType.Value);
isFiltered = true;
}
// If LicenseType provided, return only packages matching that have that type in their list of license options.
if (query.LicenseType.HasValue)
{
AddFilterAggregateClause(filter, isFiltered);
filter.AppendFormat("{0}/any(s: s eq '{1}')", nameof(PackageModel.LicenseTypes), query.LicenseType.Value);
isFiltered = true;
}
// If an Umbraco version is provided, return only packages that support that version.
if (!string.IsNullOrWhiteSpace(query.SupportsUmbracoVersionNumber) && Version.TryParse(query.SupportsUmbracoVersionNumber, out Version? version))
{
AddFilterAggregateClause(filter, isFiltered);
// Find packages with a mimimum version less than or equal to the provided version.
ApplyFilterForVersionMatch(
filter,
version,
nameof(PackageModel.MinimumUmbracoVersionNumberMajor),
nameof(PackageModel.MinimumUmbracoVersionNumberMinor),
nameof(PackageModel.MinimumUmbracoVersionNumberPatch),
"lt",
"le");
filter.Append(" and ");
// Either include packages with no maximum version set.
filter.AppendFormat(
"({0} eq null",
nameof(PackageModel.MaximumUmbracoVersionNumberMajor));
filter.Append(" or ");
// Or those with a maximum version greater than or equal to provided version when the max version is inclusive.
filter.AppendFormat("({0} eq true and ", nameof(PackageModel.MaximumUmbracoVersionNumberIsInclusive));
ApplyFilterForVersionMatch(
filter,
version,
nameof(PackageModel.MaximumUmbracoVersionNumberMajor),
nameof(PackageModel.MaximumUmbracoVersionNumberMinor),
nameof(PackageModel.MaximumUmbracoVersionNumberPatch),
"gt",
"ge");
filter.Append(")");
filter.Append(" or ");
// Or those with a maximum version greater than the provided version when the max version is exclusive.
filter.AppendFormat("({0} eq false and ", nameof(PackageModel.MaximumUmbracoVersionNumberIsInclusive));
ApplyFilterForVersionMatch(
filter,
version,
nameof(PackageModel.MaximumUmbracoVersionNumberMajor),
nameof(PackageModel.MaximumUmbracoVersionNumberMinor),
nameof(PackageModel.MaximumUmbracoVersionNumberPatch),
"gt",
"gt");
filter.Append(")");
filter.Append(")");
isFiltered = true;
}
if (query.HQOnly)
{
AddFilterAggregateClause(filter, isFiltered);
filter.AppendFormat("{0} eq true", nameof(PackageModel.IsHQ));
isFiltered = true;
}
options.Filter = filter.ToString();
}
private static void AddFilterAggregateClause(StringBuilder filter, bool isFiltered)
{
if (isFiltered)
{
filter.Append(" and ");
}
}
private static void ApplyFilterForVersionMatch(
StringBuilder filter,
Version version,
string majorPropertyName,
string minorPropertyName,
string patchPropertyName,
string majorMinorOperator,
string patchOperator)
{
filter.AppendFormat(
"({0} {1} {2}",
majorPropertyName,
majorMinorOperator,
version.Major);
filter.AppendFormat(
"or {0} eq {1} and {2} {3} {4}",
majorPropertyName,
version.Major,
minorPropertyName,
majorMinorOperator,
version.Minor);
filter.AppendFormat(
"or {0} eq {1} and {2} eq {3} and {4} {5} {6})",
majorPropertyName,
version.Major,
minorPropertyName,
version.Minor,
patchPropertyName,
patchOperator,
version.Build);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment