Skip to content

Commit b9ca840

Browse files
committed
Fixed Odata output and removed .SQL namespace
Classes from SqlServerRestApi.SQL are moved to base SqlServerRestApi. Added "value" wrapper around OData response.
1 parent 50be933 commit b9ca840

10 files changed

+93
-49
lines changed

Controller/HttpRequestMessageExtension.cs

+3-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// Licensed under the BSD License. See LICENSE.txt in the project root for license information.
33

44
using Belgrade.SqlClient;
5-
using SqlServerRestApi.SQL;
65
using System.Data.SqlClient;
76
using System.IO;
87
using System.Net;
@@ -22,7 +21,7 @@ public static async Task<HttpResponseMessage> CreateODataResponse(
2221
var querySpec = OData.UriParser.Parse(tableSpec, req);
2322
var sql = QueryBuilder.Build(querySpec, tableSpec);
2423
if (!querySpec.count)
25-
sql = sql.AsJson();
24+
sql = sql.AsJson("value");
2625
return await CreateSqlResponse(req, sqlQuery, sql);
2726
}
2827

@@ -47,7 +46,7 @@ public static async Task<HttpResponseMessage> CreateODataResponse(
4746
IQueryMapper mapper)
4847
{
4948
var querySpec = OData.UriParser.Parse(tableSpec, req);
50-
var sql = QueryBuilder.Build(querySpec, tableSpec).AsJson();
49+
var sql = QueryBuilder.Build(querySpec, tableSpec).AsJson("value");
5150
return await CreateSqlResponse(req, mapper, sql);
5251
}
5352

@@ -64,6 +63,5 @@ SqlCommand sql
6463

6564
return new HttpResponseMessage() { Content = new StringContent(body), StatusCode = httpStatus };
6665
}
67-
6866
}
69-
}
67+
}

Controller/RestApiController.cs

+49-19
Original file line numberDiff line numberDiff line change
@@ -2,66 +2,98 @@
22
// Licensed under the BSD License. See LICENSE.txt in the project root for license information.
33

44
using Belgrade.SqlClient;
5-
using SqlServerRestApi.SQL;
65
using System;
76
using System.Data.SqlClient;
87
using System.IO;
98
using System.Threading.Tasks;
109

