From 19eb121cc3614ee253bc79fbb86e8a4caa2d4724 Mon Sep 17 00:00:00 2001 From: soginga Date: Tue, 22 Jan 2019 14:27:58 +0200 Subject: [PATCH 1/5] added migration --- data/createdatabase.sql | 76 +++++++++---------- data/createuser.sql | 12 +-- .../20190122084410_InitialCreate.Designer.cs | 57 ++++++++++++++ .../20190122084410_InitialCreate.cs | 40 ++++++++++ .../TimesheetContextModelSnapshot.cs | 55 ++++++++++++++ src/MyTimesheet/MyTimesheet/Startup.cs | 2 +- 6 files changed, 197 insertions(+), 45 deletions(-) create mode 100644 src/MyTimesheet/MyTimesheet/Migrations/20190122084410_InitialCreate.Designer.cs create mode 100644 src/MyTimesheet/MyTimesheet/Migrations/20190122084410_InitialCreate.cs create mode 100644 src/MyTimesheet/MyTimesheet/Migrations/TimesheetContextModelSnapshot.cs diff --git a/data/createdatabase.sql b/data/createdatabase.sql index 41b5a17..510c70f 100644 --- a/data/createdatabase.sql +++ b/data/createdatabase.sql @@ -1,115 +1,115 @@ USE [master] GO -/****** Object: Database [sql101.firstname.lastname] Script Date: 1/21/2019 9:11:50 PM ******/ -CREATE DATABASE [sql101.firstname.lastname] +/****** Object: Database [sql101.simtembile.soginga] Script Date: 1/21/2019 9:11:50 PM ******/ +CREATE DATABASE [sql101.simtembile.soginga] CONTAINMENT = NONE ON PRIMARY -( NAME = N'sql101.firstname.lastname', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\sql101.firstname.lastname.mdf' , SIZE = 8192KB , MAXSIZE = UNLIMITED, FILEGROWTH = 65536KB ) +( NAME = N'sql101.simtembile.soginga', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\sql101.simtembile.soginga.mdf' , SIZE = 8192KB , MAXSIZE = UNLIMITED, FILEGROWTH = 65536KB ) LOG ON -( NAME = N'sql101.firstname.lastname_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\sql101.firstname.lastname_log.ldf' , SIZE = 8192KB , MAXSIZE = 2048GB , FILEGROWTH = 65536KB ) +( NAME = N'sql101.simtembile.soginga_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\sql101.simtembile.soginga_log.ldf' , SIZE = 8192KB , MAXSIZE = 2048GB , FILEGROWTH = 65536KB ) GO -ALTER DATABASE [sql101.firstname.lastname] SET COMPATIBILITY_LEVEL = 130 +ALTER DATABASE [sql101.simtembile.soginga] SET COMPATIBILITY_LEVEL = 130 GO IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled')) begin -EXEC [sql101.firstname.lastname].[dbo].[sp_fulltext_database] @action = 'enable' +EXEC [sql101.simtembile.soginga].[dbo].[sp_fulltext_database] @action = 'enable' end GO -ALTER DATABASE [sql101.firstname.lastname] SET ANSI_NULL_DEFAULT OFF +ALTER DATABASE [sql101.simtembile.soginga] SET ANSI_NULL_DEFAULT OFF GO -ALTER DATABASE [sql101.firstname.lastname] SET ANSI_NULLS OFF +ALTER DATABASE [sql101.simtembile.soginga] SET ANSI_NULLS OFF GO -ALTER DATABASE [sql101.firstname.lastname] SET ANSI_PADDING OFF +ALTER DATABASE [sql101.simtembile.soginga] SET ANSI_PADDING OFF GO -ALTER DATABASE [sql101.firstname.lastname] SET ANSI_WARNINGS OFF +ALTER DATABASE [sql101.simtembile.soginga] SET ANSI_WARNINGS OFF GO -ALTER DATABASE [sql101.firstname.lastname] SET ARITHABORT OFF +ALTER DATABASE [sql101.simtembile.soginga] SET ARITHABORT OFF GO -ALTER DATABASE [sql101.firstname.lastname] SET AUTO_CLOSE OFF +ALTER DATABASE [sql101.simtembile.soginga] SET AUTO_CLOSE OFF GO -ALTER DATABASE [sql101.firstname.lastname] SET AUTO_SHRINK OFF +ALTER DATABASE [sql101.simtembile.soginga] SET AUTO_SHRINK OFF GO -ALTER DATABASE [sql101.firstname.lastname] SET AUTO_UPDATE_STATISTICS ON +ALTER DATABASE [sql101.simtembile.soginga] SET AUTO_UPDATE_STATISTICS ON GO -ALTER DATABASE [sql101.firstname.lastname] SET CURSOR_CLOSE_ON_COMMIT OFF +ALTER DATABASE [sql101.simtembile.soginga] SET CURSOR_CLOSE_ON_COMMIT OFF GO -ALTER DATABASE [sql101.firstname.lastname] SET CURSOR_DEFAULT GLOBAL +ALTER DATABASE [sql101.simtembile.soginga] SET CURSOR_DEFAULT GLOBAL GO -ALTER DATABASE [sql101.firstname.lastname] SET CONCAT_NULL_YIELDS_NULL OFF +ALTER DATABASE [sql101.simtembile.soginga] SET CONCAT_NULL_YIELDS_NULL OFF GO -ALTER DATABASE [sql101.firstname.lastname] SET NUMERIC_ROUNDABORT OFF +ALTER DATABASE [sql101.simtembile.soginga] SET NUMERIC_ROUNDABORT OFF GO -ALTER DATABASE [sql101.firstname.lastname] SET QUOTED_IDENTIFIER OFF +ALTER DATABASE [sql101.simtembile.soginga] SET QUOTED_IDENTIFIER OFF GO -ALTER DATABASE [sql101.firstname.lastname] SET RECURSIVE_TRIGGERS OFF +ALTER DATABASE [sql101.simtembile.soginga] SET RECURSIVE_TRIGGERS OFF GO -ALTER DATABASE [sql101.firstname.lastname] SET DISABLE_BROKER +ALTER DATABASE [sql101.simtembile.soginga] SET DISABLE_BROKER GO -ALTER DATABASE [sql101.firstname.lastname] SET AUTO_UPDATE_STATISTICS_ASYNC OFF +ALTER DATABASE [sql101.simtembile.soginga] SET AUTO_UPDATE_STATISTICS_ASYNC OFF GO -ALTER DATABASE [sql101.firstname.lastname] SET DATE_CORRELATION_OPTIMIZATION OFF +ALTER DATABASE [sql101.simtembile.soginga] SET DATE_CORRELATION_OPTIMIZATION OFF GO -ALTER DATABASE [sql101.firstname.lastname] SET TRUSTWORTHY OFF +ALTER DATABASE [sql101.simtembile.soginga] SET TRUSTWORTHY OFF GO -ALTER DATABASE [sql101.firstname.lastname] SET ALLOW_SNAPSHOT_ISOLATION OFF +ALTER DATABASE [sql101.simtembile.soginga] SET ALLOW_SNAPSHOT_ISOLATION OFF GO -ALTER DATABASE [sql101.firstname.lastname] SET PARAMETERIZATION SIMPLE +ALTER DATABASE [sql101.simtembile.soginga] SET PARAMETERIZATION SIMPLE GO -ALTER DATABASE [sql101.firstname.lastname] SET READ_COMMITTED_SNAPSHOT OFF +ALTER DATABASE [sql101.simtembile.soginga] SET READ_COMMITTED_SNAPSHOT OFF GO -ALTER DATABASE [sql101.firstname.lastname] SET HONOR_BROKER_PRIORITY OFF +ALTER DATABASE [sql101.simtembile.soginga] SET HONOR_BROKER_PRIORITY OFF GO -ALTER DATABASE [sql101.firstname.lastname] SET RECOVERY FULL +ALTER DATABASE [sql101.simtembile.soginga] SET RECOVERY FULL GO -ALTER DATABASE [sql101.firstname.lastname] SET MULTI_USER +ALTER DATABASE [sql101.simtembile.soginga] SET MULTI_USER GO -ALTER DATABASE [sql101.firstname.lastname] SET PAGE_VERIFY CHECKSUM +ALTER DATABASE [sql101.simtembile.soginga] SET PAGE_VERIFY CHECKSUM GO -ALTER DATABASE [sql101.firstname.lastname] SET DB_CHAINING OFF +ALTER DATABASE [sql101.simtembile.soginga] SET DB_CHAINING OFF GO -ALTER DATABASE [sql101.firstname.lastname] SET FILESTREAM( NON_TRANSACTED_ACCESS = OFF ) +ALTER DATABASE [sql101.simtembile.soginga] SET FILESTREAM( NON_TRANSACTED_ACCESS = OFF ) GO -ALTER DATABASE [sql101.firstname.lastname] SET TARGET_RECOVERY_TIME = 60 SECONDS +ALTER DATABASE [sql101.simtembile.soginga] SET TARGET_RECOVERY_TIME = 60 SECONDS GO -ALTER DATABASE [sql101.firstname.lastname] SET DELAYED_DURABILITY = DISABLED +ALTER DATABASE [sql101.simtembile.soginga] SET DELAYED_DURABILITY = DISABLED GO -ALTER DATABASE [sql101.firstname.lastname] SET QUERY_STORE = OFF +ALTER DATABASE [sql101.simtembile.soginga] SET QUERY_STORE = OFF GO -USE [sql101.firstname.lastname] +USE [sql101.simtembile.soginga] GO ALTER DATABASE SCOPED CONFIGURATION SET LEGACY_CARDINALITY_ESTIMATION = OFF; @@ -124,7 +124,7 @@ GO ALTER DATABASE SCOPED CONFIGURATION SET QUERY_OPTIMIZER_HOTFIXES = OFF; GO -ALTER DATABASE [sql101.firstname.lastname] SET READ_WRITE +ALTER DATABASE [sql101.simtembile.soginga] SET READ_WRITE GO diff --git a/data/createuser.sql b/data/createuser.sql index bcf3038..a438325 100644 --- a/data/createuser.sql +++ b/data/createuser.sql @@ -1,18 +1,18 @@ USE [master] GO -CREATE LOGIN [firstnamelastname] WITH PASSWORD=N'rabbit123!@#' MUST_CHANGE, DEFAULT_DATABASE=[sql101.firstname.lastname], CHECK_EXPIRATION=ON, CHECK_POLICY=ON +CREATE LOGIN [simtembilesoginga] WITH PASSWORD=N'rabbit123!@#' MUST_CHANGE, DEFAULT_DATABASE=[sql101.simtembile.soginga], CHECK_EXPIRATION=ON, CHECK_POLICY=ON GO -use [sql101.firstname.lastname] +use [sql101.simtembile.soginga] GO use [master] GO -USE [sql101.firstname.lastname] +USE [sql101.simtembile.soginga] GO -CREATE USER [firstnamelastname] FOR LOGIN [firstnamelastname] +CREATE USER [simtembilesoginga] FOR LOGIN [simtembilesoginga] GO -USE [sql101.firstname.lastname] +USE [sql101.simtembile.soginga] GO -ALTER ROLE [db_owner] ADD MEMBER [firstnamelastname] +ALTER ROLE [db_owner] ADD MEMBER [simtembilesoginga] GO diff --git a/src/MyTimesheet/MyTimesheet/Migrations/20190122084410_InitialCreate.Designer.cs b/src/MyTimesheet/MyTimesheet/Migrations/20190122084410_InitialCreate.Designer.cs new file mode 100644 index 0000000..dad7983 --- /dev/null +++ b/src/MyTimesheet/MyTimesheet/Migrations/20190122084410_InitialCreate.Designer.cs @@ -0,0 +1,57 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using MyTimesheet.Models; + +namespace MyTimesheet.Migrations +{ + [DbContext(typeof(TimesheetContext))] + [Migration("20190122084410_InitialCreate")] + partial class InitialCreate + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "2.2.1-servicing-10028") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("MyTimesheet.Models.TimesheetEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Billable"); + + b.Property("Client"); + + b.Property("Date"); + + b.Property("Description"); + + b.Property("Duration"); + + b.Property("Name"); + + b.Property("Project"); + + b.Property("Surname"); + + b.Property("TimeEnd"); + + b.Property("TimeStart"); + + b.HasKey("Id"); + + b.ToTable("Entries"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/MyTimesheet/MyTimesheet/Migrations/20190122084410_InitialCreate.cs b/src/MyTimesheet/MyTimesheet/Migrations/20190122084410_InitialCreate.cs new file mode 100644 index 0000000..f49fcb6 --- /dev/null +++ b/src/MyTimesheet/MyTimesheet/Migrations/20190122084410_InitialCreate.cs @@ -0,0 +1,40 @@ +using System; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace MyTimesheet.Migrations +{ + public partial class InitialCreate : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Entries", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), + Name = table.Column(nullable: true), + Surname = table.Column(nullable: true), + Client = table.Column(nullable: true), + Project = table.Column(nullable: true), + Date = table.Column(nullable: false), + TimeStart = table.Column(nullable: false), + TimeEnd = table.Column(nullable: false), + Duration = table.Column(nullable: false), + Description = table.Column(nullable: true), + Billable = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Entries", x => x.Id); + }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Entries"); + } + } +} diff --git a/src/MyTimesheet/MyTimesheet/Migrations/TimesheetContextModelSnapshot.cs b/src/MyTimesheet/MyTimesheet/Migrations/TimesheetContextModelSnapshot.cs new file mode 100644 index 0000000..6404921 --- /dev/null +++ b/src/MyTimesheet/MyTimesheet/Migrations/TimesheetContextModelSnapshot.cs @@ -0,0 +1,55 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using MyTimesheet.Models; + +namespace MyTimesheet.Migrations +{ + [DbContext(typeof(TimesheetContext))] + partial class TimesheetContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "2.2.1-servicing-10028") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("MyTimesheet.Models.TimesheetEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Billable"); + + b.Property("Client"); + + b.Property("Date"); + + b.Property("Description"); + + b.Property("Duration"); + + b.Property("Name"); + + b.Property("Project"); + + b.Property("Surname"); + + b.Property("TimeEnd"); + + b.Property("TimeStart"); + + b.HasKey("Id"); + + b.ToTable("Entries"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/MyTimesheet/MyTimesheet/Startup.cs b/src/MyTimesheet/MyTimesheet/Startup.cs index e81072d..6bb5667 100644 --- a/src/MyTimesheet/MyTimesheet/Startup.cs +++ b/src/MyTimesheet/MyTimesheet/Startup.cs @@ -35,7 +35,7 @@ public void ConfigureServices(IServiceCollection services) c.SwaggerDoc("v1", new Info { Title = "My Timesheet API", Version = "v1" }); }); - var connection = @"Server=sql101labs1793591179000.westeurope.cloudapp.azure.com;Database=sql101.#NAME.SURNAME;User Id=myUsername;Password=myPassword;"; + var connection = @"Server=sql101labs1793591179000.westeurope.cloudapp.azure.com;Database=sql101.simtembile.soginga;User Id=simtembilesoginga;Password=Printwork31320;"; services.AddDbContext (options => options.UseSqlServer(connection)); } From 0c1c5f70f09c844b0d4b067f5afe471b5c74d2d6 Mon Sep 17 00:00:00 2001 From: soginga Date: Sat, 26 Jan 2019 09:57:15 +0200 Subject: [PATCH 2/5] configure Redis Caching --- src/MyTimesheet/MyTimesheet/CasheSecrets.config | 3 +++ src/MyTimesheet/MyTimesheet/Startup.cs | 5 +++-- src/MyTimesheet/MyTimesheet/appsettings.json | 3 ++- 3 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 src/MyTimesheet/MyTimesheet/CasheSecrets.config diff --git a/src/MyTimesheet/MyTimesheet/CasheSecrets.config b/src/MyTimesheet/MyTimesheet/CasheSecrets.config new file mode 100644 index 0000000..6799aa6 --- /dev/null +++ b/src/MyTimesheet/MyTimesheet/CasheSecrets.config @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/MyTimesheet/MyTimesheet/Startup.cs b/src/MyTimesheet/MyTimesheet/Startup.cs index 6bb5667..753825a 100644 --- a/src/MyTimesheet/MyTimesheet/Startup.cs +++ b/src/MyTimesheet/MyTimesheet/Startup.cs @@ -36,8 +36,9 @@ public void ConfigureServices(IServiceCollection services) }); var connection = @"Server=sql101labs1793591179000.westeurope.cloudapp.azure.com;Database=sql101.simtembile.soginga;User Id=simtembilesoginga;Password=Printwork31320;"; - services.AddDbContext - (options => options.UseSqlServer(connection)); + services.AddDbContext(options => options.UseSqlServer(connection)); + + services.AddSingleton(Configuration); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. diff --git a/src/MyTimesheet/MyTimesheet/appsettings.json b/src/MyTimesheet/MyTimesheet/appsettings.json index def9159..6593e23 100644 --- a/src/MyTimesheet/MyTimesheet/appsettings.json +++ b/src/MyTimesheet/MyTimesheet/appsettings.json @@ -4,5 +4,6 @@ "Default": "Warning" } }, - "AllowedHosts": "*" + "AllowedHosts": "*", + "CacheConnection": "101.redis.cache.windows.net.redis.cache.windows.net,abortConnect=false,ssl=true,password=85BYRVqUHV6aW7Jz8zIIxRnaYMgbBd2kwo4bpDiz4vw" } From 011f7d6e09f9721bba7e8ad6bd00222a9632d00b Mon Sep 17 00:00:00 2001 From: soginga Date: Sat, 26 Jan 2019 10:01:36 +0200 Subject: [PATCH 3/5] normalized TimesheetEntry to {TimesheetEntry,Developer,Project} --- .../MyTimesheet/Models/Developer.cs | 15 ++++++++++++ src/MyTimesheet/MyTimesheet/Models/Project.cs | 24 +++++++++++++++++++ .../MyTimesheet/Models/TimesheetContext.cs | 2 ++ .../MyTimesheet/Models/TimesheetEntry.cs | 20 ++++++---------- 4 files changed, 48 insertions(+), 13 deletions(-) create mode 100644 src/MyTimesheet/MyTimesheet/Models/Developer.cs create mode 100644 src/MyTimesheet/MyTimesheet/Models/Project.cs diff --git a/src/MyTimesheet/MyTimesheet/Models/Developer.cs b/src/MyTimesheet/MyTimesheet/Models/Developer.cs new file mode 100644 index 0000000..99b38be --- /dev/null +++ b/src/MyTimesheet/MyTimesheet/Models/Developer.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace MyTimesheet.Models +{ + public class Developer + { + + public int DeveloperId { get; set; } + public string Name { get; set; } + public string Surname { get; set; } + } +} diff --git a/src/MyTimesheet/MyTimesheet/Models/Project.cs b/src/MyTimesheet/MyTimesheet/Models/Project.cs new file mode 100644 index 0000000..b084816 --- /dev/null +++ b/src/MyTimesheet/MyTimesheet/Models/Project.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace MyTimesheet.Models +{ + public class Project + { + + /* Time Started | Time ended | Duration | Description | Billable + ------------ | ---------- | ---------| ----------------------- | --- + 09:00 | 11:00 | 120 | I was rocking HTML5 | YES + 13:00 | 17:00 | 240 | Grafting on golang api | YES + */ + + public string ProjectId { get; set; } + public DateTime TimeStart { get; set; } + public DateTime TimeEnd { get; set; } + public int Duration { get; set; } + public string Description { get; set; } + public bool Billable { get; set; } + } +} diff --git a/src/MyTimesheet/MyTimesheet/Models/TimesheetContext.cs b/src/MyTimesheet/MyTimesheet/Models/TimesheetContext.cs index 5bf7e22..da99a6c 100644 --- a/src/MyTimesheet/MyTimesheet/Models/TimesheetContext.cs +++ b/src/MyTimesheet/MyTimesheet/Models/TimesheetContext.cs @@ -13,6 +13,8 @@ public TimesheetContext(DbContextOptions options) { } public DbSet Entries { get; set; } + public DbSet Developers { get; set; } + public DbSet Projects { get; set; } } } diff --git a/src/MyTimesheet/MyTimesheet/Models/TimesheetEntry.cs b/src/MyTimesheet/MyTimesheet/Models/TimesheetEntry.cs index 8c65667..6752baf 100644 --- a/src/MyTimesheet/MyTimesheet/Models/TimesheetEntry.cs +++ b/src/MyTimesheet/MyTimesheet/Models/TimesheetEntry.cs @@ -8,22 +8,16 @@ namespace MyTimesheet.Models public class TimesheetEntry { /* - Name | Surname | Client | Project | Date | Time Started | Time ended | Duration | Description | Billable - --- | --- | --- | --- | --- | --- | --- | --- | --- | --- - John | Doe | Client X | Website | 2019-01-22 | 09:00 | 11:00 | 120 | I was rocking HTML5 | YES - John | Doe | Client X | API | 2019-01-22 | 13:00 | 17:00 | 240 | Grafting on golang api | YES + DeveloperId | Client | ProjectId | Date + -------------- | -------- | ------- | ---------- | + DEV1233434 | Client X | PR21 | 2019-01-22 | + DEV0133534 | Client X | PR05 | 2019-01-22 | */ - public int Id { get; set; } - public string Name { get; set; } - public string Surname { get; set; } + public int DeveloperId { get; set; } public string Client { get; set; } - public string Project { get; set; } + public string ProjectId { get; set; } public DateTime Date { get; set; } - public DateTime TimeStart { get; set; } - public DateTime TimeEnd { get; set; } - public int Duration { get; set; } - public string Description { get; set; } - public bool Billable { get; set; } + } } From 307712e04ece0f294c243f514dc3ba2930a3cc4e Mon Sep 17 00:00:00 2001 From: soginga Date: Sat, 26 Jan 2019 11:56:01 +0200 Subject: [PATCH 4/5] attempting migration after normalization --- data/createdatabase.sql | 2 +- .../Controllers/TimesheetController.cs | 22 ++- ...190126084435_PostNormalization.Designer.cs | 79 +++++++++++ .../20190126084435_PostNormalization.cs | 127 ++++++++++++++++++ .../20190126093556_onetwothree.Designer.cs | 96 +++++++++++++ .../Migrations/20190126093556_onetwothree.cs | 92 +++++++++++++ .../TimesheetContextModelSnapshot.cs | 61 +++++++-- .../MyTimesheet/Models/Developer.cs | 2 +- src/MyTimesheet/MyTimesheet/Models/Project.cs | 1 + .../MyTimesheet/Models/TimesheetEntry.cs | 9 +- .../MyTimesheet/MyTimesheet.csproj | 15 +++ 11 files changed, 489 insertions(+), 17 deletions(-) create mode 100644 src/MyTimesheet/MyTimesheet/Migrations/20190126084435_PostNormalization.Designer.cs create mode 100644 src/MyTimesheet/MyTimesheet/Migrations/20190126084435_PostNormalization.cs create mode 100644 src/MyTimesheet/MyTimesheet/Migrations/20190126093556_onetwothree.Designer.cs create mode 100644 src/MyTimesheet/MyTimesheet/Migrations/20190126093556_onetwothree.cs diff --git a/data/createdatabase.sql b/data/createdatabase.sql index 510c70f..a88c2c7 100644 --- a/data/createdatabase.sql +++ b/data/createdatabase.sql @@ -67,7 +67,7 @@ GO ALTER DATABASE [sql101.simtembile.soginga] SET AUTO_UPDATE_STATISTICS_ASYNC OFF GO -ALTER DATABASE [sql101.simtembile.soginga] SET DATE_CORRELATION_OPTIMIZATION OFF +ALTER DATABASE [sql101.simtembile.soginga] SET DATE_CORRE TION_OPTIMIZATION OFF GO ALTER DATABASE [sql101.simtembile.soginga] SET TRUSTWORTHY OFF diff --git a/src/MyTimesheet/MyTimesheet/Controllers/TimesheetController.cs b/src/MyTimesheet/MyTimesheet/Controllers/TimesheetController.cs index b2f5a7c..9e05084 100644 --- a/src/MyTimesheet/MyTimesheet/Controllers/TimesheetController.cs +++ b/src/MyTimesheet/MyTimesheet/Controllers/TimesheetController.cs @@ -1,9 +1,12 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; using MyTimesheet.Models; +using StackExchange.Redis; using System; using System.Collections.Generic; using System.Linq; +using System.Net; using System.Threading.Tasks; namespace MyTimesheet.Controllers @@ -13,9 +16,12 @@ namespace MyTimesheet.Controllers public class TimesheetController : ControllerBase { private readonly TimesheetContext _db; - public TimesheetController(TimesheetContext context) + readonly IConfiguration _config; + + public TimesheetController(TimesheetContext context, IConfiguration config) { _db = context; + _config = config; } // GET api/values @@ -34,10 +40,22 @@ public async Task> Get(int id) // POST api/values [HttpPost] - public async Task Post([FromBody] TimesheetEntry value) + public async Task Post([FromBody] TimesheetEntry value) { await _db.Entries.AddAsync(value); await _db.SaveChangesAsync(); + var CacheConnection = _config.GetValue("CacheConnection").ToString(); + var lazyConnection = new Lazy(() => + { + return ConnectionMultiplexer.Connect(CacheConnection); + }); + + IDatabase cache = lazyConnection.Value.GetDatabase(); + await cache.StringSetAsync($"{value.Date}-{value.Developer.Name}-{value.Client}-{value.Project.Name}", value.ToString()); + var cacheItem = await cache.StringGetAsync($"{value.Date}-{value.Developer.Name}-{value.Client}-{value.Project.Name}"); + lazyConnection.Value.Dispose(); + + return cacheItem; } // PUT api/values/5 diff --git a/src/MyTimesheet/MyTimesheet/Migrations/20190126084435_PostNormalization.Designer.cs b/src/MyTimesheet/MyTimesheet/Migrations/20190126084435_PostNormalization.Designer.cs new file mode 100644 index 0000000..a626ece --- /dev/null +++ b/src/MyTimesheet/MyTimesheet/Migrations/20190126084435_PostNormalization.Designer.cs @@ -0,0 +1,79 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using MyTimesheet.Models; + +namespace MyTimesheet.Migrations +{ + [DbContext(typeof(TimesheetContext))] + [Migration("20190126084435_PostNormalization")] + partial class PostNormalization + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "2.2.1-servicing-10028") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("MyTimesheet.Models.Developer", b => + { + b.Property("DeveloperId") + .ValueGeneratedOnAdd(); + + b.Property("Name"); + + b.Property("Surname"); + + b.HasKey("DeveloperId"); + + b.ToTable("Developers"); + }); + + modelBuilder.Entity("MyTimesheet.Models.Project", b => + { + b.Property("ProjectId") + .ValueGeneratedOnAdd(); + + b.Property("Billable"); + + b.Property("Description"); + + b.Property("Duration"); + + b.Property("TimeEnd"); + + b.Property("TimeStart"); + + b.HasKey("ProjectId"); + + b.ToTable("Projects"); + }); + + modelBuilder.Entity("MyTimesheet.Models.TimesheetEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Client"); + + b.Property("Date"); + + b.Property("DeveloperId"); + + b.Property("ProjectId"); + + b.HasKey("Id"); + + b.ToTable("Entries"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/MyTimesheet/MyTimesheet/Migrations/20190126084435_PostNormalization.cs b/src/MyTimesheet/MyTimesheet/Migrations/20190126084435_PostNormalization.cs new file mode 100644 index 0000000..8f2bc24 --- /dev/null +++ b/src/MyTimesheet/MyTimesheet/Migrations/20190126084435_PostNormalization.cs @@ -0,0 +1,127 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace MyTimesheet.Migrations +{ + public partial class PostNormalization : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Billable", + table: "Entries"); + + migrationBuilder.DropColumn( + name: "Description", + table: "Entries"); + + migrationBuilder.DropColumn( + name: "Duration", + table: "Entries"); + + migrationBuilder.DropColumn( + name: "Name", + table: "Entries"); + + migrationBuilder.DropColumn( + name: "TimeEnd", + table: "Entries"); + + migrationBuilder.DropColumn( + name: "TimeStart", + table: "Entries"); + + migrationBuilder.RenameColumn( + name: "Surname", + table: "Entries", + newName: "ProjectId"); + + migrationBuilder.RenameColumn( + name: "Project", + table: "Entries", + newName: "DeveloperId"); + + migrationBuilder.CreateTable( + name: "Developers", + columns: table => new + { + DeveloperId = table.Column(nullable: false), + Name = table.Column(nullable: true), + Surname = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Developers", x => x.DeveloperId); + }); + + migrationBuilder.CreateTable( + name: "Projects", + columns: table => new + { + ProjectId = table.Column(nullable: false), + TimeStart = table.Column(nullable: false), + TimeEnd = table.Column(nullable: false), + Duration = table.Column(nullable: false), + Description = table.Column(nullable: true), + Billable = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Projects", x => x.ProjectId); + }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Developers"); + + migrationBuilder.DropTable( + name: "Projects"); + + migrationBuilder.RenameColumn( + name: "ProjectId", + table: "Entries", + newName: "Surname"); + + migrationBuilder.RenameColumn( + name: "DeveloperId", + table: "Entries", + newName: "Project"); + + migrationBuilder.AddColumn( + name: "Billable", + table: "Entries", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "Description", + table: "Entries", + nullable: true); + + migrationBuilder.AddColumn( + name: "Duration", + table: "Entries", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "Name", + table: "Entries", + nullable: true); + + migrationBuilder.AddColumn( + name: "TimeEnd", + table: "Entries", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + migrationBuilder.AddColumn( + name: "TimeStart", + table: "Entries", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + } + } +} diff --git a/src/MyTimesheet/MyTimesheet/Migrations/20190126093556_onetwothree.Designer.cs b/src/MyTimesheet/MyTimesheet/Migrations/20190126093556_onetwothree.Designer.cs new file mode 100644 index 0000000..2bb4c66 --- /dev/null +++ b/src/MyTimesheet/MyTimesheet/Migrations/20190126093556_onetwothree.Designer.cs @@ -0,0 +1,96 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using MyTimesheet.Models; + +namespace MyTimesheet.Migrations +{ + [DbContext(typeof(TimesheetContext))] + [Migration("20190126093556_onetwothree")] + partial class onetwothree + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "2.2.1-servicing-10028") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("MyTimesheet.Models.Developer", b => + { + b.Property("DeveloperId") + .ValueGeneratedOnAdd(); + + b.Property("Name"); + + b.Property("Surname"); + + b.HasKey("DeveloperId"); + + b.ToTable("Developers"); + }); + + modelBuilder.Entity("MyTimesheet.Models.Project", b => + { + b.Property("ProjectId") + .ValueGeneratedOnAdd(); + + b.Property("Billable"); + + b.Property("Description"); + + b.Property("Duration"); + + b.Property("Name"); + + b.Property("TimeEnd"); + + b.Property("TimeStart"); + + b.HasKey("ProjectId"); + + b.ToTable("Projects"); + }); + + modelBuilder.Entity("MyTimesheet.Models.TimesheetEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Client"); + + b.Property("Date"); + + b.Property("DeveloperId"); + + b.Property("ProjectId"); + + b.HasKey("Id"); + + b.HasIndex("DeveloperId"); + + b.HasIndex("ProjectId"); + + b.ToTable("Entries"); + }); + + modelBuilder.Entity("MyTimesheet.Models.TimesheetEntry", b => + { + b.HasOne("MyTimesheet.Models.Developer", "Developer") + .WithMany() + .HasForeignKey("DeveloperId"); + + b.HasOne("MyTimesheet.Models.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/MyTimesheet/MyTimesheet/Migrations/20190126093556_onetwothree.cs b/src/MyTimesheet/MyTimesheet/Migrations/20190126093556_onetwothree.cs new file mode 100644 index 0000000..7ddd4ed --- /dev/null +++ b/src/MyTimesheet/MyTimesheet/Migrations/20190126093556_onetwothree.cs @@ -0,0 +1,92 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace MyTimesheet.Migrations +{ + public partial class onetwothree : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Name", + table: "Projects", + nullable: true); + + migrationBuilder.AlterColumn( + name: "ProjectId", + table: "Entries", + nullable: true, + oldClrType: typeof(string), + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "DeveloperId", + table: "Entries", + nullable: true, + oldClrType: typeof(string), + oldNullable: true); + + migrationBuilder.CreateIndex( + name: "IX_Entries_DeveloperId", + table: "Entries", + column: "DeveloperId"); + + migrationBuilder.CreateIndex( + name: "IX_Entries_ProjectId", + table: "Entries", + column: "ProjectId"); + + migrationBuilder.AddForeignKey( + name: "FK_Entries_Developers_DeveloperId", + table: "Entries", + column: "DeveloperId", + principalTable: "Developers", + principalColumn: "DeveloperId", + onDelete: ReferentialAction.Restrict); + + migrationBuilder.AddForeignKey( + name: "FK_Entries_Projects_ProjectId", + table: "Entries", + column: "ProjectId", + principalTable: "Projects", + principalColumn: "ProjectId", + onDelete: ReferentialAction.Restrict); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Entries_Developers_DeveloperId", + table: "Entries"); + + migrationBuilder.DropForeignKey( + name: "FK_Entries_Projects_ProjectId", + table: "Entries"); + + migrationBuilder.DropIndex( + name: "IX_Entries_DeveloperId", + table: "Entries"); + + migrationBuilder.DropIndex( + name: "IX_Entries_ProjectId", + table: "Entries"); + + migrationBuilder.DropColumn( + name: "Name", + table: "Projects"); + + migrationBuilder.AlterColumn( + name: "ProjectId", + table: "Entries", + nullable: true, + oldClrType: typeof(string), + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "DeveloperId", + table: "Entries", + nullable: true, + oldClrType: typeof(string), + oldNullable: true); + } + } +} diff --git a/src/MyTimesheet/MyTimesheet/Migrations/TimesheetContextModelSnapshot.cs b/src/MyTimesheet/MyTimesheet/Migrations/TimesheetContextModelSnapshot.cs index 6404921..5625da4 100644 --- a/src/MyTimesheet/MyTimesheet/Migrations/TimesheetContextModelSnapshot.cs +++ b/src/MyTimesheet/MyTimesheet/Migrations/TimesheetContextModelSnapshot.cs @@ -19,17 +19,26 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasAnnotation("Relational:MaxIdentifierLength", 128) .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - modelBuilder.Entity("MyTimesheet.Models.TimesheetEntry", b => + modelBuilder.Entity("MyTimesheet.Models.Developer", b => { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + b.Property("DeveloperId") + .ValueGeneratedOnAdd(); - b.Property("Billable"); + b.Property("Name"); - b.Property("Client"); + b.Property("Surname"); - b.Property("Date"); + b.HasKey("DeveloperId"); + + b.ToTable("Developers"); + }); + + modelBuilder.Entity("MyTimesheet.Models.Project", b => + { + b.Property("ProjectId") + .ValueGeneratedOnAdd(); + + b.Property("Billable"); b.Property("Description"); @@ -37,18 +46,48 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("Name"); - b.Property("Project"); - - b.Property("Surname"); - b.Property("TimeEnd"); b.Property("TimeStart"); + b.HasKey("ProjectId"); + + b.ToTable("Projects"); + }); + + modelBuilder.Entity("MyTimesheet.Models.TimesheetEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Client"); + + b.Property("Date"); + + b.Property("DeveloperId"); + + b.Property("ProjectId"); + b.HasKey("Id"); + b.HasIndex("DeveloperId"); + + b.HasIndex("ProjectId"); + b.ToTable("Entries"); }); + + modelBuilder.Entity("MyTimesheet.Models.TimesheetEntry", b => + { + b.HasOne("MyTimesheet.Models.Developer", "Developer") + .WithMany() + .HasForeignKey("DeveloperId"); + + b.HasOne("MyTimesheet.Models.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId"); + }); #pragma warning restore 612, 618 } } diff --git a/src/MyTimesheet/MyTimesheet/Models/Developer.cs b/src/MyTimesheet/MyTimesheet/Models/Developer.cs index 99b38be..c2330ff 100644 --- a/src/MyTimesheet/MyTimesheet/Models/Developer.cs +++ b/src/MyTimesheet/MyTimesheet/Models/Developer.cs @@ -8,7 +8,7 @@ namespace MyTimesheet.Models public class Developer { - public int DeveloperId { get; set; } + public string DeveloperId { get; set; } public string Name { get; set; } public string Surname { get; set; } } diff --git a/src/MyTimesheet/MyTimesheet/Models/Project.cs b/src/MyTimesheet/MyTimesheet/Models/Project.cs index b084816..23c9f52 100644 --- a/src/MyTimesheet/MyTimesheet/Models/Project.cs +++ b/src/MyTimesheet/MyTimesheet/Models/Project.cs @@ -15,6 +15,7 @@ public class Project */ public string ProjectId { get; set; } + public string Name { get; set; } public DateTime TimeStart { get; set; } public DateTime TimeEnd { get; set; } public int Duration { get; set; } diff --git a/src/MyTimesheet/MyTimesheet/Models/TimesheetEntry.cs b/src/MyTimesheet/MyTimesheet/Models/TimesheetEntry.cs index 6752baf..0614ed1 100644 --- a/src/MyTimesheet/MyTimesheet/Models/TimesheetEntry.cs +++ b/src/MyTimesheet/MyTimesheet/Models/TimesheetEntry.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; using System.Linq; using System.Threading.Tasks; @@ -14,9 +15,13 @@ public class TimesheetEntry DEV0133534 | Client X | PR05 | 2019-01-22 | */ - public int DeveloperId { get; set; } + + public int Id { get; set; } + + public Developer Developer { get; set; } + + public Project Project { get; set; } public string Client { get; set; } - public string ProjectId { get; set; } public DateTime Date { get; set; } } diff --git a/src/MyTimesheet/MyTimesheet/MyTimesheet.csproj b/src/MyTimesheet/MyTimesheet/MyTimesheet.csproj index 54dfccf..62f1598 100644 --- a/src/MyTimesheet/MyTimesheet/MyTimesheet.csproj +++ b/src/MyTimesheet/MyTimesheet/MyTimesheet.csproj @@ -5,6 +5,21 @@ InProcess + + + + + + + + + + + + + + + From 86aadb0a43017a481d92ce38fa502e2307d49671 Mon Sep 17 00:00:00 2001 From: soginga Date: Sat, 26 Jan 2019 12:02:48 +0200 Subject: [PATCH 5/5] corrected a tiny mistake in .sql file --- data/createdatabase.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/createdatabase.sql b/data/createdatabase.sql index a88c2c7..510c70f 100644 --- a/data/createdatabase.sql +++ b/data/createdatabase.sql @@ -67,7 +67,7 @@ GO ALTER DATABASE [sql101.simtembile.soginga] SET AUTO_UPDATE_STATISTICS_ASYNC OFF GO -ALTER DATABASE [sql101.simtembile.soginga] SET DATE_CORRE TION_OPTIMIZATION OFF +ALTER DATABASE [sql101.simtembile.soginga] SET DATE_CORRELATION_OPTIMIZATION OFF GO ALTER DATABASE [sql101.simtembile.soginga] SET TRUSTWORTHY OFF