aboutsummaryrefslogtreecommitdiff
path: root/src/Data
diff options
context:
space:
mode:
Diffstat (limited to 'src/Data')
-rw-r--r--src/Data/DevHive.Data.Models/Comment.cs20
-rw-r--r--src/Data/DevHive.Data.Models/DevHive.Data.Models.csproj11
-rw-r--r--src/Data/DevHive.Data.Models/Language.cs15
-rw-r--r--src/Data/DevHive.Data.Models/Post.cs26
-rw-r--r--src/Data/DevHive.Data.Models/ProfilePicture.cs15
-rw-r--r--src/Data/DevHive.Data.Models/Rating.cs17
-rw-r--r--src/Data/DevHive.Data.Models/Role.cs17
-rw-r--r--src/Data/DevHive.Data.Models/Technology.cs15
-rw-r--r--src/Data/DevHive.Data.Models/User.cs33
-rw-r--r--src/Data/DevHive.Data.Tests/CommentRepository.Tests.cs99
-rw-r--r--src/Data/DevHive.Data.Tests/DevHive.Data.Tests.csproj29
-rw-r--r--src/Data/DevHive.Data.Tests/FeedRepository.Tests.cs119
-rw-r--r--src/Data/DevHive.Data.Tests/LenguageRepository.Tests.cs116
-rw-r--r--src/Data/DevHive.Data.Tests/PostRepository.Tests.cs145
-rw-r--r--src/Data/DevHive.Data.Tests/RoleRepository.Tests.cs119
-rw-r--r--src/Data/DevHive.Data.Tests/TechnologyRepository.Tests.cs118
-rw-r--r--src/Data/DevHive.Data.Tests/UserRepositoryTests.cs350
-rw-r--r--src/Data/DevHive.Data/ConnectionString.json5
-rw-r--r--src/Data/DevHive.Data/DevHive.Data.csproj34
-rw-r--r--src/Data/DevHive.Data/DevHiveContext.cs115
-rw-r--r--src/Data/DevHive.Data/DevHiveContextFactory.cs23
-rw-r--r--src/Data/DevHive.Data/Interfaces/Models/IComment.cs16
-rw-r--r--src/Data/DevHive.Data/Interfaces/Models/ILanguage.cs11
-rw-r--r--src/Data/DevHive.Data/Interfaces/Models/IModel.cs9
-rw-r--r--src/Data/DevHive.Data/Interfaces/Models/IPost.cs22
-rw-r--r--src/Data/DevHive.Data/Interfaces/Models/IProfilePicture.cs13
-rw-r--r--src/Data/DevHive.Data/Interfaces/Models/IRating.cs14
-rw-r--r--src/Data/DevHive.Data/Interfaces/Models/IRole.cs10
-rw-r--r--src/Data/DevHive.Data/Interfaces/Models/ITechnology.cs11
-rw-r--r--src/Data/DevHive.Data/Interfaces/Models/IUser.cs21
-rw-r--r--src/Data/DevHive.Data/Interfaces/Repositories/ICommentRepository.cs16
-rw-r--r--src/Data/DevHive.Data/Interfaces/Repositories/IFeedRepository.cs13
-rw-r--r--src/Data/DevHive.Data/Interfaces/Repositories/ILanguageRepository.cs17
-rw-r--r--src/Data/DevHive.Data/Interfaces/Repositories/IPostRepository.cs19
-rw-r--r--src/Data/DevHive.Data/Interfaces/Repositories/IRatingRepository.cs13
-rw-r--r--src/Data/DevHive.Data/Interfaces/Repositories/IRepository.cs21
-rw-r--r--src/Data/DevHive.Data/Interfaces/Repositories/IRoleRepository.cs15
-rw-r--r--src/Data/DevHive.Data/Interfaces/Repositories/ITechnologyRepository.cs17
-rw-r--r--src/Data/DevHive.Data/Interfaces/Repositories/IUserRepository.cs22
-rw-r--r--src/Data/DevHive.Data/Migrations/20210205140955_rating.Designer.cs665
-rw-r--r--src/Data/DevHive.Data/Migrations/20210205140955_rating.cs581
-rw-r--r--src/Data/DevHive.Data/Migrations/20210205150447_Friends_Init_Config.Designer.cs643
-rw-r--r--src/Data/DevHive.Data/Migrations/20210205150447_Friends_Init_Config.cs45
-rw-r--r--src/Data/DevHive.Data/Migrations/20210205154810_PostFileAttachments.Designer.cs691
-rw-r--r--src/Data/DevHive.Data/Migrations/20210205154810_PostFileAttachments.cs51
-rw-r--r--src/Data/DevHive.Data/Migrations/20210205160520_Friends_First_Tweek.Designer.cs609
-rw-r--r--src/Data/DevHive.Data/Migrations/20210205160520_Friends_First_Tweek.cs46
-rw-r--r--src/Data/DevHive.Data/Migrations/DevHiveContextModelSnapshot.cs658
-rw-r--r--src/Data/DevHive.Data/RelationModels/PostAttachments.cs16
-rw-r--r--src/Data/DevHive.Data/RelationModels/RatedPost.cs18
-rw-r--r--src/Data/DevHive.Data/RelationModels/UserRate.cs18
-rw-r--r--src/Data/DevHive.Data/Repositories/BaseRepository.cs59
-rw-r--r--src/Data/DevHive.Data/Repositories/CommentRepository.cs74
-rw-r--r--src/Data/DevHive.Data/Repositories/FeedRepository.cs77
-rw-r--r--src/Data/DevHive.Data/Repositories/LanguageRepository.cs53
-rw-r--r--src/Data/DevHive.Data/Repositories/PostRepository.cs105
-rw-r--r--src/Data/DevHive.Data/Repositories/RatingRepository.cs35
-rw-r--r--src/Data/DevHive.Data/Repositories/RoleRepository.cs55
-rw-r--r--src/Data/DevHive.Data/Repositories/TechnologyRepository.cs53
-rw-r--r--src/Data/DevHive.Data/Repositories/UserRepository.cs108
60 files changed, 6381 insertions, 0 deletions
diff --git a/src/Data/DevHive.Data.Models/Comment.cs b/src/Data/DevHive.Data.Models/Comment.cs
new file mode 100644
index 0000000..e2bb21d
--- /dev/null
+++ b/src/Data/DevHive.Data.Models/Comment.cs
@@ -0,0 +1,20 @@
+using System;
+using DevHive.Data.Interfaces.Models;
+
+namespace DevHive.Data.Models
+{
+ public class Comment : IComment
+ {
+ public Guid Id { get; set; }
+
+ // public Guid PostId { get; set; }
+ public Post Post { get; set; }
+
+ // public Guid CreatorId { get; set; }
+ public User Creator { get; set; }
+
+ public string Message { get; set; }
+
+ public DateTime TimeCreated { get; set; }
+ }
+}
diff --git a/src/Data/DevHive.Data.Models/DevHive.Data.Models.csproj b/src/Data/DevHive.Data.Models/DevHive.Data.Models.csproj
new file mode 100644
index 0000000..ebf5f9c
--- /dev/null
+++ b/src/Data/DevHive.Data.Models/DevHive.Data.Models.csproj
@@ -0,0 +1,11 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <TargetFramework>net5.0</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\..\Common\DevHive.Common.Models\DevHive.Common.csproj" />
+ </ItemGroup>
+
+</Project>
diff --git a/src/Data/DevHive.Data.Models/Language.cs b/src/Data/DevHive.Data.Models/Language.cs
new file mode 100644
index 0000000..7ad8ff2
--- /dev/null
+++ b/src/Data/DevHive.Data.Models/Language.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using DevHive.Data.Interfaces.Models;
+
+namespace DevHive.Data.Models
+{
+ public class Language : ILanguage
+ {
+ public Guid Id { get; set; }
+
+ public string Name { get; set; }
+
+ public HashSet<User> Users { get; set; } = new();
+ }
+}
diff --git a/src/Data/DevHive.Data.Models/Post.cs b/src/Data/DevHive.Data.Models/Post.cs
new file mode 100644
index 0000000..3f3d8c9
--- /dev/null
+++ b/src/Data/DevHive.Data.Models/Post.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations.Schema;
+using DevHive.Data.Interfaces.Models;
+using DevHive.Data.RelationModels;
+
+namespace DevHive.Data.Models
+{
+ [Table("Posts")]
+ public class Post : IPost
+ {
+ public Guid Id { get; set; }
+
+ public User Creator { get; set; }
+
+ public string Message { get; set; }
+
+ public DateTime TimeCreated { get; set; }
+
+ public List<Comment> Comments { get; set; } = new();
+
+ public Rating Rating { get; set; } = new();
+
+ public List<PostAttachments> Attachments { get; set; } = new();
+ }
+}
diff --git a/src/Data/DevHive.Data.Models/ProfilePicture.cs b/src/Data/DevHive.Data.Models/ProfilePicture.cs
new file mode 100644
index 0000000..d5cc397
--- /dev/null
+++ b/src/Data/DevHive.Data.Models/ProfilePicture.cs
@@ -0,0 +1,15 @@
+using System;
+using DevHive.Data.Interfaces.Models;
+
+namespace DevHive.Data.Models
+{
+ public class ProfilePicture: IProfilePicture
+ {
+ public Guid Id { get; set; }
+
+ public Guid UserId { get; set; }
+ public User User { get; set; }
+
+ public string PictureURL { get; set; }
+ }
+}
diff --git a/src/Data/DevHive.Data.Models/Rating.cs b/src/Data/DevHive.Data.Models/Rating.cs
new file mode 100644
index 0000000..e1bedd2
--- /dev/null
+++ b/src/Data/DevHive.Data.Models/Rating.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using DevHive.Data.Interfaces.Models;
+
+namespace DevHive.Data.Models
+{
+ public class Rating : IRating
+ {
+ public Guid Id { get; set; }
+
+ public Guid PostId { get; set; }
+
+ public Post Post { get; set; }
+
+ public int Rate { get; set; }
+ }
+}
diff --git a/src/Data/DevHive.Data.Models/Role.cs b/src/Data/DevHive.Data.Models/Role.cs
new file mode 100644
index 0000000..259d867
--- /dev/null
+++ b/src/Data/DevHive.Data.Models/Role.cs
@@ -0,0 +1,17 @@
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Collections.Generic;
+using DevHive.Data.Interfaces.Models;
+using Microsoft.AspNetCore.Identity;
+using System;
+
+namespace DevHive.Data.Models
+{
+ [Table("Roles")]
+ public class Role : IdentityRole<Guid>, IRole
+ {
+ public const string DefaultRole = "User";
+ public const string AdminRole = "Admin";
+
+ public HashSet<User> Users { get; set; } = new();
+ }
+}
diff --git a/src/Data/DevHive.Data.Models/Technology.cs b/src/Data/DevHive.Data.Models/Technology.cs
new file mode 100644
index 0000000..6f98f0b
--- /dev/null
+++ b/src/Data/DevHive.Data.Models/Technology.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using DevHive.Data.Interfaces.Models;
+
+namespace DevHive.Data.Models
+{
+ public class Technology : ITechnology
+ {
+ public Guid Id { get; set; }
+
+ public string Name { get; set; }
+
+ public HashSet<User> Users { get; set; } = new();
+ }
+}
diff --git a/src/Data/DevHive.Data.Models/User.cs b/src/Data/DevHive.Data.Models/User.cs
new file mode 100644
index 0000000..983d073
--- /dev/null
+++ b/src/Data/DevHive.Data.Models/User.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations.Schema;
+using DevHive.Data.Interfaces.Models;
+using DevHive.Data.RelationModels;
+using Microsoft.AspNetCore.Identity;
+
+namespace DevHive.Data.Models
+{
+ [Table("Users")]
+ public class User : IdentityUser<Guid>, IUser
+ {
+ public string FirstName { get; set; }
+
+ public string LastName { get; set; }
+
+ public ProfilePicture ProfilePicture { get; set; }
+
+ public HashSet<Language> Languages { get; set; } = new();
+
+ public HashSet<Technology> Technologies { get; set; } = new();
+
+ public HashSet<Role> Roles { get; set; } = new();
+
+ public HashSet<Post> Posts { get; set; } = new();
+
+ public HashSet<User> Friends { get; set; } = new();
+
+ public HashSet<Comment> Comments { get; set; } = new();
+
+ public HashSet<RatedPost> RatedPosts { get; set; } = new();
+ }
+}
diff --git a/src/Data/DevHive.Data.Tests/CommentRepository.Tests.cs b/src/Data/DevHive.Data.Tests/CommentRepository.Tests.cs
new file mode 100644
index 0000000..9cbb43b
--- /dev/null
+++ b/src/Data/DevHive.Data.Tests/CommentRepository.Tests.cs
@@ -0,0 +1,99 @@
+using System;
+using System.Threading.Tasks;
+using DevHive.Data.Models;
+using DevHive.Data.Repositories;
+using Microsoft.EntityFrameworkCore;
+using NUnit.Framework;
+
+namespace DevHive.Data.Tests
+{
+ [TestFixture]
+ public class CommentRepositoryTests
+ {
+ private const string COMMENT_MESSAGE = "Comment message";
+
+ protected DevHiveContext Context { get; set; }
+
+ protected CommentRepository CommentRepository { get; set; }
+
+ #region Setups
+ [SetUp]
+ public void Setup()
+ {
+ var optionsBuilder = new DbContextOptionsBuilder<DevHiveContext>()
+ .UseInMemoryDatabase(databaseName: "DevHive_Test_Database");
+
+ this.Context = new DevHiveContext(optionsBuilder.Options);
+
+ CommentRepository = new CommentRepository(Context);
+ }
+
+ [TearDown]
+ public void TearDown()
+ {
+ this.Context.Database.EnsureDeleted();
+ }
+ #endregion
+
+ #region GetCommentByIssuerAndTimeCreatedAsync
+ [Test]
+ public async Task GetCommentByCreatorAndTimeCreatedAsync_ReturnsTheCorrectComment_IfItExists()
+ {
+ Comment comment = await this.AddEntity();
+
+ Comment resultComment = await this.CommentRepository.GetCommentByIssuerAndTimeCreatedAsync(comment.Creator.Id, comment.TimeCreated);
+
+ Assert.AreEqual(comment.Id, resultComment.Id, "GetCommentByIssuerAndTimeCreatedAsync does not return the corect comment when it exists");
+ }
+
+ [Test]
+ public async Task GetPostByCreatorAndTimeCreatedAsync_ReturnsNull_IfThePostDoesNotExist()
+ {
+ Comment comment = await this.AddEntity();
+
+ Comment resultComment = await this.CommentRepository.GetCommentByIssuerAndTimeCreatedAsync(Guid.Empty, DateTime.Now);
+
+ Assert.IsNull(resultComment, "GetCommentByIssuerAndTimeCreatedAsync does not return null when the comment does not exist");
+ }
+ #endregion
+
+ #region DoesCommentExist
+ [Test]
+ public async Task DoesCommentExist_ReturnsTrue_WhenTheCommentExists()
+ {
+ Comment comment = await this.AddEntity();
+
+ bool result = await this.CommentRepository.DoesCommentExist(comment.Id);
+
+ Assert.IsTrue(result, "DoesCommentExist does not return true whenm the Comment exists");
+ }
+
+ [Test]
+ public async Task DoesCommentExist_ReturnsFalse_WhenTheCommentDoesNotExist()
+ {
+ bool result = await this.CommentRepository.DoesCommentExist(Guid.Empty);
+
+ Assert.IsFalse(result, "DoesCommentExist does not return false whenm the Comment" +
+ " does not exist");
+ }
+ #endregion
+
+ #region HelperMethods
+ private async Task<Comment> AddEntity(string name = COMMENT_MESSAGE)
+ {
+ User creator = new User { Id = Guid.NewGuid() };
+ Comment comment = new Comment
+ {
+ Message = COMMENT_MESSAGE,
+ Creator = creator,
+ TimeCreated = DateTime.Now
+ };
+
+ this.Context.Comments.Add(comment);
+ await this.Context.SaveChangesAsync();
+
+ return comment;
+ }
+ #endregion
+ }
+}
diff --git a/src/Data/DevHive.Data.Tests/DevHive.Data.Tests.csproj b/src/Data/DevHive.Data.Tests/DevHive.Data.Tests.csproj
new file mode 100644
index 0000000..42a3273
--- /dev/null
+++ b/src/Data/DevHive.Data.Tests/DevHive.Data.Tests.csproj
@@ -0,0 +1,29 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <TargetFramework>net5.0</TargetFramework>
+
+ <IsPackable>false</IsPackable>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="5.0.1" />
+ <PackageReference Include="Moq" Version="4.16.0" />
+ <PackageReference Include="NUnit" Version="3.13.0" />
+ <PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
+ <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\DevHive.Data\DevHive.Data.csproj" />
+
+ <ProjectReference Include="..\DevHive.Data.Models\DevHive.Data.Models.csproj" />
+
+ <ProjectReference Include="..\..\Common\DevHive.Common.Models\DevHive.Common.csproj" />
+ </ItemGroup>
+
+ <PropertyGroup>
+ <EnableNETAnalyzers>true</EnableNETAnalyzers>
+ <AnalysisLevel>latest</AnalysisLevel>
+ </PropertyGroup>
+</Project>
diff --git a/src/Data/DevHive.Data.Tests/FeedRepository.Tests.cs b/src/Data/DevHive.Data.Tests/FeedRepository.Tests.cs
new file mode 100644
index 0000000..f134bf3
--- /dev/null
+++ b/src/Data/DevHive.Data.Tests/FeedRepository.Tests.cs
@@ -0,0 +1,119 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using DevHive.Data.Models;
+using DevHive.Data.Repositories;
+using Microsoft.EntityFrameworkCore;
+using NUnit.Framework;
+
+namespace DevHive.Data.Tests
+{
+ [TestFixture]
+ public class FeedRepositoryTests
+ {
+ protected DevHiveContext Context { get; set; }
+
+ protected FeedRepository FeedRepository { get; set; }
+
+ #region Setups
+ [SetUp]
+ public void Setup()
+ {
+ var optionsBuilder = new DbContextOptionsBuilder<DevHiveContext>()
+ .UseInMemoryDatabase(databaseName: "DevHive_Test_Database");
+
+ this.Context = new DevHiveContext(optionsBuilder.Options);
+
+ FeedRepository = new FeedRepository(Context);
+ }
+
+ [TearDown]
+ public void TearDown()
+ {
+ this.Context.Database.EnsureDeleted();
+ }
+ #endregion
+
+ #region GetFriendsPosts
+ [Test]
+ public async Task GetFriendsPosts_ReturnsListOfPosts_WhenTheyExist()
+ {
+ User dummyUser = this.CreateDummyUser();
+ List<User> friendsList = new List<User>();
+ friendsList.Add(dummyUser);
+
+ DateTime dateTime = new DateTime(3000, 05, 09, 9, 15, 0);
+ Console.WriteLine(dateTime.ToFileTime());
+
+ Post dummyPost = this.CreateDummyPost(dummyUser);
+ Post anotherDummnyPost = this.CreateDummyPost(dummyUser);
+
+ const int PAGE_NUMBER = 1;
+ const int PAGE_SIZE = 10;
+
+ List<Post> resultList = await this.FeedRepository.GetFriendsPosts(friendsList, dateTime, PAGE_NUMBER, PAGE_SIZE);
+
+ Assert.GreaterOrEqual(2, resultList.Count, "GetFriendsPosts does not return all correct posts");
+ }
+
+ [Test]
+ public async Task GetFriendsPosts_ReturnsNull_WhenNoSuitablePostsExist()
+ {
+ User dummyUser = this.CreateDummyUser();
+ List<User> friendsList = new List<User>();
+ friendsList.Add(dummyUser);
+
+ DateTime dateTime = new DateTime(3000, 05, 09, 9, 15, 0);
+
+ const int PAGE_NUMBER = 1;
+ const int PAGE_SIZE = 10;
+
+ List<Post> resultList = await this.FeedRepository.GetFriendsPosts(friendsList, dateTime, PAGE_NUMBER, PAGE_SIZE);
+
+ Assert.LessOrEqual(0, resultList.Count, "GetFriendsPosts does not return all correct posts");
+ }
+ #endregion
+
+ #region HelperMethods
+ private User CreateDummyUser()
+ {
+ HashSet<Role> roles = new()
+ {
+ new Role()
+ {
+ Id = Guid.NewGuid(),
+ Name = Role.DefaultRole
+ },
+ };
+
+ return new()
+ {
+ Id = Guid.NewGuid(),
+ UserName = "pioneer10",
+ FirstName = "Spas",
+ LastName = "Spasov",
+ Email = "abv@abv.bg",
+ Roles = roles
+ };
+ }
+
+ private Post CreateDummyPost(User poster)
+ {
+ const string POST_MESSAGE = "random message";
+ Guid id = Guid.NewGuid();
+ Post post = new Post
+ {
+ Id = id,
+ Message = POST_MESSAGE,
+ Creator = poster,
+ TimeCreated = new DateTime(2000, 05, 09, 9, 15, 0)
+ };
+
+ this.Context.Posts.Add(post);
+ this.Context.SaveChanges();
+
+ return post;
+ }
+ #endregion
+ }
+}
diff --git a/src/Data/DevHive.Data.Tests/LenguageRepository.Tests.cs b/src/Data/DevHive.Data.Tests/LenguageRepository.Tests.cs
new file mode 100644
index 0000000..f02a1e4
--- /dev/null
+++ b/src/Data/DevHive.Data.Tests/LenguageRepository.Tests.cs
@@ -0,0 +1,116 @@
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+using DevHive.Data.Models;
+using DevHive.Data.Repositories;
+using Microsoft.EntityFrameworkCore;
+using NUnit.Framework;
+
+namespace DevHive.Data.Tests
+{
+ [TestFixture]
+ public class LenguageRepositoryTests
+ {
+ private const string LANGUAGE_NAME = "Language test name";
+ protected DevHiveContext Context { get; set; }
+ protected LanguageRepository LanguageRepository { get; set; }
+
+ #region Setups
+ [SetUp]
+ public void Setup()
+ {
+ var optionsBuilder = new DbContextOptionsBuilder<DevHiveContext>()
+ .UseInMemoryDatabase(databaseName: "DevHive_Test_Database");
+
+ this.Context = new DevHiveContext(optionsBuilder.Options);
+
+ LanguageRepository = new LanguageRepository(Context);
+ }
+
+ [TearDown]
+ public void TearDown()
+ {
+ this.Context.Database.EnsureDeleted();
+ }
+ #endregion
+
+ #region GetByNameAsync
+ [Test]
+ public async Task GetByNameAsync_ReturnsTheCorrectLanguage_IfItExists()
+ {
+ await AddEntity();
+
+ Language language = this.Context.Languages.Where(x => x.Name == LANGUAGE_NAME).ToList().FirstOrDefault();
+
+ Language languageResult = await this.LanguageRepository.GetByNameAsync(LANGUAGE_NAME);
+
+ Assert.AreEqual(language.Id, languageResult.Id);
+ }
+
+ [Test]
+ public async Task GetByNameAsync_ReturnsNull_IfTechnologyDoesNotExists()
+ {
+ Language languageResult = await this.LanguageRepository.GetByNameAsync(LANGUAGE_NAME);
+
+ Assert.IsNull(languageResult);
+ }
+ #endregion
+
+ #region DoesLanguageExistAsync
+ [Test]
+ public async Task DoesLanguageExist_ReturnsTrue_IfIdExists()
+ {
+ await AddEntity();
+ Language language = this.Context.Languages.Where(x => x.Name == LANGUAGE_NAME).ToList().FirstOrDefault();
+
+ Guid id = language.Id;
+
+ bool result = await this.LanguageRepository.DoesLanguageExistAsync(id);
+
+ Assert.IsTrue(result, "DoesLanguageExistAsync returns flase when language exists");
+ }
+
+ [Test]
+ public async Task DoesLanguageExist_ReturnsFalse_IfIdDoesNotExists()
+ {
+ Guid id = Guid.NewGuid();
+
+ bool result = await this.LanguageRepository.DoesLanguageExistAsync(id);
+
+ Assert.IsFalse(result, "DoesLanguageExistAsync returns true when language does not exist");
+ }
+ #endregion
+
+ #region DoesTechnologyNameExistAsync
+ [Test]
+ public async Task DoesLanguageNameExist_ReturnsTrue_IfLanguageExists()
+ {
+ await AddEntity();
+
+ bool result = await this.LanguageRepository.DoesLanguageNameExistAsync(LANGUAGE_NAME);
+
+ Assert.IsTrue(result, "DoesLanguageNameExists returns true when language name does not exist");
+ }
+
+ [Test]
+ public async Task DoesLanguageNameExist_ReturnsFalse_IfLanguageDoesNotExists()
+ {
+ bool result = await this.LanguageRepository.DoesLanguageNameExistAsync(LANGUAGE_NAME);
+
+ Assert.False(result, "DoesTechnologyNameExistAsync returns true when language name does not exist");
+ }
+ #endregion
+
+ #region HelperMethods
+ private async Task AddEntity(string name = LANGUAGE_NAME)
+ {
+ Language language = new Language
+ {
+ Name = name
+ };
+
+ await this.LanguageRepository.AddAsync(language);
+ }
+ #endregion
+ }
+}
diff --git a/src/Data/DevHive.Data.Tests/PostRepository.Tests.cs b/src/Data/DevHive.Data.Tests/PostRepository.Tests.cs
new file mode 100644
index 0000000..6dacf0b
--- /dev/null
+++ b/src/Data/DevHive.Data.Tests/PostRepository.Tests.cs
@@ -0,0 +1,145 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using DevHive.Data.Interfaces.Repositories;
+using DevHive.Data.Models;
+using DevHive.Data.RelationModels;
+using DevHive.Data.Repositories;
+using Microsoft.EntityFrameworkCore;
+using Moq;
+using NUnit.Framework;
+
+namespace DevHive.Data.Tests
+{
+ [TestFixture]
+ public class PostRepositoryTests
+ {
+ private const string POST_MESSAGE = "Post test message";
+
+ private DevHiveContext Context { get; set; }
+
+ private Mock<IUserRepository> UserRepository { get; set; }
+
+ private PostRepository PostRepository { get; set; }
+
+ #region Setups
+ [SetUp]
+ public void Setup()
+ {
+ var optionsBuilder = new DbContextOptionsBuilder<DevHiveContext>()
+ .UseInMemoryDatabase(databaseName: "DevHive_Test_Database");
+
+ this.Context = new DevHiveContext(optionsBuilder.Options);
+
+ this.UserRepository = new Mock<IUserRepository>();
+
+ PostRepository = new PostRepository(Context, this.UserRepository.Object);
+ }
+
+ [TearDown]
+ public void TearDown()
+ {
+ this.Context.Database.EnsureDeleted();
+ }
+ #endregion
+
+ #region AddNewPostToCreator
+ // [Test]
+ // public async Task AddNewPostToCreator_ReturnsTrue_WhenNewPostIsAddedToCreator()
+ // {
+ // Post post = await this.AddEntity();
+ // User user = new User { Id = Guid.NewGuid() };
+ //
+ // this.UserRepository.Setup(p => p.GetByIdAsync(It.IsAny<Guid>())).Returns(Task.FromResult(user));
+ //
+ // bool result = await this.PostRepository.AddNewPostToCreator(user.Id, post);
+ //
+ // Assert.IsTrue(result, "AddNewPostToCreator does not return true when Post Is Added To Creator successfully");
+ // }
+ #endregion
+
+ #region GetByIdAsync
+ [Test]
+ public async Task GetByNameAsync_ReturnsTheCorrectPost_IfItExists()
+ {
+ Post post = await AddEntity();
+
+ Post resultTechnology = await this.PostRepository.GetByIdAsync(post.Id);
+
+ Assert.AreEqual(post.Id, resultTechnology.Id, "GetByIdAsync does not return the correct post");
+ }
+
+ [Test]
+ public async Task GetByIdAsync_ReturnsNull_IfTechnologyDoesNotExists()
+ {
+ Post resultPost = await this.PostRepository.GetByIdAsync(Guid.NewGuid());
+
+ Assert.IsNull(resultPost);
+ }
+ #endregion
+
+ #region GetPostByCreatorAndTimeCreatedAsync
+ [Test]
+ public async Task GetPostByCreatorAndTimeCreatedAsync_ReturnsTheCorrectPost_IfItExists()
+ {
+ Post post = await this.AddEntity();
+
+ Post resultPost = await this.PostRepository.GetPostByCreatorAndTimeCreatedAsync(post.Creator.Id, post.TimeCreated);
+
+ Assert.AreEqual(post.Id, resultPost.Id, "GetPostByCreatorAndTimeCreatedAsync does not return the corect post when it exists");
+ }
+
+ [Test]
+ public async Task GetPostByCreatorAndTimeCreatedAsync_ReturnsNull_IfThePostDoesNotExist()
+ {
+ Post post = await this.AddEntity();
+
+ Post resutPost = await this.PostRepository.GetPostByCreatorAndTimeCreatedAsync(Guid.Empty, DateTime.Now);
+
+ Assert.IsNull(resutPost, "GetPostByCreatorAndTimeCreatedAsync does not return null when the post does not exist");
+ }
+ #endregion
+
+ #region DoesPostExist
+ [Test]
+ public async Task DoesPostExist_ReturnsTrue_WhenThePostExists()
+ {
+ Post post = await this.AddEntity();
+
+ bool result = await this.PostRepository.DoesPostExist(post.Id);
+
+ Assert.IsTrue(result, "DoesPostExist does not return true whenm the Post exists");
+ }
+
+ [Test]
+ public async Task DoesPostExist_ReturnsFalse_WhenThePostDoesNotExist()
+ {
+ bool result = await this.PostRepository.DoesPostExist(Guid.Empty);
+
+ Assert.IsFalse(result, "DoesPostExist does not return false whenm the Post does not exist");
+ }
+ #endregion
+
+ #region HelperMethods
+ private async Task<Post> AddEntity(string name = POST_MESSAGE)
+ {
+ User creator = new User { Id = Guid.NewGuid() };
+ await this.Context.Users.AddAsync(creator);
+ Post post = new Post
+ {
+ Message = POST_MESSAGE,
+ Id = Guid.NewGuid(),
+ Creator = creator,
+ TimeCreated = DateTime.Now,
+ Attachments = new List<PostAttachments> { new PostAttachments { FileUrl = "kur" }, new PostAttachments { FileUrl = "za" }, new PostAttachments { FileUrl = "tva" } },
+ Comments = new List<Comment>()
+ };
+
+ await this.Context.Posts.AddAsync(post);
+ await this.Context.SaveChangesAsync();
+
+ return post;
+ }
+ #endregion
+ }
+}
diff --git a/src/Data/DevHive.Data.Tests/RoleRepository.Tests.cs b/src/Data/DevHive.Data.Tests/RoleRepository.Tests.cs
new file mode 100644
index 0000000..7f62c24
--- /dev/null
+++ b/src/Data/DevHive.Data.Tests/RoleRepository.Tests.cs
@@ -0,0 +1,119 @@
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+using DevHive.Data.Models;
+using DevHive.Data.Repositories;
+using Microsoft.EntityFrameworkCore;
+using NUnit.Framework;
+
+namespace DevHive.Data.Tests
+{
+ [TestFixture]
+ public class RoleRepositoryTests
+ {
+ private const string ROLE_NAME = "Role test name";
+
+ protected DevHiveContext Context { get; set; }
+
+ protected RoleRepository RoleRepository { get; set; }
+
+ #region Setups
+ [SetUp]
+ public void Setup()
+ {
+ var optionsBuilder = new DbContextOptionsBuilder<DevHiveContext>()
+ .UseInMemoryDatabase(databaseName: "DevHive_Test_Database");
+
+ this.Context = new DevHiveContext(optionsBuilder.Options);
+
+ RoleRepository = new RoleRepository(Context);
+ }
+
+ [TearDown]
+ public void TearDown()
+ {
+ this.Context.Database.EnsureDeleted();
+ }
+ #endregion
+
+ #region GetByNameAsync
+ [Test]
+ public async Task GetByNameAsync_ReturnsTheRole_WhenItExists()
+ {
+ Role role = await this.AddEntity();
+
+ Role resultRole = await this.RoleRepository.GetByNameAsync(role.Name);
+
+ Assert.AreEqual(role.Id, resultRole.Id, "GetByNameAsync does not return the correct role");
+ }
+
+ [Test]
+ public async Task GetByNameAsync_ReturnsNull_WhenTheRoleDoesNotExist()
+ {
+ Role resultRole = await this.RoleRepository.GetByNameAsync(ROLE_NAME);
+
+ Assert.IsNull(resultRole, "GetByNameAsync does not return when the role does not exist");
+ }
+ #endregion
+
+ #region DoesNameExist
+ [Test]
+ public async Task DoesNameExist_ReturnsTrue_WhenTheNameExists()
+ {
+ Role role = await this.AddEntity();
+
+ bool result = await this.RoleRepository.DoesNameExist(role.Name);
+
+ Assert.IsTrue(result, "DoesNameExist returns false when the role name exist");
+ }
+
+ [Test]
+ public async Task DoesNameExist_ReturnsFalse_WhenTheNameDoesNotExist()
+ {
+ bool result = await this.RoleRepository.DoesNameExist(ROLE_NAME);
+
+ Assert.IsFalse(result, "DoesNameExist returns false when the role name exist");
+ }
+ #endregion
+
+ #region DoesRoleExist
+ [Test]
+ public async Task DoesRoleExist_ReturnsTrue_IfIdExists()
+ {
+ await AddEntity();
+ Role role = this.Context.Roles.Where(x => x.Name == ROLE_NAME).ToList().FirstOrDefault();
+ Guid id = role.Id;
+
+ bool result = await this.RoleRepository.DoesRoleExist(id);
+
+ Assert.IsTrue(result, "DoesRoleExistAsync returns flase when role exists");
+ }
+
+ [Test]
+ public async Task DoesRoleExist_ReturnsFalse_IfIdDoesNotExists()
+ {
+ Guid id = Guid.NewGuid();
+
+ bool result = await this.RoleRepository.DoesRoleExist(id);
+
+ Assert.IsFalse(result, "DoesRoleExist returns true when role does not exist");
+ }
+ #endregion
+
+ #region HelperMethods
+ private async Task<Role> AddEntity(string name = ROLE_NAME)
+ {
+ Role role = new Role
+ {
+ Id = Guid.NewGuid(),
+ Name = name
+ };
+
+ this.Context.Roles.Add(role);
+ await this.Context.SaveChangesAsync();
+
+ return role;
+ }
+ #endregion
+ }
+}
diff --git a/src/Data/DevHive.Data.Tests/TechnologyRepository.Tests.cs b/src/Data/DevHive.Data.Tests/TechnologyRepository.Tests.cs
new file mode 100644
index 0000000..d25fd3b
--- /dev/null
+++ b/src/Data/DevHive.Data.Tests/TechnologyRepository.Tests.cs
@@ -0,0 +1,118 @@
+using DevHive.Data.Models;
+using DevHive.Data.Repositories;
+using Microsoft.EntityFrameworkCore;
+using NUnit.Framework;
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace DevHive.Data.Tests
+{
+ [TestFixture]
+ public class TechnologyRepositoryTests
+ {
+ private const string TECHNOLOGY_NAME = "Technology test name";
+
+ protected DevHiveContext Context { get; set; }
+
+ protected TechnologyRepository TechnologyRepository { get; set; }
+
+ #region Setups
+ [SetUp]
+ public void Setup()
+ {
+ var optionsBuilder = new DbContextOptionsBuilder<DevHiveContext>()
+ .UseInMemoryDatabase(databaseName: "DevHive_Test_Database");
+
+ this.Context = new DevHiveContext(optionsBuilder.Options);
+
+ TechnologyRepository = new TechnologyRepository(Context);
+ }
+
+ [TearDown]
+ public void TearDown()
+ {
+ this.Context.Database.EnsureDeleted();
+ }
+ #endregion
+
+ #region GetByNameAsync
+ [Test]
+ public async Task GetByNameAsync_ReturnsTheCorrectTechnology_IfItExists()
+ {
+ await AddEntity();
+
+ Technology technology = this.Context.Technologies.Where(x => x.Name == TECHNOLOGY_NAME).ToList().FirstOrDefault();
+
+ Technology resultTechnology = await this.TechnologyRepository.GetByNameAsync(TECHNOLOGY_NAME);
+
+ Assert.AreEqual(technology.Id, resultTechnology.Id);
+ }
+
+ [Test]
+ public async Task GetByNameAsync_ReturnsNull_IfTechnologyDoesNotExists()
+ {
+ Technology resultTechnology = await this.TechnologyRepository.GetByNameAsync(TECHNOLOGY_NAME);
+
+ Assert.IsNull(resultTechnology);
+ }
+ #endregion
+
+ #region DoesTechnologyExistAsync
+ [Test]
+ public async Task DoesTechnologyExist_ReturnsTrue_IfIdExists()
+ {
+ await AddEntity();
+ Technology technology = this.Context.Technologies.Where(x => x.Name == TECHNOLOGY_NAME).ToList().FirstOrDefault();
+ Guid id = technology.Id;
+
+ bool result = await this.TechnologyRepository.DoesTechnologyExistAsync(id);
+
+ Assert.IsTrue(result, "DoesTechnologyExistAsync returns flase hwen technology exists");
+ }
+
+ [Test]
+ public async Task DoesTechnologyExist_ReturnsFalse_IfIdDoesNotExists()
+ {
+ Guid id = Guid.NewGuid();
+
+ bool result = await this.TechnologyRepository.DoesTechnologyExistAsync(id);
+
+ Assert.IsFalse(result, "DoesTechnologyExistAsync returns true when technology does not exist");
+ }
+ #endregion
+
+ #region DoesTechnologyNameExistAsync
+ [Test]
+ public async Task DoesTechnologyNameExist_ReturnsTrue_IfTechnologyExists()
+ {
+ await AddEntity();
+
+ bool result = await this.TechnologyRepository.DoesTechnologyNameExistAsync(TECHNOLOGY_NAME);
+
+ Assert.IsTrue(result, "DoesTechnologyNameExists returns true when technology name does not exist");
+ }
+
+ [Test]
+ public async Task DoesTechnologyNameExist_ReturnsFalse_IfTechnologyDoesNotExists()
+ {
+ bool result = await this.TechnologyRepository.DoesTechnologyNameExistAsync(TECHNOLOGY_NAME);
+
+ Assert.False(result, "DoesTechnologyNameExistAsync returns true when technology name does not exist");
+ }
+ #endregion
+
+ #region HelperMethods
+ private async Task AddEntity(string name = TECHNOLOGY_NAME)
+ {
+ Technology technology = new Technology
+ {
+ Name = name
+ };
+
+ this.Context.Technologies.Add(technology);
+ await this.Context.SaveChangesAsync();
+ }
+ #endregion
+ }
+}
diff --git a/src/Data/DevHive.Data.Tests/UserRepositoryTests.cs b/src/Data/DevHive.Data.Tests/UserRepositoryTests.cs
new file mode 100644
index 0000000..43e9a36
--- /dev/null
+++ b/src/Data/DevHive.Data.Tests/UserRepositoryTests.cs
@@ -0,0 +1,350 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using DevHive.Data.Models;
+using DevHive.Data.Repositories;
+using Microsoft.EntityFrameworkCore;
+using NUnit.Framework;
+
+namespace DevHive.Data.Tests
+{
+ [TestFixture]
+ public class UserRepositoryTests
+ {
+ private DevHiveContext _context;
+ private UserRepository _userRepository;
+
+ #region Setups
+ [SetUp]
+ public void Setup()
+ {
+ var options = new DbContextOptionsBuilder<DevHiveContext>()
+ .UseInMemoryDatabase("DevHive_UserRepository_Database");
+
+ this._context = new DevHiveContext(options.Options);
+ this._userRepository = new UserRepository(_context);
+ }
+
+ [TearDown]
+ public async Task Teardown()
+ {
+ await this._context.Database.EnsureDeletedAsync();
+ }
+ #endregion
+
+ #region QueryAll
+ // [Test]
+ // public async Task QueryAll_ShouldReturnAllUsersFromDatabase_WhenTheyExist()
+ // {
+ // //Arrange
+ // User dummyUserOne = CreateDummyUser();
+ // User dummyUserTwo = CreateAnotherDummyUser();
+ //
+ // await this._userRepository.AddAsync(dummyUserOne);
+ // await this._userRepository.AddAsync(dummyUserTwo);
+ //
+ // //Act
+ // IEnumerable<User> users = this._userRepository.QueryAll();
+ //
+ // //Assert
+ // Assert.AreEqual(2, users.Count(), "Method doesn't return all instances of user");
+ // }
+
+ // [Test]
+ // public void QueryAll_ReturnsNull_WhenNoUsersExist()
+ // {
+ // IEnumerable<User> users = this._userRepository.QueryAll();
+ //
+ // Assert.AreEqual(0, users.Count(), "Method returns Users when there are non");
+ // }
+ #endregion
+
+ #region EditAsync
+ [Test]
+ public async Task EditAsync_ReturnsTrue_WhenUserIsUpdatedSuccessfully()
+ {
+ User oldUser = this.CreateDummyUser();
+ this._context.Users.Add(oldUser);
+ await this._context.SaveChangesAsync();
+
+ oldUser.UserName = "SuperSecretUserName";
+ bool result = await this._userRepository.EditAsync(oldUser.Id, oldUser);
+
+ Assert.IsTrue(result, "EditAsync does not return true when User is updated successfully");
+ }
+ #endregion
+
+ #region GetByIdAsync
+ [Test]
+ public async Task GetByIdAsync_ReturnsTheUse_WhenItExists()
+ {
+ User dummyUserOne = CreateDummyUser();
+ await this._userRepository.AddAsync(dummyUserOne);
+
+ User resultUser = await this._userRepository.GetByIdAsync(dummyUserOne.Id);
+
+ Assert.AreEqual(dummyUserOne.UserName, resultUser.UserName);
+ }
+
+ [Test]
+ public async Task GetByIdAsync_ReturnsNull_WhenUserDoesNotExist()
+ {
+ Guid id = Guid.NewGuid();
+
+ User resultUser = await this._userRepository.GetByIdAsync(id);
+
+ Assert.IsNull(resultUser);
+ }
+ #endregion
+
+ #region GetByUsernameAsync
+ [Test]
+ public async Task GetByUsernameAsync_ReturnsUserFromDatabase_WhenItExists()
+ {
+ //Arrange
+ User dummyUser = CreateDummyUser();
+ await this._userRepository.AddAsync(dummyUser);
+ string username = dummyUser.UserName;
+
+ //Act
+ User user = await this._userRepository.GetByUsernameAsync(username);
+
+ //Assert
+ Assert.AreEqual(dummyUser.Id, user.Id, "Method doesn't get the proper user from database");
+ }
+
+ [Test]
+ public async Task GetByUsernameAsync_ReturnsNull_WhenUserDoesNotExist()
+ {
+ //Act
+ User user = await this._userRepository.GetByUsernameAsync(null);
+
+ //Assert
+ Assert.IsNull(user, "Method returns user when it does not exist");
+ }
+ #endregion
+
+ #region DoesUserExistAsync
+ [Test]
+ public async Task DoesUserExistAsync_ReturnsTrue_WhenUserExists()
+ {
+ User dummyUser = this.CreateDummyUser();
+ this._context.Users.Add(dummyUser);
+ await this._context.SaveChangesAsync();
+
+ bool result = await this._userRepository.DoesUserExistAsync(dummyUser.Id);
+
+ Assert.IsTrue(result, "DoesUserExistAsync does not return true when user exists");
+ }
+
+ [Test]
+ public async Task DoesUserExistAsync_ReturnsFalse_WhenUserDoesNotExist()
+ {
+ Guid id = Guid.NewGuid();
+
+ bool result = await this._userRepository.DoesUserExistAsync(id);
+
+ Assert.IsFalse(result, "DoesUserExistAsync does not return false when user does not exist");
+ }
+ #endregion
+
+ #region DoesUserNameExistAsync
+ [Test]
+ public async Task DoesUsernameExistAsync_ReturnsTrue_WhenUserWithTheNameExists()
+ {
+ User dummyUser = this.CreateDummyUser();
+ this._context.Users.Add(dummyUser);
+ await this._context.SaveChangesAsync();
+
+ bool result = await this._userRepository.DoesUsernameExistAsync(dummyUser.UserName);
+
+ Assert.IsTrue(result, "DoesUserNameExistAsync does not return true when username exists");
+ }
+
+ [Test]
+ public async Task DoesUsernameExistAsync_ReturnsFalse_WhenUserWithTheNameDoesNotExist()
+ {
+ string userName = "Fake name";
+
+ bool result = await this._userRepository.DoesUsernameExistAsync(userName);
+
+ Assert.IsFalse(result, "DoesUserNameExistAsync does not return false when username does not exist");
+ }
+ #endregion
+
+ #region DoesEmailExistAsync
+ [Test]
+ public async Task DoesEmailExistAsync_ReturnsTrue_WhenUserWithTheEmailExists()
+ {
+ User dummyUser = this.CreateDummyUser();
+ this._context.Users.Add(dummyUser);
+ await this._context.SaveChangesAsync();
+
+ bool result = await this._userRepository.DoesEmailExistAsync(dummyUser.Email);
+
+ Assert.IsTrue(result, "DoesUserNameExistAsync does not return true when email exists");
+ }
+
+ [Test]
+ public async Task DoesEmailExistAsync_ReturnsFalse_WhenUserWithTheEmailDoesNotExist()
+ {
+ string email = "Fake email";
+
+ bool result = await this._userRepository.DoesUsernameExistAsync(email);
+
+ Assert.IsFalse(result, "DoesUserNameExistAsync does not return false when email does not exist");
+ }
+ #endregion
+
+ #region DoesUserHaveThisFriendAsync
+ //[Test]
+ //public async Task DoesUserHaveThisFriendAsync_ReturnsTrue_WhenUserHasTheGivenFriend()
+ //{
+ // User dummyUser = this.CreateDummyUser();
+ // User anotherDummyUser = this.CreateAnotherDummyUser();
+ // HashSet<User> friends = new HashSet<User>
+ // {
+ // anotherDummyUser
+ // };
+ // dummyUser.Friends = friends;
+
+ // this._context.Users.Add(dummyUser);
+ // this._context.Users.Add(anotherDummyUser);
+ // await this._context.SaveChangesAsync();
+
+ // bool result = await this._userRepository.DoesUserHaveThisFriendAsync(dummyUser.Id, anotherDummyUser.Id);
+
+ // Assert.IsTrue(result, "DoesUserHaveThisFriendAsync does not return true when user has the given friend");
+ //}
+
+ // [Test]
+ // public async Task DoesUserHaveThisFriendAsync_ReturnsFalse_WhenUserDoesNotHaveTheGivenFriend()
+ // {
+ // User dummyUser = this.CreateDummyUser();
+ // User anotherDummyUser = this.CreateAnotherDummyUser();
+ //
+ // this._context.Users.Add(dummyUser);
+ // this._context.Users.Add(anotherDummyUser);
+ // await this._context.SaveChangesAsync();
+ //
+ // bool result = await this._userRepository.DoesUserHaveThisFriendAsync(dummyUser.Id, anotherDummyUser.Id);
+ //
+ // Assert.IsFalse(result, "DoesUserHaveThisFriendAsync does not return false when user des not have the given friend");
+ // }
+ #endregion
+
+ #region DoesUserHaveThisUsername
+ [Test]
+ public async Task DoesUserHaveThisUsername_ReturnsTrue_WhenUserHasTheGivenUsername()
+ {
+ User dummyUser = this.CreateDummyUser();
+ this._context.Users.Add(dummyUser);
+ await this._context.SaveChangesAsync();
+
+ bool result = this._userRepository.DoesUserHaveThisUsername(dummyUser.Id, dummyUser.UserName);
+
+ Assert.IsTrue(result, "DoesUserHaveThisUsername does not return true when the user has the given name");
+ }
+
+ [Test]
+ public async Task DoesUserHaveThisUsername_ReturnsFalse_WhenUserDoesntHaveTheGivenUsername()
+ {
+ string username = "Fake username";
+ User dummyUser = this.CreateDummyUser();
+ this._context.Users.Add(dummyUser);
+ await this._context.SaveChangesAsync();
+
+ bool result = this._userRepository.DoesUserHaveThisUsername(dummyUser.Id, username);
+
+ Assert.IsFalse(result, "DoesUserNameExistAsync does not return false when user doesnt have the given name");
+ }
+ #endregion
+
+ #region HelperMethods
+ private User CreateDummyUser()
+ {
+ HashSet<Language> languages = new()
+ {
+ new Language()
+ {
+ Id = Guid.NewGuid(),
+ Name = "csharp"
+ },
+ };
+
+ HashSet<Technology> technologies = new()
+ {
+ new Technology()
+ {
+ Id = Guid.NewGuid(),
+ Name = "ASP.NET Core"
+ },
+ };
+
+ HashSet<Role> roles = new()
+ {
+ new Role()
+ {
+ Id = Guid.NewGuid(),
+ Name = Role.DefaultRole
+ },
+ };
+
+ return new()
+ {
+ Id = Guid.NewGuid(),
+ UserName = "dummyUser",
+ FirstName = "Spas",
+ LastName = "Spasov",
+ Email = "abv@abv.bg",
+ Languages = languages,
+ Technologies = technologies,
+ Roles = roles
+ };
+ }
+
+ private User CreateAnotherDummyUser()
+ {
+ HashSet<Language> languages = new()
+ {
+ new Language()
+ {
+ Id = Guid.NewGuid(),
+ Name = "typescript"
+ },
+ };
+
+ HashSet<Technology> technologies = new()
+ {
+ new Technology()
+ {
+ Id = Guid.NewGuid(),
+ Name = "Angular"
+ },
+ };
+
+ HashSet<Role> roles = new()
+ {
+ new Role()
+ {
+ Id = Guid.NewGuid(),
+ Name = Role.DefaultRole
+ },
+ };
+
+ return new()
+ {
+ Id = Guid.NewGuid(),
+ UserName = "anotherDummyUser",
+ FirstName = "Alex",
+ LastName = "Spiridonov",
+ Email = "a_spiridonov@abv.bg",
+ Languages = languages,
+ Technologies = technologies,
+ Roles = roles
+ };
+ }
+ #endregion
+ }
+}
diff --git a/src/Data/DevHive.Data/ConnectionString.json b/src/Data/DevHive.Data/ConnectionString.json
new file mode 100644
index 0000000..c8300b2
--- /dev/null
+++ b/src/Data/DevHive.Data/ConnectionString.json
@@ -0,0 +1,5 @@
+{
+ "ConnectionStrings": {
+ "DEV": "Server=localhost;Port=5432;Database=API;User Id=postgres;Password=password;"
+ }
+} \ No newline at end of file
diff --git a/src/Data/DevHive.Data/DevHive.Data.csproj b/src/Data/DevHive.Data/DevHive.Data.csproj
new file mode 100644
index 0000000..62b61dc
--- /dev/null
+++ b/src/Data/DevHive.Data/DevHive.Data.csproj
@@ -0,0 +1,34 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <TargetFramework>net5.0</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="AutoMapper" Version="10.1.1" />
+ <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="8.1.0" />
+
+ <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="5.0.1" />
+
+ <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.1">
+ <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+ <PrivateAssets>all</PrivateAssets>
+ </PackageReference>
+
+ <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="5.0.0" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\DevHive.Data.Models\DevHive.Data.Models.csproj" />
+
+ <ProjectReference Include="..\DevHive.Data.Tests\DevHive.Data.Tests.csproj" />
+
+ <ProjectReference Include="..\..\Common\DevHive.Common.Models\DevHive.Common.csproj" />
+ </ItemGroup>
+
+ <PropertyGroup>
+ <EnableNETAnalyzers>true</EnableNETAnalyzers>
+ <AnalysisLevel>latest</AnalysisLevel>
+ </PropertyGroup>
+
+</Project>
diff --git a/src/Data/DevHive.Data/DevHiveContext.cs b/src/Data/DevHive.Data/DevHiveContext.cs
new file mode 100644
index 0000000..9de33c3
--- /dev/null
+++ b/src/Data/DevHive.Data/DevHiveContext.cs
@@ -0,0 +1,115 @@
+using System;
+using DevHive.Data.Models;
+using DevHive.Data.RelationModels;
+using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore;
+
+namespace DevHive.Data
+{
+ public class DevHiveContext : IdentityDbContext<User, Role, Guid>
+ {
+ public DevHiveContext(DbContextOptions<DevHiveContext> options)
+ : base(options) { }
+
+ public DbSet<Technology> Technologies { get; set; }
+ public DbSet<Language> Languages { get; set; }
+ public DbSet<Post> Posts { get; set; }
+ public DbSet<PostAttachments> PostAttachments { get; set; }
+ public DbSet<Comment> Comments { get; set; }
+ public DbSet<Rating> Rating { get; set; }
+ public DbSet<RatedPost> RatedPost { get; set; }
+ public DbSet<UserRate> UserRate { get; set; }
+
+ protected override void OnModelCreating(ModelBuilder builder)
+ {
+ /* User */
+ builder.Entity<User>()
+ .HasIndex(x => x.UserName)
+ .IsUnique();
+
+ builder.Entity<User>()
+ .HasOne(x => x.ProfilePicture)
+ .WithOne(x => x.User)
+ .HasForeignKey<ProfilePicture>(x => x.UserId);
+
+ /* Roles */
+ builder.Entity<User>()
+ .HasMany(x => x.Roles)
+ .WithMany(x => x.Users);
+
+ /* Languages */
+ builder.Entity<User>()
+ .HasMany(x => x.Languages)
+ .WithMany(x => x.Users)
+ .UsingEntity(x => x.ToTable("LanguageUser"));
+
+ builder.Entity<Language>()
+ .HasMany(x => x.Users)
+ .WithMany(x => x.Languages)
+ .UsingEntity(x => x.ToTable("LanguageUser"));
+
+ /* Technologies */
+ builder.Entity<User>()
+ .HasMany(x => x.Technologies)
+ .WithMany(x => x.Users)
+ .UsingEntity(x => x.ToTable("TechnologyUser"));
+
+ builder.Entity<Technology>()
+ .HasMany(x => x.Users)
+ .WithMany(x => x.Technologies)
+ .UsingEntity(x => x.ToTable("TechnologyUser"));
+
+ /* Post */
+ builder.Entity<Post>()
+ .HasOne(x => x.Creator)
+ .WithMany(x => x.Posts);
+
+ builder.Entity<Post>()
+ .HasMany(x => x.Comments)
+ .WithOne(x => x.Post);
+
+ /* Post attachments */
+ builder.Entity<PostAttachments>()
+ .HasOne(x => x.Post)
+ .WithMany(x => x.Attachments);
+
+ /* Comment */
+ builder.Entity<Comment>()
+ .HasOne(x => x.Post)
+ .WithMany(x => x.Comments);
+
+ builder.Entity<Comment>()
+ .HasOne(x => x.Creator)
+ .WithMany(x => x.Comments);
+
+ /* Rating */
+ builder.Entity<Rating>()
+ .HasKey(x => x.Id);
+
+ builder.Entity<Rating>()
+ .HasOne(x => x.Post)
+ .WithOne(x => x.Rating)
+ .HasForeignKey<Rating>(x => x.PostId);
+
+ builder.Entity<Post>()
+ .HasOne(x => x.Rating)
+ .WithOne(x => x.Post);
+
+ /* User Rated Posts */
+ builder.Entity<RatedPost>()
+ .HasKey(x => new { x.UserId, x.PostId });
+
+ builder.Entity<RatedPost>()
+ .HasOne(x => x.User)
+ .WithMany(x => x.RatedPosts);
+
+ builder.Entity<RatedPost>()
+ .HasOne(x => x.Post);
+
+ builder.Entity<User>()
+ .HasMany(x => x.RatedPosts);
+
+ base.OnModelCreating(builder);
+ }
+ }
+}
diff --git a/src/Data/DevHive.Data/DevHiveContextFactory.cs b/src/Data/DevHive.Data/DevHiveContextFactory.cs
new file mode 100644
index 0000000..f4849d7
--- /dev/null
+++ b/src/Data/DevHive.Data/DevHiveContextFactory.cs
@@ -0,0 +1,23 @@
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Design;
+using Microsoft.Extensions.Configuration;
+using System.IO;
+
+namespace DevHive.Data
+{
+ public class DevHiveContextFactory : IDesignTimeDbContextFactory<DevHiveContext>
+ {
+ public DevHiveContext CreateDbContext(string[] args)
+ {
+ var configuration = new ConfigurationBuilder()
+ .SetBasePath(Directory.GetCurrentDirectory())
+ .AddJsonFile("ConnectionString.json")
+ .Build();
+
+ var optionsBuilder = new DbContextOptionsBuilder<DevHiveContext>()
+ .UseNpgsql(configuration.GetConnectionString("DEV"));
+
+ return new DevHiveContext(optionsBuilder.Options);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Data/DevHive.Data/Interfaces/Models/IComment.cs b/src/Data/DevHive.Data/Interfaces/Models/IComment.cs
new file mode 100644
index 0000000..97c1578
--- /dev/null
+++ b/src/Data/DevHive.Data/Interfaces/Models/IComment.cs
@@ -0,0 +1,16 @@
+using System;
+using DevHive.Data.Models;
+
+namespace DevHive.Data.Interfaces.Models
+{
+ public interface IComment : IModel
+ {
+ Post Post { get; set; }
+
+ User Creator { get; set; }
+
+ string Message { get; set; }
+
+ DateTime TimeCreated { get; set; }
+ }
+}
diff --git a/src/Data/DevHive.Data/Interfaces/Models/ILanguage.cs b/src/Data/DevHive.Data/Interfaces/Models/ILanguage.cs
new file mode 100644
index 0000000..9eed09d
--- /dev/null
+++ b/src/Data/DevHive.Data/Interfaces/Models/ILanguage.cs
@@ -0,0 +1,11 @@
+using System.Collections.Generic;
+using DevHive.Data.Models;
+
+namespace DevHive.Data.Interfaces.Models
+{
+ public interface ILanguage : IModel
+ {
+ string Name { get; set; }
+ HashSet<User> Users { get; set; }
+ }
+}
diff --git a/src/Data/DevHive.Data/Interfaces/Models/IModel.cs b/src/Data/DevHive.Data/Interfaces/Models/IModel.cs
new file mode 100644
index 0000000..f903af3
--- /dev/null
+++ b/src/Data/DevHive.Data/Interfaces/Models/IModel.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace DevHive.Data.Interfaces.Models
+{
+ public interface IModel
+ {
+ Guid Id { get; set; }
+ }
+}
diff --git a/src/Data/DevHive.Data/Interfaces/Models/IPost.cs b/src/Data/DevHive.Data/Interfaces/Models/IPost.cs
new file mode 100644
index 0000000..712d955
--- /dev/null
+++ b/src/Data/DevHive.Data/Interfaces/Models/IPost.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using DevHive.Data.Models;
+using DevHive.Data.RelationModels;
+
+namespace DevHive.Data.Interfaces.Models
+{
+ public interface IPost : IModel
+ {
+ User Creator { get; set; }
+
+ string Message { get; set; }
+
+ DateTime TimeCreated { get; set; }
+
+ List<Comment> Comments { get; set; }
+
+ // Rating Rating { get; set; }
+
+ List<PostAttachments> Attachments { get; set; }
+ }
+}
diff --git a/src/Data/DevHive.Data/Interfaces/Models/IProfilePicture.cs b/src/Data/DevHive.Data/Interfaces/Models/IProfilePicture.cs
new file mode 100644
index 0000000..c3fcbea
--- /dev/null
+++ b/src/Data/DevHive.Data/Interfaces/Models/IProfilePicture.cs
@@ -0,0 +1,13 @@
+using System;
+using DevHive.Data.Models;
+
+namespace DevHive.Data.Interfaces.Models
+{
+ public interface IProfilePicture : IModel
+ {
+ Guid UserId { get; set; }
+ User User { get; set; }
+
+ string PictureURL { get; set; }
+ }
+}
diff --git a/src/Data/DevHive.Data/Interfaces/Models/IRating.cs b/src/Data/DevHive.Data/Interfaces/Models/IRating.cs
new file mode 100644
index 0000000..d1b968f
--- /dev/null
+++ b/src/Data/DevHive.Data/Interfaces/Models/IRating.cs
@@ -0,0 +1,14 @@
+using System.Collections.Generic;
+using DevHive.Data.Models;
+
+namespace DevHive.Data.Interfaces.Models
+{
+ public interface IRating : IModel
+ {
+ // Post Post { get; set; }
+
+ int Rate { get; set; }
+
+ // HashSet<User> UsersThatRated { get; set; }
+ }
+}
diff --git a/src/Data/DevHive.Data/Interfaces/Models/IRole.cs b/src/Data/DevHive.Data/Interfaces/Models/IRole.cs
new file mode 100644
index 0000000..c8b7068
--- /dev/null
+++ b/src/Data/DevHive.Data/Interfaces/Models/IRole.cs
@@ -0,0 +1,10 @@
+using System.Collections.Generic;
+using DevHive.Data.Models;
+
+namespace DevHive.Data.Interfaces.Models
+{
+ public interface IRole
+ {
+ HashSet<User> Users { get; set; }
+ }
+}
diff --git a/src/Data/DevHive.Data/Interfaces/Models/ITechnology.cs b/src/Data/DevHive.Data/Interfaces/Models/ITechnology.cs
new file mode 100644
index 0000000..153f75f
--- /dev/null
+++ b/src/Data/DevHive.Data/Interfaces/Models/ITechnology.cs
@@ -0,0 +1,11 @@
+using System.Collections.Generic;
+using DevHive.Data.Models;
+
+namespace DevHive.Data.Interfaces.Models
+{
+ public interface ITechnology : IModel
+ {
+ string Name { get; set; }
+ HashSet<User> Users { get; set; }
+ }
+}
diff --git a/src/Data/DevHive.Data/Interfaces/Models/IUser.cs b/src/Data/DevHive.Data/Interfaces/Models/IUser.cs
new file mode 100644
index 0000000..fcd741c
--- /dev/null
+++ b/src/Data/DevHive.Data/Interfaces/Models/IUser.cs
@@ -0,0 +1,21 @@
+using System.Collections.Generic;
+using DevHive.Data.Models;
+using DevHive.Data.RelationModels;
+
+namespace DevHive.Data.Interfaces.Models
+{
+ public interface IUser : IModel
+ {
+ string FirstName { get; set; }
+
+ string LastName { get; set; }
+
+ ProfilePicture ProfilePicture { get; set; }
+
+ HashSet<Language> Languages { get; set; }
+
+ HashSet<Technology> Technologies { get; set; }
+
+ HashSet<Role> Roles { get; set; }
+ }
+}
diff --git a/src/Data/DevHive.Data/Interfaces/Repositories/ICommentRepository.cs b/src/Data/DevHive.Data/Interfaces/Repositories/ICommentRepository.cs
new file mode 100644
index 0000000..267f251
--- /dev/null
+++ b/src/Data/DevHive.Data/Interfaces/Repositories/ICommentRepository.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using DevHive.Data.Models;
+using DevHive.Data.Repositories.Interfaces;
+
+namespace DevHive.Data.Interfaces.Repositories
+{
+ public interface ICommentRepository : IRepository<Comment>
+ {
+ Task<List<Comment>> GetPostComments(Guid postId);
+
+ Task<bool> DoesCommentExist(Guid id);
+ Task<Comment> GetCommentByIssuerAndTimeCreatedAsync(Guid issuerId, DateTime timeCreated);
+ }
+}
diff --git a/src/Data/DevHive.Data/Interfaces/Repositories/IFeedRepository.cs b/src/Data/DevHive.Data/Interfaces/Repositories/IFeedRepository.cs
new file mode 100644
index 0000000..7262510
--- /dev/null
+++ b/src/Data/DevHive.Data/Interfaces/Repositories/IFeedRepository.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using DevHive.Data.Models;
+
+namespace DevHive.Data.Interfaces.Repositories
+{
+ public interface IFeedRepository
+ {
+ Task<List<Post>> GetFriendsPosts(List<User> friendsList, DateTime firstRequestIssued, int pageNumber, int pageSize);
+ Task<List<Post>> GetUsersPosts(User user, DateTime firstRequestIssued, int pageNumber, int pageSize);
+ }
+}
diff --git a/src/Data/DevHive.Data/Interfaces/Repositories/ILanguageRepository.cs b/src/Data/DevHive.Data/Interfaces/Repositories/ILanguageRepository.cs
new file mode 100644
index 0000000..db2949a
--- /dev/null
+++ b/src/Data/DevHive.Data/Interfaces/Repositories/ILanguageRepository.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using DevHive.Data.Models;
+using DevHive.Data.Repositories.Interfaces;
+
+namespace DevHive.Data.Interfaces.Repositories
+{
+ public interface ILanguageRepository : IRepository<Language>
+ {
+ HashSet<Language> GetLanguages();
+ Task<Language> GetByNameAsync(string name);
+
+ Task<bool> DoesLanguageExistAsync(Guid id);
+ Task<bool> DoesLanguageNameExistAsync(string languageName);
+ }
+}
diff --git a/src/Data/DevHive.Data/Interfaces/Repositories/IPostRepository.cs b/src/Data/DevHive.Data/Interfaces/Repositories/IPostRepository.cs
new file mode 100644
index 0000000..9f7cf85
--- /dev/null
+++ b/src/Data/DevHive.Data/Interfaces/Repositories/IPostRepository.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using DevHive.Data.Models;
+using DevHive.Data.Repositories.Interfaces;
+
+namespace DevHive.Data.Interfaces.Repositories
+{
+ public interface IPostRepository : IRepository<Post>
+ {
+ Task<bool> AddNewPostToCreator(Guid userId, Post post);
+
+ Task<Post> GetPostByCreatorAndTimeCreatedAsync(Guid issuerId, DateTime timeCreated);
+ Task<List<string>> GetFileUrls(Guid postId);
+
+ Task<bool> DoesPostExist(Guid postId);
+ Task<bool> DoesPostHaveFiles(Guid postId);
+ }
+}
diff --git a/src/Data/DevHive.Data/Interfaces/Repositories/IRatingRepository.cs b/src/Data/DevHive.Data/Interfaces/Repositories/IRatingRepository.cs
new file mode 100644
index 0000000..f77f301
--- /dev/null
+++ b/src/Data/DevHive.Data/Interfaces/Repositories/IRatingRepository.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Threading.Tasks;
+using DevHive.Data.Models;
+using DevHive.Data.Repositories.Interfaces;
+
+namespace DevHive.Data.Interfaces.Repositories
+{
+ public interface IRatingRepository : IRepository<Rating>
+ {
+ Task<Rating> GetRatingByPostId(Guid postId);
+ Task<bool> UserRatedPost(Guid userId, Guid postId);
+ }
+}
diff --git a/src/Data/DevHive.Data/Interfaces/Repositories/IRepository.cs b/src/Data/DevHive.Data/Interfaces/Repositories/IRepository.cs
new file mode 100644
index 0000000..0d11cd3
--- /dev/null
+++ b/src/Data/DevHive.Data/Interfaces/Repositories/IRepository.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Threading.Tasks;
+
+namespace DevHive.Data.Repositories.Interfaces
+{
+ public interface IRepository<TEntity>
+ where TEntity : class
+ {
+ //Add Entity to database
+ Task<bool> AddAsync(TEntity entity);
+
+ //Find entity by id
+ Task<TEntity> GetByIdAsync(Guid id);
+
+ //Modify Entity from database
+ Task<bool> EditAsync(Guid id, TEntity newEntity);
+
+ //Delete Entity from database
+ Task<bool> DeleteAsync(TEntity entity);
+ }
+}
diff --git a/src/Data/DevHive.Data/Interfaces/Repositories/IRoleRepository.cs b/src/Data/DevHive.Data/Interfaces/Repositories/IRoleRepository.cs
new file mode 100644
index 0000000..e834369
--- /dev/null
+++ b/src/Data/DevHive.Data/Interfaces/Repositories/IRoleRepository.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Threading.Tasks;
+using DevHive.Data.Models;
+using DevHive.Data.Repositories.Interfaces;
+
+namespace DevHive.Data.Interfaces.Repositories
+{
+ public interface IRoleRepository : IRepository<Role>
+ {
+ Task<Role> GetByNameAsync(string name);
+
+ Task<bool> DoesNameExist(string name);
+ Task<bool> DoesRoleExist(Guid id);
+ }
+}
diff --git a/src/Data/DevHive.Data/Interfaces/Repositories/ITechnologyRepository.cs b/src/Data/DevHive.Data/Interfaces/Repositories/ITechnologyRepository.cs
new file mode 100644
index 0000000..9126bfc
--- /dev/null
+++ b/src/Data/DevHive.Data/Interfaces/Repositories/ITechnologyRepository.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using DevHive.Data.Models;
+using DevHive.Data.Repositories.Interfaces;
+
+namespace DevHive.Data.Interfaces.Repositories
+{
+ public interface ITechnologyRepository : IRepository<Technology>
+ {
+ Task<Technology> GetByNameAsync(string name);
+ HashSet<Technology> GetTechnologies();
+
+ Task<bool> DoesTechnologyExistAsync(Guid id);
+ Task<bool> DoesTechnologyNameExistAsync(string technologyName);
+ }
+}
diff --git a/src/Data/DevHive.Data/Interfaces/Repositories/IUserRepository.cs b/src/Data/DevHive.Data/Interfaces/Repositories/IUserRepository.cs
new file mode 100644
index 0000000..5ebe3d3
--- /dev/null
+++ b/src/Data/DevHive.Data/Interfaces/Repositories/IUserRepository.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using DevHive.Data.Models;
+using DevHive.Data.Repositories.Interfaces;
+
+namespace DevHive.Data.Interfaces.Repositories
+{
+ public interface IUserRepository : IRepository<User>
+ {
+ //Read
+ Task<User> GetByUsernameAsync(string username);
+ Task<bool> UpdateProfilePicture(Guid userId, string pictureUrl);
+
+ //Validations
+ Task<bool> ValidateFriendsCollectionAsync(List<string> usernames);
+ Task<bool> DoesEmailExistAsync(string email);
+ Task<bool> DoesUserExistAsync(Guid id);
+ Task<bool> DoesUsernameExistAsync(string username);
+ bool DoesUserHaveThisUsername(Guid id, string username);
+ }
+}
diff --git a/src/Data/DevHive.Data/Migrations/20210205140955_rating.Designer.cs b/src/Data/DevHive.Data/Migrations/20210205140955_rating.Designer.cs
new file mode 100644
index 0000000..8d2adc4
--- /dev/null
+++ b/src/Data/DevHive.Data/Migrations/20210205140955_rating.Designer.cs
@@ -0,0 +1,665 @@
+// <auto-generated />
+using System;
+using System.Collections.Generic;
+using DevHive.Data;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+namespace DevHive.Data.Migrations
+{
+ [DbContext(typeof(DevHiveContext))]
+ [Migration("20210205140955_rating")]
+ partial class rating
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .UseIdentityByDefaultColumns()
+ .HasAnnotation("Relational:MaxIdentifierLength", 63)
+ .HasAnnotation("ProductVersion", "5.0.1");
+
+ modelBuilder.Entity("DevHive.Data.Models.Comment", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<Guid?>("CreatorId")
+ .HasColumnType("uuid");
+
+ b.Property<string>("Message")
+ .HasColumnType("text");
+
+ b.Property<Guid?>("PostId")
+ .HasColumnType("uuid");
+
+ b.Property<DateTime>("TimeCreated")
+ .HasColumnType("timestamp without time zone");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CreatorId");
+
+ b.HasIndex("PostId");
+
+ b.ToTable("Comments");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Language", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<string>("Name")
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("Languages");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Post", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<Guid?>("CreatorId")
+ .HasColumnType("uuid");
+
+ b.Property<List<string>>("FileUrls")
+ .HasColumnType("text[]");
+
+ b.Property<string>("Message")
+ .HasColumnType("text");
+
+ b.Property<DateTime>("TimeCreated")
+ .HasColumnType("timestamp without time zone");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CreatorId");
+
+ b.ToTable("Posts");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.ProfilePicture", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<string>("PictureURL")
+ .HasColumnType("text");
+
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId")
+ .IsUnique();
+
+ b.ToTable("ProfilePicture");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Rating", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("PostId")
+ .HasColumnType("uuid");
+
+ b.Property<int>("Rate")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("PostId")
+ .IsUnique();
+
+ b.ToTable("Rating");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Role", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<string>("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasColumnType("text");
+
+ b.Property<string>("Name")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property<string>("NormalizedName")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedName")
+ .IsUnique()
+ .HasDatabaseName("RoleNameIndex");
+
+ b.ToTable("AspNetRoles");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Technology", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<string>("Name")
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("Technologies");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.User", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<int>("AccessFailedCount")
+ .HasColumnType("integer");
+
+ b.Property<string>("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasColumnType("text");
+
+ b.Property<string>("Email")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property<bool>("EmailConfirmed")
+ .HasColumnType("boolean");
+
+ b.Property<string>("FirstName")
+ .HasColumnType("text");
+
+ b.Property<string>("LastName")
+ .HasColumnType("text");
+
+ b.Property<bool>("LockoutEnabled")
+ .HasColumnType("boolean");
+
+ b.Property<DateTimeOffset?>("LockoutEnd")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property<string>("NormalizedEmail")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property<string>("NormalizedUserName")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property<string>("PasswordHash")
+ .HasColumnType("text");
+
+ b.Property<string>("PhoneNumber")
+ .HasColumnType("text");
+
+ b.Property<bool>("PhoneNumberConfirmed")
+ .HasColumnType("boolean");
+
+ b.Property<string>("SecurityStamp")
+ .HasColumnType("text");
+
+ b.Property<bool>("TwoFactorEnabled")
+ .HasColumnType("boolean");
+
+ b.Property<string>("UserName")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedEmail")
+ .HasDatabaseName("EmailIndex");
+
+ b.HasIndex("NormalizedUserName")
+ .IsUnique()
+ .HasDatabaseName("UserNameIndex");
+
+ b.HasIndex("UserName")
+ .IsUnique();
+
+ b.ToTable("AspNetUsers");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.RatedPost", b =>
+ {
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("PostId")
+ .HasColumnType("uuid");
+
+ b.HasKey("UserId", "PostId");
+
+ b.HasIndex("PostId");
+
+ b.ToTable("RatedPosts");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.UserFriend", b =>
+ {
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("FriendId")
+ .HasColumnType("uuid");
+
+ b.HasKey("UserId", "FriendId");
+
+ b.HasIndex("FriendId");
+
+ b.ToTable("UserFriends");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.UserRate", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<bool>("Liked")
+ .HasColumnType("boolean");
+
+ b.Property<Guid?>("PostId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid?>("UserId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("PostId");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("UserRates");
+ });
+
+ modelBuilder.Entity("LanguageUser", b =>
+ {
+ b.Property<Guid>("LanguagesId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("UsersId")
+ .HasColumnType("uuid");
+
+ b.HasKey("LanguagesId", "UsersId");
+
+ b.HasIndex("UsersId");
+
+ b.ToTable("LanguageUser");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .UseIdentityByDefaultColumn();
+
+ b.Property<string>("ClaimType")
+ .HasColumnType("text");
+
+ b.Property<string>("ClaimValue")
+ .HasColumnType("text");
+
+ b.Property<Guid>("RoleId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetRoleClaims");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .UseIdentityByDefaultColumn();
+
+ b.Property<string>("ClaimType")
+ .HasColumnType("text");
+
+ b.Property<string>("ClaimValue")
+ .HasColumnType("text");
+
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserClaims");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b =>
+ {
+ b.Property<string>("LoginProvider")
+ .HasColumnType("text");
+
+ b.Property<string>("ProviderKey")
+ .HasColumnType("text");
+
+ b.Property<string>("ProviderDisplayName")
+ .HasColumnType("text");
+
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.HasKey("LoginProvider", "ProviderKey");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserLogins");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b =>
+ {
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("RoleId")
+ .HasColumnType("uuid");
+
+ b.HasKey("UserId", "RoleId");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetUserRoles");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b =>
+ {
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.Property<string>("LoginProvider")
+ .HasColumnType("text");
+
+ b.Property<string>("Name")
+ .HasColumnType("text");
+
+ b.Property<string>("Value")
+ .HasColumnType("text");
+
+ b.HasKey("UserId", "LoginProvider", "Name");
+
+ b.ToTable("AspNetUserTokens");
+ });
+
+ modelBuilder.Entity("RoleUser", b =>
+ {
+ b.Property<Guid>("RolesId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("UsersId")
+ .HasColumnType("uuid");
+
+ b.HasKey("RolesId", "UsersId");
+
+ b.HasIndex("UsersId");
+
+ b.ToTable("RoleUser");
+ });
+
+ modelBuilder.Entity("TechnologyUser", b =>
+ {
+ b.Property<Guid>("TechnologiesId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("UsersId")
+ .HasColumnType("uuid");
+
+ b.HasKey("TechnologiesId", "UsersId");
+
+ b.HasIndex("UsersId");
+
+ b.ToTable("TechnologyUser");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Comment", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", "Creator")
+ .WithMany("Comments")
+ .HasForeignKey("CreatorId");
+
+ b.HasOne("DevHive.Data.Models.Post", "Post")
+ .WithMany("Comments")
+ .HasForeignKey("PostId");
+
+ b.Navigation("Creator");
+
+ b.Navigation("Post");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Post", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", "Creator")
+ .WithMany("Posts")
+ .HasForeignKey("CreatorId");
+
+ b.Navigation("Creator");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.ProfilePicture", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", "User")
+ .WithOne("ProfilePicture")
+ .HasForeignKey("DevHive.Data.Models.ProfilePicture", "UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Rating", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Post", "Post")
+ .WithOne("Rating")
+ .HasForeignKey("DevHive.Data.Models.Rating", "PostId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Post");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.RatedPost", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Post", "Post")
+ .WithMany()
+ .HasForeignKey("PostId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", "User")
+ .WithMany("RatedPosts")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Post");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.UserFriend", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", "Friend")
+ .WithMany("FriendsOf")
+ .HasForeignKey("FriendId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", "User")
+ .WithMany("MyFriends")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Friend");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.UserRate", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Post", "Post")
+ .WithMany()
+ .HasForeignKey("PostId");
+
+ b.HasOne("DevHive.Data.Models.User", "User")
+ .WithMany()
+ .HasForeignKey("UserId");
+
+ b.Navigation("Post");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("LanguageUser", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Language", null)
+ .WithMany()
+ .HasForeignKey("LanguagesId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UsersId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Role", null)
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Role", null)
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("RoleUser", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Role", null)
+ .WithMany()
+ .HasForeignKey("RolesId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UsersId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("TechnologyUser", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Technology", null)
+ .WithMany()
+ .HasForeignKey("TechnologiesId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UsersId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Post", b =>
+ {
+ b.Navigation("Comments");
+
+ b.Navigation("Rating");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.User", b =>
+ {
+ b.Navigation("Comments");
+
+ b.Navigation("FriendsOf");
+
+ b.Navigation("MyFriends");
+
+ b.Navigation("Posts");
+
+ b.Navigation("ProfilePicture");
+
+ b.Navigation("RatedPosts");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/src/Data/DevHive.Data/Migrations/20210205140955_rating.cs b/src/Data/DevHive.Data/Migrations/20210205140955_rating.cs
new file mode 100644
index 0000000..d507dae
--- /dev/null
+++ b/src/Data/DevHive.Data/Migrations/20210205140955_rating.cs
@@ -0,0 +1,581 @@
+using System;
+using System.Collections.Generic;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+namespace DevHive.Data.Migrations
+{
+ public partial class rating : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.CreateTable(
+ name: "AspNetRoles",
+ columns: table => new
+ {
+ Id = table.Column<Guid>(type: "uuid", nullable: false),
+ Name = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
+ NormalizedName = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
+ ConcurrencyStamp = table.Column<string>(type: "text", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AspNetRoles", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "AspNetUsers",
+ columns: table => new
+ {
+ Id = table.Column<Guid>(type: "uuid", nullable: false),
+ FirstName = table.Column<string>(type: "text", nullable: true),
+ LastName = table.Column<string>(type: "text", nullable: true),
+ UserName = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
+ NormalizedUserName = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
+ Email = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
+ NormalizedEmail = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
+ EmailConfirmed = table.Column<bool>(type: "boolean", nullable: false),
+ PasswordHash = table.Column<string>(type: "text", nullable: true),
+ SecurityStamp = table.Column<string>(type: "text", nullable: true),
+ ConcurrencyStamp = table.Column<string>(type: "text", nullable: true),
+ PhoneNumber = table.Column<string>(type: "text", nullable: true),
+ PhoneNumberConfirmed = table.Column<bool>(type: "boolean", nullable: false),
+ TwoFactorEnabled = table.Column<bool>(type: "boolean", nullable: false),
+ LockoutEnd = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
+ LockoutEnabled = table.Column<bool>(type: "boolean", nullable: false),
+ AccessFailedCount = table.Column<int>(type: "integer", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AspNetUsers", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Languages",
+ columns: table => new
+ {
+ Id = table.Column<Guid>(type: "uuid", nullable: false),
+ Name = table.Column<string>(type: "text", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Languages", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Technologies",
+ columns: table => new
+ {
+ Id = table.Column<Guid>(type: "uuid", nullable: false),
+ Name = table.Column<string>(type: "text", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Technologies", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "AspNetRoleClaims",
+ columns: table => new
+ {
+ Id = table.Column<int>(type: "integer", nullable: false)
+ .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ RoleId = table.Column<Guid>(type: "uuid", nullable: false),
+ ClaimType = table.Column<string>(type: "text", nullable: true),
+ ClaimValue = table.Column<string>(type: "text", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id);
+ table.ForeignKey(
+ name: "FK_AspNetRoleClaims_AspNetRoles_RoleId",
+ column: x => x.RoleId,
+ principalTable: "AspNetRoles",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "AspNetUserClaims",
+ columns: table => new
+ {
+ Id = table.Column<int>(type: "integer", nullable: false)
+ .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ UserId = table.Column<Guid>(type: "uuid", nullable: false),
+ ClaimType = table.Column<string>(type: "text", nullable: true),
+ ClaimValue = table.Column<string>(type: "text", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AspNetUserClaims", x => x.Id);
+ table.ForeignKey(
+ name: "FK_AspNetUserClaims_AspNetUsers_UserId",
+ column: x => x.UserId,
+ principalTable: "AspNetUsers",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "AspNetUserLogins",
+ columns: table => new
+ {
+ LoginProvider = table.Column<string>(type: "text", nullable: false),
+ ProviderKey = table.Column<string>(type: "text", nullable: false),
+ ProviderDisplayName = table.Column<string>(type: "text", nullable: true),
+ UserId = table.Column<Guid>(type: "uuid", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey });
+ table.ForeignKey(
+ name: "FK_AspNetUserLogins_AspNetUsers_UserId",
+ column: x => x.UserId,
+ principalTable: "AspNetUsers",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "AspNetUserRoles",
+ columns: table => new
+ {
+ UserId = table.Column<Guid>(type: "uuid", nullable: false),
+ RoleId = table.Column<Guid>(type: "uuid", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId });
+ table.ForeignKey(
+ name: "FK_AspNetUserRoles_AspNetRoles_RoleId",
+ column: x => x.RoleId,
+ principalTable: "AspNetRoles",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ name: "FK_AspNetUserRoles_AspNetUsers_UserId",
+ column: x => x.UserId,
+ principalTable: "AspNetUsers",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "AspNetUserTokens",
+ columns: table => new
+ {
+ UserId = table.Column<Guid>(type: "uuid", nullable: false),
+ LoginProvider = table.Column<string>(type: "text", nullable: false),
+ Name = table.Column<string>(type: "text", nullable: false),
+ Value = table.Column<string>(type: "text", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name });
+ table.ForeignKey(
+ name: "FK_AspNetUserTokens_AspNetUsers_UserId",
+ column: x => x.UserId,
+ principalTable: "AspNetUsers",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Posts",
+ columns: table => new
+ {
+ Id = table.Column<Guid>(type: "uuid", nullable: false),
+ CreatorId = table.Column<Guid>(type: "uuid", nullable: true),
+ Message = table.Column<string>(type: "text", nullable: true),
+ TimeCreated = table.Column<DateTime>(type: "timestamp without time zone", nullable: false),
+ FileUrls = table.Column<List<string>>(type: "text[]", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Posts", x => x.Id);
+ table.ForeignKey(
+ name: "FK_Posts_AspNetUsers_CreatorId",
+ column: x => x.CreatorId,
+ principalTable: "AspNetUsers",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "ProfilePicture",
+ columns: table => new
+ {
+ Id = table.Column<Guid>(type: "uuid", nullable: false),
+ UserId = table.Column<Guid>(type: "uuid", nullable: false),
+ PictureURL = table.Column<string>(type: "text", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_ProfilePicture", x => x.Id);
+ table.ForeignKey(
+ name: "FK_ProfilePicture_AspNetUsers_UserId",
+ column: x => x.UserId,
+ principalTable: "AspNetUsers",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "RoleUser",
+ columns: table => new
+ {
+ RolesId = table.Column<Guid>(type: "uuid", nullable: false),
+ UsersId = table.Column<Guid>(type: "uuid", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_RoleUser", x => new { x.RolesId, x.UsersId });
+ table.ForeignKey(
+ name: "FK_RoleUser_AspNetRoles_RolesId",
+ column: x => x.RolesId,
+ principalTable: "AspNetRoles",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ name: "FK_RoleUser_AspNetUsers_UsersId",
+ column: x => x.UsersId,
+ principalTable: "AspNetUsers",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "UserFriends",
+ columns: table => new
+ {
+ UserId = table.Column<Guid>(type: "uuid", nullable: false),
+ FriendId = table.Column<Guid>(type: "uuid", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_UserFriends", x => new { x.UserId, x.FriendId });
+ table.ForeignKey(
+ name: "FK_UserFriends_AspNetUsers_FriendId",
+ column: x => x.FriendId,
+ principalTable: "AspNetUsers",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ name: "FK_UserFriends_AspNetUsers_UserId",
+ column: x => x.UserId,
+ principalTable: "AspNetUsers",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "LanguageUser",
+ columns: table => new
+ {
+ LanguagesId = table.Column<Guid>(type: "uuid", nullable: false),
+ UsersId = table.Column<Guid>(type: "uuid", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_LanguageUser", x => new { x.LanguagesId, x.UsersId });
+ table.ForeignKey(
+ name: "FK_LanguageUser_AspNetUsers_UsersId",
+ column: x => x.UsersId,
+ principalTable: "AspNetUsers",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ name: "FK_LanguageUser_Languages_LanguagesId",
+ column: x => x.LanguagesId,
+ principalTable: "Languages",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "TechnologyUser",
+ columns: table => new
+ {
+ TechnologiesId = table.Column<Guid>(type: "uuid", nullable: false),
+ UsersId = table.Column<Guid>(type: "uuid", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_TechnologyUser", x => new { x.TechnologiesId, x.UsersId });
+ table.ForeignKey(
+ name: "FK_TechnologyUser_AspNetUsers_UsersId",
+ column: x => x.UsersId,
+ principalTable: "AspNetUsers",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ name: "FK_TechnologyUser_Technologies_TechnologiesId",
+ column: x => x.TechnologiesId,
+ principalTable: "Technologies",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Comments",
+ columns: table => new
+ {
+ Id = table.Column<Guid>(type: "uuid", nullable: false),
+ PostId = table.Column<Guid>(type: "uuid", nullable: true),
+ CreatorId = table.Column<Guid>(type: "uuid", nullable: true),
+ Message = table.Column<string>(type: "text", nullable: true),
+ TimeCreated = table.Column<DateTime>(type: "timestamp without time zone", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Comments", x => x.Id);
+ table.ForeignKey(
+ name: "FK_Comments_AspNetUsers_CreatorId",
+ column: x => x.CreatorId,
+ principalTable: "AspNetUsers",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_Comments_Posts_PostId",
+ column: x => x.PostId,
+ principalTable: "Posts",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "RatedPosts",
+ columns: table => new
+ {
+ UserId = table.Column<Guid>(type: "uuid", nullable: false),
+ PostId = table.Column<Guid>(type: "uuid", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_RatedPosts", x => new { x.UserId, x.PostId });
+ table.ForeignKey(
+ name: "FK_RatedPosts_AspNetUsers_UserId",
+ column: x => x.UserId,
+ principalTable: "AspNetUsers",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ name: "FK_RatedPosts_Posts_PostId",
+ column: x => x.PostId,
+ principalTable: "Posts",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Rating",
+ columns: table => new
+ {
+ Id = table.Column<Guid>(type: "uuid", nullable: false),
+ PostId = table.Column<Guid>(type: "uuid", nullable: false),
+ Rate = table.Column<int>(type: "integer", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Rating", x => x.Id);
+ table.ForeignKey(
+ name: "FK_Rating_Posts_PostId",
+ column: x => x.PostId,
+ principalTable: "Posts",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "UserRates",
+ columns: table => new
+ {
+ Id = table.Column<Guid>(type: "uuid", nullable: false),
+ UserId = table.Column<Guid>(type: "uuid", nullable: true),
+ Liked = table.Column<bool>(type: "boolean", nullable: false),
+ PostId = table.Column<Guid>(type: "uuid", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_UserRates", x => x.Id);
+ table.ForeignKey(
+ name: "FK_UserRates_AspNetUsers_UserId",
+ column: x => x.UserId,
+ principalTable: "AspNetUsers",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_UserRates_Posts_PostId",
+ column: x => x.PostId,
+ principalTable: "Posts",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ });
+
+ migrationBuilder.CreateIndex(
+ name: "IX_AspNetRoleClaims_RoleId",
+ table: "AspNetRoleClaims",
+ column: "RoleId");
+
+ migrationBuilder.CreateIndex(
+ name: "RoleNameIndex",
+ table: "AspNetRoles",
+ column: "NormalizedName",
+ unique: true);
+
+ migrationBuilder.CreateIndex(
+ name: "IX_AspNetUserClaims_UserId",
+ table: "AspNetUserClaims",
+ column: "UserId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_AspNetUserLogins_UserId",
+ table: "AspNetUserLogins",
+ column: "UserId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_AspNetUserRoles_RoleId",
+ table: "AspNetUserRoles",
+ column: "RoleId");
+
+ migrationBuilder.CreateIndex(
+ name: "EmailIndex",
+ table: "AspNetUsers",
+ column: "NormalizedEmail");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_AspNetUsers_UserName",
+ table: "AspNetUsers",
+ column: "UserName",
+ unique: true);
+
+ migrationBuilder.CreateIndex(
+ name: "UserNameIndex",
+ table: "AspNetUsers",
+ column: "NormalizedUserName",
+ unique: true);
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Comments_CreatorId",
+ table: "Comments",
+ column: "CreatorId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Comments_PostId",
+ table: "Comments",
+ column: "PostId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_LanguageUser_UsersId",
+ table: "LanguageUser",
+ column: "UsersId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Posts_CreatorId",
+ table: "Posts",
+ column: "CreatorId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_ProfilePicture_UserId",
+ table: "ProfilePicture",
+ column: "UserId",
+ unique: true);
+
+ migrationBuilder.CreateIndex(
+ name: "IX_RatedPosts_PostId",
+ table: "RatedPosts",
+ column: "PostId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Rating_PostId",
+ table: "Rating",
+ column: "PostId",
+ unique: true);
+
+ migrationBuilder.CreateIndex(
+ name: "IX_RoleUser_UsersId",
+ table: "RoleUser",
+ column: "UsersId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_TechnologyUser_UsersId",
+ table: "TechnologyUser",
+ column: "UsersId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_UserFriends_FriendId",
+ table: "UserFriends",
+ column: "FriendId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_UserRates_PostId",
+ table: "UserRates",
+ column: "PostId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_UserRates_UserId",
+ table: "UserRates",
+ column: "UserId");
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "AspNetRoleClaims");
+
+ migrationBuilder.DropTable(
+ name: "AspNetUserClaims");
+
+ migrationBuilder.DropTable(
+ name: "AspNetUserLogins");
+
+ migrationBuilder.DropTable(
+ name: "AspNetUserRoles");
+
+ migrationBuilder.DropTable(
+ name: "AspNetUserTokens");
+
+ migrationBuilder.DropTable(
+ name: "Comments");
+
+ migrationBuilder.DropTable(
+ name: "LanguageUser");
+
+ migrationBuilder.DropTable(
+ name: "ProfilePicture");
+
+ migrationBuilder.DropTable(
+ name: "RatedPosts");
+
+ migrationBuilder.DropTable(
+ name: "Rating");
+
+ migrationBuilder.DropTable(
+ name: "RoleUser");
+
+ migrationBuilder.DropTable(
+ name: "TechnologyUser");
+
+ migrationBuilder.DropTable(
+ name: "UserFriends");
+
+ migrationBuilder.DropTable(
+ name: "UserRates");
+
+ migrationBuilder.DropTable(
+ name: "Languages");
+
+ migrationBuilder.DropTable(
+ name: "AspNetRoles");
+
+ migrationBuilder.DropTable(
+ name: "Technologies");
+
+ migrationBuilder.DropTable(
+ name: "Posts");
+
+ migrationBuilder.DropTable(
+ name: "AspNetUsers");
+ }
+ }
+}
diff --git a/src/Data/DevHive.Data/Migrations/20210205150447_Friends_Init_Config.Designer.cs b/src/Data/DevHive.Data/Migrations/20210205150447_Friends_Init_Config.Designer.cs
new file mode 100644
index 0000000..c11374a
--- /dev/null
+++ b/src/Data/DevHive.Data/Migrations/20210205150447_Friends_Init_Config.Designer.cs
@@ -0,0 +1,643 @@
+// <auto-generated />
+using System;
+using System.Collections.Generic;
+using DevHive.Data;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+namespace DevHive.Data.Migrations
+{
+ [DbContext(typeof(DevHiveContext))]
+ [Migration("20210205150447_Friends_Init_Config")]
+ partial class Friends_Init_Config
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .UseIdentityByDefaultColumns()
+ .HasAnnotation("Relational:MaxIdentifierLength", 63)
+ .HasAnnotation("ProductVersion", "5.0.1");
+
+ modelBuilder.Entity("DevHive.Data.Models.Comment", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<Guid?>("CreatorId")
+ .HasColumnType("uuid");
+
+ b.Property<string>("Message")
+ .HasColumnType("text");
+
+ b.Property<Guid?>("PostId")
+ .HasColumnType("uuid");
+
+ b.Property<DateTime>("TimeCreated")
+ .HasColumnType("timestamp without time zone");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CreatorId");
+
+ b.HasIndex("PostId");
+
+ b.ToTable("Comments");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Language", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<string>("Name")
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("Languages");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Post", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<Guid?>("CreatorId")
+ .HasColumnType("uuid");
+
+ b.Property<List<string>>("FileUrls")
+ .HasColumnType("text[]");
+
+ b.Property<string>("Message")
+ .HasColumnType("text");
+
+ b.Property<DateTime>("TimeCreated")
+ .HasColumnType("timestamp without time zone");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CreatorId");
+
+ b.ToTable("Posts");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.ProfilePicture", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<string>("PictureURL")
+ .HasColumnType("text");
+
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId")
+ .IsUnique();
+
+ b.ToTable("ProfilePicture");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Rating", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<int>("Rate")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.ToTable("Rating");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Role", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<string>("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasColumnType("text");
+
+ b.Property<string>("Name")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property<string>("NormalizedName")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedName")
+ .IsUnique()
+ .HasDatabaseName("RoleNameIndex");
+
+ b.ToTable("AspNetRoles");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Technology", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<string>("Name")
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("Technologies");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.User", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<int>("AccessFailedCount")
+ .HasColumnType("integer");
+
+ b.Property<string>("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasColumnType("text");
+
+ b.Property<string>("Email")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property<bool>("EmailConfirmed")
+ .HasColumnType("boolean");
+
+ b.Property<string>("FirstName")
+ .HasColumnType("text");
+
+ b.Property<string>("LastName")
+ .HasColumnType("text");
+
+ b.Property<bool>("LockoutEnabled")
+ .HasColumnType("boolean");
+
+ b.Property<DateTimeOffset?>("LockoutEnd")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property<string>("NormalizedEmail")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property<string>("NormalizedUserName")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property<string>("PasswordHash")
+ .HasColumnType("text");
+
+ b.Property<string>("PhoneNumber")
+ .HasColumnType("text");
+
+ b.Property<bool>("PhoneNumberConfirmed")
+ .HasColumnType("boolean");
+
+ b.Property<string>("SecurityStamp")
+ .HasColumnType("text");
+
+ b.Property<bool>("TwoFactorEnabled")
+ .HasColumnType("boolean");
+
+ b.Property<Guid?>("UserId")
+ .HasColumnType("uuid");
+
+ b.Property<string>("UserName")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedEmail")
+ .HasDatabaseName("EmailIndex");
+
+ b.HasIndex("NormalizedUserName")
+ .IsUnique()
+ .HasDatabaseName("UserNameIndex");
+
+ b.HasIndex("UserId");
+
+ b.HasIndex("UserName")
+ .IsUnique();
+
+ b.ToTable("AspNetUsers");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.RatedPost", b =>
+ {
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("PostId")
+ .HasColumnType("uuid");
+
+ b.HasKey("UserId", "PostId");
+
+ b.HasIndex("PostId");
+
+ b.ToTable("RatedPosts");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.UserFriend", b =>
+ {
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("FriendId")
+ .HasColumnType("uuid");
+
+ b.HasKey("UserId", "FriendId");
+
+ b.HasIndex("FriendId");
+
+ b.ToTable("UserFriends");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.UserRate", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<bool>("Rate")
+ .HasColumnType("boolean");
+
+ b.Property<Guid?>("UserId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("UserRates");
+ });
+
+ modelBuilder.Entity("LanguageUser", b =>
+ {
+ b.Property<Guid>("LanguagesId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("UsersId")
+ .HasColumnType("uuid");
+
+ b.HasKey("LanguagesId", "UsersId");
+
+ b.HasIndex("UsersId");
+
+ b.ToTable("LanguageUser");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .UseIdentityByDefaultColumn();
+
+ b.Property<string>("ClaimType")
+ .HasColumnType("text");
+
+ b.Property<string>("ClaimValue")
+ .HasColumnType("text");
+
+ b.Property<Guid>("RoleId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetRoleClaims");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .UseIdentityByDefaultColumn();
+
+ b.Property<string>("ClaimType")
+ .HasColumnType("text");
+
+ b.Property<string>("ClaimValue")
+ .HasColumnType("text");
+
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserClaims");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b =>
+ {
+ b.Property<string>("LoginProvider")
+ .HasColumnType("text");
+
+ b.Property<string>("ProviderKey")
+ .HasColumnType("text");
+
+ b.Property<string>("ProviderDisplayName")
+ .HasColumnType("text");
+
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.HasKey("LoginProvider", "ProviderKey");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserLogins");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b =>
+ {
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("RoleId")
+ .HasColumnType("uuid");
+
+ b.HasKey("UserId", "RoleId");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetUserRoles");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b =>
+ {
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.Property<string>("LoginProvider")
+ .HasColumnType("text");
+
+ b.Property<string>("Name")
+ .HasColumnType("text");
+
+ b.Property<string>("Value")
+ .HasColumnType("text");
+
+ b.HasKey("UserId", "LoginProvider", "Name");
+
+ b.ToTable("AspNetUserTokens");
+ });
+
+ modelBuilder.Entity("RoleUser", b =>
+ {
+ b.Property<Guid>("RolesId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("UsersId")
+ .HasColumnType("uuid");
+
+ b.HasKey("RolesId", "UsersId");
+
+ b.HasIndex("UsersId");
+
+ b.ToTable("RoleUser");
+ });
+
+ modelBuilder.Entity("TechnologyUser", b =>
+ {
+ b.Property<Guid>("TechnologiesId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("UsersId")
+ .HasColumnType("uuid");
+
+ b.HasKey("TechnologiesId", "UsersId");
+
+ b.HasIndex("UsersId");
+
+ b.ToTable("TechnologyUser");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Comment", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", "Creator")
+ .WithMany("Comments")
+ .HasForeignKey("CreatorId");
+
+ b.HasOne("DevHive.Data.Models.Post", "Post")
+ .WithMany("Comments")
+ .HasForeignKey("PostId");
+
+ b.Navigation("Creator");
+
+ b.Navigation("Post");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Post", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", "Creator")
+ .WithMany("Posts")
+ .HasForeignKey("CreatorId");
+
+ b.Navigation("Creator");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.ProfilePicture", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", "User")
+ .WithOne("ProfilePicture")
+ .HasForeignKey("DevHive.Data.Models.ProfilePicture", "UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.User", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany("Friends")
+ .HasForeignKey("UserId");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.RatedPost", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Post", "Post")
+ .WithMany()
+ .HasForeignKey("PostId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", "User")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Post");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.UserFriend", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", "Friend")
+ .WithMany()
+ .HasForeignKey("FriendId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", "User")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Friend");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.UserRate", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", "User")
+ .WithMany()
+ .HasForeignKey("UserId");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("LanguageUser", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Language", null)
+ .WithMany()
+ .HasForeignKey("LanguagesId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UsersId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Role", null)
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Role", null)
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("RoleUser", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Role", null)
+ .WithMany()
+ .HasForeignKey("RolesId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UsersId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("TechnologyUser", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Technology", null)
+ .WithMany()
+ .HasForeignKey("TechnologiesId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UsersId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Post", b =>
+ {
+ b.Navigation("Comments");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.User", b =>
+ {
+ b.Navigation("Comments");
+
+ b.Navigation("Friends");
+
+ b.Navigation("Posts");
+
+ b.Navigation("ProfilePicture");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/src/Data/DevHive.Data/Migrations/20210205150447_Friends_Init_Config.cs b/src/Data/DevHive.Data/Migrations/20210205150447_Friends_Init_Config.cs
new file mode 100644
index 0000000..1fc970d
--- /dev/null
+++ b/src/Data/DevHive.Data/Migrations/20210205150447_Friends_Init_Config.cs
@@ -0,0 +1,45 @@
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace DevHive.Data.Migrations
+{
+ public partial class Friends_Init_Config : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AddColumn<Guid>(
+ name: "UserId",
+ table: "AspNetUsers",
+ type: "uuid",
+ nullable: true);
+
+ migrationBuilder.CreateIndex(
+ name: "IX_AspNetUsers_UserId",
+ table: "AspNetUsers",
+ column: "UserId");
+
+ migrationBuilder.AddForeignKey(
+ name: "FK_AspNetUsers_AspNetUsers_UserId",
+ table: "AspNetUsers",
+ column: "UserId",
+ principalTable: "AspNetUsers",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropForeignKey(
+ name: "FK_AspNetUsers_AspNetUsers_UserId",
+ table: "AspNetUsers");
+
+ migrationBuilder.DropIndex(
+ name: "IX_AspNetUsers_UserId",
+ table: "AspNetUsers");
+
+ migrationBuilder.DropColumn(
+ name: "UserId",
+ table: "AspNetUsers");
+ }
+ }
+}
diff --git a/src/Data/DevHive.Data/Migrations/20210205154810_PostFileAttachments.Designer.cs b/src/Data/DevHive.Data/Migrations/20210205154810_PostFileAttachments.Designer.cs
new file mode 100644
index 0000000..5d8e13a
--- /dev/null
+++ b/src/Data/DevHive.Data/Migrations/20210205154810_PostFileAttachments.Designer.cs
@@ -0,0 +1,691 @@
+// <auto-generated />
+using System;
+using DevHive.Data;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+namespace DevHive.Data.Migrations
+{
+ [DbContext(typeof(DevHiveContext))]
+ [Migration("20210205154810_PostFileAttachments")]
+ partial class PostFileAttachments
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .UseIdentityByDefaultColumns()
+ .HasAnnotation("Relational:MaxIdentifierLength", 63)
+ .HasAnnotation("ProductVersion", "5.0.1");
+
+ modelBuilder.Entity("DevHive.Data.Models.Comment", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<Guid?>("CreatorId")
+ .HasColumnType("uuid");
+
+ b.Property<string>("Message")
+ .HasColumnType("text");
+
+ b.Property<Guid?>("PostId")
+ .HasColumnType("uuid");
+
+ b.Property<DateTime>("TimeCreated")
+ .HasColumnType("timestamp without time zone");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CreatorId");
+
+ b.HasIndex("PostId");
+
+ b.ToTable("Comments");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Language", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<string>("Name")
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("Languages");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Post", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<Guid?>("CreatorId")
+ .HasColumnType("uuid");
+
+ b.Property<string>("Message")
+ .HasColumnType("text");
+
+ b.Property<DateTime>("TimeCreated")
+ .HasColumnType("timestamp without time zone");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CreatorId");
+
+ b.ToTable("Posts");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.ProfilePicture", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<string>("PictureURL")
+ .HasColumnType("text");
+
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId")
+ .IsUnique();
+
+ b.ToTable("ProfilePicture");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Rating", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("PostId")
+ .HasColumnType("uuid");
+
+ b.Property<int>("Rate")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("PostId")
+ .IsUnique();
+
+ b.ToTable("Rating");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Role", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<string>("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasColumnType("text");
+
+ b.Property<string>("Name")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property<string>("NormalizedName")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedName")
+ .IsUnique()
+ .HasDatabaseName("RoleNameIndex");
+
+ b.ToTable("AspNetRoles");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Technology", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<string>("Name")
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("Technologies");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.User", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<int>("AccessFailedCount")
+ .HasColumnType("integer");
+
+ b.Property<string>("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasColumnType("text");
+
+ b.Property<string>("Email")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property<bool>("EmailConfirmed")
+ .HasColumnType("boolean");
+
+ b.Property<string>("FirstName")
+ .HasColumnType("text");
+
+ b.Property<string>("LastName")
+ .HasColumnType("text");
+
+ b.Property<bool>("LockoutEnabled")
+ .HasColumnType("boolean");
+
+ b.Property<DateTimeOffset?>("LockoutEnd")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property<string>("NormalizedEmail")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property<string>("NormalizedUserName")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property<string>("PasswordHash")
+ .HasColumnType("text");
+
+ b.Property<string>("PhoneNumber")
+ .HasColumnType("text");
+
+ b.Property<bool>("PhoneNumberConfirmed")
+ .HasColumnType("boolean");
+
+ b.Property<string>("SecurityStamp")
+ .HasColumnType("text");
+
+ b.Property<bool>("TwoFactorEnabled")
+ .HasColumnType("boolean");
+
+ b.Property<string>("UserName")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedEmail")
+ .HasDatabaseName("EmailIndex");
+
+ b.HasIndex("NormalizedUserName")
+ .IsUnique()
+ .HasDatabaseName("UserNameIndex");
+
+ b.HasIndex("UserName")
+ .IsUnique();
+
+ b.ToTable("AspNetUsers");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.PostAttachments", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<string>("FileUrl")
+ .HasColumnType("text");
+
+ b.Property<Guid?>("PostId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("PostId");
+
+ b.ToTable("PostAttachments");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.RatedPost", b =>
+ {
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("PostId")
+ .HasColumnType("uuid");
+
+ b.HasKey("UserId", "PostId");
+
+ b.HasIndex("PostId");
+
+ b.ToTable("RatedPosts");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.UserFriend", b =>
+ {
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("FriendId")
+ .HasColumnType("uuid");
+
+ b.HasKey("UserId", "FriendId");
+
+ b.HasIndex("FriendId");
+
+ b.ToTable("UserFriends");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.UserRate", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<bool>("Liked")
+ .HasColumnType("boolean");
+
+ b.Property<Guid?>("PostId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid?>("UserId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("PostId");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("UserRates");
+ });
+
+ modelBuilder.Entity("LanguageUser", b =>
+ {
+ b.Property<Guid>("LanguagesId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("UsersId")
+ .HasColumnType("uuid");
+
+ b.HasKey("LanguagesId", "UsersId");
+
+ b.HasIndex("UsersId");
+
+ b.ToTable("LanguageUser");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .UseIdentityByDefaultColumn();
+
+ b.Property<string>("ClaimType")
+ .HasColumnType("text");
+
+ b.Property<string>("ClaimValue")
+ .HasColumnType("text");
+
+ b.Property<Guid>("RoleId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetRoleClaims");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .UseIdentityByDefaultColumn();
+
+ b.Property<string>("ClaimType")
+ .HasColumnType("text");
+
+ b.Property<string>("ClaimValue")
+ .HasColumnType("text");
+
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserClaims");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b =>
+ {
+ b.Property<string>("LoginProvider")
+ .HasColumnType("text");
+
+ b.Property<string>("ProviderKey")
+ .HasColumnType("text");
+
+ b.Property<string>("ProviderDisplayName")
+ .HasColumnType("text");
+
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.HasKey("LoginProvider", "ProviderKey");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserLogins");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b =>
+ {
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("RoleId")
+ .HasColumnType("uuid");
+
+ b.HasKey("UserId", "RoleId");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetUserRoles");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b =>
+ {
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.Property<string>("LoginProvider")
+ .HasColumnType("text");
+
+ b.Property<string>("Name")
+ .HasColumnType("text");
+
+ b.Property<string>("Value")
+ .HasColumnType("text");
+
+ b.HasKey("UserId", "LoginProvider", "Name");
+
+ b.ToTable("AspNetUserTokens");
+ });
+
+ modelBuilder.Entity("RoleUser", b =>
+ {
+ b.Property<Guid>("RolesId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("UsersId")
+ .HasColumnType("uuid");
+
+ b.HasKey("RolesId", "UsersId");
+
+ b.HasIndex("UsersId");
+
+ b.ToTable("RoleUser");
+ });
+
+ modelBuilder.Entity("TechnologyUser", b =>
+ {
+ b.Property<Guid>("TechnologiesId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("UsersId")
+ .HasColumnType("uuid");
+
+ b.HasKey("TechnologiesId", "UsersId");
+
+ b.HasIndex("UsersId");
+
+ b.ToTable("TechnologyUser");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Comment", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", "Creator")
+ .WithMany("Comments")
+ .HasForeignKey("CreatorId");
+
+ b.HasOne("DevHive.Data.Models.Post", "Post")
+ .WithMany("Comments")
+ .HasForeignKey("PostId");
+
+ b.Navigation("Creator");
+
+ b.Navigation("Post");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Post", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", "Creator")
+ .WithMany("Posts")
+ .HasForeignKey("CreatorId");
+
+ b.Navigation("Creator");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.ProfilePicture", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", "User")
+ .WithOne("ProfilePicture")
+ .HasForeignKey("DevHive.Data.Models.ProfilePicture", "UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Rating", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Post", "Post")
+ .WithOne("Rating")
+ .HasForeignKey("DevHive.Data.Models.Rating", "PostId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Post");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.PostAttachments", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Post", "Post")
+ .WithMany("Attachments")
+ .HasForeignKey("PostId");
+
+ b.Navigation("Post");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.RatedPost", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Post", "Post")
+ .WithMany()
+ .HasForeignKey("PostId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", "User")
+ .WithMany("RatedPosts")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Post");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.UserFriend", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", "Friend")
+ .WithMany("FriendsOf")
+ .HasForeignKey("FriendId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", "User")
+ .WithMany("MyFriends")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Friend");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.UserRate", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Post", "Post")
+ .WithMany()
+ .HasForeignKey("PostId");
+
+ b.HasOne("DevHive.Data.Models.User", "User")
+ .WithMany()
+ .HasForeignKey("UserId");
+
+ b.Navigation("Post");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("LanguageUser", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Language", null)
+ .WithMany()
+ .HasForeignKey("LanguagesId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UsersId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Role", null)
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Role", null)
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("RoleUser", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Role", null)
+ .WithMany()
+ .HasForeignKey("RolesId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UsersId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("TechnologyUser", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Technology", null)
+ .WithMany()
+ .HasForeignKey("TechnologiesId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UsersId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Post", b =>
+ {
+ b.Navigation("Attachments");
+
+ b.Navigation("Comments");
+
+ b.Navigation("Rating");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.User", b =>
+ {
+ b.Navigation("Comments");
+
+ b.Navigation("FriendsOf");
+
+ b.Navigation("MyFriends");
+
+ b.Navigation("Posts");
+
+ b.Navigation("ProfilePicture");
+
+ b.Navigation("RatedPosts");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/src/Data/DevHive.Data/Migrations/20210205154810_PostFileAttachments.cs b/src/Data/DevHive.Data/Migrations/20210205154810_PostFileAttachments.cs
new file mode 100644
index 0000000..7b7b933
--- /dev/null
+++ b/src/Data/DevHive.Data/Migrations/20210205154810_PostFileAttachments.cs
@@ -0,0 +1,51 @@
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace DevHive.Data.Migrations
+{
+ public partial class PostFileAttachments : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropColumn(
+ name: "FileUrls",
+ table: "Posts");
+
+ migrationBuilder.CreateTable(
+ name: "PostAttachments",
+ columns: table => new
+ {
+ Id = table.Column<Guid>(type: "uuid", nullable: false),
+ PostId = table.Column<Guid>(type: "uuid", nullable: true),
+ FileUrl = table.Column<string>(type: "text", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_PostAttachments", x => x.Id);
+ table.ForeignKey(
+ name: "FK_PostAttachments_Posts_PostId",
+ column: x => x.PostId,
+ principalTable: "Posts",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ });
+
+ migrationBuilder.CreateIndex(
+ name: "IX_PostAttachments_PostId",
+ table: "PostAttachments",
+ column: "PostId");
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "PostAttachments");
+
+ migrationBuilder.AddColumn<string[]>(
+ name: "FileUrls",
+ table: "Posts",
+ type: "text[]",
+ nullable: true);
+ }
+ }
+}
diff --git a/src/Data/DevHive.Data/Migrations/20210205160520_Friends_First_Tweek.Designer.cs b/src/Data/DevHive.Data/Migrations/20210205160520_Friends_First_Tweek.Designer.cs
new file mode 100644
index 0000000..3ad3ec8
--- /dev/null
+++ b/src/Data/DevHive.Data/Migrations/20210205160520_Friends_First_Tweek.Designer.cs
@@ -0,0 +1,609 @@
+// <auto-generated />
+using System;
+using System.Collections.Generic;
+using DevHive.Data;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+namespace DevHive.Data.Migrations
+{
+ [DbContext(typeof(DevHiveContext))]
+ [Migration("20210205160520_Friends_First_Tweek")]
+ partial class Friends_First_Tweek
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .UseIdentityByDefaultColumns()
+ .HasAnnotation("Relational:MaxIdentifierLength", 63)
+ .HasAnnotation("ProductVersion", "5.0.1");
+
+ modelBuilder.Entity("DevHive.Data.Models.Comment", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<Guid?>("CreatorId")
+ .HasColumnType("uuid");
+
+ b.Property<string>("Message")
+ .HasColumnType("text");
+
+ b.Property<Guid?>("PostId")
+ .HasColumnType("uuid");
+
+ b.Property<DateTime>("TimeCreated")
+ .HasColumnType("timestamp without time zone");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CreatorId");
+
+ b.HasIndex("PostId");
+
+ b.ToTable("Comments");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Language", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<string>("Name")
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("Languages");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Post", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<Guid?>("CreatorId")
+ .HasColumnType("uuid");
+
+ b.Property<List<string>>("FileUrls")
+ .HasColumnType("text[]");
+
+ b.Property<string>("Message")
+ .HasColumnType("text");
+
+ b.Property<DateTime>("TimeCreated")
+ .HasColumnType("timestamp without time zone");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CreatorId");
+
+ b.ToTable("Posts");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.ProfilePicture", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<string>("PictureURL")
+ .HasColumnType("text");
+
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId")
+ .IsUnique();
+
+ b.ToTable("ProfilePicture");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Rating", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<int>("Rate")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.ToTable("Rating");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Role", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<string>("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasColumnType("text");
+
+ b.Property<string>("Name")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property<string>("NormalizedName")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedName")
+ .IsUnique()
+ .HasDatabaseName("RoleNameIndex");
+
+ b.ToTable("AspNetRoles");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Technology", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<string>("Name")
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("Technologies");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.User", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<int>("AccessFailedCount")
+ .HasColumnType("integer");
+
+ b.Property<string>("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasColumnType("text");
+
+ b.Property<string>("Email")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property<bool>("EmailConfirmed")
+ .HasColumnType("boolean");
+
+ b.Property<string>("FirstName")
+ .HasColumnType("text");
+
+ b.Property<string>("LastName")
+ .HasColumnType("text");
+
+ b.Property<bool>("LockoutEnabled")
+ .HasColumnType("boolean");
+
+ b.Property<DateTimeOffset?>("LockoutEnd")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property<string>("NormalizedEmail")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property<string>("NormalizedUserName")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property<string>("PasswordHash")
+ .HasColumnType("text");
+
+ b.Property<string>("PhoneNumber")
+ .HasColumnType("text");
+
+ b.Property<bool>("PhoneNumberConfirmed")
+ .HasColumnType("boolean");
+
+ b.Property<string>("SecurityStamp")
+ .HasColumnType("text");
+
+ b.Property<bool>("TwoFactorEnabled")
+ .HasColumnType("boolean");
+
+ b.Property<Guid?>("UserId")
+ .HasColumnType("uuid");
+
+ b.Property<string>("UserName")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedEmail")
+ .HasDatabaseName("EmailIndex");
+
+ b.HasIndex("NormalizedUserName")
+ .IsUnique()
+ .HasDatabaseName("UserNameIndex");
+
+ b.HasIndex("UserId");
+
+ b.HasIndex("UserName")
+ .IsUnique();
+
+ b.ToTable("AspNetUsers");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.RatedPost", b =>
+ {
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("PostId")
+ .HasColumnType("uuid");
+
+ b.HasKey("UserId", "PostId");
+
+ b.HasIndex("PostId");
+
+ b.ToTable("RatedPosts");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.UserRate", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<bool>("Rate")
+ .HasColumnType("boolean");
+
+ b.Property<Guid?>("UserId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("UserRates");
+ });
+
+ modelBuilder.Entity("LanguageUser", b =>
+ {
+ b.Property<Guid>("LanguagesId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("UsersId")
+ .HasColumnType("uuid");
+
+ b.HasKey("LanguagesId", "UsersId");
+
+ b.HasIndex("UsersId");
+
+ b.ToTable("LanguageUser");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .UseIdentityByDefaultColumn();
+
+ b.Property<string>("ClaimType")
+ .HasColumnType("text");
+
+ b.Property<string>("ClaimValue")
+ .HasColumnType("text");
+
+ b.Property<Guid>("RoleId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetRoleClaims");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .UseIdentityByDefaultColumn();
+
+ b.Property<string>("ClaimType")
+ .HasColumnType("text");
+
+ b.Property<string>("ClaimValue")
+ .HasColumnType("text");
+
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserClaims");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b =>
+ {
+ b.Property<string>("LoginProvider")
+ .HasColumnType("text");
+
+ b.Property<string>("ProviderKey")
+ .HasColumnType("text");
+
+ b.Property<string>("ProviderDisplayName")
+ .HasColumnType("text");
+
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.HasKey("LoginProvider", "ProviderKey");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserLogins");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b =>
+ {
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("RoleId")
+ .HasColumnType("uuid");
+
+ b.HasKey("UserId", "RoleId");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetUserRoles");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b =>
+ {
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.Property<string>("LoginProvider")
+ .HasColumnType("text");
+
+ b.Property<string>("Name")
+ .HasColumnType("text");
+
+ b.Property<string>("Value")
+ .HasColumnType("text");
+
+ b.HasKey("UserId", "LoginProvider", "Name");
+
+ b.ToTable("AspNetUserTokens");
+ });
+
+ modelBuilder.Entity("RoleUser", b =>
+ {
+ b.Property<Guid>("RolesId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("UsersId")
+ .HasColumnType("uuid");
+
+ b.HasKey("RolesId", "UsersId");
+
+ b.HasIndex("UsersId");
+
+ b.ToTable("RoleUser");
+ });
+
+ modelBuilder.Entity("TechnologyUser", b =>
+ {
+ b.Property<Guid>("TechnologiesId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("UsersId")
+ .HasColumnType("uuid");
+
+ b.HasKey("TechnologiesId", "UsersId");
+
+ b.HasIndex("UsersId");
+
+ b.ToTable("TechnologyUser");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Comment", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", "Creator")
+ .WithMany("Comments")
+ .HasForeignKey("CreatorId");
+
+ b.HasOne("DevHive.Data.Models.Post", "Post")
+ .WithMany("Comments")
+ .HasForeignKey("PostId");
+
+ b.Navigation("Creator");
+
+ b.Navigation("Post");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Post", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", "Creator")
+ .WithMany("Posts")
+ .HasForeignKey("CreatorId");
+
+ b.Navigation("Creator");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.ProfilePicture", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", "User")
+ .WithOne("ProfilePicture")
+ .HasForeignKey("DevHive.Data.Models.ProfilePicture", "UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.User", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany("Friends")
+ .HasForeignKey("UserId");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.RatedPost", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Post", "Post")
+ .WithMany()
+ .HasForeignKey("PostId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", "User")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Post");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.UserRate", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", "User")
+ .WithMany()
+ .HasForeignKey("UserId");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("LanguageUser", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Language", null)
+ .WithMany()
+ .HasForeignKey("LanguagesId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UsersId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Role", null)
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Role", null)
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("RoleUser", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Role", null)
+ .WithMany()
+ .HasForeignKey("RolesId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UsersId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("TechnologyUser", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Technology", null)
+ .WithMany()
+ .HasForeignKey("TechnologiesId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UsersId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Post", b =>
+ {
+ b.Navigation("Comments");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.User", b =>
+ {
+ b.Navigation("Comments");
+
+ b.Navigation("Friends");
+
+ b.Navigation("Posts");
+
+ b.Navigation("ProfilePicture");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/src/Data/DevHive.Data/Migrations/20210205160520_Friends_First_Tweek.cs b/src/Data/DevHive.Data/Migrations/20210205160520_Friends_First_Tweek.cs
new file mode 100644
index 0000000..565f863
--- /dev/null
+++ b/src/Data/DevHive.Data/Migrations/20210205160520_Friends_First_Tweek.cs
@@ -0,0 +1,46 @@
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace DevHive.Data.Migrations
+{
+ public partial class Friends_First_Tweek : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "UserFriends");
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.CreateTable(
+ name: "UserFriends",
+ columns: table => new
+ {
+ UserId = table.Column<Guid>(type: "uuid", nullable: false),
+ FriendId = table.Column<Guid>(type: "uuid", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_UserFriends", x => new { x.UserId, x.FriendId });
+ table.ForeignKey(
+ name: "FK_UserFriends_AspNetUsers_FriendId",
+ column: x => x.FriendId,
+ principalTable: "AspNetUsers",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ name: "FK_UserFriends_AspNetUsers_UserId",
+ column: x => x.UserId,
+ principalTable: "AspNetUsers",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateIndex(
+ name: "IX_UserFriends_FriendId",
+ table: "UserFriends",
+ column: "FriendId");
+ }
+ }
+}
diff --git a/src/Data/DevHive.Data/Migrations/DevHiveContextModelSnapshot.cs b/src/Data/DevHive.Data/Migrations/DevHiveContextModelSnapshot.cs
new file mode 100644
index 0000000..dc5739c
--- /dev/null
+++ b/src/Data/DevHive.Data/Migrations/DevHiveContextModelSnapshot.cs
@@ -0,0 +1,658 @@
+// <auto-generated />
+using System;
+using DevHive.Data;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+namespace DevHive.Data.Migrations
+{
+ [DbContext(typeof(DevHiveContext))]
+ partial class DevHiveContextModelSnapshot : ModelSnapshot
+ {
+ protected override void BuildModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .UseIdentityByDefaultColumns()
+ .HasAnnotation("Relational:MaxIdentifierLength", 63)
+ .HasAnnotation("ProductVersion", "5.0.1");
+
+ modelBuilder.Entity("DevHive.Data.Models.Comment", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<Guid?>("CreatorId")
+ .HasColumnType("uuid");
+
+ b.Property<string>("Message")
+ .HasColumnType("text");
+
+ b.Property<Guid?>("PostId")
+ .HasColumnType("uuid");
+
+ b.Property<DateTime>("TimeCreated")
+ .HasColumnType("timestamp without time zone");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CreatorId");
+
+ b.HasIndex("PostId");
+
+ b.ToTable("Comments");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Language", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<string>("Name")
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("Languages");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Post", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<Guid?>("CreatorId")
+ .HasColumnType("uuid");
+
+ b.Property<string>("Message")
+ .HasColumnType("text");
+
+ b.Property<DateTime>("TimeCreated")
+ .HasColumnType("timestamp without time zone");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CreatorId");
+
+ b.ToTable("Posts");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.ProfilePicture", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<string>("PictureURL")
+ .HasColumnType("text");
+
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId")
+ .IsUnique();
+
+ b.ToTable("ProfilePicture");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Rating", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("PostId")
+ .HasColumnType("uuid");
+
+ b.Property<int>("Rate")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("PostId")
+ .IsUnique();
+
+ b.ToTable("Rating");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Role", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<string>("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasColumnType("text");
+
+ b.Property<string>("Name")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property<string>("NormalizedName")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedName")
+ .IsUnique()
+ .HasDatabaseName("RoleNameIndex");
+
+ b.ToTable("AspNetRoles");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Technology", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<string>("Name")
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("Technologies");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.User", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<int>("AccessFailedCount")
+ .HasColumnType("integer");
+
+ b.Property<string>("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasColumnType("text");
+
+ b.Property<string>("Email")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property<bool>("EmailConfirmed")
+ .HasColumnType("boolean");
+
+ b.Property<string>("FirstName")
+ .HasColumnType("text");
+
+ b.Property<string>("LastName")
+ .HasColumnType("text");
+
+ b.Property<bool>("LockoutEnabled")
+ .HasColumnType("boolean");
+
+ b.Property<DateTimeOffset?>("LockoutEnd")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property<string>("NormalizedEmail")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property<string>("NormalizedUserName")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property<string>("PasswordHash")
+ .HasColumnType("text");
+
+ b.Property<string>("PhoneNumber")
+ .HasColumnType("text");
+
+ b.Property<bool>("PhoneNumberConfirmed")
+ .HasColumnType("boolean");
+
+ b.Property<string>("SecurityStamp")
+ .HasColumnType("text");
+
+ b.Property<bool>("TwoFactorEnabled")
+ .HasColumnType("boolean");
+
+ b.Property<Guid?>("UserId")
+ .HasColumnType("uuid");
+
+ b.Property<string>("UserName")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedEmail")
+ .HasDatabaseName("EmailIndex");
+
+ b.HasIndex("NormalizedUserName")
+ .IsUnique()
+ .HasDatabaseName("UserNameIndex");
+
+ b.HasIndex("UserId");
+
+ b.HasIndex("UserName")
+ .IsUnique();
+
+ b.ToTable("AspNetUsers");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.PostAttachments", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<string>("FileUrl")
+ .HasColumnType("text");
+
+ b.Property<Guid?>("PostId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("PostId");
+
+ b.ToTable("PostAttachments");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.RatedPost", b =>
+ {
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("PostId")
+ .HasColumnType("uuid");
+
+ b.HasKey("UserId", "PostId");
+
+ b.HasIndex("PostId");
+
+ b.ToTable("RatedPosts");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.UserRate", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property<bool>("Liked")
+ .HasColumnType("boolean");
+
+ b.Property<Guid?>("PostId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid?>("UserId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("PostId");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("UserRates");
+ });
+
+ modelBuilder.Entity("LanguageUser", b =>
+ {
+ b.Property<Guid>("LanguagesId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("UsersId")
+ .HasColumnType("uuid");
+
+ b.HasKey("LanguagesId", "UsersId");
+
+ b.HasIndex("UsersId");
+
+ b.ToTable("LanguageUser");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .UseIdentityByDefaultColumn();
+
+ b.Property<string>("ClaimType")
+ .HasColumnType("text");
+
+ b.Property<string>("ClaimValue")
+ .HasColumnType("text");
+
+ b.Property<Guid>("RoleId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetRoleClaims");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .UseIdentityByDefaultColumn();
+
+ b.Property<string>("ClaimType")
+ .HasColumnType("text");
+
+ b.Property<string>("ClaimValue")
+ .HasColumnType("text");
+
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserClaims");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b =>
+ {
+ b.Property<string>("LoginProvider")
+ .HasColumnType("text");
+
+ b.Property<string>("ProviderKey")
+ .HasColumnType("text");
+
+ b.Property<string>("ProviderDisplayName")
+ .HasColumnType("text");
+
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.HasKey("LoginProvider", "ProviderKey");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserLogins");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b =>
+ {
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("RoleId")
+ .HasColumnType("uuid");
+
+ b.HasKey("UserId", "RoleId");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetUserRoles");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b =>
+ {
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid");
+
+ b.Property<string>("LoginProvider")
+ .HasColumnType("text");
+
+ b.Property<string>("Name")
+ .HasColumnType("text");
+
+ b.Property<string>("Value")
+ .HasColumnType("text");
+
+ b.HasKey("UserId", "LoginProvider", "Name");
+
+ b.ToTable("AspNetUserTokens");
+ });
+
+ modelBuilder.Entity("RoleUser", b =>
+ {
+ b.Property<Guid>("RolesId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("UsersId")
+ .HasColumnType("uuid");
+
+ b.HasKey("RolesId", "UsersId");
+
+ b.HasIndex("UsersId");
+
+ b.ToTable("RoleUser");
+ });
+
+ modelBuilder.Entity("TechnologyUser", b =>
+ {
+ b.Property<Guid>("TechnologiesId")
+ .HasColumnType("uuid");
+
+ b.Property<Guid>("UsersId")
+ .HasColumnType("uuid");
+
+ b.HasKey("TechnologiesId", "UsersId");
+
+ b.HasIndex("UsersId");
+
+ b.ToTable("TechnologyUser");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Comment", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", "Creator")
+ .WithMany("Comments")
+ .HasForeignKey("CreatorId");
+
+ b.HasOne("DevHive.Data.Models.Post", "Post")
+ .WithMany("Comments")
+ .HasForeignKey("PostId");
+
+ b.Navigation("Creator");
+
+ b.Navigation("Post");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Post", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", "Creator")
+ .WithMany("Posts")
+ .HasForeignKey("CreatorId");
+
+ b.Navigation("Creator");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.ProfilePicture", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", "User")
+ .WithOne("ProfilePicture")
+ .HasForeignKey("DevHive.Data.Models.ProfilePicture", "UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Rating", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Post", "Post")
+ .WithOne("Rating")
+ .HasForeignKey("DevHive.Data.Models.Rating", "PostId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Post");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.PostAttachments", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Post", "Post")
+ .WithMany("Attachments")
+ .HasForeignKey("PostId");
+
+ b.Navigation("Post");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.RatedPost", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Post", "Post")
+ .WithMany()
+ .HasForeignKey("PostId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", "User")
+ .WithMany("RatedPosts")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Post");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("DevHive.Data.RelationModels.UserRate", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Post", "Post")
+ .WithMany()
+ .HasForeignKey("PostId");
+
+ b.HasOne("DevHive.Data.Models.User", "User")
+ .WithMany()
+ .HasForeignKey("UserId");
+
+ b.Navigation("Post");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("LanguageUser", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Language", null)
+ .WithMany()
+ .HasForeignKey("LanguagesId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UsersId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Role", null)
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Role", null)
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b =>
+ {
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("RoleUser", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Role", null)
+ .WithMany()
+ .HasForeignKey("RolesId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UsersId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("TechnologyUser", b =>
+ {
+ b.HasOne("DevHive.Data.Models.Technology", null)
+ .WithMany()
+ .HasForeignKey("TechnologiesId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("DevHive.Data.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UsersId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.Post", b =>
+ {
+ b.Navigation("Attachments");
+
+ b.Navigation("Comments");
+
+ b.Navigation("Rating");
+ });
+
+ modelBuilder.Entity("DevHive.Data.Models.User", b =>
+ {
+ b.Navigation("Comments");
+
+ b.Navigation("Friends");
+
+ b.Navigation("Posts");
+
+ b.Navigation("ProfilePicture");
+
+ b.Navigation("RatedPosts");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/src/Data/DevHive.Data/RelationModels/PostAttachments.cs b/src/Data/DevHive.Data/RelationModels/PostAttachments.cs
new file mode 100644
index 0000000..48aa8ff
--- /dev/null
+++ b/src/Data/DevHive.Data/RelationModels/PostAttachments.cs
@@ -0,0 +1,16 @@
+using System;
+using System.ComponentModel.DataAnnotations.Schema;
+using DevHive.Data.Models;
+
+namespace DevHive.Data.RelationModels
+{
+ [Table("PostAttachments")]
+ public class PostAttachments
+ {
+ public Guid Id { get; set; }
+
+ public Post Post { get; set; }
+
+ public string FileUrl { get; set; }
+ }
+}
diff --git a/src/Data/DevHive.Data/RelationModels/RatedPost.cs b/src/Data/DevHive.Data/RelationModels/RatedPost.cs
new file mode 100644
index 0000000..7001d92
--- /dev/null
+++ b/src/Data/DevHive.Data/RelationModels/RatedPost.cs
@@ -0,0 +1,18 @@
+using System;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Reflection.Metadata.Ecma335;
+using DevHive.Data.Models;
+using Microsoft.EntityFrameworkCore;
+
+namespace DevHive.Data.RelationModels
+{
+ [Table("RatedPosts")]
+ public class RatedPost
+ {
+ public Guid UserId { get; set; }
+ public User User { get; set; }
+
+ public Guid PostId { get; set; }
+ public Post Post { get; set; }
+ }
+}
diff --git a/src/Data/DevHive.Data/RelationModels/UserRate.cs b/src/Data/DevHive.Data/RelationModels/UserRate.cs
new file mode 100644
index 0000000..696e6f3
--- /dev/null
+++ b/src/Data/DevHive.Data/RelationModels/UserRate.cs
@@ -0,0 +1,18 @@
+using System;
+using System.ComponentModel.DataAnnotations.Schema;
+using DevHive.Data.Models;
+
+namespace DevHive.Data.RelationModels
+{
+ [Table("UserRates")]
+ public class UserRate
+ {
+ public Guid Id { get; set; }
+
+ public User User { get; set; }
+
+ public bool Liked { get; set; }
+
+ public Post Post { get; set; }
+ }
+}
diff --git a/src/Data/DevHive.Data/Repositories/BaseRepository.cs b/src/Data/DevHive.Data/Repositories/BaseRepository.cs
new file mode 100644
index 0000000..ece372e
--- /dev/null
+++ b/src/Data/DevHive.Data/Repositories/BaseRepository.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Threading.Tasks;
+using DevHive.Data.Repositories.Interfaces;
+using Microsoft.EntityFrameworkCore;
+
+namespace DevHive.Data.Repositories
+{
+ public class BaseRepository<TEntity> : IRepository<TEntity>
+ where TEntity : class
+ {
+ private readonly DbContext _context;
+
+ public BaseRepository(DbContext context)
+ {
+ this._context = context;
+ }
+
+ public virtual async Task<bool> AddAsync(TEntity entity)
+ {
+ await this._context
+ .Set<TEntity>()
+ .AddAsync(entity);
+
+ return await this.SaveChangesAsync();
+ }
+
+ public virtual async Task<TEntity> GetByIdAsync(Guid id)
+ {
+ return await this._context
+ .Set<TEntity>()
+ .FindAsync(id);
+ }
+
+ public virtual async Task<bool> EditAsync(Guid id, TEntity newEntity)
+ {
+ var entry = this._context.Entry(newEntity);
+ if (entry.State == EntityState.Detached)
+ this._context.Attach(newEntity);
+
+ entry.State = EntityState.Modified;
+
+ return await this.SaveChangesAsync();
+ }
+
+ public virtual async Task<bool> DeleteAsync(TEntity entity)
+ {
+ this._context.Remove(entity);
+
+ return await this.SaveChangesAsync();
+ }
+
+ public virtual async Task<bool> SaveChangesAsync()
+ {
+ int result = await _context.SaveChangesAsync();
+
+ return result >= 1;
+ }
+ }
+}
diff --git a/src/Data/DevHive.Data/Repositories/CommentRepository.cs b/src/Data/DevHive.Data/Repositories/CommentRepository.cs
new file mode 100644
index 0000000..bee7624
--- /dev/null
+++ b/src/Data/DevHive.Data/Repositories/CommentRepository.cs
@@ -0,0 +1,74 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Threading.Tasks;
+using DevHive.Data.Interfaces.Repositories;
+using DevHive.Data.Models;
+using Microsoft.EntityFrameworkCore;
+
+namespace DevHive.Data.Repositories
+{
+ public class CommentRepository : BaseRepository<Comment>, ICommentRepository
+ {
+ private readonly DevHiveContext _context;
+
+ public CommentRepository(DevHiveContext context)
+ : base(context)
+ {
+ this._context = context;
+ }
+
+ #region Read
+ public override async Task<Comment> GetByIdAsync(Guid id)
+ {
+ return await this._context.Comments
+ .Include(x => x.Creator)
+ .Include(x => x.Post)
+ .FirstOrDefaultAsync(x => x.Id == id);
+ }
+
+ /// <summary>
+ /// This method returns the comment that is made at exactly the given time and by the given creator
+ /// </summary>
+ public async Task<Comment> GetCommentByIssuerAndTimeCreatedAsync(Guid issuerId, DateTime timeCreated)
+ {
+ return await this._context.Comments
+ .FirstOrDefaultAsync(p => p.Creator.Id == issuerId &&
+ p.TimeCreated == timeCreated);
+ }
+
+ public async Task<List<Comment>> GetPostComments(Guid postId)
+ {
+ return await this._context.Posts
+ .SelectMany(x => x.Comments)
+ .Where(x => x.Post.Id == postId)
+ .ToListAsync();
+ }
+ #endregion
+
+ #region Update
+ public override async Task<bool> EditAsync(Guid id, Comment newEntity)
+ {
+ Comment comment = await this.GetByIdAsync(id);
+
+ this._context
+ .Entry(comment)
+ .CurrentValues
+ .SetValues(newEntity);
+
+ return await this.SaveChangesAsync();
+ }
+ #endregion
+
+
+ #region Validations
+ public async Task<bool> DoesCommentExist(Guid id)
+ {
+ return await this._context.Comments
+ .AsNoTracking()
+ .AnyAsync(r => r.Id == id);
+ }
+ #endregion
+ }
+}
diff --git a/src/Data/DevHive.Data/Repositories/FeedRepository.cs b/src/Data/DevHive.Data/Repositories/FeedRepository.cs
new file mode 100644
index 0000000..8d3e5e1
--- /dev/null
+++ b/src/Data/DevHive.Data/Repositories/FeedRepository.cs
@@ -0,0 +1,77 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using AutoMapper.Internal;
+using DevHive.Data.Interfaces.Repositories;
+using DevHive.Data.Models;
+using Microsoft.EntityFrameworkCore;
+
+namespace DevHive.Data.Repositories
+{
+ public class FeedRepository : IFeedRepository
+ {
+ private readonly DevHiveContext _context;
+
+ public FeedRepository(DevHiveContext context)
+ {
+ this._context = context;
+ }
+
+ /// <summary>
+ /// This returns a given amount of posts of all given friends, created before "firstRequestIssued",
+ /// ordered from latest to oldest (time created).
+ /// PageSize specifies how many posts to get, and pageNumber specifices how many posts to skip (pageNumber * pageSize).
+ ///
+ /// This method is used in the feed page.
+ /// Posts from friends are meant to be gotten in chunks, meaning you get X posts, and then get another amount of posts,
+ /// that are after the first X posts.
+ /// </summary>
+ public async Task<List<Post>> GetFriendsPosts(List<User> friendsList, DateTime firstRequestIssued, int pageNumber, int pageSize)
+ {
+ List<Guid> friendsIds = friendsList.Select(f => f.Id).ToList();
+
+ List<Post> posts = await this._context.Posts
+ .Where(post => post.TimeCreated < firstRequestIssued)
+ .Where(p => friendsIds.Contains(p.Creator.Id))
+ .ToListAsync();
+
+ // Ordering by descending can't happen in query, because it doesn't order it
+ // completely correctly (example: in query these two times are ordered
+ // like this: 2021-01-30T11:49:45, 2021-01-28T21:37:40.701244)
+ posts = posts
+ .OrderByDescending(x => x.TimeCreated.ToFileTime())
+ .Skip((pageNumber - 1) * pageSize)
+ .Take(pageSize)
+ .ToList();
+
+ return posts;
+ }
+
+ /// <summary>
+ /// This returns a given amount of posts, that a user has made, created before "firstRequestIssued",
+ /// ordered from latest to oldest (time created).
+ /// PageSize specifies how many posts to get, and pageNumber specifices how many posts to skip (pageNumber * pageSize).
+ ///
+ /// This method is used in the profile page.
+ /// Posts from friends are meant to be gotten in chunks, meaning you get X posts, and then get another amount of posts,
+ /// that are after the first X posts.
+ /// </summary>
+ public async Task<List<Post>> GetUsersPosts(User user, DateTime firstRequestIssued, int pageNumber, int pageSize)
+ {
+ List<Post> posts = await this._context.Posts
+ .Where(post => post.TimeCreated < firstRequestIssued)
+ .Where(p => p.Creator.Id == user.Id)
+ .ToListAsync();
+
+ // Look at GetFriendsPosts on why this is done like this
+ posts = posts
+ .OrderByDescending(x => x.TimeCreated.ToFileTime())
+ .Skip((pageNumber - 1) * pageSize)
+ .Take(pageSize)
+ .ToList();
+
+ return posts;
+ }
+ }
+}
diff --git a/src/Data/DevHive.Data/Repositories/LanguageRepository.cs b/src/Data/DevHive.Data/Repositories/LanguageRepository.cs
new file mode 100644
index 0000000..31d0b86
--- /dev/null
+++ b/src/Data/DevHive.Data/Repositories/LanguageRepository.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using DevHive.Data.Interfaces.Repositories;
+using DevHive.Data.Models;
+using Microsoft.EntityFrameworkCore;
+
+namespace DevHive.Data.Repositories
+{
+ public class LanguageRepository : BaseRepository<Language>, ILanguageRepository
+ {
+ private readonly DevHiveContext _context;
+
+ public LanguageRepository(DevHiveContext context)
+ : base(context)
+ {
+ this._context = context;
+ }
+
+ #region Read
+ public async Task<Language> GetByNameAsync(string languageName)
+ {
+ return await this._context.Languages
+ .FirstOrDefaultAsync(x => x.Name == languageName);
+ }
+
+ /// <summary>
+ /// Returns all technologies that exist in the database
+ /// </summary>
+ public HashSet<Language> GetLanguages()
+ {
+ return this._context.Languages.ToHashSet();
+ }
+ #endregion
+
+ #region Validations
+ public async Task<bool> DoesLanguageNameExistAsync(string languageName)
+ {
+ return await this._context.Languages
+ .AsNoTracking()
+ .AnyAsync(r => r.Name == languageName);
+ }
+
+ public async Task<bool> DoesLanguageExistAsync(Guid id)
+ {
+ return await this._context.Languages
+ .AsNoTracking()
+ .AnyAsync(r => r.Id == id);
+ }
+ #endregion
+ }
+}
diff --git a/src/Data/DevHive.Data/Repositories/PostRepository.cs b/src/Data/DevHive.Data/Repositories/PostRepository.cs
new file mode 100644
index 0000000..52c5b4e
--- /dev/null
+++ b/src/Data/DevHive.Data/Repositories/PostRepository.cs
@@ -0,0 +1,105 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using DevHive.Data.Interfaces.Repositories;
+using DevHive.Data.Models;
+using DevHive.Data.RelationModels;
+using Microsoft.EntityFrameworkCore;
+
+namespace DevHive.Data.Repositories
+{
+ public class PostRepository : BaseRepository<Post>, IPostRepository
+ {
+ private readonly DevHiveContext _context;
+ private readonly IUserRepository _userRepository;
+
+ public PostRepository(DevHiveContext context, IUserRepository userRepository)
+ : base(context)
+ {
+ this._context = context;
+ this._userRepository = userRepository;
+ }
+
+ public async Task<bool> AddNewPostToCreator(Guid userId, Post post)
+ {
+ User user = await this._userRepository.GetByIdAsync(userId);
+ user.Posts.Add(post);
+
+ return await this.SaveChangesAsync();
+ }
+
+ #region Read
+ public override async Task<Post> GetByIdAsync(Guid id)
+ {
+ return await this._context.Posts
+ .Include(x => x.Comments)
+ .Include(x => x.Creator)
+ .Include(x => x.Attachments)
+ // .Include(x => x.Rating)
+ .FirstOrDefaultAsync(x => x.Id == id);
+ }
+
+ /// <summary>
+ /// This method returns the post that is made at exactly the given time and by the given creator
+ /// </summary>
+ public async Task<Post> GetPostByCreatorAndTimeCreatedAsync(Guid creatorId, DateTime timeCreated)
+ {
+ return await this._context.Posts
+ .FirstOrDefaultAsync(p => p.Creator.Id == creatorId &&
+ p.TimeCreated == timeCreated);
+ }
+
+ public async Task<List<string>> GetFileUrls(Guid postId)
+ {
+ return (await this.GetByIdAsync(postId)).Attachments.Select(x => x.FileUrl).ToList();
+ }
+ #endregion
+
+ #region Update
+ public override async Task<bool> EditAsync(Guid id, Post newEntity)
+ {
+ Post post = await this.GetByIdAsync(id);
+ // var ratingId = post.Rating.Id;
+
+ this._context
+ .Entry(post)
+ .CurrentValues
+ .SetValues(newEntity);
+
+ List<PostAttachments> postAttachments = new();
+ foreach(var attachment in newEntity.Attachments)
+ postAttachments.Add(attachment);
+ post.Attachments = postAttachments;
+
+ post.Comments.Clear();
+ foreach(var comment in newEntity.Comments)
+ post.Comments.Add(comment);
+
+ // post.Rating.Id = ratingId;
+
+ this._context.Entry(post).State = EntityState.Modified;
+
+ return await this.SaveChangesAsync();
+ }
+ #endregion
+
+ #region Validations
+ public async Task<bool> DoesPostExist(Guid postId)
+ {
+ return await this._context.Posts
+ .AsNoTracking()
+ .AnyAsync(r => r.Id == postId);
+ }
+
+ public async Task<bool> DoesPostHaveFiles(Guid postId)
+ {
+ return await this._context.Posts
+ .AsNoTracking()
+ .Where(x => x.Id == postId)
+ .Select(x => x.Attachments)
+ .AnyAsync();
+ }
+ #endregion
+ }
+}
diff --git a/src/Data/DevHive.Data/Repositories/RatingRepository.cs b/src/Data/DevHive.Data/Repositories/RatingRepository.cs
new file mode 100644
index 0000000..1be8fe8
--- /dev/null
+++ b/src/Data/DevHive.Data/Repositories/RatingRepository.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+using DevHive.Data.Interfaces.Repositories;
+using DevHive.Data.Models;
+using Microsoft.EntityFrameworkCore;
+
+namespace DevHive.Data.Repositories
+{
+ public class RatingRepository : BaseRepository<Rating>, IRatingRepository
+ {
+ private readonly DevHiveContext _context;
+ private readonly IPostRepository _postRepository;
+
+ public RatingRepository(DevHiveContext context, IPostRepository postRepository)
+ : base(context)
+ {
+ this._context = context;
+ this._postRepository = postRepository;
+ }
+
+ public async Task<Rating> GetRatingByPostId(Guid postId)
+ {
+ return await this._context.Rating
+ .FirstOrDefaultAsync(x => x.Post.Id == postId);
+ }
+
+ public async Task<bool> UserRatedPost(Guid userId, Guid postId)
+ {
+ return await this._context.UserRate
+ .Where(x => x.Post.Id == postId)
+ .AnyAsync(x => x.User.Id == userId);
+ }
+ }
+}
diff --git a/src/Data/DevHive.Data/Repositories/RoleRepository.cs b/src/Data/DevHive.Data/Repositories/RoleRepository.cs
new file mode 100644
index 0000000..441efef
--- /dev/null
+++ b/src/Data/DevHive.Data/Repositories/RoleRepository.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Threading.Tasks;
+using DevHive.Data.Interfaces.Repositories;
+using DevHive.Data.Models;
+using Microsoft.EntityFrameworkCore;
+
+namespace DevHive.Data.Repositories
+{
+ public class RoleRepository : BaseRepository<Role>, IRoleRepository
+ {
+ private readonly DevHiveContext _context;
+
+ public RoleRepository(DevHiveContext context)
+ : base(context)
+ {
+ this._context = context;
+ }
+
+ #region Read
+ public async Task<Role> GetByNameAsync(string name)
+ {
+ return await this._context.Roles
+ .FirstOrDefaultAsync(x => x.Name == name);
+ }
+ #endregion
+
+ public override async Task<bool> EditAsync(Guid id, Role newEntity)
+ {
+ Role role = await this.GetByIdAsync(id);
+
+ this._context
+ .Entry(role)
+ .CurrentValues
+ .SetValues(newEntity);
+
+ return await this.SaveChangesAsync();
+ }
+
+ #region Validations
+ public async Task<bool> DoesNameExist(string name)
+ {
+ return await this._context.Roles
+ .AsNoTracking()
+ .AnyAsync(r => r.Name == name);
+ }
+
+ public async Task<bool> DoesRoleExist(Guid id)
+ {
+ return await this._context.Roles
+ .AsNoTracking()
+ .AnyAsync(r => r.Id == id);
+ }
+ #endregion
+ }
+}
diff --git a/src/Data/DevHive.Data/Repositories/TechnologyRepository.cs b/src/Data/DevHive.Data/Repositories/TechnologyRepository.cs
new file mode 100644
index 0000000..6f0d10f
--- /dev/null
+++ b/src/Data/DevHive.Data/Repositories/TechnologyRepository.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using DevHive.Data.Interfaces.Repositories;
+using DevHive.Data.Models;
+using Microsoft.EntityFrameworkCore;
+
+namespace DevHive.Data.Repositories
+{
+ public class TechnologyRepository : BaseRepository<Technology>, ITechnologyRepository
+ {
+ private readonly DevHiveContext _context;
+
+ public TechnologyRepository(DevHiveContext context)
+ : base(context)
+ {
+ this._context = context;
+ }
+
+ #region Read
+ public async Task<Technology> GetByNameAsync(string technologyName)
+ {
+ return await this._context.Technologies
+ .FirstOrDefaultAsync(x => x.Name == technologyName);
+ }
+
+ /// <summary>
+ /// Returns all technologies that exist in the database
+ /// </summary>
+ public HashSet<Technology> GetTechnologies()
+ {
+ return this._context.Technologies.ToHashSet();
+ }
+ #endregion
+
+ #region Validations
+ public async Task<bool> DoesTechnologyNameExistAsync(string technologyName)
+ {
+ return await this._context.Technologies
+ .AsNoTracking()
+ .AnyAsync(r => r.Name == technologyName);
+ }
+
+ public async Task<bool> DoesTechnologyExistAsync(Guid id)
+ {
+ return await this._context.Technologies
+ .AsNoTracking()
+ .AnyAsync(x => x.Id == id);
+ }
+ #endregion
+ }
+}
diff --git a/src/Data/DevHive.Data/Repositories/UserRepository.cs b/src/Data/DevHive.Data/Repositories/UserRepository.cs
new file mode 100644
index 0000000..6e97e60
--- /dev/null
+++ b/src/Data/DevHive.Data/Repositories/UserRepository.cs
@@ -0,0 +1,108 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Threading.Tasks;
+using AutoMapper.Mappers;
+using DevHive.Data.Interfaces.Repositories;
+using DevHive.Data.Models;
+using DevHive.Data.RelationModels;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.EntityFrameworkCore;
+
+namespace DevHive.Data.Repositories
+{
+ public class UserRepository : BaseRepository<User>, IUserRepository
+ {
+ private readonly DevHiveContext _context;
+
+ public UserRepository(DevHiveContext context)
+ : base(context)
+ {
+ this._context = context;
+ }
+
+ #region Read
+ public override async Task<User> GetByIdAsync(Guid id)
+ {
+ return await this._context.Users
+ .Include(x => x.Roles)
+ .Include(x => x.Languages)
+ .Include(x => x.Technologies)
+ .Include(x => x.Posts)
+ .Include(x => x.Friends)
+ .Include(x => x.ProfilePicture)
+ .FirstOrDefaultAsync(x => x.Id == id);
+ }
+
+ public async Task<User> GetByUsernameAsync(string username)
+ {
+ return await this._context.Users
+ .Include(x => x.Roles)
+ .Include(x => x.Languages)
+ .Include(x => x.Technologies)
+ .Include(x => x.Posts)
+ .Include(x => x.Friends)
+ .Include(x => x.ProfilePicture)
+ .FirstOrDefaultAsync(x => x.UserName == username);
+ }
+ #endregion
+
+ #region Update
+ public async Task<bool> UpdateProfilePicture(Guid userId, string pictureUrl)
+ {
+ User user = await this.GetByIdAsync(userId);
+
+ user.ProfilePicture.PictureURL = pictureUrl;
+
+ return await this.SaveChangesAsync();
+ }
+ #endregion
+
+ #region Validations
+ public async Task<bool> DoesUserExistAsync(Guid id)
+ {
+ return await this._context.Users
+ .AsNoTracking()
+ .AnyAsync(x => x.Id == id);
+ }
+
+ public async Task<bool> DoesUsernameExistAsync(string username)
+ {
+ return await this._context.Users
+ .AsNoTracking()
+ .AnyAsync(u => u.UserName == username);
+ }
+
+ public async Task<bool> DoesEmailExistAsync(string email)
+ {
+ return await this._context.Users
+ .AsNoTracking()
+ .AnyAsync(u => u.Email == email);
+ }
+
+ public async Task<bool> ValidateFriendsCollectionAsync(List<string> usernames)
+ {
+ bool valid = true;
+
+ foreach (var username in usernames)
+ {
+ if (!await this._context.Users.AnyAsync(x => x.UserName == username))
+ {
+ valid = false;
+ break;
+ }
+ }
+ return valid;
+ }
+
+ public bool DoesUserHaveThisUsername(Guid id, string username)
+ {
+ return this._context.Users
+ .AsNoTracking()
+ .Any(x => x.Id == id &&
+ x.UserName == username);
+ }
+ #endregion
+ }
+}