FlexitimeTracker/DataCenter_Windows/WindowsDataCenter/SQLiteRepository/SQLiteRepository.cs
Chris.Watts90@outlook.com c56144d9b3 create db version object for table to hold our db version.
update assemblyinfo so that it uses static const properties.
Create 0.2 upgrade script.
Add code to repository class that will check version of the database currently being referenced. IT will then proceed to run upgrade scripts (in order) from the oldest to newest version on the database, before finally setting the db version number.

#85
2018-03-06 17:07:05 +00:00

874 lines
33 KiB
C#

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using Interfaces;
using SQLite.Net;
using SQLite.Net.Platform.Win32;
using SQLiteRepository.Properties;
namespace SQLiteRepository
{
public class SQLiteRepository : IRepository
{
private readonly SQLiteConnection _connection;
private readonly ILogger _logger;
private string _path = "flexitimedb.db";
public SQLiteRepository(ILogger logger)
{
_path =
new Uri(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().CodeBase), "flexitimedb.db"))
.LocalPath;
if (logger == null) throw new ArgumentNullException(nameof(logger));
_logger = logger;
_connection = new SQLiteConnection(new SQLitePlatformWin32(), _path);
_connection.CreateTable<CardUniqueId>();
_connection.CreateTable<UserIdentity>();
_connection.CreateTable<TimeLogDb>();
_connection.CreateTable<GroupDb>();
_connection.CreateTable<UserGroupJoinDb>();
_connection.CreateTable<DbVersion>();
_logger.Trace("Initialised SQLite Repository");
_logger.Trace("Checking For Upgrades");
CheckForDbUpgrade();
}
private void CheckForDbUpgrade()
{
var data = _connection.Query<DbVersion>("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 <version>.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 (Stream stream = assembly.GetManifestResourceStream(upgradeScript))
using(StreamReader str = new StreamReader(stream))
{
string script = str.ReadToEnd();
_connection.Execute(script);
}
}
SetDbVersion(AssemblyInfo.ASSEMBLY_VERSION);
}
private void SetDbVersion(string vers)
{
_connection.DeleteAll<DbVersion>();
_connection.Insert(new DbVersion {VersionNumber = vers});
}
public UserList GetUsers(int pageNumber = -1, int pageSize = -1, int groupId = -1)
{
var ret = new UserList();
List<UserIdentity> users;
int userCount;
if (pageNumber != -1 && pageSize != -1)
{
users = _connection.Query<UserIdentity>(SQLiteProcedures.GET_ALL_USERS_PAGINATE,
pageSize, (pageNumber - 1) * pageSize);
userCount = _connection.ExecuteScalar<int>(SQLiteProcedures.GET_TOTAL_USER_COUNT);
}
else if (groupId != -1)
{
users =
_connection.Query<UserIdentity>(
SQLiteProcedures.GET_ALL_USERS_BY_GROUP,
groupId);
userCount = users.Count;
}
else
{
users = _connection.Query<UserIdentity>(SQLiteProcedures.GET_ALL_USERS);
userCount = users.Count;
}
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);
userObj.AssociatedIdentifiers = GetAssociatedIdentifiers(user.Id);
userObj.State = GetUserState(GetLogDirection(user.Id));
userObj.LastEventDateTime = GetLastLogDateTime(GetLastTimeLog(user.Id));
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);
var ret = new UserList();
searchParam = string.Format("%{0}%", searchParam);
var users = _connection.Query<UserIdentity>(
SQLiteProcedures.SEARCH_USER_LIST,
searchParam, searchParam);
_logger.Trace("Got {0} results for term: {1}", users.Count, searchParam);
if (!users.Any())
{
ret.PageNumber = 1;
ret.PageSize = 20;
return ret;
}
foreach (var user in users)
{
var userObj = ChangeToUserObject(user);
var cards = _connection.Query<CardUniqueId>(
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.State = GetUserState(GetLogDirection(user.Id));
ret.Users.Add(userObj);
}
//TODO: figure out paging here. - should there be any?
ret.PageSize = 20;
ret.PageNumber = 1;
return ret;
}
public User GetUser(int id)
{
var ret = new User();
try
{
var users = _connection.Query<UserIdentity>(
SQLiteProcedures.GET_USER_BY_ID,
id);
if (!users.Any()) return ret;
var user = users.First();
ret = ChangeToUserObject(user);
ret.Groups = GetGroups();
var usersGroups = GetGroups(user.Id);
foreach (var group in usersGroups)
{
ret.Groups.First(x => x.Id == group.Id).IsAssociatedToUser = true;
}
var cards = _connection.Query<CardUniqueId>(
SQLiteProcedures.GET_CARDS_BY_USER_ID,
user.Id);
foreach (var card in cards)
{
ret.AssociatedIdentifiers.Add(new Identifier { UniqueId = card.CardUId, IsAssociatedToUser = true, Id = card.Id });
}
}
catch (Exception ex)
{
_logger.Error(ex, "Error in GetUser with Id: {0}", id);
ret.UserId = id;
ret.FirstName = ret.LastName = string.Empty;
ret.HoursPerWeek = -1.0f;
ret.IsContractor = false;
ret.AssociatedIdentifiers.Clear();
}
return ret;
}
public TimeLogList GetTimeLogs(int userId)
{
return GetTimeLogs(userId, DateTime.UtcNow);
}
public TimeLogList GetTimeLogs(int userId, DateTime selectedDate)
{
var ret = new TimeLogList { SelectedDate = selectedDate.Date };
var calendarWeek = GetIso8601CalendarWeek(selectedDate);
ret.CalendarWeek = calendarWeek;
try
{
ret.TimeLogs = GetTimeLogList(userId, calendarWeek, selectedDate.Year);
}
catch (Exception ex)
{
_logger.Error(ex, "Error in GetTimeLogs with Id: {0} and selected date: {1}, Exception: {2}", userId, selectedDate, ex);
}
try
{
ret.HoursPerWeekMinutes = GetUserContractedHours(userId) * 60.0f;
}
catch (Exception ex)
{
_logger.Error(ex, "Error in GetUserContracterHours with Id: {0} and selected date: {1}, Exception: {2}", userId, selectedDate, ex);
}
ret.UserInformation = GetUser(userId);
return ret;
}
private float GetUserContractedHours(int userId)
{
var hoursQuery = _connection.Query<UserIdentity>(SQLiteProcedures.GET_USER_CONTRACTED_HOURS, userId);
if (hoursQuery.Any())
{
return hoursQuery.First().HoursPerWeek;
}
return -1.0f;
}
public IdentifierList GetUnassignedIdentifierList()
{
var ret = new IdentifierList();
var cardQuery = _connection.Query<CardUniqueId>(
SQLiteProcedures.GET_UNASSIGNED_CARD_LIST,
Constants.UNASSIGNED_CARD_USER_ID);
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
});
}
return ret;
}
//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<int>();
//Get a list of current associated identifiers, convert into a list of Identifier Objects..
var currentCards =
_connection.Query<CardUniqueId>(SQLiteProcedures.GET_CARDS_BY_USER_ID, user.UserId)
.Select(x => new Identifier { Id = x.Id, IsAssociatedToUser = true, UniqueId = x.CardUId });
var cardsToRemove = currentCards.Except(user.AssociatedIdentifiers).Select(x => x.Id).ToList();
#region GetUnique Identifiers
foreach (var card in user.AssociatedIdentifiers)
{
var existingCard = _connection.Query<CardUniqueId>(
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<UserIdentity>(
SQLiteProcedures.UPDATE_USER_DETAILS,
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
};
_connection.Insert(userInsert);
userId = userInsert.Id;
if (ret < OperationResponse.CREATED)
ret = OperationResponse.CREATED;
}
#endregion
#region Update Card/Unique Id entries.
foreach (var cardId in cardIds)
{
_connection.Query<CardUniqueId>(
SQLiteProcedures.UPDATE_CARD_USER_ID,
userId, cardId);
}
foreach (var card in cardsToRemove)
{
_connection.Query<CardUniqueId>(
SQLiteProcedures.UPDATE_CARD_USER_ID,
-1, card);
}
#endregion
#region Update Group Associations
SetUserGroups(userId, user.Groups.Where(x => x.IsAssociatedToUser).ToList());
#endregion
userIdResult = userId;
return ret;
}
public LogEventResponse LogEventTime(Identifier identifier, out int logId)
{
var ret = new LogEventResponse();
var cardIdQuery = _connection.Query<CardUniqueId>(
SQLiteProcedures.GET_CARDS_BY_UNIQUE_ID,
identifier.UniqueId);
#region Get/Insert the PK Id Identifier to associate the time log to.
var ident = new CardUniqueId();
if (!cardIdQuery.Any())
{
//new card, create it!
ident.UserId_FK = -1;
ident.CardUId = identifier.UniqueId;
_connection.Insert(ident);
UpdateIdentifierLastUsed(DateTimeOffset.UtcNow, ident.Id);
logId = -1;
//dont try to log any timelogs against this card, as it is unassigned to a user.
ret.ProcessResponse=OperationResponse.SUCCESS;
ret.Direction = LogDirection.UNKNOWN;
return ret;
}
else
{
//TODO: log when more than one comes back. should NEVER happen but....
ident = cardIdQuery.First();
}
#endregion
// Get The User Direction (are they going in or out)?
var logDirection = GetLogDirection(ident.UserId_FK);
#region Check the user hasnt registered an event in the last few minutes..
if (ident.UserId_FK != -1)
{ //only check log gap if the card is associated to a user
var hysteresisThresholdMinutes = Convert.ToInt32(ConfigurationHandler.ConfigurationHandler.GetConfiguration("SwipeTimeGap") ?? "3");
var threshold = DateTime.UtcNow.AddMinutes(0 - hysteresisThresholdMinutes);
var logs = _connection.Query<TimeLogDb>(
SQLiteProcedures.GET_LOGS_IN_LAST_X_MINUTES,
threshold.Ticks, ident.UserId_FK);
_logger.Trace("Checking last swipe event gap");
if (logs.Any())
{
_logger.Error("Not logging event for user id: {0}, logged event within TimeGap Threshold of {1}", ident.UserId_FK, threshold);
logId = -1;
ret.ProcessResponse = OperationResponse.FAILED;
ret.Direction = LogDirection.UNKNOWN;
return ret;
}
}
#endregion
#region Get the current time (for swiping). and calendar week/year to help recall the data.
var logTime = DateTime.UtcNow;
var calendarWeek = GetIso8601CalendarWeek(logTime);
var year = logTime.Year;
#endregion
var timeLog = new TimeLogDb
{
SwipeEventDateTime = DateTime.UtcNow,
UserId_FK = ident.UserId_FK,
IdentifierId = ident.Id,
Direction = logDirection,
Year = year,
CalendarWeek = calendarWeek,
Source = LogSourceDb.IDENTIFIER
};
_connection.Insert(timeLog);
UpdateIdentifierLastUsed(timeLog.SwipeEventDateTime, timeLog.IdentifierId);
logId = timeLog.Id;
ret.Direction = (LogDirection)(int)logDirection;
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 groupDb = new GroupDb { GroupName = group.Name };
var resp = _connection.Insert(groupDb);
groupId = groupDb.GroupId;
return OperationResponse.CREATED;
}
public List<Group> GetGroups(int userId = -1)
{
var ret = new List<Group>();
List<GroupDb> query;
if (userId == -1)
{
query = _connection.Query<GroupDb>("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");
}
else
{
query =
_connection.Query<GroupDb>(
"select gdb.GroupId, gdb.GroupName, gdb.AssignedUserCount" +
" from GroupDb gdb" +
" left join UserGroupJoinDb ujdb" +
" on gdb.GroupId = ujdb.GroupId_FK" +
" where ujdb.UserId_FK = ?",
userId);
}
foreach (var group in query)
{
ret.Add(new Group
{
Id = group.GroupId,
Name = group.GroupName,
UserCount = int.Parse(group.AssignedUserCount ?? "0")
});
}
return ret;
}
public Group GetGroup(int groupId)
{
var query = _connection.Query<GroupDb>("select * from GroupDb where GroupId = ?", groupId);
if (query.Any())
{
var group = query.First();
return new Group
{
Id = group.GroupId,
Name = group.GroupName,
UserCount = 0
};
}
return new Group();
}
public OperationResponse UpdateGroup(Group group)
{
//TODO: I would probably prefer to do this manually....
var resp = _connection.Query<GroupDb>("update GroupDb set GroupName=? where GroupId=?", group.Name, group.Id);
//var resp = _connection.Update(groupDb);
return OperationResponse.UPDATED;
}
public OperationResponse DeleteGroup(int groupId)
{
_connection.Delete<GroupDb>(groupId);
return OperationResponse.DELETED;
}
public OperationResponse DeleteLog(TimeLog log)
{
var query = _connection.Query<TimeLogDb>(
"select * from TimeLogDb where Id=?", log.Id);
if (!query.Any())
return OperationResponse.FAILED;
_connection.ExecuteScalar<TimeLogDb>("delete from TimeLogDb where Id=?", log.Id);
return OperationResponse.DELETED;
}
public OperationResponse CreateLog(TimeLog log)
{
var calendarWeek = GetIso8601CalendarWeek(log.EventTime.UtcDateTime);
var year = log.EventTime.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),
};
_connection.Insert(dbLog);
return OperationResponse.CREATED;
}
public OperationResponse UpdateLog(TimeLog log)
{
var query = _connection.Query<TimeLogDb>(
"select * from TimeLogDb where Id=?", log.Id);
if(!query.Any())
return OperationResponse.FAILED;
if (log.CalendarWeek > 52 || log.CalendarWeek < 1)
{
log.CalendarWeek = GetIso8601CalendarWeek(log.EventTime.UtcDateTime);
}
if (log.Year < 2017)
{
log.Year = log.EventTime.Year;
}
_connection.ExecuteScalar<TimeLogDb>(
"update TimeLogDb set UserId_FK=?, Direction=?,SwipeEventDateTime=?,CalendarWeek=?,Year=?,Source=? where Id=?",
log.UserId, (LogDirectionDb) (int) log.Direction, log.EventTime, log.CalendarWeek, log.Year,
(LogSourceDb) (int) log.Source, log.Id);
return OperationResponse.UPDATED;
}
private DateTime GetLastLogDateTime(TimeLogDb timeLog)
{
if (timeLog != null)
{
return timeLog.SwipeEventDateTime.DateTime;
}
return DateTime.MinValue;
}
private bool GetUserState(LogDirectionDb logDirection)
{
switch (logDirection)
{
case LogDirectionDb.OUT:
return true;
default:
return false;
}
}
private int ConvertSourceToIdentifierId(LogSource logSource)
{
switch (logSource)
{
case LogSource.UI:
return -100;
case LogSource.TRAYAPP:
return -200;
default:
return -10;
}
}
private bool SetUserGroups(int userId, List<Group> groups)
{
var groupIds = GetGroupIds(groups.Select(x => x.Name).ToList());
return SetUserGroups(userId, groupIds);
}
private bool SetUserGroups(int userId, int[] groupIds)
{
//remove the existing user>group associations
_connection.Query<UserGroupJoinDb>("delete from UserGroupJoinDb where UserId_FK = ?", userId);
//add the new group associations.
_connection.InsertAll(groupIds.Select(x => new UserGroupJoinDb { GroupId_FK = x, UserId_FK = userId }));
return true;
}
private int[] GetGroupIds(List<string> groupNames)
{
var ret = new List<int>();
foreach (var g in groupNames)
{
var query = _connection.Query<GroupDb>("select GroupId from GroupDb where GroupName=?", g);
if (!query.Any()) continue;
var id = query.First();
ret.Add(id.GroupId);
}
return ret.ToArray();
}
private List<DailyLogs> GetTimeLogList(int userId, int calendarWeek, int year)
{
var timeLogList = _connection.Query<TimeLogDb>(
SQLiteProcedures.GET_TIMELOGS,
userId, calendarWeek, year);
var timeLogs = timeLogList.Select(x => new TimeLog
{
Id = x.Id,
CalendarWeek = x.CalendarWeek,
Direction = (LogDirection)x.Direction,
IdentifierId = x.IdentifierId,
EventTime = x.SwipeEventDateTime,
UserId = x.UserId_FK,
Year = x.Year
}).OrderBy(x=>x.EventTime.UtcDateTime).ToList();
var dict = new Dictionary<DayOfWeek, DailyLogs>();
var logList = new List<DailyLogs>();
//make sure each day of the week is accounted for in the dictionary.
foreach (DayOfWeek day in Enum.GetValues(typeof(DayOfWeek)))
{
dict.Add(day, new DailyLogs());
}
//add the logs to the respective day of the week.
foreach (var log in timeLogs.OrderBy(x=>x.EventTime))
{
dict[log.EventTime.DayOfWeek].Logs.Add(log);
}
var logGroups = timeLogs.GroupBy(x => x.EventTime.DayOfWeek);
foreach (var group in logGroups)
{
var groupLogs = group.ToList();
var dailyLog = new DailyLogs
{
Logs = groupLogs,
Day = group.Key,
DayOfWeek = group.Key.ToString()
};
dailyLog.DailyTotal = CalculateDailyTotal(dailyLog);
logList.Add(dailyLog);
}
foreach (DayOfWeek day in Enum.GetValues(typeof(DayOfWeek)))
{
if (logList.Any(x => x.Day == day)) continue;
var dailyLog = new DailyLogs { Day = day, DayOfWeek = day.ToString() };
logList.Add(dailyLog);
}
foreach (var dailyCollection in dict)
{
dailyCollection.Value.DailyTotal = CalculateDailyTotal(dailyCollection.Value);
}
return logList.OrderBy(x => ((int)x.Day + 6) % 7).ToList();
}
private double CalculateDailyTotal(DailyLogs dailyLogs)
{
var totalInTime = TimeSpan.FromSeconds(0);
var logs = dailyLogs.Logs.OrderBy(x => x.EventTime.UtcDateTime).ToArray();
var totalCalcMax = IsOdd(logs.Length) ? logs.Length - 1 : logs.Length;
for (int i = 0; i < totalCalcMax; i += 2)
{
totalInTime += (logs[i + 1].EventTime - logs[i].EventTime);
}
return Math.Round(totalInTime.TotalMinutes, 2);
}
/// <summary>
/// determines if the number is an odd or even value
/// </summary>
/// <param name="value">number to determine is odd or even</param>
/// <returns>true - number is odd</returns>
private bool IsOdd(int value)
{
return value % 2 != 0;
}
/// <summary>
/// Get the new direction for the user based on previous entry logs in the system.
/// </summary>
/// <remarks>
/// If the user has not logged in today, the direction will be In.
/// If the user has logged in already today, the direction will be the opposite of the last
/// recorded log direction. ("out" if "in", "in" if "out")
/// </remarks>
/// <param name="userId">Id of the user to get the log direction of.</param>
/// <returns><see cref="LogDirectionDb"/> indicating what direction the new log is.</returns>
private LogDirectionDb GetLogDirection(int userId)
{
var logDirection = LogDirectionDb.UNKNOWN;
if (userId != -1)
{
var lastEntry = GetLastTimeLog(userId);
if (lastEntry != null)
{
// See if the datetime retrieved is yesterday. If yesterday, logDirection = true (in)
if (IsLogDateTimeYesterdayOrOlder(lastEntry.SwipeEventDateTime.DateTime))
{
logDirection = LogDirectionDb.IN;
}
else
{
// we have a time log from today already, so just do the opposite of what we last did!
if (lastEntry.Direction == LogDirectionDb.IN)
logDirection = LogDirectionDb.OUT;
else if (lastEntry.Direction == LogDirectionDb.OUT)
logDirection = LogDirectionDb.IN;
}
}
else
{
//assume its the first then!
logDirection = LogDirectionDb.IN;
}
}
return logDirection;
}
private TimeLogDb GetLastTimeLog(int userId)
{
var lastEntry = _connection.Query<TimeLogDb>(
SQLiteProcedures.GET_LAST_TIMELOG_DIRECTION,
userId);
if (lastEntry.Any())
{
return lastEntry.First();
}
return null;
}
private void UpdateIdentifierLastUsed(DateTimeOffset dt, int cardId)
{
var res = _connection.ExecuteScalar<CardUniqueId>(SQLiteProcedures.UPDATE_CARD_LAST_USED,
dt,
cardId);
}
private List<Identifier> GetAssociatedIdentifiers(int userId)
{
var cards = _connection.Query<CardUniqueId>(
SQLiteProcedures.GET_CARDS_BY_USER_ID,
userId);
var ret = new List<Identifier>();
foreach (var card in cards)
{
ret.Add(new Identifier()
{
UniqueId = card.CardUId,
IsAssociatedToUser = true,
Id = card.Id
});
}
return ret;
}
/// <summary>
/// Get the calendar week of the year according to the ISO8601 standard (starts monday).
/// </summary>
/// <param name="date">the date to get the calendar week of.</param>
/// <returns>the calendar week of the year in integer form (1-52)</returns>
private int GetIso8601CalendarWeek(DateTime date)
{
var day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(date);
if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday)
{
date = date.AddDays(3);
}
return CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(date, CalendarWeekRule.FirstFourDayWeek,
DayOfWeek.Monday);
}
/// <summary>
/// Check whether the specified DateTime is from yesterday or older.
/// </summary>
/// <param name="dt">the DateTime object to check is yesterday or older</param>
/// <returns>true - is yesterday or older.</returns>
private bool IsLogDateTimeYesterdayOrOlder(DateTime dt)
{
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
};
}
}
}