Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
yorek committed Feb 29, 2024
1 parent b50dd2c commit b76c445
Show file tree
Hide file tree
Showing 18 changed files with 606 additions and 0 deletions.
1 change: 1 addition & 0 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
MSSQL="SERVER=.database.windows.net;DATABASE=dynamic-schema;UID=dynamic-schema-test-user;PWD=Super_Str0ng*P@ZZword!;"
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -396,3 +396,6 @@ FodyWeavers.xsd

# JetBrains Rider
*.sln.iml

# Custom
.env
30 changes: 30 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (web)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/bin/Debug/net8.0/azure-sql-db-dynamic-schema-ef.dll",
"args": [],
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"envFile": "${workspaceFolder}/.env"

},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"processId": "${command:pickProcess}"
}
]
}
42 changes: 42 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/azure-sql-db-dynamic-schema-ef.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/azure-sql-db-dynamic-schema-ef.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"${workspaceFolder}/azure-sql-db-dynamic-schema-ef.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
}
]
}
79 changes: 79 additions & 0 deletions Controllers/ToDoHybridController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using System.Data;
using System.Threading.Tasks;
using System.Linq;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Configuration;
using Microsoft.EntityFrameworkCore;

namespace Azure.SQLDB.Samples.DynamicSchema;

[ApiController]
[Route("todo/hybrid")]
public class ToDoHybridController(IConfiguration config, ILogger<ToDoHybridController> logger, ToDoContext context) : ControllerBase
{
private readonly ILogger<ToDoHybridController> _logger = logger;
private readonly IConfiguration _config = config;
private readonly ToDoContext _context = context;

[HttpGet]
public async Task<IEnumerable<ToDo>> Get()
{
var todos = await _context.ToDo.Take(10).ToListAsync();
var todoList = todos.Select(t => {
t.Url = HttpContext.Request.Scheme + "://" + HttpContext.Request.Host + $"/{RouteData.Values["controller"]}/{t.Id}";
return t;
}).ToList();
return todoList;
}

[HttpGet]
[Route("{id}")]
public async Task<ToDo> Get(int id)
{
var todo = await _context.ToDo.FindAsync(id);
todo.Url = HttpContext.Request.Scheme + "://" + HttpContext.Request.Host + $"/{RouteData.Values["controller"]}/{todo.Id}";
return todo;
}

[HttpPost]
public async Task<ToDo> Post([FromBody]ToDo todo)
{
await _context.ToDo.AddAsync(todo);
await _context.SaveChangesAsync();

return todo;
}

[HttpPatch]
[Route("{id}")]
public async Task<ToDo> Patch(int id, [FromBody]ToDo todo)
{
var existing = await _context.ToDo.FindAsync(id);
existing.Title = todo.Title;
existing.Completed = todo.Completed;
existing.Extensions = todo.Extensions;
_context.SaveChanges();
existing.Url = HttpContext.Request.Scheme + "://" + HttpContext.Request.Host + $"/{RouteData.Values["controller"]}/{existing.Id}";
return existing;
}

[HttpDelete]
[Route("{id}")]
public async Task<ToDo> Delete(int id)
{
var todo = await _context.ToDo.FindAsync(id);
_context.ToDo.Remove(todo);
_context.SaveChanges();
todo.Url = HttpContext.Request.Scheme + "://" + HttpContext.Request.Host + $"/{RouteData.Values["controller"]}/{todo.Id}";
return todo;
}

[HttpDelete]
public void Delete()
{
_context.ToDo.RemoveRange(_context.ToDo);
_context.SaveChanges();
}
}
16 changes: 16 additions & 0 deletions Database/00-create.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
create schema [web] authorization [dbo];
go

create user [dynamic-schema-test-user] with password = 'Super_Str0ng*P@ZZword!'
go

alter role db_datareader add member [dynamic-schema-test-user]
alter role db_datawriter add member [dynamic-schema-test-user]
go

create sequence dbo.[global_sequence]
as int
start with 1
increment by 1;
go

