Skip to content

Commit 8814df5

Browse files
committed
Refactoring
Builders and PArsers converted to static methods.
1 parent 3424728 commit 8814df5

File tree

5 files changed

+59
-30
lines changed

5 files changed

+59
-30
lines changed

Controller/RestApiController.cs

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using Belgrade.SqlClient;
2+
using SqlServerRestApi.SQL;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using System.Threading.Tasks;
7+
8+
namespace SqlServerRestApi.Controller
9+
{
10+
public class RestApiController : Microsoft.AspNetCore.Mvc.Controller
11+
{
12+
IQueryPipe sqlQuery = null;
13+
TableSpec tableSpec = null;
14+
15+
public RestApiController(TableSpec tableSpec, IQueryPipe sqlQueryService)
16+
{
17+
this.sqlQuery = sqlQueryService;
18+
this.tableSpec = tableSpec;
19+
}
20+
21+
public async Task ProcessODataRequest(string defaultOutput)
22+
{
23+
var querySpec = OData.UriParser.Parse(this.tableSpec, this.Request);
24+
var sql = QueryBuilder.Build(querySpec, tableSpec).AsJson();
25+
await sqlQuery.Stream(sql, Response.Body, defaultOutput);
26+
}
27+
28+
29+
public async Task ProcessJQueryDataTablesRequest(string defaultOutput)
30+
{
31+
var querySpec = JQueryDataTable.UriParser.Parse(this.tableSpec, this.Request);
32+
var sql = QueryBuilder.Build(querySpec, tableSpec).AsJson();
33+
await sqlQuery.Stream(sql, Response.Body, defaultOutput);
34+
}
35+
}
36+
}

