Skip to content

Commit

Permalink
root writer and labels
Browse files Browse the repository at this point in the history
  • Loading branch information
quinchs committed Jan 17, 2024
1 parent 5ca77ff commit 06b9167
Show file tree
Hide file tree
Showing 10 changed files with 278 additions and 158 deletions.
68 changes: 42 additions & 26 deletions src/EdgeDB.Net.QueryBuilder/QueryBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -202,9 +202,20 @@ private TNode AddNode<TNode>(NodeContext context, bool autoGenerated = false, Qu
/// <returns>
/// A <see cref="BuiltQuery"/> which is the current query this builder has constructed.
/// </returns>
internal BuiltQuery InternalBuild(bool includeGlobalsInQuery = true, Action<QueryNode>? preFinalizerModifier = null)
internal BuiltQuery InternalBuild(bool? includeGlobalsInQuery = true, Action<QueryNode>? preFinalizerModifier = null)
{
var writer = new QueryStringWriter();

InternalBuild(writer, includeGlobalsInQuery, preFinalizerModifier);

return new BuiltQuery(writer.Compile(_schemaInfo).ToString())
{
Parameters = _queryVariables, Globals = _queryGlobals
};
}

internal void InternalBuild(QueryStringWriter writer, bool? includeGlobalsInQuery = true, Action<QueryNode>? preFinalizerModifier = null)
{
List<string> query = new();
List<IDictionary<string, object?>> parameters = new();

var nodes = _nodes;
Expand All @@ -215,11 +226,10 @@ internal BuiltQuery InternalBuild(bool includeGlobalsInQuery = true, Action<Quer
node.SchemaInfo ??= _schemaInfo;
if (preFinalizerModifier is not null)
preFinalizerModifier(node);
node.FinalizeQuery();
}

// create a with block if we have any globals
if (includeGlobalsInQuery && _queryGlobals.Any())
if ((includeGlobalsInQuery ?? false) && _queryGlobals.Any())
{
var builder = new NodeBuilder(new WithContext(typeof(TType))
{
Expand All @@ -236,23 +246,29 @@ internal BuiltQuery InternalBuild(bool includeGlobalsInQuery = true, Action<Quer
nodes = nodes.Prepend(with).ToList();
}

// build each node starting at the last node.
for (int i = nodes.Count - 1; i >= 0; i--)
for (var i = 0; i != nodes.Count; i++)
{
var node = nodes[i];

var result = node.Build();

// add the nodes query string if its not null or empty.
if (!string.IsNullOrEmpty(result.Query))
query.Add(result.Query);

// add any parameters the node has.
parameters.Add(result.Parameters);
nodes[i].FinalizeQuery(writer);
parameters.Add(nodes[i].Builder.QueryVariables);
}

// reverse our query string since we built our nodes in reverse.
query.Reverse();
// // build each node starting at the last node.
// for (int i = nodes.Count - 1; i >= 0; i--)
// {
// var node = nodes[i];
//
// var result = node.Build();
//
// // add the nodes query string if its not null or empty.
// if (!string.IsNullOrEmpty(result.Query))
// query.Add(result.Query);
//
// // add any parameters the node has.
// parameters.Add(result.Parameters);
// }

// // reverse our query string since we built our nodes in reverse.
// query.Reverse();

// flatten our parameters into a single collection and make it distinct.
var variables = parameters
Expand All @@ -262,14 +278,14 @@ internal BuiltQuery InternalBuild(bool includeGlobalsInQuery = true, Action<Quer
// 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)));

// construct a built query with our query text, variables, and globals.
return new BuiltQuery(string.Join(' ', query))
{
Parameters = variables
.ToDictionary(x => x.Key, x => x.Value),

Globals = !includeGlobalsInQuery ? _queryGlobals : null
};
// // construct a built query with our query text, variables, and globals.
// return new BuiltQuery(string.Join(' ', query))
// {
// Parameters = variables
// .ToDictionary(x => x.Key, x => x.Value),
//
// Globals = !includeGlobalsInQuery ? _queryGlobals : null
// };
}

/// <inheritdoc/>
Expand Down
29 changes: 12 additions & 17 deletions src/EdgeDB.Net.QueryBuilder/QueryNodes/ForNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,26 +98,21 @@ public override void FinalizeQuery(QueryStringWriter writer)
ParseExpression(writer, _name, _jsonName, _json);

// finalize and build our sub nodes
var iterator = SubNodes.Select(x =>
writer.Wrapped(writer =>
{
x.SchemaInfo = SchemaInfo;
x.FinalizeQuery();
var builtNode = x.Build();
foreach (var variable in builtNode.Parameters)
SetVariable(variable.Key, variable.Value);
// copy the globals & variables to the current builder
foreach (var global in x.ReferencedGlobals)
SetGlobal(global.Name, global.Value, global.Reference);
foreach (var node in SubNodes)
{
node.SchemaInfo = SchemaInfo;
node.FinalizeQuery(writer);
// we don't need to copy variables or nodes here since we did that in the parse step
return builtNode.Query;
}).Where(x => !string.IsNullOrEmpty(x)).Aggregate((x, y) => $"{x} {y}");
foreach (var variable in node.Builder.QueryVariables)
SetVariable(variable.Key, variable.Value);
// append union statement's content
Writer.Append($"({iterator})");
// copy the globals & variables to the current builder
foreach (var global in node.ReferencedGlobals)
SetGlobal(global.Name, global.Value, global.Reference);
}
});
}
}
}
2 changes: 1 addition & 1 deletion src/EdgeDB.Net.QueryBuilder/QueryNodes/GroupNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public GroupNode(NodeBuilder builder) : base(builder)
{
}

public override void Visit()
public override void FinalizeQuery(QueryStringWriter writer)
{
throw new NotImplementedException();
}
Expand Down
14 changes: 7 additions & 7 deletions src/EdgeDB.Net.QueryBuilder/QueryNodes/InsertNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -224,13 +224,13 @@ public override void Visit()
}

