Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hackathon/peachy/chrispre/paths #2739

Open
wants to merge 3 commits into
base: hackathon/peachy/main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions CsdlToPaths/CsdlToPaths.Demo/CsdlToPathsDemo.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">

<ItemGroup>
<ProjectReference Include="..\CsdlToPaths\CsdlToPaths.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Odata.Edm" Version="7.18.0" />
</ItemGroup>

<ItemGroup>
<None Update="data\directory.csdl.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="data\example89.csdl.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="data\users.csdl.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
Empty file.
109 changes: 109 additions & 0 deletions CsdlToPaths/CsdlToPaths.Demo/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
using System.Xml;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Csdl;

class Program
{

private static void Main()
{
var args = Args.Parse();


using var reader = XmlReader.Create(args.InputFile);
if (!CsdlReader.TryParse(reader, out var model, out var errors))
{
Console.WriteLine(string.Join(Environment.NewLine, errors));
return;
}

var analyzer = new ModelAnalyzer(model);
var tree = analyzer.CreateTree();

// format tree
if (!args.HideTree)
{
using var writer = new TreeWriter(Console.Out, true);
writer.Display(tree);
}

// list of paths
if (args.ShowPaths)
{
foreach (var path in tree.Paths())
{
// just path
// Console.WriteLine("{0}", path.Segments.SeparatedBy("/"));

// path and response type
Console.WriteLine("{0} \x1b[36m{1}\x1b[m", path.Segments.SeparatedBy("/"), path.ResponseType.Format());

// // path, response type and a procedure like signature
// Console.WriteLine("{0}\n\t\x1b[36m{1}\x1b[m",
// path.Segments.SeparatedBy("/"),
// Signature(path));
}
}
}


static string Signature((IEnumerable<string> Segments, IEdmType ResponseType) path)
{
var parameters = string.Join(", ", path.Segments.Where(s => s.StartsWith('{')).Select(w => w.Trim('{', '}')));
var name = string.Join("Of", path.Segments.Where(s => !s.StartsWith('{')).Select(s => s.Capitalize()).Reverse());

return $"{name}({parameters}) -> {path.ResponseType.Format()}";
}
}

class Args
{


const string DEFAULT_INPUT = "data/directory.csdl.xml";


public string InputFile { get; private set; } = null!;
public bool ShowPaths { get; private set; }
public bool HideTree { get; private set; }

public static Args Parse()
{
var result = new Args();
var defaultArgProvided = false;
var args = Environment.GetCommandLineArgs();
for (int i = 1; i < args.Length; i++)
{
var arg = args[i];
switch (arg)
{
case "--paths":
case "-p":
result.ShowPaths = true;
break;
case "--no-tree":
case "-t":
result.HideTree = true;
break;
case string s when s.StartsWith("--"):
throw new Exception($"unknown option {arg}");
default:
if (defaultArgProvided)
{
throw new Exception($"two default arguments provided");
}
else
{
result.InputFile = arg;
defaultArgProvided = true;
}
break;
}
}
if (result.InputFile == null)
{
result.InputFile = DEFAULT_INPUT;
}
return result;
}
}
60 changes: 60 additions & 0 deletions CsdlToPaths/CsdlToPaths.Demo/data/directory.csdl.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
xmlns="http://docs.oasis-open.org/odata/ns/edm" Version="4.0">


<edmx:DataServices>
<Schema Namespace="Directory">

<EntityType Name="DirectoryObject">
<Key>
<PropertyRef Name="id" />
</Key>
<Property Name="id" Type="Edm.String" Nullable="false" />
<NavigationProperty Name="memberOf" Type="Collection(Directory.Group)"
Nullable="false" Partner="members" />
</EntityType>
<EntityType Name="User" BaseType="Directory.DirectoryObject">
<Property Name="name" Type="Edm.Int32" Nullable="false" />
<Property Name="createdDate" Type="Edm.Date" />

</EntityType>
<EntityType Name="Group" BaseType="Directory.DirectoryObject">
<Property Name="name" Type="Edm.String" Nullable="false">
<Annotation Term="Core.IsLanguageDependent" />

</Property>
<Property Name="createdDate" Type="Edm.Date" />
<NavigationProperty Name="members" Type="Collection(Directory.DirectoryObject)"
Nullable="false" Partner="memberOf" />
</EntityType>

<EntityContainer Name="DemoService">
<EntitySet Name="users" EntityType="Directory.User">
<NavigationPropertyBinding Path="memberOf" Target="directoryObjects" />
</EntitySet>

<EntitySet Name="groups" EntityType="Directory.Group">
<NavigationPropertyBinding Path="members" Target="directoryObjects" />
</EntitySet>

<EntitySet Name="directoryObjects" EntityType="Directory.DirectoryObject">
<NavigationPropertyBinding Path="products" Target="Products" />

<NavigationPropertyBinding Path="address/country"
Target="countries" />

<Annotation Term="Core.OptimisticConcurrency">

<Collection>

<PropertyPath>Concurrency</PropertyPath>

</Collection>

</Annotation>

</EntitySet>
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
152 changes: 152 additions & 0 deletions CsdlToPaths/CsdlToPaths.Demo/data/example89.csdl.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
xmlns="http://docs.oasis-open.org/odata/ns/edm" Version="4.0">
<edmx:Reference
Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.xml">

