From 492314a956d782d2f3ff639a0e9c1fd9bbc33ef6 Mon Sep 17 00:00:00 2001 From: "Chris.Watts90@outlook.com" Date: Fri, 1 Jun 2018 10:08:43 +0100 Subject: [PATCH 1/6] beginnings of refactor for repository project. #95 --- .../Converters/TimeLogConverter.cs | 122 +++++++++ .../Converters/UserConverter.cs | 57 +++++ .../SQLiteRepository/SQLiteProcedures.cs | 34 +++ .../SQLiteRepository/SQLiteRepository.cs | 232 ++++++++---------- 4 files changed, 315 insertions(+), 130 deletions(-) create mode 100644 DataCenter_Windows/WindowsDataCenter/SQLiteRepository/Converters/TimeLogConverter.cs create mode 100644 DataCenter_Windows/WindowsDataCenter/SQLiteRepository/Converters/UserConverter.cs diff --git a/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/Converters/TimeLogConverter.cs b/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/Converters/TimeLogConverter.cs new file mode 100644 index 0000000..3669272 --- /dev/null +++ b/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/Converters/TimeLogConverter.cs @@ -0,0 +1,122 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Interfaces; + +namespace SQLiteRepository.Converters +{ + static class TimeLogConverter + { + public static TimeLog ConvertToTimeLogDto(TimeLogDb log) + { + return new TimeLog + { + CalendarWeek = log.CalendarWeek, + Direction = LogDirectionConverter.ConvertToLogDirectionDto(log.Direction), + EventTime = log.SwipeEventDateTime, + Id = log.Id, + IdentifierId = log.IdentifierId, + UserId = log.UserId_FK, + Source = LogSourceConverter.ConvertToLogSourceDto(log.Source), + Year = log.Year + }; + } + + public static TimeLogDb ConvertFromTimeLogDto(TimeLog log) + { + return new TimeLogDb + { + CalendarWeek = log.CalendarWeek, + Year = log.Year, + UserId_FK = log.UserId, + IdentifierId = log.IdentifierId, + Direction = LogDirectionConverter.ConvertFromLogDirectionDto(log.Direction), + Id = log.Id, + Source = LogSourceConverter.ConvertFromLogSourceDto(log.Source), + SwipeEventDateTime = log.EventTime + }; + } + } + + static class LogSourceConverter + { + public static LogSource ConvertToLogSourceDto(LogSourceDb source) + { + switch (source) + { + case LogSourceDb.IDENTIFIER: + return LogSource.IDENTIFIER; + case LogSourceDb.TRAYAPP: + return LogSource.TRAYAPP; + case LogSourceDb.UI: + return LogSource.UI; + default: + return LogSource.UNKNOWN; + } + } + + public static LogSourceDb ConvertFromLogSourceDto(LogSource source) + { + switch (source) + { + case LogSource.IDENTIFIER: + return LogSourceDb.IDENTIFIER; + case LogSource.TRAYAPP: + return LogSourceDb.TRAYAPP; + case LogSource.UI: + return LogSourceDb.UI; + default: + return LogSourceDb.UNKNOWN; + } + } + } + + static class LogDirectionConverter + { + public static LogDirection ConvertToLogDirectionDto(LogDirectionDb direction) + { + switch (direction) + { + case LogDirectionDb.IN: + return LogDirection.IN; + case LogDirectionDb.OUT: + return LogDirection.OUT; + default: + return LogDirection.UNKNOWN; + } + } + + public static LogDirectionDb ConvertFromLogDirectionDto(LogDirection direction) + { + switch (direction) + { + case LogDirection.IN: + return LogDirectionDb.IN; + case LogDirection.OUT: + return LogDirectionDb.OUT; + default: + return LogDirectionDb.UNKNOWN; + } + } + + public static LogDirectionDb InvertLogDirectionDb(LogDirectionDb direction) + { + return (LogDirectionDb)(int)InvertLogDirection((LogDirection)(int)direction); + } + + public static LogDirection InvertLogDirection(LogDirection direction) + { + switch (direction) + { + case LogDirection.IN: + return LogDirection.OUT; + case LogDirection.OUT: + return LogDirection.IN; + default: + return LogDirection.UNKNOWN; + } + } + } +} diff --git a/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/Converters/UserConverter.cs b/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/Converters/UserConverter.cs new file mode 100644 index 0000000..60f8c59 --- /dev/null +++ b/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/Converters/UserConverter.cs @@ -0,0 +1,57 @@ +using System; +using Interfaces; + +namespace SQLiteRepository.Converters +{ + static class UserConverter + { + public static User ConvertToUserDto(UserIdentity user) + { + return new User + { + UserId = user.Id, + FirstName = user.FirstName, + LastName = user.LastName, + IsContractor = user.IsContractor, + HoursPerWeek = user.HoursPerWeek, + }; + } + + public static UserIdentity ConvertFromUserDto(User user) + { + return new UserIdentity + { + Id = user.UserId, + FirstName = user.FirstName, + LastName = user.LastName, + HoursPerWeek = user.HoursPerWeek, + IsContractor = user.IsContractor + }; + } + } + + static class IdentifierConverter + { + public static Identifier ConvertToIdentifierDto(CardUniqueId ident) + { + return new Identifier + { + Id = ident.Id, + UniqueId = ident.CardUId, + IsAssociatedToUser = ident.UserId_FK != Constants.UNASSIGNED_CARD_USER_ID, + LastUsed = ident.LastUsed.DateTime + }; + } + + public static CardUniqueId ConvertFromIdentifierDto(Identifier ident, int userId) + { + return new CardUniqueId + { + CardUId = ident.UniqueId, + Id = ident.Id, + UserId_FK = userId, + LastUsed = ident.LastUsed + }; + } + } +} diff --git a/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/SQLiteProcedures.cs b/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/SQLiteProcedures.cs index bcded4e..a8a08a9 100644 --- a/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/SQLiteProcedures.cs +++ b/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/SQLiteProcedures.cs @@ -92,5 +92,39 @@ namespace SQLiteRepository public const string GET_USER_CONTRACTED_HOURS = "select " + nameof(UserIdentity.HoursPerWeek) + " From UserIdentity where " + nameof(UserIdentity.Id) + "=?"; + + public const string GET_GROUPS = "select gp."+ nameof(GroupDb.GroupId)+ ", gp."+nameof(GroupDb.GroupName)+", " + + "sum(case when gp." + nameof(GroupDb.GroupId) + " = ujdb." + nameof(UserGroupJoinDb.GroupId_FK) + " then 1 else 0 end) as " + nameof(GroupDb.AssignedUserCount) + + " from " + nameof(GroupDb) + " gp" + + " left join " + nameof(UserGroupJoinDb) + " ujdb " + + "on ujdb." + nameof(UserGroupJoinDb.GroupId_FK) + " = gp." + nameof(GroupDb.GroupId) + + " group by gp." + nameof(GroupDb.GroupId); + + public const string GET_GROUPS_FOR_USER = "select gdb." + nameof(GroupDb.GroupId) + ", gdb." + nameof(GroupDb.GroupName) + ", gdb.AssignedUserCount" + + " from " + nameof(GroupDb) + " gdb" + + " left join " + nameof(UserGroupJoinDb) + " ujdb" + + " on gdb." + nameof(GroupDb.GroupId) + " = ujdb." + nameof(UserGroupJoinDb.GroupId_FK) + + " where ujdb." + nameof(UserGroupJoinDb.UserId_FK) + " = ?"; + + public const string GET_GROUP_BY_ID = + "select * from " + nameof(GroupDb) + " where " + nameof(GroupDb.GroupId) + " =?"; + + public const string UPDATE_GROUP = "update " + nameof(GroupDb) + " set " + nameof(GroupDb.GroupName) + + "=? where " + nameof(GroupDb.GroupId) + "=?"; + + public const string GET_TIMELOG_ENTRY = + "select * from " + nameof(TimeLogDb) + " where " + nameof(TimeLogDb.Id) + "=?"; + + public const string DELETE_TIMELOG_ENTRY = + "delete from " + nameof(TimeLogDb) + " where " + nameof(TimeLogDb.Id) + "=?"; + + public const string UPDATE_TIMELOG_ENTRY = "update " + nameof(TimeLogDb) + + " set " + nameof(TimeLogDb.UserId_FK) + "=?, " + + nameof(TimeLogDb.Direction) + "=?," + + nameof(TimeLogDb.SwipeEventDateTime) + "=?," + + nameof(TimeLogDb.CalendarWeek) + "=?," + + nameof(TimeLogDb.Year) + "=?," + + nameof(TimeLogDb.Source) + "=? " + + "where " + nameof(TimeLogDb.Id) + "=?"; } } \ No newline at end of file diff --git a/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/SQLiteRepository.cs b/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/SQLiteRepository.cs index 89c510b..9d32477 100644 --- a/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/SQLiteRepository.cs +++ b/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/SQLiteRepository.cs @@ -8,6 +8,7 @@ using System.Reflection; using Interfaces; using SQLite.Net; using SQLite.Net.Platform.Win32; +using SQLiteRepository.Converters; using SQLiteRepository.Properties; namespace SQLiteRepository @@ -16,12 +17,13 @@ namespace SQLiteRepository { private readonly SQLiteConnection _connection; private readonly ILogger _logger; - private string _path = "flexitimedb.db"; + private readonly string _path; + private const string DATABASE_NAME = "flexitimedb.db"; public SQLiteRepository(ILogger logger) { _path = - new Uri(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().CodeBase), "flexitimedb.db")) + new Uri(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().CodeBase), DATABASE_NAME)) .LocalPath; if (logger == null) throw new ArgumentNullException(nameof(logger)); _logger = logger; @@ -38,65 +40,6 @@ namespace SQLiteRepository _logger.Trace("Checking For Upgrades"); CheckForDbUpgrade(); } - - private void CheckForDbUpgrade() - { - var data = _connection.Query("select * from DbVersion"); - if (!data.Any()) - { - //Pre-Upgrade database, need upgrading - _logger.Trace("Pre version 0.2 RC database found, performing update.."); - ExecuteUpgradeFromVersion("0.1"); //execute 0.2 upgrade scripts onwards. - } - else - { - var installedVersion = new Version(data.First().VersionNumber); - var currentVersion = new Version(AssemblyInfo.ASSEMBLY_VERSION); - if (currentVersion.CompareTo(installedVersion) > 0) //greater than 0 - current version is newer - { - _logger.Trace("Installed Database Version: {0} is older than current version {1}"); - ExecuteUpgradeFromVersion(installedVersion.ToString()); - } - } - } - - private void ExecuteUpgradeFromVersion(string installedVersion) - { - const string PREFIX = "SQLiteRepository.UpgradeScripts."; - var instVers = new Version(installedVersion); - //so we have established that each script for upgrade will be .sql, so now start at lowest version and work up! - var assembly = Assembly.GetExecutingAssembly(); - var upgradeScripts = assembly.GetManifestResourceNames() - .Where(x=>x.StartsWith(PREFIX)) - .OrderBy(x=>new Version(Path.GetFileNameWithoutExtension(x.Replace(PREFIX, "")))) - .Where(x => - { - var scriptVersion = new Version(Path.GetFileNameWithoutExtension(x.Replace(PREFIX, ""))).CompareTo(instVers); - return scriptVersion > 0; - } - ) - .ToList(); - //now have an ordered list of upgrade script files, so execute in order! - foreach (var upgradeScript in upgradeScripts) - { - using (var stream = assembly.GetManifestResourceStream(upgradeScript)) - using(var str = new StreamReader(stream)) - { - var script = str.ReadToEnd(); - _logger.Trace("Executing upgrade script with name: {0}", upgradeScript); - _connection.Execute(script); - } - } - SetDbVersion(AssemblyInfo.ASSEMBLY_VERSION); - } - - private void SetDbVersion(string vers) - { - _connection.DeleteAll(); - _connection.Insert(new DbVersion {VersionNumber = vers}); - _logger.Trace("Set Database version to: {0}", vers); - } - public UserList GetUsers(int pageNumber = -1, int pageSize = -1, int groupId = -1) { var ret = new UserList(); @@ -139,7 +82,7 @@ namespace SQLiteRepository foreach (var user in users) { - var userObj = ChangeToUserObject(user); + var userObj = UserConverter.ConvertToUserDto(user); userObj.AssociatedIdentifiers = GetAssociatedIdentifiers(user.Id); userObj.State = GetUserState(GetLogDirection(user.Id)); @@ -180,19 +123,20 @@ namespace SQLiteRepository foreach (var user in users) { - var userObj = ChangeToUserObject(user); + var userObj = UserConverter.ConvertToUserDto(user); var cards = _connection.Query( SQLiteProcedures.GET_CARDS_BY_USER_ID, user.Id); foreach (var card in cards) { - userObj.AssociatedIdentifiers.Add(new Identifier() - { - UniqueId = card.CardUId, - IsAssociatedToUser = true, - Id = card.Id - }); + userObj.AssociatedIdentifiers.Add(IdentifierConverter.ConvertToIdentifierDto(card)); + //userObj.AssociatedIdentifiers.Add(new Identifier() + //{ + // UniqueId = card.CardUId, + // IsAssociatedToUser = true, + // Id = card.Id + //}); } userObj.State = GetUserState(GetLogDirection(user.Id)); ret.Users.Add(userObj); @@ -217,7 +161,7 @@ namespace SQLiteRepository if (!users.Any()) return ret; var user = users.First(); - ret = ChangeToUserObject(user); + ret = UserConverter.ConvertToUserDto(user); ret.Groups = GetGroups(); var usersGroups = GetGroups(user.Id); foreach (var group in usersGroups) @@ -230,7 +174,13 @@ namespace SQLiteRepository foreach (var card in cards) { - ret.AssociatedIdentifiers.Add(new Identifier { UniqueId = card.CardUId, IsAssociatedToUser = true, Id = card.Id }); + ret.AssociatedIdentifiers.Add(IdentifierConverter.ConvertToIdentifierDto(card)); + //new Identifier + //{ + // UniqueId = card.CardUId, + // IsAssociatedToUser = true, + // Id = card.Id + //}); } } catch (Exception ex) @@ -298,13 +248,14 @@ namespace SQLiteRepository foreach (var card in cardQuery) { - ret.data.Add(new Identifier - { - Id = card.Id, - IsAssociatedToUser = card.UserId_FK != Constants.UNASSIGNED_CARD_USER_ID, - UniqueId = card.CardUId, - LastUsed = card.LastUsed.DateTime - }); + ret.data.Add(IdentifierConverter.ConvertToIdentifierDto(card)); + // new Identifier + //{ + // Id = card.Id, + // IsAssociatedToUser = card.UserId_FK != Constants.UNASSIGNED_CARD_USER_ID, + // UniqueId = card.CardUId, + // LastUsed = card.LastUsed.DateTime + //}); } return ret; } @@ -319,15 +270,13 @@ namespace SQLiteRepository //TODO: Check time logs table on update to ensure associated cards/unique identifiers are removed/added as appropriate. public OperationResponse UpdateUser(User user, out int userIdResult) { - //if(user.UserId <=0) return OperationResponse.FAILED; - var ret = OperationResponse.NONE; var cardIds = new List(); //Get a list of current associated identifiers, convert into a list of Identifier Objects.. var currentCards = _connection.Query(SQLiteProcedures.GET_CARDS_BY_USER_ID, user.UserId) - .Select(x => new Identifier { Id = x.Id, IsAssociatedToUser = true, UniqueId = x.CardUId }); + .Select(IdentifierConverter.ConvertToIdentifierDto); var cardsToRemove = currentCards.Except(user.AssociatedIdentifiers).Select(x => x.Id).ToList(); #region GetUnique Identifiers @@ -338,7 +287,7 @@ namespace SQLiteRepository if (!existingCard.Any()) { - var cardInsert = new CardUniqueId { CardUId = card.UniqueId, UserId_FK = -1 }; + var cardInsert = IdentifierConverter.ConvertFromIdentifierDto(card, Constants.UNASSIGNED_CARD_USER_ID); _connection.Insert(cardInsert); cardIds.Add(cardInsert.Id); if (ret < OperationResponse.CREATED) @@ -371,13 +320,7 @@ namespace SQLiteRepository } else { - var userInsert = new UserIdentity - { - FirstName = user.FirstName, - LastName = user.LastName, - HoursPerWeek = user.HoursPerWeek, - IsContractor = user.IsContractor - }; + var userInsert = UserConverter.ConvertFromUserDto(user); _connection.Insert(userInsert); userId = userInsert.Id; if (ret < OperationResponse.CREATED) @@ -396,7 +339,7 @@ namespace SQLiteRepository { _connection.Query( SQLiteProcedures.UPDATE_CARD_USER_ID, - -1, card); + Constants.UNASSIGNED_CARD_USER_ID, card); } #endregion @@ -469,7 +412,7 @@ namespace SQLiteRepository var calendarWeek = GetIso8601CalendarWeek(logTime); var year = logTime.Year; #endregion - + var timeLog = new TimeLogDb { SwipeEventDateTime = DateTime.UtcNow, @@ -506,22 +449,12 @@ namespace SQLiteRepository List query; if (userId == -1) { - query = _connection.Query("select gp.GroupId, gp.GroupName, " + - "sum(case when gp.GroupId = ujdb.GroupId_FK then 1 else 0 end) as AssignedUserCount " + - "from GroupDb gp " + - "left join UserGroupJoinDb ujdb " + - "on ujdb.GroupId_FK = gp.GroupId " + - "group by gp.GroupId"); + query = _connection.Query(SQLiteProcedures.GET_GROUPS); } else { query = - _connection.Query( - "select gdb.GroupId, gdb.GroupName, gdb.AssignedUserCount" + - " from GroupDb gdb" + - " left join UserGroupJoinDb ujdb" + - " on gdb.GroupId = ujdb.GroupId_FK" + - " where ujdb.UserId_FK = ?", + _connection.Query(SQLiteProcedures.GET_GROUPS_FOR_USER, userId); } foreach (var group in query) @@ -538,7 +471,7 @@ namespace SQLiteRepository public Group GetGroup(int groupId) { - var query = _connection.Query("select * from GroupDb where GroupId = ?", groupId); + var query = _connection.Query(SQLiteProcedures.GET_GROUP_BY_ID, groupId); if (query.Any()) { var group = query.First(); @@ -554,8 +487,7 @@ namespace SQLiteRepository public OperationResponse UpdateGroup(Group group) { - //TODO: I would probably prefer to do this manually.... - var resp = _connection.Query("update GroupDb set GroupName=? where GroupId=?", group.Name, group.Id); + var resp = _connection.Query(SQLiteProcedures.UPDATE_GROUP, group.Name, group.Id); return OperationResponse.UPDATED; } @@ -569,14 +501,14 @@ namespace SQLiteRepository public OperationResponse DeleteLog(TimeLog log) { var query = _connection.Query( - "select * from TimeLogDb where Id=?", log.Id); + SQLiteProcedures.GET_TIMELOG_ENTRY, log.Id); if (!query.Any()) return OperationResponse.FAILED; UpdateExistingLogDirections(log); - _connection.ExecuteScalar("delete from TimeLogDb where Id=?", log.Id); + _connection.ExecuteScalar(SQLiteProcedures.DELETE_TIMELOG_ENTRY, log.Id); return OperationResponse.DELETED; } @@ -608,7 +540,7 @@ namespace SQLiteRepository public OperationResponse UpdateLog(TimeLog log) { var query = _connection.Query( - "select * from TimeLogDb where Id=?", log.Id); + SQLiteProcedures.GET_TIMELOG_ENTRY, log.Id); if(!query.Any()) return OperationResponse.FAILED; @@ -621,12 +553,70 @@ namespace SQLiteRepository log.Year = log.EventTime.Year; } _connection.ExecuteScalar( - "update TimeLogDb set UserId_FK=?, Direction=?,SwipeEventDateTime=?,CalendarWeek=?,Year=?,Source=? where Id=?", + SQLiteProcedures.UPDATE_TIMELOG_ENTRY, log.UserId, (LogDirectionDb) (int) log.Direction, log.EventTime, log.CalendarWeek, log.Year, (LogSourceDb) (int) log.Source, log.Id); return OperationResponse.UPDATED; } + + private void CheckForDbUpgrade() + { + var data = _connection.Query("select * from DbVersion"); + if (!data.Any()) + { + //Pre-Upgrade database, need upgrading + _logger.Trace("Pre version 0.2 RC database found, performing update.."); + ExecuteUpgradeFromVersion("0.1"); //execute 0.2 upgrade scripts onwards. + } + else + { + var installedVersion = new Version(data.First().VersionNumber); + var currentVersion = new Version(AssemblyInfo.ASSEMBLY_VERSION); + if (currentVersion.CompareTo(installedVersion) > 0) //greater than 0 - current version is newer + { + _logger.Trace("Installed Database Version: {0} is older than current version {1}"); + ExecuteUpgradeFromVersion(installedVersion.ToString()); + } + } + } + + private void ExecuteUpgradeFromVersion(string installedVersion) + { + const string PREFIX = "SQLiteRepository.UpgradeScripts."; + var instVers = new Version(installedVersion); + //so we have established that each script for upgrade will be .sql, so now start at lowest version and work up! + var assembly = Assembly.GetExecutingAssembly(); + var upgradeScripts = assembly.GetManifestResourceNames() + .Where(x=>x.StartsWith(PREFIX)) + .OrderBy(x=>new Version(Path.GetFileNameWithoutExtension(x.Replace(PREFIX, "")))) + .Where(x => + { + var scriptVersion = new Version(Path.GetFileNameWithoutExtension(x.Replace(PREFIX, ""))).CompareTo(instVers); + return scriptVersion > 0; + } + ) + .ToList(); + //now have an ordered list of upgrade script files, so execute in order! + foreach (var upgradeScript in upgradeScripts) + { + using (var stream = assembly.GetManifestResourceStream(upgradeScript)) + using(var str = new StreamReader(stream)) + { + var script = str.ReadToEnd(); + _logger.Trace("Executing upgrade script with name: {0}", upgradeScript); + _connection.Execute(script); + } + } + SetDbVersion(AssemblyInfo.ASSEMBLY_VERSION); + } + + private void SetDbVersion(string vers) + { + _connection.DeleteAll(); + _connection.Insert(new DbVersion {VersionNumber = vers}); + _logger.Trace("Set Database version to: {0}", vers); + } private DateTime GetLastLogDateTime(TimeLogDb timeLog) { @@ -797,7 +787,7 @@ namespace SQLiteRepository else { // we have a time log from today already, so just do the opposite of what we last did! - logDirection = InvertLogDirectionDb(lastEntry.Direction); + logDirection = LogDirectionConverter.InvertLogDirectionDb(lastEntry.Direction); } } else @@ -901,29 +891,11 @@ namespace SQLiteRepository var currentlogDirection = log.Direction; for (var i = 0; i < logs.Count; i++) { - logs[i].Direction = InvertLogDirection(currentlogDirection); + logs[i].Direction = LogDirectionConverter.InvertLogDirection(currentlogDirection); UpdateLog(logs[i]); currentlogDirection = logs[i].Direction; } } } - - private LogDirectionDb InvertLogDirectionDb(LogDirectionDb direction) - { - return (LogDirectionDb) (int) InvertLogDirection((LogDirection) (int) direction); - } - - private LogDirection InvertLogDirection(LogDirection direction) - { - switch (direction) - { - case LogDirection.IN: - return LogDirection.OUT; - case LogDirection.OUT: - return LogDirection.IN; - default: - return LogDirection.UNKNOWN; - } - } } } From f871c2363173f3a2e688b57731c7977cb0fc46ed Mon Sep 17 00:00:00 2001 From: "Chris.Watts90@outlook.com" Date: Mon, 4 Jun 2018 11:07:29 +0100 Subject: [PATCH 2/6] add converters to help convert from/to data transfer objects. removed conversion code from SQLiteRepository.cs in favour of new converters. pulled out string queries from SQLiteRepository and moved to SQLiteProcedures.cs. #95 --- .../Converters/LogDirectionConverter.cs | 51 ++++++++++++ .../Converters/LogSourceConverter.cs | 37 +++++++++ .../Converters/TimeLogConverter.cs | 80 ------------------- .../SQLiteRepository/SQLiteProcedures.cs | 2 + .../SQLiteRepository/SQLiteRepository.cs | 37 +++------ .../SQLiteRepository/SQLiteRepository.csproj | 4 + .../WindowsDataCenter.csproj | 1 + 7 files changed, 104 insertions(+), 108 deletions(-) create mode 100644 DataCenter_Windows/WindowsDataCenter/SQLiteRepository/Converters/LogDirectionConverter.cs create mode 100644 DataCenter_Windows/WindowsDataCenter/SQLiteRepository/Converters/LogSourceConverter.cs diff --git a/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/Converters/LogDirectionConverter.cs b/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/Converters/LogDirectionConverter.cs new file mode 100644 index 0000000..72a536e --- /dev/null +++ b/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/Converters/LogDirectionConverter.cs @@ -0,0 +1,51 @@ +using Interfaces; + +namespace SQLiteRepository.Converters +{ + static class LogDirectionConverter + { + public static LogDirection ConvertToLogDirectionDto(LogDirectionDb direction) + { + switch (direction) + { + case LogDirectionDb.IN: + return LogDirection.IN; + case LogDirectionDb.OUT: + return LogDirection.OUT; + default: + return LogDirection.UNKNOWN; + } + } + + public static LogDirectionDb ConvertFromLogDirectionDto(LogDirection direction) + { + switch (direction) + { + case LogDirection.IN: + return LogDirectionDb.IN; + case LogDirection.OUT: + return LogDirectionDb.OUT; + default: + return LogDirectionDb.UNKNOWN; + } + } + + public static LogDirectionDb InvertLogDirectionDb(LogDirectionDb direction) + { + return (LogDirectionDb)(int)InvertLogDirection((LogDirection)(int)direction); + } + + public static LogDirection InvertLogDirection(LogDirection direction) + { + switch (direction) + { + case LogDirection.IN: + return LogDirection.OUT; + case LogDirection.OUT: + return LogDirection.IN; + default: + return LogDirection.UNKNOWN; + } + } + } +} \ No newline at end of file diff --git a/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/Converters/LogSourceConverter.cs b/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/Converters/LogSourceConverter.cs new file mode 100644 index 0000000..6ebc7c1 --- /dev/null +++ b/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/Converters/LogSourceConverter.cs @@ -0,0 +1,37 @@ +using Interfaces; + +namespace SQLiteRepository.Converters +{ + static class LogSourceConverter + { + public static LogSource ConvertToLogSourceDto(LogSourceDb source) + { + switch (source) + { + case LogSourceDb.IDENTIFIER: + return LogSource.IDENTIFIER; + case LogSourceDb.TRAYAPP: + return LogSource.TRAYAPP; + case LogSourceDb.UI: + return LogSource.UI; + default: + return LogSource.UNKNOWN; + } + } + + public static LogSourceDb ConvertFromLogSourceDto(LogSource source) + { + switch (source) + { + case LogSource.IDENTIFIER: + return LogSourceDb.IDENTIFIER; + case LogSource.TRAYAPP: + return LogSourceDb.TRAYAPP; + case LogSource.UI: + return LogSourceDb.UI; + default: + return LogSourceDb.UNKNOWN; + } + } + } +} \ No newline at end of file diff --git a/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/Converters/TimeLogConverter.cs b/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/Converters/TimeLogConverter.cs index 3669272..a118836 100644 --- a/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/Converters/TimeLogConverter.cs +++ b/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/Converters/TimeLogConverter.cs @@ -39,84 +39,4 @@ namespace SQLiteRepository.Converters }; } } - - static class LogSourceConverter - { - public static LogSource ConvertToLogSourceDto(LogSourceDb source) - { - switch (source) - { - case LogSourceDb.IDENTIFIER: - return LogSource.IDENTIFIER; - case LogSourceDb.TRAYAPP: - return LogSource.TRAYAPP; - case LogSourceDb.UI: - return LogSource.UI; - default: - return LogSource.UNKNOWN; - } - } - - public static LogSourceDb ConvertFromLogSourceDto(LogSource source) - { - switch (source) - { - case LogSource.IDENTIFIER: - return LogSourceDb.IDENTIFIER; - case LogSource.TRAYAPP: - return LogSourceDb.TRAYAPP; - case LogSource.UI: - return LogSourceDb.UI; - default: - return LogSourceDb.UNKNOWN; - } - } - } - - static class LogDirectionConverter - { - public static LogDirection ConvertToLogDirectionDto(LogDirectionDb direction) - { - switch (direction) - { - case LogDirectionDb.IN: - return LogDirection.IN; - case LogDirectionDb.OUT: - return LogDirection.OUT; - default: - return LogDirection.UNKNOWN; - } - } - - public static LogDirectionDb ConvertFromLogDirectionDto(LogDirection direction) - { - switch (direction) - { - case LogDirection.IN: - return LogDirectionDb.IN; - case LogDirection.OUT: - return LogDirectionDb.OUT; - default: - return LogDirectionDb.UNKNOWN; - } - } - - public static LogDirectionDb InvertLogDirectionDb(LogDirectionDb direction) - { - return (LogDirectionDb)(int)InvertLogDirection((LogDirection)(int)direction); - } - - public static LogDirection InvertLogDirection(LogDirection direction) - { - switch (direction) - { - case LogDirection.IN: - return LogDirection.OUT; - case LogDirection.OUT: - return LogDirection.IN; - default: - return LogDirection.UNKNOWN; - } - } - } } diff --git a/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/SQLiteProcedures.cs b/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/SQLiteProcedures.cs index a8a08a9..c6d0e80 100644 --- a/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/SQLiteProcedures.cs +++ b/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/SQLiteProcedures.cs @@ -126,5 +126,7 @@ namespace SQLiteRepository + nameof(TimeLogDb.Year) + "=?," + nameof(TimeLogDb.Source) + "=? " + "where " + nameof(TimeLogDb.Id) + "=?"; + + public const string GET_DB_VERSION = "select * from DbVersion"; } } \ No newline at end of file diff --git a/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/SQLiteRepository.cs b/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/SQLiteRepository.cs index 9d32477..9fedbd3 100644 --- a/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/SQLiteRepository.cs +++ b/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/SQLiteRepository.cs @@ -515,20 +515,12 @@ namespace SQLiteRepository public OperationResponse CreateLog(TimeLog log) { - var calendarWeek = GetIso8601CalendarWeek(log.EventTime.UtcDateTime); - var year = log.EventTime.Year; - log.CalendarWeek = calendarWeek; - log.Year = year; - var dbLog = new TimeLogDb - { - SwipeEventDateTime = log.EventTime, - Direction = (LogDirectionDb)(int)log.Direction, - Year = year, - CalendarWeek = calendarWeek, - Source = (LogSourceDb)(int)log.Source, - UserId_FK = log.UserId, - IdentifierId = ConvertSourceToIdentifierId(log.Source), - }; + log.CalendarWeek = GetIso8601CalendarWeek(log.EventTime.UtcDateTime); + log.Year= log.EventTime.Year; + + var dbLog = TimeLogConverter.ConvertFromTimeLogDto(log); + dbLog.IdentifierId = ConvertSourceToIdentifierId(log.Source); + #region update in/out directions for manual logs. UpdateExistingLogDirections(log); #endregion @@ -541,6 +533,7 @@ namespace SQLiteRepository { var query = _connection.Query( SQLiteProcedures.GET_TIMELOG_ENTRY, log.Id); + if(!query.Any()) return OperationResponse.FAILED; @@ -562,7 +555,7 @@ namespace SQLiteRepository private void CheckForDbUpgrade() { - var data = _connection.Query("select * from DbVersion"); + var data = _connection.Query(SQLiteProcedures.GET_DB_VERSION); if (!data.Any()) { //Pre-Upgrade database, need upgrading @@ -813,7 +806,7 @@ namespace SQLiteRepository private void UpdateIdentifierLastUsed(DateTimeOffset dt, int cardId) { - var res = _connection.ExecuteScalar(SQLiteProcedures.UPDATE_CARD_LAST_USED, + _connection.ExecuteScalar(SQLiteProcedures.UPDATE_CARD_LAST_USED, dt, cardId); } @@ -862,18 +855,6 @@ namespace SQLiteRepository return dt.Date.CompareTo(DateTime.Today.Date) < 0; } - private User ChangeToUserObject(UserIdentity user) - { - return new User - { - UserId = user.Id, - FirstName = user.FirstName, - LastName = user.LastName, - HoursPerWeek = user.HoursPerWeek, - IsContractor = user.IsContractor - }; - } - private void UpdateExistingLogDirections(TimeLog log) { //need to make this generic so that both create and delete will update the log directions.. but ARGH. diff --git a/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/SQLiteRepository.csproj b/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/SQLiteRepository.csproj index 46517fc..a666342 100644 --- a/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/SQLiteRepository.csproj +++ b/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/SQLiteRepository.csproj @@ -78,6 +78,10 @@ + + + + diff --git a/DataCenter_Windows/WindowsDataCenter/WindowsDataCenter/WindowsDataCenter.csproj b/DataCenter_Windows/WindowsDataCenter/WindowsDataCenter/WindowsDataCenter.csproj index 4dee973..e18caab 100644 --- a/DataCenter_Windows/WindowsDataCenter/WindowsDataCenter/WindowsDataCenter.csproj +++ b/DataCenter_Windows/WindowsDataCenter/WindowsDataCenter/WindowsDataCenter.csproj @@ -55,6 +55,7 @@ prompt MinimumRecommendedRules.ruleset true + bin\ReleaseInstallers\WindowsDataCenter.XML From b329fd6e5a15408a4d9b1bfb6123f0a74b06d289 Mon Sep 17 00:00:00 2001 From: "Chris.Watts90@outlook.com" Date: Wed, 6 Jun 2018 10:45:22 +0100 Subject: [PATCH 3/6] add method to use SQL In queries to retrieve lists. add queries DELETE_TIMELOG_ENTRIES and GET_CARDS_BY_UNIQUE_ID_LIST that use the IN command. this will delete all timelog entries where the ids exist in the list, or get cards in the db where the unique Id exists in the DB respectively. GET_GROUP_BY_NAME is to be used for checking whether a group already exists on create and is designed to only return one record. #95 --- .../SQLiteRepository/SQLiteProcedures.cs | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/SQLiteProcedures.cs b/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/SQLiteProcedures.cs index c6d0e80..56611d7 100644 --- a/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/SQLiteProcedures.cs +++ b/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/SQLiteProcedures.cs @@ -1,3 +1,8 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Design; +using System.Linq; + namespace SQLiteRepository { internal static class SQLiteProcedures @@ -60,6 +65,9 @@ namespace SQLiteRepository public const string GET_CARDS_BY_UNIQUE_ID = "select * from " + nameof(CardUniqueId) + " where " + nameof(CardUniqueId.CardUId) + "=?"; + public const string GET_CARDS_BY_UNIQUE_ID_LIST = + "select * from " + nameof(CardUniqueId) + " where " + nameof(CardUniqueId.CardUId) + " in (#IN#)"; + public const string GET_UNASSIGNED_CARD_LIST = "select * from " + nameof(CardUniqueId) + " where " + nameof(CardUniqueId.UserId_FK) + "=?"; @@ -112,12 +120,18 @@ namespace SQLiteRepository public const string UPDATE_GROUP = "update " + nameof(GroupDb) + " set " + nameof(GroupDb.GroupName) + "=? where " + nameof(GroupDb.GroupId) + "=?"; + public const string GET_GROUP_BY_NAME = + "select 1 from " + nameof(GroupDb)+" where "+nameof(GroupDb.GroupName)+"= ?"; + public const string GET_TIMELOG_ENTRY = "select * from " + nameof(TimeLogDb) + " where " + nameof(TimeLogDb.Id) + "=?"; public const string DELETE_TIMELOG_ENTRY = "delete from " + nameof(TimeLogDb) + " where " + nameof(TimeLogDb.Id) + "=?"; + public const string DELETE_TIMELOG_ENTRIES = + "delete from " + nameof(TimeLogDb) + " where " + nameof(TimeLogDb.Id) + "in (#IN#)"; + public const string UPDATE_TIMELOG_ENTRY = "update " + nameof(TimeLogDb) + " set " + nameof(TimeLogDb.UserId_FK) + "=?, " + nameof(TimeLogDb.Direction) + "=?," @@ -128,5 +142,25 @@ namespace SQLiteRepository + "where " + nameof(TimeLogDb.Id) + "=?"; public const string GET_DB_VERSION = "select * from DbVersion"; + + /// + /// This works on the tokenisation of the query string. + /// where the list of params is to be inserted, the query should have #IN# + /// + /// the query to add the list of parameters to + /// the parameters to add to the query. + /// + public static string FormatInQuery(string query, List args) + { + if (!query.Contains("#IN#")) + { + throw new ArgumentException("query doesnt contain any #IN# tokenisation"); + } + //Convert to a comma separated list e.g.: val1,val2,val3 + //but we need to use string.. so.. enclose in single quotes 'val1','val2'..etc + var argsFormatted = string.Join(",", args.Select(x=>$"'{x}'")); + + return query.Replace("#IN#", argsFormatted); + } } } \ No newline at end of file From 72e98bdd2e1a6bb3b7f593ead45080f03b3081c5 Mon Sep 17 00:00:00 2001 From: "Chris.Watts90@outlook.com" Date: Wed, 6 Jun 2018 10:50:06 +0100 Subject: [PATCH 4/6] optimise code to reduce code complexity on UpdateUser method in particular. code has been split into smaller methods, and queries on db have been optimised to make fewer, larger queries than lots of small queries. (using IN sql queries). restructured UpdateUser to be more logical which has reduced some of the complexity of the method. When deleting unassociated cards, the system will ensure all timelogs associated to those Ids are deleted also. CreateGroup will now not allow duplicate groups, but will return the ID of the existing Group found in the DB. pulled out GetUserCount method to simplify the GetUsers method. removed empty quotes in favour of string.empty #95 --- .../SQLiteRepository/SQLiteRepository.cs | 240 +++++++++--------- 1 file changed, 124 insertions(+), 116 deletions(-) diff --git a/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/SQLiteRepository.cs b/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/SQLiteRepository.cs index 9fedbd3..94e09ed 100644 --- a/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/SQLiteRepository.cs +++ b/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/SQLiteRepository.cs @@ -19,6 +19,7 @@ namespace SQLiteRepository private readonly ILogger _logger; private readonly string _path; private const string DATABASE_NAME = "flexitimedb.db"; + private const string UPGRADE_SCRIPT_PREFIX = "SQLiteRepository.UpgradeScripts."; public SQLiteRepository(ILogger logger) { @@ -40,43 +41,27 @@ namespace SQLiteRepository _logger.Trace("Checking For Upgrades"); CheckForDbUpgrade(); } + public UserList GetUsers(int pageNumber = -1, int pageSize = -1, int groupId = -1) { var ret = new UserList(); - List users; - int userCount; - if (pageNumber != -1 && pageSize != -1) + List users = GetUserList(groupId, pageSize, pageNumber); + + var userCount = GetUserCount(); + + if (pageNumber == -1 && pageSize == -1) { - users = _connection.Query(SQLiteProcedures.GET_ALL_USERS_PAGINATE, - pageSize, (pageNumber - 1) * pageSize); - userCount = _connection.ExecuteScalar(SQLiteProcedures.GET_TOTAL_USER_COUNT); - } - else if (groupId != -1) - { - users = - _connection.Query( - SQLiteProcedures.GET_ALL_USERS_BY_GROUP, - groupId); - userCount = users.Count; + ret.PageNumber = 1; + ret.PageSize = 20; } else { - users = _connection.Query(SQLiteProcedures.GET_ALL_USERS); - userCount = users.Count; + ret.PageNumber = pageNumber; + ret.PageSize = pageSize; } if (!users.Any()) { - if (pageNumber == -1 && pageSize == -1) - { - ret.PageNumber = 1; - ret.PageSize = 20; - } - else - { - ret.PageNumber = pageNumber; - ret.PageSize = pageSize; - } return ret; } @@ -90,20 +75,11 @@ namespace SQLiteRepository userObj.Groups = GetGroups(user.Id); ret.Users.Add(userObj); } - if (pageNumber == -1 && pageSize == -1) - { - ret.PageSize = 10; - ret.PageNumber = 1; - } - else - { - ret.PageSize = pageSize; - ret.PageNumber = pageNumber; - } + ret.TotalUserCount = userCount; return ret; } - + public UserList Search(string searchParam) { _logger.Trace("Searching SQLite database for the term: {0}", searchParam); @@ -131,19 +107,12 @@ namespace SQLiteRepository foreach (var card in cards) { userObj.AssociatedIdentifiers.Add(IdentifierConverter.ConvertToIdentifierDto(card)); - //userObj.AssociatedIdentifiers.Add(new Identifier() - //{ - // UniqueId = card.CardUId, - // IsAssociatedToUser = true, - // Id = card.Id - //}); } userObj.State = GetUserState(GetLogDirection(user.Id)); ret.Users.Add(userObj); } - //TODO: figure out paging here. - should there be any? ret.PageSize = 20; - ret.PageNumber = 1; + ret.PageNumber = (int)Math.Ceiling((double)ret.Users.Count/(double)ret.PageSize); return ret; } @@ -175,12 +144,6 @@ namespace SQLiteRepository foreach (var card in cards) { ret.AssociatedIdentifiers.Add(IdentifierConverter.ConvertToIdentifierDto(card)); - //new Identifier - //{ - // UniqueId = card.CardUId, - // IsAssociatedToUser = true, - // Id = card.Id - //}); } } catch (Exception ex) @@ -262,60 +225,35 @@ namespace SQLiteRepository public void ClearUnassignedIdentifiers() { + var unassignedIdentifiers = _connection.Query(SQLiteProcedures.GET_UNASSIGNED_CARD_LIST); + + //remove the logs from the timelog db + _connection.Query( + SQLiteProcedures.FormatInQuery(SQLiteProcedures.DELETE_TIMELOG_ENTRIES, + unassignedIdentifiers.Select(x => x.Id.ToString()).ToList())); + + //now remove the unassigned identifiers/cards _connection.Execute( SQLiteProcedures.CLEAR_UNASSIGNED_CARDS, Constants.UNASSIGNED_CARD_USER_ID); } - //TODO: Check time logs table on update to ensure associated cards/unique identifiers are removed/added as appropriate. public OperationResponse UpdateUser(User user, out int userIdResult) { var ret = OperationResponse.NONE; - var cardIds = new List(); //Get a list of current associated identifiers, convert into a list of Identifier Objects.. var currentCards = _connection.Query(SQLiteProcedures.GET_CARDS_BY_USER_ID, user.UserId) .Select(IdentifierConverter.ConvertToIdentifierDto); var cardsToRemove = currentCards.Except(user.AssociatedIdentifiers).Select(x => x.Id).ToList(); - - #region GetUnique Identifiers - foreach (var card in user.AssociatedIdentifiers) - { - var existingCard = _connection.Query( - SQLiteProcedures.GET_CARDS_BY_UNIQUE_ID, card.UniqueId); - - if (!existingCard.Any()) - { - var cardInsert = IdentifierConverter.ConvertFromIdentifierDto(card, Constants.UNASSIGNED_CARD_USER_ID); - _connection.Insert(cardInsert); - cardIds.Add(cardInsert.Id); - if (ret < OperationResponse.CREATED) - ret = OperationResponse.CREATED; //only change it if my status supercedes. - } - else - { - cardIds.Add(existingCard.First().Id); - if (ret < OperationResponse.UPDATED) - ret = OperationResponse.UPDATED; - } - } - #endregion - + #region Update/Create User int userId; if (user.UserId != -1) { - //edit.. - _connection.Query( - SQLiteProcedures.UPDATE_USER_DETAILS, - user.FirstName, - user.LastName, - user.HoursPerWeek, - user.IsContractor, - user.UserId - ); + UpdateUserDetails(user.FirstName, user.LastName, user.HoursPerWeek, user.IsContractor, user.UserId); userId = user.UserId; } else @@ -328,21 +266,34 @@ namespace SQLiteRepository } #endregion - #region Update Card/Unique Id entries. - foreach (var cardId in cardIds) + #region GetUnique Identifiers + + var existingCards = _connection.Query(SQLiteProcedures.FormatInQuery( + SQLiteProcedures.GET_CARDS_BY_UNIQUE_ID_LIST, + user.AssociatedIdentifiers.Select(x => x.UniqueId.ToString()).ToList())); + + foreach (var card in user.AssociatedIdentifiers) { - _connection.Query( - SQLiteProcedures.UPDATE_CARD_USER_ID, - userId, cardId); - } - foreach (var card in cardsToRemove) - { - _connection.Query( - SQLiteProcedures.UPDATE_CARD_USER_ID, - Constants.UNASSIGNED_CARD_USER_ID, card); + if (existingCards.All(x => x.CardUId != card.UniqueId)) + { + //this card is not currently in the system.. + var cardInsert = IdentifierConverter.ConvertFromIdentifierDto(card, user.UserId); + _connection.Insert(cardInsert); + existingCards.Add(cardInsert); + if (ret < OperationResponse.CREATED) + ret = OperationResponse.CREATED; //only change it if my status supercedes. + } } #endregion + #region Update Card/Unique Id entries/associations + //make sure all identifiers are associated to the right user + UpdateIdentifierUserId(existingCards.Select(x=>x.Id).ToList(), userId); + + //make sure to remove all identifiers that have been deselected in edit are removed from user + UpdateIdentifierUserId(cardsToRemove, Constants.UNASSIGNED_CARD_USER_ID); + #endregion + #region Update Group Associations SetUserGroups(userId, user.Groups.Where(x => x.IsAssociatedToUser).ToList()); @@ -375,11 +326,11 @@ namespace SQLiteRepository ret.Direction = LogDirection.UNKNOWN; return ret; } - else - { - //TODO: log when more than one comes back. should NEVER happen but.... - ident = cardIdQuery.First(); - } + + ident = cardIdQuery.First(); + _logger.Warn("More than 1 Identifier returned with ID {0}, card ids returned: {2}", + ident.CardUId, + string.Join(",", cardIdQuery.Select(x => x.CardUId).ToList())); #endregion // Get The User Direction (are they going in or out)? @@ -432,11 +383,15 @@ namespace SQLiteRepository ret.ProcessResponse = OperationResponse.SUCCESS; return ret; } - - /*Groups*/ - //TODO: check group name can only be entered once. + public OperationResponse CreateGroup(Group group, out int groupId) { + var query = _connection.Query(SQLiteProcedures.GET_GROUP_BY_NAME, group.Name); + if (query.Any()) + { + groupId = query[0].GroupId; + return OperationResponse.NONE; + } var groupDb = new GroupDb { GroupName = group.Name }; var resp = _connection.Insert(groupDb); groupId = groupDb.GroupId; @@ -487,7 +442,7 @@ namespace SQLiteRepository public OperationResponse UpdateGroup(Group group) { - var resp = _connection.Query(SQLiteProcedures.UPDATE_GROUP, group.Name, group.Id); + _connection.Query(SQLiteProcedures.UPDATE_GROUP, @group.Name, @group.Id); return OperationResponse.UPDATED; } @@ -553,6 +508,34 @@ namespace SQLiteRepository return OperationResponse.UPDATED; } + private int GetUserCount() + { + return _connection.ExecuteScalar(SQLiteProcedures.GET_TOTAL_USER_COUNT); + } + + private List GetUserList(int groupId = -1, int pageSize=-1, int pageNumber=-1) + { + List users; + if (pageNumber != -1 && pageSize != -1) + { + users = _connection.Query(SQLiteProcedures.GET_ALL_USERS_PAGINATE, + pageSize, (pageNumber - 1) * pageSize); + } + else if (groupId != -1) + { + users = + _connection.Query( + SQLiteProcedures.GET_ALL_USERS_BY_GROUP, + groupId); + } + else + { + users = _connection.Query(SQLiteProcedures.GET_ALL_USERS); + } + + return users; + } + private void CheckForDbUpgrade() { var data = _connection.Query(SQLiteProcedures.GET_DB_VERSION); @@ -576,20 +559,21 @@ namespace SQLiteRepository private void ExecuteUpgradeFromVersion(string installedVersion) { - const string PREFIX = "SQLiteRepository.UpgradeScripts."; var instVers = new Version(installedVersion); //so we have established that each script for upgrade will be .sql, so now start at lowest version and work up! var assembly = Assembly.GetExecutingAssembly(); var upgradeScripts = assembly.GetManifestResourceNames() - .Where(x=>x.StartsWith(PREFIX)) - .OrderBy(x=>new Version(Path.GetFileNameWithoutExtension(x.Replace(PREFIX, "")))) - .Where(x => - { - var scriptVersion = new Version(Path.GetFileNameWithoutExtension(x.Replace(PREFIX, ""))).CompareTo(instVers); - return scriptVersion > 0; - } - ) - .ToList(); + .Where(x => x.StartsWith(UPGRADE_SCRIPT_PREFIX)) + .OrderBy(x => + new Version(Path.GetFileNameWithoutExtension(x.Replace(UPGRADE_SCRIPT_PREFIX, string.Empty)))) + .Where(x => + { + var scriptVersion = + new Version(Path.GetFileNameWithoutExtension(x.Replace(UPGRADE_SCRIPT_PREFIX, string.Empty))) + .CompareTo(instVers); + return scriptVersion > 0; + }) + .ToList(); //now have an ordered list of upgrade script files, so execute in order! foreach (var upgradeScript in upgradeScripts) { @@ -878,5 +862,29 @@ namespace SQLiteRepository } } } + + private void UpdateIdentifierUserId(List cardsToUpdate, int userId) + { + foreach (var card in cardsToUpdate) + { + _connection.Query( + SQLiteProcedures.UPDATE_CARD_USER_ID, + userId, card); + } + } + + private void UpdateUserDetails(string firstName, string lastName, float hoursPerWeek, bool isContractor, + int userId) + { + _connection.Query( + SQLiteProcedures.UPDATE_USER_DETAILS, + firstName, + lastName, + hoursPerWeek, + isContractor, + userId + ); + } + } } From 7552390bec7539d34ab8db70dda96c7e97202ce0 Mon Sep 17 00:00:00 2001 From: "Chris.Watts90@outlook.com" Date: Wed, 6 Jun 2018 10:50:47 +0100 Subject: [PATCH 5/6] correct script so it wont create duplicate groups, will check for existing prior to creating and only create if it doesnt exist. #95 --- .../WindowsDataCenter/SQLiteRepository/UpgradeScripts/0.2.sql | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/UpgradeScripts/0.2.sql b/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/UpgradeScripts/0.2.sql index 5eeccd7..8eb6cd4 100644 --- a/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/UpgradeScripts/0.2.sql +++ b/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/UpgradeScripts/0.2.sql @@ -1 +1,3 @@ -insert into GroupDb values ((select max(groupId) from GroupDb)+1,'Archived',0) \ No newline at end of file +insert into GroupDb(GroupId, GroupName, AssignedUserCount) +select (select max(GroupId) from GroupDb)+1, 'Archived', 0 +WHERE NOT EXISTS(select * from GroupDb where GroupName='Archived'); \ No newline at end of file From ebbc8c0fde92e70a95623d0e9317cdcfc2875564 Mon Sep 17 00:00:00 2001 From: "Chris.Watts90@outlook.com" Date: Wed, 6 Jun 2018 10:51:24 +0100 Subject: [PATCH 6/6] removing todo - return userId from CreateUser API method #95 --- .../WindowsDataCenter/Controllers/UsersController.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/DataCenter_Windows/WindowsDataCenter/WindowsDataCenter/Controllers/UsersController.cs b/DataCenter_Windows/WindowsDataCenter/WindowsDataCenter/Controllers/UsersController.cs index 763ffe6..675c33a 100644 --- a/DataCenter_Windows/WindowsDataCenter/WindowsDataCenter/Controllers/UsersController.cs +++ b/DataCenter_Windows/WindowsDataCenter/WindowsDataCenter/Controllers/UsersController.cs @@ -93,8 +93,7 @@ namespace WindowsDataCenter { int userId; _repo.UpdateUser(user, out userId); - //TODO return ID. - return ResponseMessage(new HttpResponseMessage(HttpStatusCode.OK) {Content = new StringContent("unknownIdTODO")}); + return ResponseMessage(new HttpResponseMessage(HttpStatusCode.OK) {Content = new StringContent(userId.ToString())}); } [HttpPost]