1110
namespace SqlServerRestApi
1211
{
13-
public class ODataHandler
12+
public class RequestHandler
1413
{
15-
private SqlCommand cmd;
16-
private IQueryPipe pipe;
17-
private Stream stream;
14+
protected SqlCommand cmd;
15+
protected IQueryPipe pipe;
16+
protected Stream stream;
1817

19-
internal ODataHandler(SqlCommand cmd, IQueryPipe pipe, Stream stream)
18+
internal RequestHandler(SqlCommand cmd, IQueryPipe pipe, Stream stream)
2019
{
2120
this.cmd = cmd;
2221
this.pipe = pipe;
2322
this.stream = stream;
2423
}
25-
public ODataHandler OnError(Action<Exception> onErrorHandler)
24+
25+
public virtual RequestHandler OnError(Action<Exception> onErrorHandler)
2626
{
2727
pipe.OnError(onErrorHandler);
2828
return this;
2929
}
3030

31-
public async Task Process()
31+
public virtual async Task Process()
32+
{
33+
await pipe.Stream(cmd, stream, "[]");
34+
}
35+
}
36+
37+
public class JQueryDataTablesHandler : RequestHandler
38+
{
39+
private string draw;
40+
private int length;
41+
private int start;
42+
43+
internal JQueryDataTablesHandler(SqlCommand cmd, string draw, int start, int length, IQueryPipe pipe, Stream stream): base(cmd, pipe, stream)
44+
{
45+
this.draw = draw;
46+
this.start = start;
47+
this.length = length;
48+
}
49+
50+
public override async Task Process()
3251
{
52+
var header = System.Text.Encoding.UTF8.GetBytes(
53+
$@"{{
54+
""draw"":""{draw}"",
55+
""recordsTotal"":""{start + length + 1}"",
56+
""recordsFiltered"":""{start + length + 1}"",
57+
""data"":");
58+
await stream.WriteAsync(header, 0, header.Length);
3359
await pipe.Stream(cmd, stream, "[]");
60+
await stream.WriteAsync(System.Text.Encoding.UTF8.GetBytes("}"), 0, 1);
3461
}
62+
}
3563

64+
public class ODataHandler: RequestHandler
65+
{
66+
internal ODataHandler(SqlCommand cmd, IQueryPipe pipe, Stream stream): base(cmd, pipe, stream)
67+
{
68+
}
3669
}
3770

3871
public static class RestApiControllerExtensions
3972
{
40-
41-
public static ODataHandler ODataHandler(
73+
public static RequestHandler ODataHandler(
4274
this Microsoft.AspNetCore.Mvc.Controller ctrl,
4375
TableSpec tableSpec,
4476
IQueryPipe sqlQuery)
4577
{
4678
var querySpec = SqlServerRestApi.OData.UriParser.Parse(tableSpec, ctrl.Request);
47-
var sql = SqlServerRestApi.SQL.QueryBuilder.Build(querySpec, tableSpec);
79+
var sql = SqlServerRestApi.QueryBuilder.Build(querySpec, tableSpec);
4880
if (!querySpec.count)
49-
sql = sql.AsJson();
81+
sql = sql.AsJson("value");
5082
return new ODataHandler(sql, sqlQuery, ctrl.Response.Body);
5183
}
5284

53-
public static async Task ProcessODataRequest(
85+
public static RequestHandler JQueryDataTablesHandler(
5486
this Microsoft.AspNetCore.Mvc.Controller ctrl,
5587
TableSpec tableSpec,
5688
IQueryPipe sqlQuery)
5789
{
58-
var querySpec = OData.UriParser.Parse(tableSpec, ctrl.Request);
59-
var sql = QueryBuilder.Build(querySpec, tableSpec);
90+
var querySpec = SqlServerRestApi.JQueryDataTable.UriParser.Parse(tableSpec, ctrl.Request);
91+
var sql = SqlServerRestApi.QueryBuilder.Build(querySpec, tableSpec);
6092
if (!querySpec.count)
6193
sql = sql.AsJson();
62-
await sqlQuery.Stream(sql, ctrl.Response.Body, "[]");
94+
return new JQueryDataTablesHandler(sql, ctrl.Request.Query["draw"].ToString(), Convert.ToInt32(ctrl.Request.Query["start"]), Convert.ToInt32(ctrl.Request.Query["length"]), sqlQuery, ctrl.Response.Body);
6395
}
64-
96+
6597
public static async Task ProcessJQueryDataTablesRequest(
6698
this Microsoft.AspNetCore.Mvc.Controller ctrl,
6799
TableSpec tableSpec,
@@ -78,11 +110,9 @@ public static async Task ProcessJQueryDataTablesRequest(
78110
""recordsFiltered"":""{start + length + 1}"",
79111
""data"":");
80112
await ctrl.Response.Body.WriteAsync(header, 0, header.Length);
81-
82113
var querySpec = JQueryDataTable.UriParser.Parse(tableSpec, Request);
83114
var sql = QueryBuilder.Build(querySpec, tableSpec).AsJson();
84115
await sqlQuery.Stream(sql, ctrl.Response.Body, "[]");
85-
86116
await ctrl.Response.Body.WriteAsync(System.Text.Encoding.UTF8.GetBytes("}"), 0, 1);
87117
}
88118
}

JQueryDataTables/UriParser.cs

-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// Licensed under the BSD License. See LICENSE.txt in the project root for license information.
33

44
using Microsoft.AspNetCore.Http;
5-
using SqlServerRestApi.SQL;
65
using System;
76
using System.Collections;
87

OData/FilterTranslator.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,12 @@ public const int
4040
};
4141

4242

43-
SqlServerRestApi.SQL.TableSpec tableSpec;
44-
SqlServerRestApi.SQL.QuerySpec querySpec;
43+
SqlServerRestApi.TableSpec tableSpec;
44+
SqlServerRestApi.QuerySpec querySpec;
4545
int i = 0;
4646
public FilterTranslator(ICharStream input,
47-
SqlServerRestApi.SQL.TableSpec tableSpec,
48-
SqlServerRestApi.SQL.QuerySpec querySpec): base(input)
47+
SqlServerRestApi.TableSpec tableSpec,
48+
SqlServerRestApi.QuerySpec querySpec): base(input)
4949
{
5050
this.tableSpec = tableSpec;
5151
this.querySpec = querySpec;

OData/FilterTranslator.g4

+4-4
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
lexer grammar FilterTranslator;
44

55
@lexer::members {
6-
SqlServerRestApi.SQL.TableSpec tableSpec;
7-
SqlServerRestApi.SQL.QuerySpec querySpec;
6+
SqlServerRestApi.TableSpec tableSpec;
7+
SqlServerRestApi.QuerySpec querySpec;
88
int i = 0;
99
public FilterTranslator(ICharStream input,
10-
SqlServerRestApi.SQL.TableSpec tableSpec,
11-
SqlServerRestApi.SQL.QuerySpec querySpec): base(input)
10+
SqlServerRestApi.TableSpec tableSpec,
11+
SqlServerRestApi.QuerySpec querySpec): base(input)
1212
{
1313
this.tableSpec = tableSpec;
1414
this.querySpec = querySpec;

OData/UriParser.cs

-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
using Antlr4.Runtime;
55
using Microsoft.AspNetCore.Http;
6-
using SqlServerRestApi.SQL;
76
using System;
87
using System.Collections;
98
using System.Net.Http;

SQL/QueryBuilder.cs

+1-13
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
using System.Data.SqlClient;
66
using System.Text;
77

8-
namespace SqlServerRestApi.SQL
8+
namespace SqlServerRestApi
99
{
1010
public static class QueryBuilder
1111
{
@@ -192,17 +192,5 @@ private static void BuildOffsetFetchClause(QuerySpec spec, StringBuilder sql)
192192
sql.AppendFormat(" FETCH NEXT {0} ROWS ONLY ", spec.top);
193193

194194
}
195-
196-
public static SqlCommand AsJson(this SqlCommand cmd)
197-
{
198-
cmd.CommandText += " FOR JSON PATH";
199-
return cmd;
200-
}
201-
202-
public static SqlCommand AsSingleJson(this SqlCommand cmd)
203-
{
204-
cmd.CommandText += " FOR JSON PATH, WITHOUT_ARRAY_WRAPPER";
205-
return cmd;
206-
}
207195
}
208196
}

SQL/QuerySpec.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
using System.Collections.Generic;
66
using System.Data.SqlClient;
77

8-
namespace SqlServerRestApi.SQL
8+
namespace SqlServerRestApi
99
{
1010
public class QuerySpec
1111
{

SQL/SqlCommandExtensions.cs

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright (c) Jovan Popovic. All Rights Reserved.
2+
// Licensed under the BSD License. See LICENSE.txt in the project root for license information.
3+
4+
using System.Collections;
5+
using System.Data.SqlClient;
6+
using System.Text;
7+
8+
namespace SqlServerRestApi
9+
{
10+
public static class SqlCommandExtensions
11+
{
12+
public static SqlCommand AsJson(this SqlCommand cmd)
13+
{
14+
cmd.CommandText += " FOR JSON PATH";
15+
return cmd;
16+
}
17+
18+
public static SqlCommand AsJson(this SqlCommand cmd, string root)
19+
{
20+
cmd.CommandText += " FOR JSON PATH, ROOT('"+root+"')";
21+
return cmd;
22+
}
23+
24+
public static SqlCommand AsSingleJson(this SqlCommand cmd)
25+
{
26+
cmd.CommandText += " FOR JSON PATH, WITHOUT_ARRAY_WRAPPER";
27+
return cmd;
28+
}
29+
}
30+
}

SQL/TableSpec.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
using System.Collections.Generic;
66
using System.Linq;
77

8-
namespace SqlServerRestApi.SQL
8+
namespace SqlServerRestApi
99
{
1010
public class TableSpec
1111
{

0 commit comments

Comments
 (0)