17 changes: 17 additions & 0 deletions Database/01-hybrid.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
drop table if exists [dbo].[todo_hybrid];
create table [dbo].[todo_hybrid]
(
[id] [int] not null,
[todo] [nvarchar](100) not null,
[completed] [tinyint] not null,
[extension] nvarchar(max) null,
)
go
alter table [dbo].[todo_hybrid] add constraint pk__todo_hybrid primary key clustered ([id] asc) with (optimize_for_sequential_key = on)
go
alter table [dbo].[todo_hybrid] add constraint df__todo_hybrid__id default (next value for [global_sequence]) for [id]
go
alter table [dbo].[todo_hybrid] add constraint df__todo_hybrid__completed default ((0)) for [completed]
go
alter table [dbo].[todo_hybrid] add constraint ck__todo_hybrid__other check (isjson([extension]) = 1)
go
2 changes: 2 additions & 0 deletions Database/cleanup.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
drop table if exists dbo.[todo_hybrid];
drop sequence if exists dbo.[global_sequence];
89 changes: 89 additions & 0 deletions Database/misc/01-sample-hybrid.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
delete from dbo.[todo_hybrid];
go

declare @t nvarchar(max) = '{
"title": "test",
"completed": 0,
"extension": {
"order": 1,
"createdOn": "2020-10-25 10:00:00"
}
}';

insert into
dbo.[todo_hybrid] (todo, completed, [extension])
select
title,
completed,
[extension]
from
openjson(@t) with
(
title nvarchar(100) '$.title',
completed bit '$.completed',
[extension] nvarchar(max) '$.extension' as json
)
go

declare @t2 nvarchar(max) = '{
"title": "another test",
"completed": 1,
"extension": {
"order": 2,
"createdOn": "2020-10-24 22:00:00"
}
}';

insert into
dbo.[todo_hybrid] (todo, completed, [extension])
select
title,
completed,
[extension]
from
openjson(@t2) with
(
title nvarchar(100) '$.title',
completed bit '$.completed',
[extension] nvarchar(max) '$.extension' as json
)
go

select * from dbo.[todo_hybrid]
go

/*
GET
*/
exec web.get_todo_hybrid '{"id": 50}'
go

/*
POST
*/
declare @j nvarchar(max) = '{
"title": "hello again!",
"completed": 1,
"extension": {
"order": 2,
"createdOn": "2020-10-28 10:00:00"
}
}';

exec web.post_todo_hybrid @j

/*
PATCH
*/
declare @j nvarchar(max) = '{
"id": 52,
"todo": {
"title": "hello again, with patches!",
"extension": {
"order": 42
}
}
}';

exec web.patch_todo_hybrid @j
go
29 changes: 29 additions & 0 deletions Database/misc/99b-add-column-test.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
drop table if exists dbo.todo_test;
go

select * into dbo.todo_test from dbo.todo_sample;
go

with cte as
(
select top (1000000) n = row_number() over (order by a.[object_id]) from sys.[all_columns] a, sys.[all_columns] b
)
insert into
dbo.[todo_test]
select
n as id,
'Todo Test ' + cast(n as nvarchar(10)) as todo,
0 as completed,
n as [order]
from
cte
;

select top (10) * from dbo.[todo_test];
go

alter table dbo.[todo_test]
add createdOn datetime2 null
go


26 changes: 26 additions & 0 deletions DbContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.EventSource;

namespace Azure.SQLDB.Samples.DynamicSchema;

public class ToDoContext(DbContextOptions<ToDoContext> options) : DbContext(options)
{
public DbSet<ToDo> ToDo { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<ToDo>(
eb => {
eb.OwnsOne(todo => todo.Extensions, builder => { builder.ToJson("extension"); });
}
);
}

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.LogTo(Console.WriteLine, (_, level) => level == LogLevel.Information)
.EnableSensitiveDataLogging();

}
Loading

0 comments on commit b76c445

Please sign in to comment.