Skip to content

Commit

Permalink
Handle optional function args better internally
Browse files Browse the repository at this point in the history
  • Loading branch information
Quin Lynch committed Apr 27, 2024
1 parent 4663959 commit de28bc3
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 34 deletions.
34 changes: 22 additions & 12 deletions src/EdgeDB.Net.QueryBuilder/Grammar/Terms.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,17 @@ public static QueryWriter Function(this QueryWriter writer, string name, Deferra
for (var i = 0; i < args.Length;)
{
int commaPos = 0;
LooseLinkedList<Value>.Node? comma = null;
if (i > 0)
{
commaPos = writer.TailIndex;
writer.Append(", ", out comma);
}
var arg = args[i++];
bool isEmpty = false;
var isEmpty = false;
writer.Marker(
MarkerType.FunctionArg,
Expand All @@ -148,24 +157,25 @@ public static QueryWriter Function(this QueryWriter writer, string name, Deferra
Value.Of(
writer =>
{
if (writer.AppendIsEmpty(arg.Value, out _, out var node))
if (arg.Named is not null)
{
isEmpty = true;
return;
writer.AppendPrefixIfNotEmpty(
Value.Of(writer => writer.Append(arg.Named, " := ")),
arg.Value,
out isEmpty
);
}
else
{
writer.Append(arg.Value);
}
// append the named part if its specified
if (arg.Named is not null)
writer.Prepend(node, Value.Of(writer => writer.Append(arg.Named, " := ")));
}
)
);
if(isEmpty)
continue;
if (!isEmpty || comma is null) continue;
if (i != args.Length)
writer.Append(", ");
writer.Remove(commaPos, comma);
}
writer.Append(')');
Expand Down
71 changes: 51 additions & 20 deletions src/EdgeDB.Net.QueryBuilder/Lexical/QueryWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public void Dispose()
private ValueNode? _track;
private readonly bool _debug;

private int TailIndex => _tokens.Count - 1;
public int TailIndex => _tokens.Count - 1;

public QueryWriter(bool debug = false)
{
Expand Down Expand Up @@ -74,8 +74,9 @@ private ValueNode AddTracked(in Value value, bool after)
// track is already updated.
return head ?? _track!;
}
else if (_track is null)
_track = _tokens.AddFirst(in value); //Set(ref _tokens.AddFirst(in value));

if (_track is null)
_track = _tokens.AddFirst(in value);
else
{
_track = after
Expand Down Expand Up @@ -172,6 +173,23 @@ public QueryWriter Marker(MarkerType type, string name, Deferrable<string>? debu

public QueryWriter Remove(int position, ValueNode head, int count = 1)
{
if (count == 0)
return this;

if (count < 0)
{
count *= -1;
var countForCopy = count - 1;

for (var i = 0; i < countForCopy; i++)
{
if (head.Previous is null)
count--;
else
head = head.Previous;
}
}

var headPrev = head.Previous;

_tokens.Remove(head, count, (node) =>
Expand All @@ -197,32 +215,24 @@ public QueryWriter Replace(ValueNode node, int position, int size, in Value valu
return this;
}

public QueryWriter Prepend(ValueNode node, in Value value)
public QueryWriter Append(in Value value, out ValueNode node)
{
var index = GetIndexOfNode(node);

if (index == -1)
throw new InvalidOperationException("Node cannot be found in collection of tokens");

// change the track to the node
var oldTrack = _track;
node = AddAfterTracked(in value);

_track = node;
OnNodeAdd(AddBeforeTracked(in value));
_track = oldTrack;
OnNodeAdd(node);

Markers.Update(index - 1, 1);
Markers.Update(TailIndex, 1);

return this;
}

public QueryWriter Append(in Value value, out ValueNode node)
public QueryWriter Append(in Value value, out ValueNode node, out int size)
{
node = AddAfterTracked(in value);
var pos = TailIndex;

OnNodeAdd(node);
Append(in value, out node);

Markers.Update(TailIndex, 1);
size = TailIndex - pos;

return this;
}
Expand Down Expand Up @@ -272,14 +282,35 @@ public bool AppendIsEmpty(in Value value)
public bool AppendIsEmpty(in Value value, out int size)
=> AppendIsEmpty(in value, out size, out _);

public bool AppendIsEmpty(in Value value, out int size, out ValueNode node)
public bool AppendIsEmpty(in Value value, out int size, [MaybeNullWhen(true)] out ValueNode node)
{
if (value == Value.Empty)
{
size = 0;
node = _track;
return true;
}

var index = TailIndex;
Append(in value, out node);
size = TailIndex - index;
return size == 0;
}

public QueryWriter AppendPrefixIfNotEmpty(in Value prefix, in Value value, out bool wasEmpty)
{
var pos = TailIndex;
Append(in prefix, out var prefixHead, out var prefixSize);

if (AppendIsEmpty(in value))
{
Remove(pos, prefixHead, prefixSize);
wasEmpty = true;
}
else wasEmpty = false;
return this;
}

public StringBuilder Compile(StringBuilder? builder = null)
{
builder ??= new StringBuilder();
Expand Down
12 changes: 11 additions & 1 deletion src/EdgeDB.Net.QueryBuilder/Lexical/Value.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
namespace EdgeDB;

[DebuggerDisplay("{DebugDisplay()}")]
internal readonly struct Value
internal readonly struct Value : IEquatable<Value>
{
[MemberNotNullWhen(false, nameof(_callback))]
public bool IsScalar
Expand Down Expand Up @@ -104,4 +104,14 @@ public override string ToString()
public static implicit operator Value(WriterProxy callback) => new(callback);
public static implicit operator Value(int v) => new(v.ToString());
public static implicit operator Value(long v) => new(v.ToString());

public bool Equals(Value other) => Equals(_callback, other._callback) && Equals(_value, other._value) && _str == other._str && _ch == other._ch;

public override bool Equals(object? obj) => obj is Value other && Equals(other);

public override int GetHashCode() => HashCode.Combine(_callback, _value, _str, _ch);

public static bool operator ==(Value left, Value right) => left.Equals(right);

public static bool operator !=(Value left, Value right) => !left.Equals(right);
}
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ public static void TranslateMethod(QueryWriter writer, MethodCallExpression meth
/// </returns>
protected Value OptionalArg(TranslatedParameter? arg)
{
if (arg is null)
if (arg is null || arg.IsNullValue)
return Value.Empty;
else
return arg;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ public bool IsLinkType
public bool IsMultiLinkType
=> EdgeDBTypeUtils.IsLink(ParameterType, out var isMulti, out _) && isMulti;

public bool IsNullValue
=> RawValue is ConstantExpression {Value: null};

/// <summary>
/// Constructs a new <see cref="TranslatedParameter"/>.
/// </summary>
Expand Down

0 comments on commit de28bc3

Please sign in to comment.