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] 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; - } - } } }