JQueryDataTables/UriParser.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace SqlServerRestApi.JQueryDataTable
77
{
88
public class UriParser
99
{
10-
public QuerySpec Parse (TableSpec tabSpec, HttpRequest Request)
10+
public static QuerySpec Parse (TableSpec tabSpec, HttpRequest Request)
1111
{
1212
var spec = new QuerySpec();
1313
spec.skip = Convert.ToInt32(Request.Query["start"]);

OData/UriParser.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace SqlServerRestApi.OData
1010

1111
public class UriParser
1212
{
13-
public QuerySpec Parse (TableSpec tabSpec, HttpRequest Request)
13+
public static QuerySpec Parse (TableSpec tabSpec, HttpRequest Request)
1414
{
1515
var spec = new QuerySpec();
1616
spec.skip = Convert.ToInt32(Request.Query["$skip"]);

README.md

+8-12
Original file line numberDiff line numberDiff line change
@@ -67,34 +67,30 @@ Note that FOR JSON clause is used in SQL query. FOR JSON clause will generate JS
6767

6868
## Implement OData service
6969

70-
To implement OData Service, you would need to add the following fields in your controller:
71-
- TableSpec hat describes the structure of the table that will be queried (name and columns)
72-
- UriParser that will parse OData Http request and extract information from $select, $filter, $orderby, $top, and $skip parameters
73-
- QueryBuilder that will create T-SQL query that will be executed.
74-
75-
Example is shown in the following code:
70+
To implement OData Service, you would need to add the TableSpec object that describes the structure of the table that will be queried (name and columns). An example is shown in the following code:
7671
```
7772
IQueryPipe sqlQuery = null;
7873
7974
TableSpec tableSpec = new TableSpec("dbo.People", "name,surname,address,town");
80-
UriParser uriParser = new UriParser();
81-
QueryBuilder queryBuilder = new QueryBuilder();
82-
75+
8376
public PeopleController(IQueryPipe sqlQueryService)
8477
{
8578
this.sqlQuery = sqlQueryService;
8679
}
8780
```
8881

89-
Now you need to create async method that will serve OData requests. First, you need to parse Request parameters using UriParser in order to extract QuerySpec. Then you need to use QueryBuilder to create SQL query using the QuerySpec. Then you need to provide sql query to QueryPipe that will stream results to client using Response.Body:
82+
Now you need to create async method that will serve OData requests with following classes:
83+
- UriParser that will parse OData Http request and extract information from $select, $filter, $orderby, $top, and $skip parameters
84+
- QueryBuilder that will create T-SQL query that will be executed.
85+
First, you need to parse Request parameters using UriParser in order to extract the definition of query (QuerySpec object). Then you need to use QueryBuilder to create SQL query using the QuerySpec. Then you need to provide sql query to QueryPipe that will stream results to client using Response.Body:
9086

9187
```
9288
// GET api/People
9389
[HttpGet]
9490
public async Task Get()
9591
{
96-
var querySpec = uriParser.Parse(tableSpec, this.Request);
97-
var sql = queryBuilder.Build(querySpec, tableSpec).AsJson();
92+
var querySpec = OData.UriParser.Parse(tableSpec, this.Request);
93+
var sql = QueryBuilder.Build(querySpec, tableSpec).AsJson();
9894
await sqlQuery.Stream(sql, Response.Body, "[]");
9995
}
10096
```

SQL/QueryBuilder.cs

+13-16
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,24 @@
44

55
namespace SqlServerRestApi.SQL
66
{
7-
internal class QueryBuilder
7+
public static class QueryBuilder
88
{
9-
private StringBuilder sql = new StringBuilder();
10-
internal SqlCommand Build(QuerySpec spec, TableSpec table)
9+
10+
public static SqlCommand Build(QuerySpec spec, TableSpec table)
1111
{
1212
SqlCommand res = new SqlCommand();
13-
14-
BuildSelectClause(spec, table);
15-
BuildWherePredicate(spec, res);
16-
BuildOrderByClause(spec);
17-
BuildOffsetFetchClause(spec);
13+
StringBuilder sql = new StringBuilder();
14+
15+
BuildSelectClause(spec, table, sql);
16+
BuildWherePredicate(spec, res, sql);
17+
BuildOrderByClause(spec, sql);
18+
BuildOffsetFetchClause(spec, sql);
1819

1920
res.CommandText = sql.ToString();
2021
return res;
2122
}
2223

23-
private void BuildSelectClause(QuerySpec spec, TableSpec table)
24+
private static void BuildSelectClause(QuerySpec spec, TableSpec table, StringBuilder sql)
2425
{
2526
sql.Append("select ");
2627

@@ -39,7 +40,7 @@ private void BuildSelectClause(QuerySpec spec, TableSpec table)
3940
/// </summary>
4041
/// <param name="spec"></param>
4142
/// <param name="res"></param>
42-
private void BuildWherePredicate(QuerySpec spec, SqlCommand res)
43+
private static void BuildWherePredicate(QuerySpec spec, SqlCommand res, StringBuilder sql)
4344
{
4445
if (spec.predicate != null)
4546
{
@@ -111,7 +112,7 @@ private void BuildWherePredicate(QuerySpec spec, SqlCommand res)
111112
}
112113
}
113114

114-
private void BuildOrderByClause(QuerySpec spec)
115+
private static void BuildOrderByClause(QuerySpec spec, StringBuilder sql)
115116
{
116117
if (spec.order != null && spec.order.Count > 0)
117118
{
@@ -131,7 +132,7 @@ private void BuildOrderByClause(QuerySpec spec)
131132
}
132133
}
133134

134-
private void BuildOffsetFetchClause(QuerySpec spec)
135+
private static void BuildOffsetFetchClause(QuerySpec spec, StringBuilder sql)
135136
{
136137
if (spec.top == 0 && spec.skip == 0)
137138
return; // Nothing to generate
@@ -150,10 +151,6 @@ private void BuildOffsetFetchClause(QuerySpec spec)
150151

151152
}
152153

153-
}
154-
155-
public static class QueryBuilderExtension
156-
{
157154
public static SqlCommand AsJson(this SqlCommand cmd)
158155
{
159156
cmd.CommandText += " for json path";

0 commit comments

Comments
 (0)