diff --git a/ToDo.yaml b/ToDo.yaml index 855e616..f162401 100755 --- a/ToDo.yaml +++ b/ToDo.yaml @@ -50,6 +50,7 @@ Client: resume/editor: Not fully tested yet + Veteran needs to be moved from the Resume/millitary into the Resume so it doesnt have to save the whole millitary object to the db if not needed Company: Need to impliment Add employee diff --git a/src/Server/Services/DatabaseService/Resume.cs b/src/Server/Services/DatabaseService/Resume.cs index 35cf14e..916704e 100644 --- a/src/Server/Services/DatabaseService/Resume.cs +++ b/src/Server/Services/DatabaseService/Resume.cs @@ -58,101 +58,47 @@ namespace BoredCareers.Services.DatabaseService { return resumes.ToArray(); } + private async Task ExecuteReaderAsync(MySqlConnection conn, string query, int resumeId) { + var cmd = new MySqlCommand(query, conn); + cmd.Parameters.AddWithValue("@ResumeID", resumeId); + return await cmd.ExecuteReaderAsync(); + } + public async Task GetResume(int ResumeID) { - // Open connections for multi-threaded request - MySqlConnection resumeConnection = GetConnection(); - MySqlConnection ResumeExperienceConnection = GetConnection(); - MySqlConnection ResumeExperienceBulletConnection = GetConnection(); - MySqlConnection ResumeMilitaryConnection = GetConnection(); - MySqlConnection ResumeMilitaryBulletConnection = GetConnection(); - MySqlConnection ResumeEducationConnection = GetConnection(); - MySqlConnection ResumeSkillConnection = GetConnection(); - MySqlConnection ResumeLanguageConnection = GetConnection(); - MySqlConnection ResumeCertificationConnection = GetConnection(); - MySqlConnection ResumeProjectConnection = GetConnection(); + using (var conn = GetConnection()) { + await conn.OpenAsync(); - // Open the connections - Task resumeopen = resumeConnection.OpenAsync(); - Task resumeexperienceopen = ResumeExperienceConnection.OpenAsync(); - Task resumeexperiencebulletopen = ResumeExperienceBulletConnection.OpenAsync(); - Task resumemilitaryopen = ResumeMilitaryConnection.OpenAsync(); - Task resumemilitarybulletopen = ResumeMilitaryBulletConnection.OpenAsync(); - Task resumeeducationopen = ResumeEducationConnection.OpenAsync(); - Task resumeskillopen = ResumeSkillConnection.OpenAsync(); - Task resumelanguageopen = ResumeLanguageConnection.OpenAsync(); - Task resumecertifcationopen = ResumeCertificationConnection.OpenAsync(); - Task resumeprojectopen = ResumeProjectConnection.OpenAsync(); + Resume? resume = await GetResume(await ExecuteReaderAsync(conn, "SELECT * FROM Resume WHERE ID = @ResumeID;", ResumeID)); + if (resume == null) { return null; } - // Wait for all the connections to open - await Task.WhenAll(resumeopen, resumeexperienceopen, resumeexperiencebulletopen, resumemilitaryopen, resumemilitarybulletopen, - resumeeducationopen, resumeskillopen, resumelanguageopen, resumecertifcationopen, resumeprojectopen); + Task[] tasks = [ + ExecuteReaderAsync(conn, "SELECT * FROM ResumeExperience WHERE ResumeID = @ResumeID;", ResumeID), + ExecuteReaderAsync(conn, "SELECT * FROM ResumeExperienceBullet WHERE ResumeID = @ResumeID;", ResumeID), + ExecuteReaderAsync(conn, "SELECT * FROM ResumeMilitary WHERE ResumeID = @ResumeID;", ResumeID), + ExecuteReaderAsync(conn, "SELECT * FROM ResumeMilitaryBullet WHERE ResumeID = @ResumeID;", ResumeID), + ExecuteReaderAsync(conn, "SELECT * FROM ResumeEducation WHERE ResumeID = @ResumeID;", ResumeID), + ExecuteReaderAsync(conn, "SELECT * FROM ResumeSkill WHERE ResumeID = @ResumeID;", ResumeID), + ExecuteReaderAsync(conn, "SELECT * FROM ResumeLanguage WHERE ResumeID = @ResumeID;", ResumeID), + ExecuteReaderAsync(conn, "SELECT * FROM ResumeCertification WHERE ResumeID = @ResumeID;", ResumeID), + ExecuteReaderAsync(conn, "SELECT * FROM ResumeProject WHERE ResumeID = @ResumeID;", ResumeID), + ]; + await Task.WhenAll(tasks); - // Setup the commands for the connections - MySqlCommand resumeCommand = new MySqlCommand("SELECT * FROM Resume WHERE ID = @ResumeID;", resumeConnection); - MySqlCommand ResumeExperienceCommand = new MySqlCommand("SELECT * FROM ResumeExperience WHERE ResumeID = @ResumeID;", ResumeExperienceConnection); - MySqlCommand ResumeExperienceBulletCommand = new MySqlCommand("SELECT * FROM ResumeExperienceBullet WHERE ResumeID = @ResumeID;", ResumeExperienceBulletConnection); - MySqlCommand ResumeMilitaryCommand = new MySqlCommand("SELECT * FROM ResumeMilitary WHERE ResumeID = @ResumeID;", ResumeMilitaryConnection); - MySqlCommand ResumeMilitaryBulletCommand = new MySqlCommand("SELECT * FROM ResumeMilitaryBullet WHERE ResumeID = @ResumeID", ResumeMilitaryBulletConnection); - MySqlCommand ResumeEducationCommand = new MySqlCommand("SELECT * FROM ResumeEducation WHERE ResumeID = @ResumeID;", ResumeEducationConnection); - MySqlCommand ResumeSkillCommand = new MySqlCommand("SELECT * FROM ResumeSkill WHERE ResumeID = @ResumeID;", ResumeSkillConnection); - MySqlCommand ResumeLanguageCommand = new MySqlCommand("SELECT * FROM ResumeLanguage WHERE ResumeID = @ResumeID;", ResumeLanguageConnection); - MySqlCommand ResumeCertificationCommand = new MySqlCommand("SELECT * FROM ResumeCertification WHERE ResumeID = @ResumeID;", ResumeCertificationConnection); - MySqlCommand ResumeProjectCommand = new MySqlCommand("SELECT * FROM ResumeProject WHERE ResumeID = @ResumeID;", ResumeProjectConnection); + ResumeExperience[] experience = await GetResumeExperience(await tasks[0]); + ResumeExperienceBullet[] bullets = await GetResumeExperienceBullets(await tasks[1]); + ResumeMilitary? military = await GetResumeMilitary(await tasks[2]); + ResumeMilitaryBullet[] militaryBullets = await GetResumeMilitaryBullets(await tasks[3]); + ResumeEducation[] education = await GetResumeEducation(await tasks[4]); + ResumeSkill[] skills = await GetResumeSkills(await tasks[5]); + ResumeLanguage[] languages = await GetResumeLanguages(await tasks[6]); + ResumeCertification[] certs = await GetResumeCertification(await tasks[7]); + ResumeProject[] projects = await GetResumeProjects(await tasks[8]); - // Add parameters to the commands - resumeCommand.Parameters.AddWithValue("@ResumeID", ResumeID); - ResumeExperienceCommand.Parameters.AddWithValue("@ResumeID", ResumeID); - ResumeExperienceBulletCommand.Parameters.AddWithValue("@ResumeID", ResumeID); - ResumeMilitaryCommand.Parameters.AddWithValue("@ResumeID", ResumeID); - ResumeMilitaryBulletCommand.Parameters.AddWithValue("@ResumeID", ResumeID); - ResumeEducationCommand.Parameters.AddWithValue("@ResumeID", ResumeID); - ResumeSkillCommand.Parameters.AddWithValue("@ResumeID", ResumeID); - ResumeLanguageCommand.Parameters.AddWithValue("@ResumeID", ResumeID); - ResumeCertificationCommand.Parameters.AddWithValue("@ResumeID", ResumeID); - ResumeProjectCommand.Parameters.AddWithValue("@ResumeID", ResumeID); - - // Run the commands - Task ResumeReader = resumeCommand.ExecuteReaderAsync(); - Task ResumeExperienceReader = ResumeExperienceCommand.ExecuteReaderAsync(); - Task ResumeExperienceBulletReader = ResumeExperienceBulletCommand.ExecuteReaderAsync(); - Task ResumeMilitaryReader = ResumeMilitaryCommand.ExecuteReaderAsync(); - Task ResumeMilitaryBulletReader = ResumeMilitaryBulletCommand.ExecuteReaderAsync(); - Task ResumeEducationReader = ResumeEducationCommand.ExecuteReaderAsync(); - Task ResumeSkillReader = ResumeSkillCommand.ExecuteReaderAsync(); - Task ResumeLanguageReader = ResumeLanguageCommand.ExecuteReaderAsync(); - Task ResumeCertificationReader = ResumeCertificationCommand.ExecuteReaderAsync(); - Task ResumeProjectReader = ResumeProjectCommand.ExecuteReaderAsync(); - - // Wait for all the commands to process - await Task.WhenAll(ResumeReader, ResumeExperienceReader, ResumeExperienceBulletReader, ResumeMilitaryReader, ResumeMilitaryBulletReader, - ResumeEducationReader, ResumeSkillReader, ResumeLanguageReader, ResumeCertificationReader, ResumeProjectReader); - - // Get Resume - Resume? resume = await GetResume( await ResumeReader ); - if (resume != null) { - - // Get Resume Parts - ResumeExperience[] experience = await GetResumeExperience(await ResumeExperienceReader); - ResumeExperienceBullet[] experienceBullets = await GetResumeExperienceBullets(await ResumeExperienceBulletReader); - ResumeMilitary? military = await GetResumeMilitary(await ResumeMilitaryReader); - ResumeMilitaryBullet[] militaryBullets = await GetResumeMilitaryBullets(await ResumeMilitaryBulletReader); - ResumeEducation[] education = await GetResumeEducation(await ResumeEducationReader); - ResumeSkill[] skills = await GetResumeSkills(await ResumeSkillReader); - ResumeLanguage[] languages = await GetResumeLanguages(await ResumeLanguageReader); - ResumeCertification[] certs = await GetResumeCertification(await ResumeCertificationReader); - ResumeProject[] projects = await GetResumeProjects(await ResumeProjectReader); - - // Split into grouped lists and add to experience - Dictionary groupedExperienceBullets = experienceBullets.GroupBy(b => b.ResumeExperienceID).ToDictionary(g => g.Key, g => g.ToArray()); - foreach (ResumeExperience cur in experience) { - cur.ExperienceBullets = groupedExperienceBullets[Convert.ToInt32(cur.ID)]; + Dictionary groupedExperienceBullets = bullets.GroupBy(b => b.ResumeExperienceID).ToDictionary(g => g.Key, g => g.ToArray()); + foreach (var exp in experience) { + exp.ExperienceBullets = groupedExperienceBullets.TryGetValue(Convert.ToInt32(exp.ID), out var b) ? b : Array.Empty(); } - // Add the parts to the resume - if (military != null) { - military.MillitaryBullets = militaryBullets; - resume.Millitary = military; - } resume.Experience = experience; resume.Educations = education; resume.Skills = skills; @@ -160,63 +106,52 @@ namespace BoredCareers.Services.DatabaseService { resume.Certification = certs; resume.Projects = projects; + if (military != null) { + military.MillitaryBullets = militaryBullets; + resume.Millitary = military; + } + return resume; } - return null; } public async Task SetResume(Resume resume) { + using (var conn = GetConnection()) { + await conn.OpenAsync(); - // Open connections for multi-threaded request - MySqlConnection resumeConnection = GetConnection(); - MySqlConnection ResumeExperienceConnection = GetConnection(); - MySqlConnection ResumeExperienceBulletConnection = GetConnection(); - MySqlConnection ResumeMilitaryConnection = GetConnection(); - MySqlConnection ResumeMilitaryBulletConnection = GetConnection(); - MySqlConnection ResumeEducationConnection = GetConnection(); - MySqlConnection ResumeSkillConnection = GetConnection(); - MySqlConnection ResumeLanguageConnection = GetConnection(); - MySqlConnection ResumeCertificationConnection = GetConnection(); - MySqlConnection ResumeProjectConnection = GetConnection(); + // Set ResumeID on layer 1 nodes + int _ResumeID = await SetResume(conn, resume); + if (resume.Millitary != null) { resume.Millitary.ResumeID = _ResumeID; } + foreach (ResumeExperience cur in resume.Experience) { cur.ResumeID = _ResumeID; } + foreach (ResumeEducation cur in resume.Educations) { cur.ResumeID = _ResumeID; } + foreach (ResumeSkill cur in resume.Skills) { cur.ResumeID = _ResumeID; } + foreach (ResumeLanguage cur in resume.Languages) { cur.ResumeID = _ResumeID; } + foreach (ResumeCertification cur in resume.Certification) { cur.ResumeID = _ResumeID; } + foreach (ResumeProject cur in resume.Projects) { cur.ResumeID = _ResumeID; } - // Open the connections - Task resumeopen = resumeConnection.OpenAsync(); - Task resumeexperienceopen = ResumeExperienceConnection.OpenAsync(); - Task resumeexperiencebulletopen = ResumeExperienceBulletConnection.OpenAsync(); - Task resumemilitaryopen = ResumeMilitaryConnection.OpenAsync(); - Task resumemilitarybulletopen = ResumeMilitaryBulletConnection.OpenAsync(); - Task resumeeducationopen = ResumeEducationConnection.OpenAsync(); - Task resumeskillopen = ResumeSkillConnection.OpenAsync(); - Task resumelanguageopen = ResumeLanguageConnection.OpenAsync(); - Task resumecertifcationopen = ResumeCertificationConnection.OpenAsync(); - Task resumeprojectopen = ResumeProjectConnection.OpenAsync(); + Task[] tasks = [ + SetResumeExperience(conn, resume.Experience), + SetResumeMilitary(conn, resume.Millitary), + SetResumeEducation(conn, resume.Educations), + SetResumeSkills(conn, resume.Skills), + SetResumeLanguages(conn, resume.Languages), + SetResumeCertification(conn, resume.Certification), + SetResumeProjects(conn, resume.Projects) + ]; + await Task.WhenAll(tasks); - // Wait for all the connections to open - await Task.WhenAll(resumeopen, resumeexperienceopen, resumeexperiencebulletopen, resumemilitaryopen, resumemilitarybulletopen, - resumeeducationopen, resumeskillopen, resumelanguageopen, resumecertifcationopen, resumeprojectopen); - - // Get all the experience bullets and run all the updates - List bullets = new List(); - foreach (ResumeExperience cur in resume.Experience) { - foreach (ResumeExperienceBullet bullet in cur.ExperienceBullets) { - bullets.Add(bullet); + List bullets = new List(); + foreach (ResumeExperience cur in resume.Experience) { + foreach (ResumeExperienceBullet bullet in cur.ExperienceBullets) { + bullets.Add(bullet); + } } + + Task ResumeExperienceBulletTask = SetResumeExperienceBullets(ResumeExperienceBulletConnection, bullets.ToArray()); + Task ResumeMilitaryBulletTask = SetResumeMilitaryBullets(ResumeMilitaryBulletConnection, resume.Millitary.MillitaryBullets); + + return resume; } - Task ResumeExperienceBulletTask = SetResumeExperienceBullets(ResumeExperienceBulletConnection, bullets.ToArray()); - Task ResumeTask = SetResume(resumeConnection, resume); - Task ResumeExperienceTask = SetResumeExperience(ResumeExperienceConnection, resume.Experience); - Task ResumeMilitaryTask = SetResumeMilitary(ResumeMilitaryConnection, resume.Millitary); - Task ResumeMilitaryBulletTask = SetResumeMilitaryBullets(ResumeMilitaryBulletConnection, resume.Millitary.MillitaryBullets); - Task ResumeEducationTask = SetResumeEducation(ResumeEducationConnection, resume.Educations); - Task ResumeSkllTask = SetResumeSkills(ResumeSkillConnection, resume.Skills); - Task ResumeLanguageTask = SetResumeLanguages(ResumeLanguageConnection, resume.Languages); - Task ResumeCertTask = SetResumeCertification(ResumeCertificationConnection, resume.Certification); - Task ResumeProjectTask = SetResumeProjects(ResumeProjectConnection, resume.Projects); - - // Allow update to finish before closing process - await Task.WhenAll(ResumeTask, ResumeExperienceTask, ResumeExperienceBulletTask, ResumeMilitaryTask, ResumeMilitaryBulletTask, - ResumeEducationTask, ResumeSkllTask, ResumeLanguageTask, ResumeCertTask, ResumeProjectTask); - } public async Task DeleteResume( int ResumeID ) { diff --git a/src/Server/Services/DatabaseService/ResumeParts/SetResumeParts.cs b/src/Server/Services/DatabaseService/ResumeParts/SetResumeParts.cs index 85c993d..ddef872 100644 --- a/src/Server/Services/DatabaseService/ResumeParts/SetResumeParts.cs +++ b/src/Server/Services/DatabaseService/ResumeParts/SetResumeParts.cs @@ -4,7 +4,7 @@ using MySql.Data.MySqlClient; namespace BoredCareers.Services.DatabaseService { public partial class DatabaseService { - public async Task SetResume(MySqlConnection connection, Resume resume) { + public async Task SetResume(MySqlConnection connection, Resume resume) { string command = @" INSERT INTO Resume (ID,AccountID,Title,Name,Field,Email,PhoneNumber,PostalCode,Country,StateOrRegion,City,IsActive) @@ -22,6 +22,8 @@ namespace BoredCareers.Services.DatabaseService { StateOrRegion = @StateOrRegion, City = @City, IsActive = @IsActive; + + SELECT LAST_INSERT_ID(); "; MySqlCommand cmd = new MySqlCommand(command, connection); @@ -37,8 +39,14 @@ namespace BoredCareers.Services.DatabaseService { cmd.Parameters.AddWithValue("@StateOrRegion", resume.StateOrRegion); cmd.Parameters.AddWithValue("@City", resume.City); cmd.Parameters.AddWithValue("@IsActive", resume.IsActive); + object? result = await cmd.ExecuteScalarAsync(); - await cmd.ExecuteNonQueryAsync(); + if (resume.ID != null && resume.ID != 0) { + return Convert.ToInt32(resume.ID); + } else { + cmd.CommandText = ""; + return Convert.ToInt32(result); + } } public async Task SetResumeExperienceBullets(MySqlConnection connection, ResumeExperienceBullet[] bullets) { @@ -64,7 +72,7 @@ namespace BoredCareers.Services.DatabaseService { } } - public async Task SetResumeExperience(MySqlConnection connection, ResumeExperience[] experiences) { + public async Task SetResumeExperience(MySqlConnection connection, ResumeExperience[] experiences) { foreach (ResumeExperience cur in experiences) { string command = @" INSERT INTO Resume @@ -82,6 +90,8 @@ namespace BoredCareers.Services.DatabaseService { DateStarted = @DateStarted, StillEmployed = @StillEmployed, DateEnded = @DateEnded; + + SELECT LAST_INSERT_ID(); "; MySqlCommand cmd = new MySqlCommand(command, connection); @@ -93,8 +103,14 @@ namespace BoredCareers.Services.DatabaseService { cmd.Parameters.AddWithValue("@DateStarted", cur.DateStarted.ToUniversalTime()); cmd.Parameters.AddWithValue("@StillEmployed", cur.StillEmployed); cmd.Parameters.AddWithValue("@DateEnded", cur.DateEnded.ToUniversalTime()); + object? result = await cmd.ExecuteScalarAsync(); - await cmd.ExecuteNonQueryAsync(); + if (cur.ID != null && cur.ID != 0) { + return Convert.ToInt32(cur.ID); + } else { + cmd.CommandText = ""; + return Convert.ToInt32(result); + } } } @@ -123,33 +139,41 @@ namespace BoredCareers.Services.DatabaseService { } } - public async Task SetResumeMilitary(MySqlConnection connection, ResumeMilitary military) { - string command = @" - INSERT INTO Resume - (ID,ResumeID,Veteran,Country,Rank,DateStarted,StillServing,DateEnded) - VALUES - (@ID,@ResumeID,@Veteran,@Country,@Rank,@DateStarted,@StillServing,@DateEnded) - ON DUPLICATE KEY UPDATE - ResumeID = @ResumeID, - Veteran = @Veteran, - Country = @Country, - Rank = @Rank, - DateStarted = @DateStarted, - StillServing = @StillServing, - DateEnded = @DateEnded; - "; + public async Task SetResumeMilitary(MySqlConnection connection, ResumeMilitary? military) { + if (military != null) { + string command = @" + INSERT INTO Resume + (ID,ResumeID,Country,Rank,DateStarted,StillServing,DateEnded) + VALUES + (@ID,@ResumeID,@Country,@Rank,@DateStarted,@StillServing,@DateEnded) + ON DUPLICATE KEY UPDATE + ResumeID = @ResumeID, + Country = @Country, + Rank = @Rank, + DateStarted = @DateStarted, + StillServing = @StillServing, + DateEnded = @DateEnded; - MySqlCommand cmd = new MySqlCommand(command, connection); - cmd.Parameters.AddWithValue("@ID", military.ID); - cmd.Parameters.AddWithValue("@ResumeID", military.ResumeID); - cmd.Parameters.AddWithValue("@Veteran", military.Veteran); - cmd.Parameters.AddWithValue("@Country", military.Country); - cmd.Parameters.AddWithValue("@Rank", military.Rank); - cmd.Parameters.AddWithValue("@DateStarted", military.DateStarted.ToUniversalTime()); - cmd.Parameters.AddWithValue("@StillServing", military.StillServing); - cmd.Parameters.AddWithValue("@DateEnded", military.DateEnded.ToUniversalTime()); + SELECT LAST_INSERT_ID(); + "; - await cmd.ExecuteNonQueryAsync(); + MySqlCommand cmd = new MySqlCommand(command, connection); + cmd.Parameters.AddWithValue("@ID", military.ID); + cmd.Parameters.AddWithValue("@ResumeID", military.ResumeID); + cmd.Parameters.AddWithValue("@Country", military.Country); + cmd.Parameters.AddWithValue("@Rank", military.Rank); + cmd.Parameters.AddWithValue("@DateStarted", military.DateStarted.ToUniversalTime()); + cmd.Parameters.AddWithValue("@StillServing", military.StillServing); + cmd.Parameters.AddWithValue("@DateEnded", military.DateEnded.ToUniversalTime()); + object? result = await cmd.ExecuteScalarAsync(); + + if (military.ID != null && military.ID != 0) { + return Convert.ToInt32(military.ID); + } else { + cmd.CommandText = ""; + return Convert.ToInt32(result); + } + } } public async Task SetResumeEducation(MySqlConnection connection, ResumeEducation[] educations) {