-
Notifications
You must be signed in to change notification settings - Fork 349
Expand file tree
/
Copy pathSqlInsertQueryStructure.cs
More file actions
134 lines (121 loc) · 5.28 KB
/
Copy pathSqlInsertQueryStructure.cs
File metadata and controls
134 lines (121 loc) · 5.28 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
131
132
133
134
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System.Net;
using Azure.DataApiBuilder.Auth;
using Azure.DataApiBuilder.Config.DatabasePrimitives;
using Azure.DataApiBuilder.Config.ObjectModel;
using Azure.DataApiBuilder.Core.Models;
using Azure.DataApiBuilder.Core.Services;
using Azure.DataApiBuilder.Service.Exceptions;
using Azure.DataApiBuilder.Service.GraphQLBuilder.Mutations;
using HotChocolate.Resolvers;
using Microsoft.AspNetCore.Http;
namespace Azure.DataApiBuilder.Core.Resolvers
{
/// <summary>
/// Wraps all the required data and logic to write a SQL INSERT query
/// </summary>
public class SqlInsertStructure : BaseSqlQueryStructure
{
/// <summary>
/// Column names to insert into the given columns
/// </summary>
public List<string> InsertColumns { get; }
/// <summary>
/// Values to insert into the given columns
/// </summary>
public List<string> Values { get; }
/// <summary>
/// The inserted columns that the insert will OUTPUT
/// </summary>
public List<LabelledColumn> OutputColumns { get; }
public SqlInsertStructure(
IMiddlewareContext context,
string entityName,
ISqlMetadataProvider sqlMetadataProvider,
IAuthorizationResolver authorizationResolver,
GQLFilterParser gQLFilterParser,
IDictionary<string, object?> mutationParams,
HttpContext httpContext,
bool isLinkingEntity = false
) : this(
entityName,
sqlMetadataProvider,
authorizationResolver,
gQLFilterParser,
GQLMutArgumentToDictParams(context, CreateMutationBuilder.INPUT_ARGUMENT_NAME, mutationParams),
httpContext,
isLinkingEntity)
{ }
public SqlInsertStructure(
string entityName,
ISqlMetadataProvider sqlMetadataProvider,
IAuthorizationResolver authorizationResolver,
GQLFilterParser gQLFilterParser,
IDictionary<string, object?> mutationParams,
HttpContext httpContext,
bool isLinkingEntity = false
)
: base(
metadataProvider: sqlMetadataProvider,
authorizationResolver: authorizationResolver,
gQLFilterParser: gQLFilterParser,
entityName: entityName,
httpContext: httpContext,
operationType: EntityActionOperation.Create,
isLinkingEntity: isLinkingEntity)
{
InsertColumns = new();
Values = new();
OutputColumns = GenerateOutputColumns();
foreach (KeyValuePair<string, object?> param in mutationParams)
{
MetadataProvider.TryGetBackingColumn(EntityName, param.Key, out string? backingColumn);
PopulateColumnsAndParams(backingColumn!, param.Value);
}
if (FieldsReferencedInDbPolicyForCreateAction.Count > 0)
{
// If the size of this set FieldsReferencedInDbPolicyForCreateAction is 0,
// it implies that all the fields referenced in the database policy for create action are being included in the insert statement, and we are good.
// However, if the size is non-zero, we throw a Forbidden request exception.
throw new DataApiBuilderException(
message: "One or more fields referenced by the database policy are not present in the request body.",
statusCode: HttpStatusCode.Forbidden,
subStatusCode: DataApiBuilderException.SubStatusCodes.AuthorizationCheckFailed);
}
}
/// <summary>
/// Populates the column name in Columns, creates parameter
/// and adds its value to Values.
/// </summary>
/// <param name="columnName">The name of the column.</param>
/// <param name="value">The value of the column.</param>
private void PopulateColumnsAndParams(string columnName, object? value)
{
InsertColumns.Add(columnName);
// As we add columns to the InsertColumns list for SqlInsertQueryStructure one by one,
// we remove the columns (if present) from the FieldsReferencedInDbPolicyForCreateAction.
// This is necessary because any field referenced in database policy but not present in insert statement would result in an exception.
FieldsReferencedInDbPolicyForCreateAction.Remove(columnName);
string paramName;
if (value is not null)
{
string stringValue = GetStringifiedValue(value);
paramName = MakeDbConnectionParam(
GetParamAsSystemType(stringValue, columnName, GetColumnSystemType(columnName)), columnName);
}
else
{
paramName = MakeDbConnectionParam(null, columnName);
}
Values.Add($"{paramName}");
}
/// <summary>
/// Get the definition of a column by name
/// </summary>
public ColumnDefinition GetColumnDefinition(string columnName)
{
return GetUnderlyingSourceDefinition().Columns[columnName];
}
}
}