-
Notifications
You must be signed in to change notification settings - Fork 37
Expand file tree
/
Copy pathQueryJoinOnConfig.cs
More file actions
130 lines (113 loc) · 5.98 KB
/
Copy pathQueryJoinOnConfig.cs
File metadata and controls
130 lines (113 loc) · 5.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Copyright (c) Avanade. Licensed under the MIT License. See https://github.com/Avanade/Beef
using OnRamp;
using OnRamp.Config;
using System;
using System.Linq;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
namespace Beef.CodeGen.Config.Database
{
/// <summary>
/// Represents the table join on condition configuration.
/// </summary>
[CodeGenClass("QueryJoinOn", Title = "'QueryJoinOn' object (database-driven)",
Description = "The `QueryJoinOn` object defines the join on characteristics for a join within a query.",
ExampleMarkdown = @"A YAML configuration example is as follows:
``` yaml
queries:
- { name: Table, schema: Test, view: true, viewName: vwTestQuery, excludeColumns: [CreatedBy, UpdatedBy], permission: TestSec,
joins: [
{ name: Person, schema: Demo, excludeColumns: [CreatedDate, UpdatedDate], aliasColumns: [RowVersion ^ RowVersionP],
on: [
{ name: PersonId, toColumn: TableId }
]
}
]
}
```")]
[CodeGenCategory("Key", Title = "Provides the _key_ configuration.")]
public class QueryJoinOnConfig : ConfigBase<CodeGenConfig, QueryJoinConfig>
{
/// <summary>
/// <inheritdoc/>
/// </summary>
/// <remarks><inheritdoc/></remarks>
public override string? QualifiedKeyName => BuildQualifiedKeyName("QueryJoinOn", Name);
#region Key
/// <summary>
/// Gets or sets the name of the join column (from the `Join` table).
/// </summary>
[JsonPropertyName("name")]
[CodeGenProperty("Key", Title = "The name of the join column (from the `Join` table).", IsMandatory = true, IsImportant = true)]
public string? Name { get; set; }
/// <summary>
/// Gets or sets the name of the other join to table schema.
/// </summary>
[JsonPropertyName("toSchema")]
[CodeGenProperty("Key", Title = "The name of the other join to table schema.",
Description = "Defaults to `Table.Schema`; i.e. same schema. See also `ToTable` and `ToColumn` as these all relate.")]
public string? ToSchema { get; set; }
/// <summary>
/// Gets or sets the name of the other join to table.
/// </summary>
[JsonPropertyName("toTable")]
[CodeGenProperty("Key", Title = "The name of the other join to table.",
Description = "Defaults to `Table.Name`; i.e. primary table. See also `ToSchema` and `ToColumn` as these all relate.")]
public string? ToTable { get; set; }
/// <summary>
/// Gets or sets the name of the other join to column.
/// </summary>
[JsonPropertyName("toColumn")]
[CodeGenProperty("Key", Title = "The name of the other join to column.", IsImportant = true,
Description = "Defaults to `Name`; i.e. assumes same name. See also `ToSchema` and `ToTable` as these all relate.")]
public string? ToColumn { get; set; }
/// <summary>
/// Gets or sets the fully qualified name (`Alias.Name`) of the other column being joined to or other valid SQL (e.g. function) bypassing the corresponding `Schema`, `Table` and `Column` logic.
/// </summary>
[JsonPropertyName("toStatement")]
[CodeGenProperty("Key", Title = "The fully qualified name (`Alias.Name`) of the other column being joined to or other valid SQL (e.g. function) bypassing the corresponding `Schema`, `Table` and `Column` logic.")]
public string? ToStatement { get; set; }
#endregion
/// <summary>
/// Gets the formatted Join On SQL statement.
/// </summary>
public string JoinOnSql => $"[{Parent!.Alias}].[{Name}] = {ToStatement}";
/// <summary>
/// <inheritdoc/>
/// </summary>
protected override Task PrepareAsync()
{
if (Name != null && Name.StartsWith("@", StringComparison.OrdinalIgnoreCase))
Name = Name[1..];
var c = Parent!.DbTable!.Columns.Where(x => x.Name == Name).SingleOrDefault();
if (c == null)
throw new CodeGenException(this, nameof(Name), $"JoinOn '{Name}' (Schema.Table '{Parent!.Schema}.{Parent!.Name}') not found in database.");
if (string.IsNullOrEmpty(ToStatement))
{
ToSchema = DefaultWhereNull(ToSchema, () => Parent!.Parent!.Schema);
ToTable = DefaultWhereNull(ToTable, () => Parent!.Parent!.Name);
ToColumn = DefaultWhereNull(ToColumn, () => Name);
c = Root!.DbTables!.Where(x => x.Schema == ToSchema && x.Name == ToTable).SingleOrDefault()?.Columns.Where(x => x.Name == ToColumn).SingleOrDefault();
if (c == null)
throw new CodeGenException(this, nameof(ToColumn), $"JoinOn To '{ToColumn}' (Schema.Table '{ToSchema}.{ToTable}') not found in database.");
if (ToSchema == Parent!.Parent!.Schema && ToTable == Parent!.Parent!.Name)
{
if (Parent!.Parent!.DbTable!.Columns.Where(x => x.Name == ToColumn).SingleOrDefault() == null)
throw new CodeGenException(this, nameof(ToColumn), $"JoinOn To '{ToColumn}' (Schema.Table '{ToSchema}.{ToTable}') not found in Table/Join configuration.");
ToStatement = $"[{Parent!.Parent!.Alias}].[{ToColumn}]";
}
else
{
var t = Parent!.Parent!.Joins!.Where(x => ToSchema == x.Schema && ToTable == x.Name).SingleOrDefault();
if (t != null && t.DbTable!.Columns.Where(x => x.Name == ToColumn).SingleOrDefault() != null)
{
ToStatement = $"[{t.Alias}].[{ToColumn}]";
}
else
throw new CodeGenException(this, nameof(ToColumn), $"JoinOn To '{ToColumn}' (Schema.Table '{ToSchema}.{ToTable}') not found in Table/Join configuration.");
}
}
return Task.CompletedTask;
}
}
}