diff --git a/src/HelloShop.IdentityService/Constants/DbConstants.cs b/src/HelloShop.IdentityService/Constants/DbConstants.cs new file mode 100644 index 0000000..a2825ed --- /dev/null +++ b/src/HelloShop.IdentityService/Constants/DbConstants.cs @@ -0,0 +1,7 @@ +namespace HelloShop.IdentityService.Constants +{ + public class DbConstants + { + public const string ConnectionStringName = "IdentityDatabase"; + } +} diff --git a/src/HelloShop.IdentityService/Controllers/UsersController.cs b/src/HelloShop.IdentityService/Controllers/UsersController.cs new file mode 100644 index 0000000..b3c67c2 --- /dev/null +++ b/src/HelloShop.IdentityService/Controllers/UsersController.cs @@ -0,0 +1,36 @@ +using HelloShop.IdentityService.Entities; +using HelloShop.IdentityService.EntityFrameworks; +using Microsoft.AspNetCore.Mvc; + +// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 + +namespace HelloShop.IdentityService.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class UsersController(IdentityServiceDbContext dbContext) : ControllerBase + { + [HttpGet] + public IEnumerable Get() + { + return dbContext.Set(); + } + + // GET api//5 + [HttpGet("{id}")] + public User? Get(int id) + { + return dbContext.Set().Find(id); + } + + // POST api/ + [HttpPost] + public void Post([FromBody] User value) + { + value.CreationTime = DateTimeOffset.Now; + + dbContext.Add(value); + dbContext.SaveChanges(); + } + } +} diff --git a/src/HelloShop.IdentityService/Entities/User.cs b/src/HelloShop.IdentityService/Entities/User.cs new file mode 100644 index 0000000..4577e53 --- /dev/null +++ b/src/HelloShop.IdentityService/Entities/User.cs @@ -0,0 +1,13 @@ +namespace HelloShop.IdentityService.Entities +{ + public class User + { + public int Id { get; set; } + + public string UserName { get; set; } = default!; + + public string PasswordHash { get; set; } = default!; + + public DateTimeOffset CreationTime { get; set; } = DateTimeOffset.UtcNow; + } +} diff --git a/src/HelloShop.IdentityService/EntityFrameworks/EntityConfigurations/UserEntityTypeConfiguration.cs b/src/HelloShop.IdentityService/EntityFrameworks/EntityConfigurations/UserEntityTypeConfiguration.cs new file mode 100644 index 0000000..3798553 --- /dev/null +++ b/src/HelloShop.IdentityService/EntityFrameworks/EntityConfigurations/UserEntityTypeConfiguration.cs @@ -0,0 +1,20 @@ +using HelloShop.IdentityService.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace HelloShop.IdentityService.EntityFrameworks.EntityConfigurations +{ + public class UserEntityTypeConfiguration : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("Users"); + + builder.HasKey(u => u.Id); + builder.Property(u => u.Id).HasColumnOrder(1); + + builder.Property(u => u.UserName).HasMaxLength(50).HasColumnOrder(3); + builder.Property(u => u.PasswordHash).HasMaxLength(100).HasColumnOrder(2); + } + } +} diff --git a/src/HelloShop.IdentityService/EntityFrameworks/IdentityServiceDbContext.cs b/src/HelloShop.IdentityService/EntityFrameworks/IdentityServiceDbContext.cs new file mode 100644 index 0000000..ee5925c --- /dev/null +++ b/src/HelloShop.IdentityService/EntityFrameworks/IdentityServiceDbContext.cs @@ -0,0 +1,18 @@ +using Microsoft.EntityFrameworkCore; +using System.Reflection; + +namespace HelloShop.IdentityService.EntityFrameworks +{ + public class IdentityServiceDbContext(DbContextOptions options) : DbContext(options) + { + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly()); + + AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true); + AppContext.SetSwitch("Npgsql.DisableDateTimeInfinityConversions", true); + } + } +} diff --git a/src/HelloShop.IdentityService/EntityFrameworks/Migrations/20240302004354_InitialCreate.Designer.cs b/src/HelloShop.IdentityService/EntityFrameworks/Migrations/20240302004354_InitialCreate.Designer.cs new file mode 100644 index 0000000..d62939c --- /dev/null +++ b/src/HelloShop.IdentityService/EntityFrameworks/Migrations/20240302004354_InitialCreate.Designer.cs @@ -0,0 +1,59 @@ +// +using System; +using HelloShop.IdentityService.EntityFrameworks; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace HelloShop.IdentityService.EntityFrameworks.Migrations +{ + [DbContext(typeof(IdentityServiceDbContext))] + [Migration("20240302004354_InitialCreate")] + partial class InitialCreate + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.2") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("HelloShop.IdentityService.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnOrder(1); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("PasswordHash") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasColumnOrder(2); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .HasColumnOrder(3); + + b.HasKey("Id"); + + b.ToTable("Users", (string)null); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/HelloShop.IdentityService/EntityFrameworks/Migrations/20240302004354_InitialCreate.cs b/src/HelloShop.IdentityService/EntityFrameworks/Migrations/20240302004354_InitialCreate.cs new file mode 100644 index 0000000..8186ecb --- /dev/null +++ b/src/HelloShop.IdentityService/EntityFrameworks/Migrations/20240302004354_InitialCreate.cs @@ -0,0 +1,38 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace HelloShop.IdentityService.EntityFrameworks.Migrations +{ + /// + public partial class InitialCreate : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Users", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + PasswordHash = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + UserName = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + CreationTime = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Users", x => x.Id); + }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Users"); + } + } +} diff --git a/src/HelloShop.IdentityService/EntityFrameworks/Migrations/IdentityServiceDbContextModelSnapshot.cs b/src/HelloShop.IdentityService/EntityFrameworks/Migrations/IdentityServiceDbContextModelSnapshot.cs new file mode 100644 index 0000000..d28c2ee --- /dev/null +++ b/src/HelloShop.IdentityService/EntityFrameworks/Migrations/IdentityServiceDbContextModelSnapshot.cs @@ -0,0 +1,56 @@ +// +using System; +using HelloShop.IdentityService.EntityFrameworks; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace HelloShop.IdentityService.EntityFrameworks.Migrations +{ + [DbContext(typeof(IdentityServiceDbContext))] + partial class IdentityServiceDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.2") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("HelloShop.IdentityService.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnOrder(1); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("PasswordHash") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasColumnOrder(2); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .HasColumnOrder(3); + + b.HasKey("Id"); + + b.ToTable("Users", (string)null); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/HelloShop.IdentityService/EntityFrameworks/README.md b/src/HelloShop.IdentityService/EntityFrameworks/README.md new file mode 100644 index 0000000..ca72c96 --- /dev/null +++ b/src/HelloShop.IdentityService/EntityFrameworks/README.md @@ -0,0 +1,6 @@ +```shell +dotnet ef database drop --force +dotnet ef migrations remove +dotnet ef migrations add InitialCreate --output-dir EntityFrameworks/Migrations +dotnet ef database update +``` \ No newline at end of file diff --git a/src/HelloShop.IdentityService/HelloShop.IdentityService.csproj b/src/HelloShop.IdentityService/HelloShop.IdentityService.csproj index a97a79f..9e3561c 100644 --- a/src/HelloShop.IdentityService/HelloShop.IdentityService.csproj +++ b/src/HelloShop.IdentityService/HelloShop.IdentityService.csproj @@ -6,6 +6,11 @@ true + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + diff --git a/src/HelloShop.IdentityService/Program.cs b/src/HelloShop.IdentityService/Program.cs index edda8a7..8d62b4d 100644 --- a/src/HelloShop.IdentityService/Program.cs +++ b/src/HelloShop.IdentityService/Program.cs @@ -1,3 +1,7 @@ +using HelloShop.IdentityService.Constants; +using HelloShop.IdentityService.EntityFrameworks; +using Microsoft.EntityFrameworkCore; + var builder = WebApplication.CreateBuilder(args); builder.AddServiceDefaults(); @@ -9,6 +13,11 @@ builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); +builder.Services.AddDbContext(options => +{ + options.UseNpgsql(builder.Configuration.GetConnectionString(DbConstants.ConnectionStringName)); +}); + var app = builder.Build(); app.MapDefaultEndpoints(); diff --git a/src/HelloShop.IdentityService/appsettings.json b/src/HelloShop.IdentityService/appsettings.json index 10f68b8..553fd17 100644 --- a/src/HelloShop.IdentityService/appsettings.json +++ b/src/HelloShop.IdentityService/appsettings.json @@ -5,5 +5,8 @@ "Microsoft.AspNetCore": "Warning" } }, + "ConnectionStrings": { + "IdentityDatabase": "Host=localhost;Port=5432;Database=IdentityService;Username=postgres;Password=postgres" + }, "AllowedHosts": "*" }