Skip to content

Commit

Permalink
fix tests and queryable project
Browse files Browse the repository at this point in the history
  • Loading branch information
quinchs committed Jan 13, 2024
1 parent 6f64d6e commit 2e5b5d4
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 43 deletions.
87 changes: 47 additions & 40 deletions src/EdgeDB.Net.Queryable/GenericlessQueryBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ private TNode AddNode<TNode>(NodeContext context, bool autoGenerated = false, Qu
}

#region Query methods

#region With

public GenericlessQueryBuilder With(object variables)
{
if (variables is null)
Expand All @@ -110,7 +112,8 @@ public GenericlessQueryBuilder With(object variables)
{
var varName = QueryUtils.GenerateRandomVariableName();
_queryVariables.Add(varName, value);
_queryGlobals.Add(new QueryGlobal(property.Name, new SubQuery($"<{scalarInfo}>${varName}")));
_queryGlobals.Add(new QueryGlobal(property.Name,
new SubQuery(writer => writer.QueryArgument(scalarInfo, varName))));
}
else if (property.PropertyType.IsAssignableTo(typeof(IQueryBuilder)))
{
Expand All @@ -131,30 +134,32 @@ public GenericlessQueryBuilder With(object variables)
var referenceValue = property.PropertyType.GetProperty("Value")!.GetValue(value);
var jsonVarName = QueryUtils.GenerateRandomVariableName();
_queryVariables.Add(jsonVarName, DataTypes.Json.Serialize(referenceValue));
_queryGlobals.Add(new QueryGlobal(property.Name, new SubQuery($"<json>${jsonVarName}"), value));
_queryGlobals.Add(new QueryGlobal(property.Name,
new SubQuery(writer => writer.QueryArgument("json", jsonVarName)), value));
}
else
throw new InvalidOperationException($"Cannot serialize {property.Name}: No serialization strategy found for {property.PropertyType}");
throw new InvalidOperationException(
$"Cannot serialize {property.Name}: No serialization strategy found for {property.PropertyType}");
}

return this;
}

#endregion

#region For

public GenericlessQueryBuilder For(IEnumerable collection, LambdaExpression iterator, Type? type = null)
{
AddNode<ForNode>(new ForContext(EnterType(type))
{
Expression = iterator,
Set = collection
});
AddNode<ForNode>(new ForContext(EnterType(type)) { Expression = iterator, Set = collection });

return this;
}

#endregion

#region Select

