Skip to content

Commit

Permalink
Rebase to v1 driver
Browse files Browse the repository at this point in the history
  • Loading branch information
quinchs committed Oct 19, 2022
1 parent 945c2ed commit ec76977
Show file tree
Hide file tree
Showing 278 changed files with 13,369 additions and 38 deletions.
16 changes: 15 additions & 1 deletion EdgeDB.Net.sln
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EdgeDB.Examples.ExampleTODO
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "EdgeDB.Examples.FSharp", "examples\EdgeDB.Examples.FSharp\EdgeDB.Examples.FSharp.fsproj", "{F25AA805-163F-46B4-942E-B1A5EBE8383C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EdgeDB.DocGenerator", "tools\EdgeDB.DocGenerator\EdgeDB.DocGenerator.csproj", "{776EAE34-5A30-45B0-9277-C399CC2ABA53}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EdgeDB.DocGenerator", "tools\EdgeDB.DocGenerator\EdgeDB.DocGenerator.csproj", "{776EAE34-5A30-45B0-9277-C399CC2ABA53}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EdgeDB.Net.QueryBuilder", "src\EdgeDB.Net.QueryBuilder\EdgeDB.Net.QueryBuilder.csproj", "{0E7F8D0A-621C-4F82-84B6-136DA819E10C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EdgeDB.QueryBuilder.StandardLibGenerator", "tools\EdgeDB.QueryBuilder.StandardLibGenerator\EdgeDB.QueryBuilder.StandardLibGenerator.csproj", "{A13D17CE-1715-44AE-9E89-66DFE37583B1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -83,6 +87,14 @@ Global
{776EAE34-5A30-45B0-9277-C399CC2ABA53}.Debug|Any CPU.Build.0 = Debug|Any CPU
{776EAE34-5A30-45B0-9277-C399CC2ABA53}.Release|Any CPU.ActiveCfg = Release|Any CPU
{776EAE34-5A30-45B0-9277-C399CC2ABA53}.Release|Any CPU.Build.0 = Release|Any CPU
{0E7F8D0A-621C-4F82-84B6-136DA819E10C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0E7F8D0A-621C-4F82-84B6-136DA819E10C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0E7F8D0A-621C-4F82-84B6-136DA819E10C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0E7F8D0A-621C-4F82-84B6-136DA819E10C}.Release|Any CPU.Build.0 = Release|Any CPU
{A13D17CE-1715-44AE-9E89-66DFE37583B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A13D17CE-1715-44AE-9E89-66DFE37583B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A13D17CE-1715-44AE-9E89-66DFE37583B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A13D17CE-1715-44AE-9E89-66DFE37583B1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -99,6 +111,8 @@ Global
{E38429C6-53A5-4311-8189-1F78238666DC} = {6FC214F5-C912-4D99-91B1-3E9F52A4E11B}
{F25AA805-163F-46B4-942E-B1A5EBE8383C} = {6FC214F5-C912-4D99-91B1-3E9F52A4E11B}
{776EAE34-5A30-45B0-9277-C399CC2ABA53} = {67ED9EF0-7828-44C0-8CB0-DEBD69EC94CA}
{0E7F8D0A-621C-4F82-84B6-136DA819E10C} = {025AAADF-16AF-4367-9C3D-9E60EDED832F}
{A13D17CE-1715-44AE-9E89-66DFE37583B1} = {67ED9EF0-7828-44C0-8CB0-DEBD69EC94CA}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4E90C94F-D693-4411-82F3-2051DE1BE052}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

<ItemGroup>
<ProjectReference Include="..\..\src\EdgeDB.Net.Driver\EdgeDB.Net.Driver.csproj" />
<ProjectReference Include="..\..\src\EdgeDB.Net.QueryBuilder\EdgeDB.Net.QueryBuilder.csproj" />
</ItemGroup>