<edmx:Include Namespace="Org.OData.Core.V1" Alias="Core">

<Annotation Term="Core.DefaultNamespace" />

</edmx:Include>

</edmx:Reference>

<edmx:Reference
Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Measures.V1.xml">

<edmx:Include Alias="Measures" Namespace="Org.OData.Measures.V1" />

</edmx:Reference>

<edmx:DataServices>
<Schema Namespace="ODataDemo">
<EntityType Name="Product" HasStream="true">
<Key>
<PropertyRef Name="productId" />
</Key>
<Property Name="productId" Type="Edm.Int32" Nullable="false" />
<Property Name="description" Type="Edm.String">
<Annotation Term="Core.IsLanguageDependent" />

</Property>

<Property Name="releaseDate" Type="Edm.Date" />
<Property Name="discontinuedDate" Type="Edm.Date" />
<Property Name="rating" Type="Edm.Int32" />
<Property Name="price" Type="Edm.Decimal" Scale="variable">
<Annotation Term="Measures.ISOCurrency" Path="Currency" />

</Property>

<Property Name="currency" Type="Edm.String" MaxLength="3" />

<NavigationProperty Name="category" Type="ODataDemo.Category"
Nullable="false" Partner="products" />

<NavigationProperty Name="supplier" Type="ODataDemo.Supplier"
Partner="products" />
</EntityType>
<EntityType Name="Category">
<Key>
<PropertyRef Name="categoryId" />
</Key>
<Property Name="categoryId" Type="Edm.Int32" Nullable="false" />
<Property Name="name" Type="Edm.String" Nullable="false">
<Annotation Term="Core.IsLanguageDependent" />

</Property>

<NavigationProperty Name="products" Partner="Category"
Type="Collection(ODataDemo.Product)">
<OnDelete Action="Cascade" />
</NavigationProperty>
</EntityType>
<EntityType Name="Supplier">
<Key>
<PropertyRef Name="supplierId" />
</Key>
<Property Name="supplierId" Type="Edm.String" Nullable="false" />
<Property Name="name" Type="Edm.String" />
<Property Name="address" Type="ODataDemo.Address" Nullable="false" />
<Property Name="concurrency" Type="Edm.Int32" Nullable="false" />
<NavigationProperty Name="products" Partner="Supplier"
Type="Collection(ODataDemo.Product)" />

</EntityType>
<EntityType Name="Country">

<Key>

<PropertyRef Name="code" />

</Key>

<Property Name="code" Type="Edm.String" MaxLength="2"
Nullable="false" />

<Property Name="name" Type="Edm.String" />

</EntityType>

<ComplexType Name="Address">
<Property Name="street" Type="Edm.String" />
<Property Name="city" Type="Edm.String" />
<Property Name="state" Type="Edm.String" />
<Property Name="zipCode" Type="Edm.String" />
<Property Name="countryName" Type="Edm.String" />
<NavigationProperty Name="country" Type="ODataDemo.Country">

<ReferentialConstraint Property="countryName"
ReferencedProperty="name" />

</NavigationProperty>

</ComplexType>
<Function Name="ProductsByRating">
<Parameter Name="rating" Type="Edm.Int32" />

<ReturnType Type="Collection(ODataDemo.Product)" />
</Function>
<EntityContainer Name="DemoService">
<EntitySet Name="products" EntityType="ODataDemo.Product">
<NavigationPropertyBinding Path="Category" Target="Categories" />

</EntitySet>
<EntitySet Name="categories" EntityType="ODataDemo.Category">
<NavigationPropertyBinding Path="Products" Target="Products" />

<Annotation Term="Core.Description" String="Product Categories" />

</EntitySet>
<EntitySet Name="suppliers" EntityType="ODataDemo.Supplier">
<NavigationPropertyBinding Path="products" Target="Products" />

<NavigationPropertyBinding Path="address/country"
Target="countries" />

<Annotation Term="Core.OptimisticConcurrency">

<Collection>

<PropertyPath>Concurrency</PropertyPath>

</Collection>

</Annotation>

</EntitySet>
<Singleton Name="mainSupplier" Type="ODataDemo.Supplier">
<NavigationPropertyBinding Path="Products" Target="Products" />

<Annotation Term="Core.Description" String="Primary Supplier" />

</Singleton>

<EntitySet Name="countries" EntityType="ODataDemo.Country" />

<FunctionImport Name="ProductsByRating" EntitySet="Products"
Function="ODataDemo.ProductsByRating" />
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
27 changes: 27 additions & 0 deletions CsdlToPaths/CsdlToPaths.Demo/data/users.csdl.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
xmlns="http://docs.oasis-open.org/odata/ns/edm" Version="4.0">


<edmx:DataServices>
<Schema Namespace="Directory">

<EntityType Name="User">
<Key>
<PropertyRef Name="id" />
</Key>
<Property Name="id" Type="Edm.String" Nullable="false" />
<Property Name="name" Type="Edm.Int32" Nullable="false" />
<Property Name="createdDate" Type="Edm.Date" />
<NavigationProperty Name="manager" Type="Directory.User"
Nullable="false" Partner="reports" />
<NavigationProperty Name="reports" Type="Collection(Directory.User)"
Nullable="false" Partner="manager" />
</EntityType>

<EntityContainer Name="DemoService">
<EntitySet Name="users" EntityType="Directory.User">
</EntitySet>
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
Loading