public GenericlessQueryBuilder Select(Type? type = null)
{
AddNode<SelectNode>(new SelectContext(EnterType(type)));
Expand All @@ -165,11 +170,7 @@ public GenericlessQueryBuilder Select(IShapeBuilder? shape, Type? type = null)
{
type ??= EnterType(type);

AddNode<SelectNode>(new SelectContext(type)
{
Shape = shape,
IsFreeObject = type.IsAnonymousType()
});
AddNode<SelectNode>(new SelectContext(type) { Shape = shape, IsFreeObject = type.IsAnonymousType() });

return this;
}
Expand All @@ -180,24 +181,21 @@ public GenericlessQueryBuilder SelectExp(LambdaExpression expression, Type? type

AddNode<SelectNode>(new SelectContext(type)
{
Expression = expression,
IncludeShape = false,
IsFreeObject = type.IsAnonymousType(),
Expression = expression, IncludeShape = false, IsFreeObject = type.IsAnonymousType(),
});

return this;
}

#endregion

#region Insert

public GenericlessQueryBuilder Insert(object value, bool returnInsertedValue = true, Type? type = null)
{
type ??= EnterType(type);

var insertNode = AddNode<InsertNode>(new InsertContext(type)
{
Value = value
});
var insertNode = AddNode<InsertNode>(new InsertContext(type) { Value = value });

if (returnInsertedValue)
{
Expand All @@ -206,17 +204,16 @@ public GenericlessQueryBuilder Insert(object value, bool returnInsertedValue = t

return this;
}

#endregion

#region Update

public GenericlessQueryBuilder Update(LambdaExpression func, bool returnUpdatedValue = true, Type? type = null)
{
type ??= EnterType(type);

var updateNode = AddNode<UpdateNode>(new UpdateContext(type)
{
UpdateExpression = func
});
var updateNode = AddNode<UpdateNode>(new UpdateContext(type) { UpdateExpression = func });

if (returnUpdatedValue)
{
Expand All @@ -225,18 +222,23 @@ public GenericlessQueryBuilder Update(LambdaExpression func, bool returnUpdatedV

return this;
}

#endregion

#region Delete

public GenericlessQueryBuilder Delete(Type? type = null)
{
AddNode<DeleteNode>(new DeleteContext(EnterType(type)));
return this;
}

#endregion

#endregion

#region Query node attributes

public GenericlessQueryBuilder Filter(LambdaExpression expression)
{
switch (CurrentUserNode)
Expand All @@ -250,10 +252,12 @@ public GenericlessQueryBuilder Filter(LambdaExpression expression)
default:
throw new InvalidOperationException($"Cannot filter on a {CurrentUserNode}");
}

return this;
}

public GenericlessQueryBuilder OrderBy(bool asc, LambdaExpression selector, OrderByNullPlacement? placement = null)
public GenericlessQueryBuilder OrderBy(bool asc, LambdaExpression selector,
OrderByNullPlacement? placement = null)
{
if (CurrentUserNode is not SelectNode selectNode)
throw new InvalidOperationException($"Cannot order by on a {CurrentUserNode}");
Expand Down Expand Up @@ -357,13 +361,17 @@ public GenericlessQueryBuilder Else(Func<GenericlessQueryBuilder, GenericlessQue

return this;
}

#endregion

#region Building

private async ValueTask<BuiltQuery> IntrospectAndBuildAsync(IEdgeDBQueryable edgedb, CancellationToken token)
{
if (_nodes.Any(x => x.RequiresIntrospection) || _queryGlobals.Any(x => x.Value is SubQuery subQuery && subQuery.RequiresIntrospection))
_schemaInfo ??= await SchemaIntrospector.GetOrCreateSchemaIntrospectionAsync(edgedb, token).ConfigureAwait(false);
if (_nodes.Any(x => x.RequiresIntrospection) ||
_queryGlobals.Any(x => x.Value is SubQuery subQuery && subQuery.RequiresIntrospection))
_schemaInfo ??= await SchemaIntrospector.GetOrCreateSchemaIntrospectionAsync(edgedb, token)
.ConfigureAwait(false);

var result = Build();
_nodes.Clear();
Expand All @@ -372,7 +380,8 @@ private async ValueTask<BuiltQuery> IntrospectAndBuildAsync(IEdgeDBQueryable edg
return result;
}

internal BuiltQuery InternalBuild(bool includeGlobalsInQuery = true, Action<QueryNode>? preFinalizerModifier = null)
internal BuiltQuery InternalBuild(bool includeGlobalsInQuery = true,
Action<QueryNode>? preFinalizerModifier = null)
{
List<string> query = new();
List<IDictionary<string, object?>> parameters = new();
Expand All @@ -391,15 +400,10 @@ internal BuiltQuery InternalBuild(bool includeGlobalsInQuery = true, Action<Quer
// create a with block if we have any globals
if (includeGlobalsInQuery && _queryGlobals.Any())
{
var builder = new NodeBuilder(new WithContext(QueryType)
{
Values = _queryGlobals,
}, _queryGlobals, nodes, _queryVariables);
var builder = new NodeBuilder(new WithContext(QueryType) { Values = _queryGlobals, }, _queryGlobals,
nodes, _queryVariables);

var with = new WithNode(builder)
{
SchemaInfo = _schemaInfo
};
var with = new WithNode(builder) { SchemaInfo = _schemaInfo };

// visit the with node and add it to the front of our local collection of nodes.
with.Visit();
Expand All @@ -426,8 +430,8 @@ internal BuiltQuery InternalBuild(bool includeGlobalsInQuery = true, Action<Quer

// flatten our parameters into a single collection and make it distinct.
var variables = parameters
.SelectMany(x => x)
.DistinctBy(x => x.Key);
.SelectMany(x => x)
.DistinctBy(x => x.Key);

// add any variables that might have been added by other builders in a sub-query context.
variables = variables.Concat(_queryVariables.Where(x => !variables.Any(x => x.Key == x.Key)));
Expand All @@ -436,8 +440,7 @@ internal BuiltQuery InternalBuild(bool includeGlobalsInQuery = true, Action<Quer
return new BuiltQuery(string.Join(' ', query))
{
Parameters = variables
.ToDictionary(x => x.Key, x => x.Value),

.ToDictionary(x => x.Key, x => x.Value),
Globals = !includeGlobalsInQuery ? _queryGlobals : null
};
}
Expand All @@ -453,16 +456,20 @@ public ValueTask<BuiltQuery> BuildAsync(IEdgeDBQueryable edgedb, CancellationTok
/// <inheritdoc cref="IQueryBuilder.BuildWithGlobals"/>
public BuiltQuery BuildWithGlobals(Action<QueryNode>? preFinalizerModifier = null)
=> InternalBuild(false, preFinalizerModifier);

#endregion

#region IQueryBuilder

IReadOnlyCollection<QueryNode> IQueryBuilder.Nodes
=> _nodes.ToImmutableArray();

IReadOnlyCollection<QueryGlobal> IQueryBuilder.Globals
=> _queryGlobals.ToImmutableArray();

IReadOnlyDictionary<string, object?> IQueryBuilder.Variables
=> _queryVariables.ToImmutableDictionary();

#endregion
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,10 @@ public static void AssertExpression<T>(

public static void AssertExpression(Func<ExpressionContext> contextFactory, Expression expression, string expected)
{
var result = ExpressionTranslator.ContextualTranslate(expression, contextFactory());
var writer = new QueryStringWriter();
ExpressionTranslator.ContextualTranslate(expression, contextFactory(), writer);

Assert.AreEqual(expected, result);
Assert.AreEqual(expected, writer.Compile().ToString());
}

public static void AssertException<T, TException>(
Expand All @@ -77,7 +78,8 @@ public static void AssertException<T, TException>(
public static void AssertException<TException>(Func<ExpressionContext> contextFactory, Expression expression)
where TException : Exception
{
Assert.ThrowsException<TException>(() => ExpressionTranslator.ContextualTranslate(expression, contextFactory()));
var writer = new QueryStringWriter();
Assert.ThrowsException<TException>(() => ExpressionTranslator.ContextualTranslate(expression, contextFactory(), writer));
}
}
}

0 comments on commit 2e5b5d4

Please sign in to comment.