Skip to content

Commit 423cae4

Browse files
committed
Merge branch 'release/universe-1.4.1' into prod
2 parents c0b5b44 + ca4c750 commit 423cae4

File tree

5 files changed

+73
-40
lines changed

5 files changed

+73
-40
lines changed

code/Universe/Galaxy.cs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ protected Galaxy(CosmosClient client, string database, string container, string
2626

2727
private static QueryDefinition CreateQuery(IList<Catalyst> catalysts, ColumnOptions? columnOptions = null, IList<Sorting.Option> sorting = null, IList<string> groups = null)
2828
{
29+
// Validate Catalysts
30+
if (catalysts is not null && catalysts.Any() && catalysts.Any(c => c.RuleViolations().Any()))
31+
{
32+
List<IEnumerable<string>> violationsPerCatalyst = catalysts.Select(c => c.RuleViolations()).ToList();
33+
List<string> violations = violationsPerCatalyst.SelectMany(v => v).ToList().Distinct().ToList();
34+
throw new UniverseException(string.Join(Environment.NewLine, violations));
35+
}
36+
2937
// Column Options Builder
3038
string columnsInQuery = "*";
3139
if (columnOptions is not null)
@@ -82,19 +90,21 @@ private static QueryDefinition CreateQuery(IList<Catalyst> catalysts, ColumnOpti
8290

8391
// Parameters Builder
8492
QueryDefinition query = new(queryBuilder.ToString());
85-
if (!catalysts.Any()) return query;
86-
{
87-
query = query.WithParameter($"@{catalysts[0].ParameterName()}", catalysts[0].Value);
88-
foreach (Catalyst catalyst in catalysts.Where(p => p.Column != catalysts[0].Column).ToList())
89-
query = query.WithParameter($"@{catalyst.ParameterName()}", catalyst.Value);
90-
}
93+
if (!catalysts.Any())
94+
return query;
95+
96+
query = query.WithParameter($"@{catalysts[0].ParameterName()}", catalysts[0].Value);
97+
foreach (Catalyst catalyst in catalysts.Where(p => p.Column != catalysts[0].Column).ToList())
98+
query = query.WithParameter($"@{catalyst.ParameterName()}", catalyst.Value);
9199

92100
return query;
93101

94102
static string WhereClauseBuilder(Catalyst catalyst) => catalyst.Operator switch
95103
{
96104
Q.Operator.In => $"ARRAY_CONTAINS(c.{catalyst.Column}, @{catalyst.ParameterName()})",
97105
Q.Operator.NotIn => $"NOT ARRAY_CONTAINS(c.{catalyst.Column}, @{catalyst.ParameterName()})",
106+
Q.Operator.Defined => $"IS_DEFINED(c.{catalyst.Column})",
107+
Q.Operator.NotDefined => $"NOT IS_DEFINED(c.{catalyst.Column})",
98108
_ => $"c.{catalyst.Column} {catalyst.Operator.Value()} @{catalyst.ParameterName()}",
99109
};
100110
}
@@ -363,4 +373,4 @@ public void Dispose()
363373
Dispose(disposing: true);
364374
GC.SuppressFinalize(this);
365375
}
366-
}
376+
}

code/Universe/Options/Parameters.cs

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,48 @@ namespace Universe.Options.Query;
77
/// </summary>
88
/// <param name="Column">Column name</param>
99
/// <param name="Value">Value for the where clause associated with the Column</param>
10-
/// <param name="Alias">
11-
/// Column name alias excluding the @ symbol for SQL Parameters.
12-
/// If not supplied, this will use the value from <paramref name="Column"/>
13-
/// </param>
1410
/// <param name="Where">Where operator (eg AND / OR)</param>
1511
/// <param name="Operator">Boolean expression operator</param>
16-
public record struct Catalyst(
12+
public readonly record struct Catalyst(
1713
string Column,
18-
object Value,
19-
string Alias = null,
14+
object Value = null,
2015
Q.Where Where = Q.Where.And,
21-
Q.Operator Operator = Q.Operator.Eq);
22-
23-
/// <summary></summary>
24-
public static class CatalystExtension
16+
Q.Operator Operator = Q.Operator.Eq)
2517
{
26-
/// <summary></summary>
27-
public static string ParameterName(this Catalyst catalyst)
18+
/// <summary>Creates a list of rule violations when creating a CosmosDb query catalyst</summary>
19+
public IEnumerable<string> RuleViolations()
2820
{
29-
if (string.IsNullOrWhiteSpace(catalyst.Alias))
30-
return Regex.Replace(catalyst.Column, "[^\\w\\d]", string.Empty);
21+
List<string> violations = new();
22+
23+
// Column name cannot be null or empty
24+
if (string.IsNullOrWhiteSpace(Column))
25+
violations.Add("Column name is required");
26+
27+
// Value should be null if using IS_DEFINED or NOT IS_DEFINED operators
28+
if (Value is not null && Operator is Q.Operator.Defined or Q.Operator.NotDefined)
29+
violations.Add("Value should not be supplied when using the Defined or NotDefined operators");
30+
31+
// Value should have wildcard for Like and Not Like operators
32+
if (Value is not null && Operator is Q.Operator.Like or Q.Operator.NotLike)
33+
{
34+
string value = Value.ToString();
35+
if (string.IsNullOrWhiteSpace(value))
36+
violations.Add("Value is required when using the Like or NotLike operators");
37+
else if (!value.Contains('%'))
38+
violations.Add("Value should contain a wildcard (%) for Like and NotLike operators");
39+
}
3140

32-
return catalyst.Alias;
41+
// Value is required for all other operators
42+
if (Value is null && Operator is not Q.Operator.Defined and not Q.Operator.NotDefined)
43+
violations.Add("Value is required for all operators except Defined and NotDefined");
44+
45+
return violations;
3346
}
3447
}
48+
49+
/// <summary></summary>
50+
public static class CatalystExtension
51+
{
52+
/// <summary></summary>
53+
public static string ParameterName(this Catalyst catalyst) => Regex.Replace(catalyst.Column, "[^\\w\\d]", string.Empty);
54+
}

code/Universe/Options/QueryOptions.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,13 @@ public enum Operator
4747
Like,
4848

4949
/// <summary>Not Like</summary>
50-
NotLike
50+
NotLike,
51+
52+
/// <summary>IS_DEFINED</summary>
53+
Defined,
54+
55+
/// <summary>NOT IS_DEFINED</summary>
56+
NotDefined
5157
}
5258
}
5359

@@ -79,6 +85,8 @@ public static class OperatorExtension
7985
Q.Operator.NotIn => "NOT IN",
8086
Q.Operator.Like => "LIKE",
8187
Q.Operator.NotLike => "NOT LIKE",
88+
Q.Operator.Defined => "IS_DEFINED",
89+
Q.Operator.NotDefined => "NOT IS_DEFINED",
8290
_ => throw new UniverseException("Unrecognized OPERATOR keyword")
8391
};
8492
}

code/Universe/UniverseQuery.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
<ItemGroup>
4545
<Folder Include="Exception\" />
4646
<Folder Include="Options\" />
47-
<Folder Include="Responses\" />
47+
<Folder Include="Response\" />
4848
</ItemGroup>
4949

5050
<ItemGroup>

code/Universe/UniverseQuery.xml

Lines changed: 10 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)