</Project>
290 changes: 290 additions & 0 deletions examples/EdgeDB.Examples.CSharp/Examples/QueryBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,290 @@
using EdgeDB.QueryNodes;
using EdgeDB.Schema;
using EdgeDB.Schema.DataTypes;
using EdgeDB.Translators.Methods;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace EdgeDB.ExampleApp.Examples
{
internal class QueryBuilderExample : IExample
{
public ILogger? Logger { get; set; }

public class LinkPerson
{
public string? Name { get; set; }
public string? Email { get; set; }
public LinkPerson? BestFriend { get; set; }
}

public class MultiLinkPerson
{
public Guid Id { get; set; }
public string? Name { get; set; }
public string? Email { get; set; }
public MultiLinkPerson[]? BestFriends { get; set; }
}

public class ArrayPerson
{
public string? Name { get; set; }
public string? Email { get; set; }

public IEnumerable<string>? Roles { get; set; }
}

public class PropertyConstraintPerson
{
public string? Name { get; set; }
public string? Email { get; set; }
}

public class ConstraintPerson
{
public string? Name { get; set; }
public string? Email { get; set; }
}

public async Task ExecuteAsync(EdgeDBClient client)
{
await QueryBuilderDemo(client);
await QueryableCollectionDemo(client);
}

private static async Task QueryBuilderDemo(EdgeDBClient client)
{
// Selecting a type with autogen shape
var query = QueryBuilder.Select<LinkPerson>().Build().Prettify();

// Adding a filter, orderby, offset, and limit
query = QueryBuilder
.Select<LinkPerson>()
.Filter(x => EdgeQL.ILike(x.Name, "e%"))
.OrderByDesending(x => x.Name)
.Offset(2)
.Limit(10)
.Build()
.Prettify();

// Specifying a shape
query = QueryBuilder.Select((ctx) => new LinkPerson
{
Email = ctx.Include<string>(),
Name = ctx.Include<string>(),
BestFriend = ctx.IncludeLink(() => new LinkPerson
{
Email = ctx.Include<string>(),
})
}).Build().Prettify();

// Adding computed properties in our shape
// Note: we need to use a new instance of query builder to provide the
// 'LinkPerson' type as a generic, since its being used for local context
// in the anon type.
query = new QueryBuilder<LinkPerson>().Select((ctx) => new
{
Name = ctx.Include<string>(),
Email = ctx.Include<string>(),
HasBestfriend = ctx.Local("BestFriend") != null
}).Build().Prettify();

// selecting things that are not types
query = QueryBuilder.Select(() =>
EdgeQL.Count(
QueryBuilder.Select<LinkPerson>()
)
).Build().Prettify();

// selecting 'free objects'
query = QueryBuilder.Select(ctx => new
{
MyString = "This is a string",
MyNumber = 42,
SeveralNumbers = new long[] { 1, 2, 3 },
People = ctx.SubQuery(QueryBuilder.Select<MultiLinkPerson>())
}).Build().Prettify();

// Backlinks
query = new QueryBuilder<MultiLinkPerson>().Select(ctx => new
{
Name = ctx.Include<string>(),
Email = ctx.Include<string>(),
BestFriends = ctx.IncludeLink(() => new MultiLinkPerson
{
Name = ctx.Include<string>(),
Email = ctx.Include<string>(),
}),
// The 'ReferencedFriends' will be equal to '.<best_friends[is MultiLinkPerson] { name, email }'
// The '[is x]' statement is only inserted when a property selector is used with the generic,
// you can pass in a string instead of an expression to select out a 'EdgeDBObject' type.
ReferencedFriends = ctx.BackLink(x => x.BestFriends, () => new MultiLinkPerson
{
Name = ctx.Include<string>(),
Email = ctx.Include<string>(),
})
}).Build().Prettify();

// With object variables
query = QueryBuilder.With(new
{
Args = EdgeQL.AsJson(new ConstraintPerson
{
Name = "Example",
Email = "[email protected]"
})
}).Select(ctx => new
{
PassedName = ctx.Variables.Args.Value.Name,
PassedEmail = ctx.Variables.Args.Value.Email
}).Build().Pretty;

// Inserting a new type
var person = new LinkPerson
{
Email = "[email protected]",
Name = "example"
};

query = QueryBuilder.Insert(person).Build().Prettify();

// Complex insert with links & dealing with conflicts
query = (await QueryBuilder
.Insert(new LinkPerson
{
BestFriend = person,
Name = "example2",
Email = "[email protected]"
})
.UnlessConflict()
.ElseReturn()
.BuildAsync(client))
.Prettify();

// Manual conflicts
query = QueryBuilder
.Insert(person)
.UnlessConflictOn(x => x.Email)
.ElseReturn()
.Build()
.Prettify();

// Autogenerating unless conflict with introspection
query = (await QueryBuilder
.Insert(person)
.UnlessConflict()
.ElseReturn()
.BuildAsync(client))
.Prettify();

// Bulk inserts
var data = new LinkPerson[]
{
new LinkPerson
{
Email = "[email protected]",
Name = "test1",
},
new LinkPerson
{
Email = "[email protected]",
Name = "test2",
BestFriend = new LinkPerson
{
Email = "[email protected]",
Name = "test3",
}
}
};

var tquery = (await QueryBuilder.For(data,
x => QueryBuilder.Insert(x)
).BuildAsync(client));

// Else statements (upsert demo)
query = (await QueryBuilder
.Insert(person)
.UnlessConflict()
.Else(q =>
q.Update(old => new LinkPerson
{
Name = old!.Name!.ToLower()
})
)
.BuildAsync(client))
.Prettify();

// Updating a type
query = QueryBuilder
.Update<LinkPerson>(old => new LinkPerson
{
Name = "example new name"
})
.Filter(x => x.Email == "[email protected]")
.Build()
.Prettify();

// Deleting types
query = QueryBuilder
.Delete<LinkPerson>()
.Filter(x => EdgeQL.ILike(x.Name, "e%"))
.Build()
.Prettify();
}

private static async Task QueryableCollectionDemo(EdgeDBClient client)
{
// Get a 'collection' object, this class wraps the query
// builder and provides simple CRUD methods.
var collection = client.GetCollection<LinkPerson>();

// Get or add a value
var person = await collection.GetOrAddAsync(new LinkPerson
{
Email = "[email protected]",
Name = "example"
});

// we can change properties locally and then call UpdateAsync to update the type in the database.
person.Name = "example new name";

await collection.UpdateAsync(person);

// or we can provide an update function
person = await collection.UpdateAsync(person, old => new LinkPerson
{
Name = "example"
});

// we can select types based on a filter
var people = await collection.WhereAsync(x => EdgeQL.ILike(x.Name, "e%"));

// we can add or update a type
var otherPerson = await collection.AddOrUpdateAsync(new LinkPerson
{
Name = "example2",
Email = "[email protected]",
BestFriend = person
});

// we can delete types
var toBeDeleted = await collection.GetOrAddAsync(new LinkPerson
{
Email = "[email protected]",
Name = "example3"
});

// the result of this delete functions is whether or not it was deleted.
var success = await collection.DeleteAsync(toBeDeleted);

// we can also delete types based on a filter
var count = await collection.DeleteWhereAsync(x => EdgeQL.ILike(x.Name, "e%"));
}
}
}
21 changes: 3 additions & 18 deletions src/EdgeDB.Net.Driver/Attributes/EdgeDBPropertyAttribute.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace EdgeDB
namespace EdgeDB
{
/// <summary>
/// Marks the current field or property as a valid target for serializing/deserializing.
Expand All @@ -7,24 +7,9 @@
public class EdgeDBPropertyAttribute : Attribute
{
/// <summary>
/// Gets or sets whether or not this member is a link.
/// Gets or sets whether or not the property is on a link.
/// </summary>
internal bool IsLink { get; set; }

/// <summary>
/// Gets or sets whether or not this member is required.
/// </summary>
internal bool IsRequired { get; set; }

/// <summary>
/// Gets or sets whether or not this member is a computed value.
/// </summary>
internal bool IsComputed { get; set; }

/// <summary>
/// Gets or sets whether or not this member is read-only.
/// </summary>
internal bool IsReadOnly { get; set; }
public bool IsLinkProperty { get; set; }

internal readonly string? Name;

Expand Down
8 changes: 6 additions & 2 deletions src/EdgeDB.Net.Driver/Attributes/EdgeDBTypeAttribute.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
namespace EdgeDB
namespace EdgeDB
{
/// <summary>
/// Marks this class or struct as a valid type to use when serializing/deserializing.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum)]
public class EdgeDBTypeAttribute : Attribute
{
/// <summary>
/// Gets or sets the module name for this type.
/// </summary>
public string? ModuleName { get; init; }
internal readonly string? Name;

/// <summary>
Expand Down
Loading

0 comments on commit ec76977

Please sign in to comment.