/// <inheritdoc/>
public override void FinalizeQuery()
public override void FinalizeQuery(QueryStringWriter writer)
{
Writer.Append("insert ")
writer.Append("insert ")
.Append(OperatingType.GetEdgeDBTypeName())
.Append(' ');

_shape.Build(Writer, SchemaInfo);
_shape.Build(writer, SchemaInfo);

if (_autogenerateUnlessConflict)
{
Expand All @@ -241,17 +241,17 @@ public override void FinalizeQuery()
if (!SchemaInfo.TryGetObjectInfo(OperatingType, out var typeInfo))
throw new NotSupportedException($"Could not find type info for {OperatingType}");

Writer.Append(' ');
ConflictUtils.GenerateExclusiveConflictStatement(Writer, typeInfo, _elseStatement is not null);
writer.Append(' ');
ConflictUtils.GenerateExclusiveConflictStatement(writer, typeInfo, _elseStatement is not null);
}

if (_elseStatement is not null)
_elseStatement(Writer);
_elseStatement(writer);

if (Context.SetAsGlobal && Context.GlobalName is not null)
{
SetGlobal(Context.GlobalName, new SubQuery(writer => writer
.Wrapped(Writer)
.Wrapped(writer)
), null);
}
}
Expand Down
49 changes: 31 additions & 18 deletions src/EdgeDB.Net.QueryBuilder/QueryNodes/QueryNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -200,28 +200,41 @@ protected void TranslateExpression(LambdaExpression root, Expression expression,

internal void ReplaceSubqueryAsLiteral(QueryStringWriter writer, QueryGlobal global, Action<QueryGlobal, QueryStringWriter> compile)
{
var index = writer.IndexOf(global.Name);
if (!writer.TryGetLabeled(global.Name, out var markers))
return;

if (index is -1)
throw new InvalidOperationException("Global could not be found within the query string");

string? cached = null;

while (index is not -1)
foreach (var marker in markers)
{
if (cached is null)
marker.Replace(writer =>
{
var globalWriter = writer.GetPositionalWriter(index);
compile(global, globalWriter);
cached = globalWriter.ToString();
}
else
{
writer.Insert(index, cached);
}

index = writer.IndexOf(global.Name);
compile(global, writer);
});
}



// var index = writer.IndexOf(global.Name);
//
// if (index is -1)
// throw new InvalidOperationException("Global could not be found within the query string");
//
// string? cached = null;
//
// while (index is not -1)
// {
// if (cached is null)
// {
// var globalWriter = writer.GetPositionalWriter(index);
// compile(global, globalWriter);
// cached = globalWriter.ToString();
// }
// else
// {
// writer.Insert(index, cached);
// }
//
// index = writer.IndexOf(global.Name);
// }
}
}
}
Loading

0 comments on commit 06b9167

Please sign in to comment.