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
new file mode 100644
index 0000000..a118836
--- /dev/null
+++ b/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/Converters/TimeLogConverter.cs
@@ -0,0 +1,42 @@
+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
+ };
+ }
+ }
+}
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..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) + "=?";
@@ -92,5 +100,67 @@ 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_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) + "=?,"
+ + nameof(TimeLogDb.SwipeEventDateTime) + "=?,"
+ + nameof(TimeLogDb.CalendarWeek) + "=?,"
+ + nameof(TimeLogDb.Year) + "=?,"
+ + nameof(TimeLogDb.Source) + "=? "
+ + "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
diff --git a/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/SQLiteRepository.cs b/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/SQLiteRepository.cs
index 89c510b..94e09ed 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,14 @@ 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";
+ private const string UPGRADE_SCRIPT_PREFIX = "SQLiteRepository.UpgradeScripts.";
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;
@@ -39,107 +42,32 @@ namespace SQLiteRepository
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();
- 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;
}
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));
@@ -147,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);
@@ -180,26 +99,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.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;
}
@@ -217,7 +130,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 +143,7 @@ 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));
}
}
catch (Exception ex)
@@ -298,86 +211,54 @@ 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;
}
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)
{
- //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
- foreach (var card in user.AssociatedIdentifiers)
- {
- var existingCard = _connection.Query(
- SQLiteProcedures.GET_CARDS_BY_UNIQUE_ID, card.UniqueId);
-
- if (!existingCard.Any())
- {
- var cardInsert = new CardUniqueId { CardUId = card.UniqueId, UserId_FK = -1 };
- _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
{
- 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)
@@ -385,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,
- -1, 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());
@@ -432,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)?
@@ -469,7 +363,7 @@ namespace SQLiteRepository
var calendarWeek = GetIso8601CalendarWeek(logTime);
var year = logTime.Year;
#endregion
-
+
var timeLog = new TimeLogDb
{
SwipeEventDateTime = DateTime.UtcNow,
@@ -489,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;
@@ -506,22 +404,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 +426,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 +442,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);
+ _connection.Query(SQLiteProcedures.UPDATE_GROUP, @group.Name, @group.Id);
return OperationResponse.UPDATED;
}
@@ -569,34 +456,26 @@ 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;
}
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
@@ -608,7 +487,8 @@ 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 +501,99 @@ 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 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);
+ 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)
+ {
+ 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(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)
+ {
+ 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 +764,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
@@ -823,7 +790,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);
}
@@ -872,18 +839,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.
@@ -901,29 +856,35 @@ 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)
+ private void UpdateIdentifierUserId(List cardsToUpdate, int userId)
{
- return (LogDirectionDb) (int) InvertLogDirection((LogDirection) (int) direction);
- }
-
- private LogDirection InvertLogDirection(LogDirection direction)
- {
- switch (direction)
+ foreach (var card in cardsToUpdate)
{
- case LogDirection.IN:
- return LogDirection.OUT;
- case LogDirection.OUT:
- return LogDirection.IN;
- default:
- return LogDirection.UNKNOWN;
+ _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
+ );
+ }
+
}
}
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/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
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]
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