278 lines
10 KiB
C#
278 lines
10 KiB
C#
using Microsoft.Data.SqlClient;
|
|
using System.Collections.Concurrent;
|
|
using System.Data;
|
|
using System.Threading.Tasks;
|
|
using Telerik.Windows.Documents.Fixed.Model.Editing.Lists;
|
|
using Telerik.Windows.Documents.Fixed.Model.Navigation;
|
|
using XAct;
|
|
|
|
namespace TireTargets.Components.CSharp
|
|
{
|
|
|
|
public class DatabaseDriver : IDisposable
|
|
{
|
|
private bool disposedValue;
|
|
|
|
private ConcurrentBag<System.Threading.Tasks.Task> _tasks = new ConcurrentBag<System.Threading.Tasks.Task>();
|
|
private bool isExiting = false;
|
|
|
|
private static string _connectionString = "Server=BigMac; Database=TireTargets; Integrated Security=SSPI;MultipleActiveResultSets=True;TrustServerCertificate=True;";
|
|
protected virtual void Dispose(bool disposing)
|
|
{
|
|
if (!disposedValue)
|
|
{
|
|
if (disposing)
|
|
{
|
|
isExiting = true;
|
|
Task.WaitAll(_tasks.ToArray());
|
|
}
|
|
disposedValue = true;
|
|
}
|
|
}
|
|
public void Dispose()
|
|
{
|
|
Dispose(disposing: true);
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
public static async Task<bool> SignIn(string platform, string id, string fname, string email)
|
|
{
|
|
try
|
|
{
|
|
using (var cn = new SqlConnection(_connectionString))
|
|
{
|
|
await cn.OpenAsync();
|
|
await using var queryCmd = new SqlCommand(String.Format("SELECT COUNT(UniqID) FROM [dbo].[User] WHERE {0}ID = '{1}'", platform, id), cn);
|
|
await using var rd = await queryCmd.ExecuteReaderAsync();
|
|
|
|
// Get number of occurences of this ID/Platform combo
|
|
int count = -1;
|
|
while (await rd.ReadAsync())
|
|
{
|
|
count = rd.GetInt32(0);
|
|
}
|
|
|
|
if (count > 0) // If the account already exists, read from the DB for session info
|
|
{
|
|
|
|
}
|
|
else // Otherwise, we need to create a new account
|
|
{
|
|
await using var insertCmd = new SqlCommand(String.Format("INSERT INTO [dbo].[User] ({0}ID, {0}Name, {0}Email) VALUES (@id, @fname, @email)", platform), cn);
|
|
|
|
insertCmd.Parameters.AddWithValue("@id", id);
|
|
insertCmd.Parameters.AddWithValue("@fname", fname);
|
|
insertCmd.Parameters.AddWithValue("@email", email);
|
|
|
|
insertCmd.ExecuteNonQuery();
|
|
}
|
|
|
|
cn.Close();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine(ex.Message);
|
|
return false;
|
|
}
|
|
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
public static async Task<List<Location>> GetLocationInfoForUser(string id, string platform)
|
|
{
|
|
try
|
|
{
|
|
using (var cn = new SqlConnection(_connectionString))
|
|
{
|
|
await cn.OpenAsync();
|
|
|
|
|
|
// Confirm that user has a valid location ID set
|
|
string locQueryString = "";
|
|
if (platform == "Google")
|
|
locQueryString = String.Format("SELECT [LocationID] FROM [dbo].[User] WHERE [GoogleID] = '{0}'", id.Replace("'","''"));
|
|
else if (platform == "FB")
|
|
locQueryString = String.Format("SELECT [LocationID] FROM [dbo].[User] WHERE [FBID] = '{0}'", id.Replace("'", "''"));
|
|
|
|
|
|
await using var locQuery = new SqlCommand(locQueryString, cn);
|
|
await using var locRd = await locQuery.ExecuteReaderAsync();
|
|
|
|
// Extract loc id
|
|
int locationId = -1;
|
|
while (await locRd.ReadAsync())
|
|
{
|
|
locationId = locRd.GetInt32(0);
|
|
}
|
|
|
|
|
|
|
|
// Check if user's LocID is a RootID
|
|
string rootString = String.Format("SELECT COUNT(*) FROM [dbo].[Location] WHERE RootID = {0}", ("" + locationId).Replace("'","''"));
|
|
SqlCommand cmd = new SqlCommand(rootString, cn);
|
|
Int32 val = (Int32)cmd.ExecuteScalar();
|
|
|
|
string locInfoString = "";
|
|
if (val > 1)
|
|
{
|
|
locInfoString = String.Format("SELECT * FROM [dbo].[Location] WHERE RootID = {0}", ("" + locationId).Replace("'", "''"));
|
|
}
|
|
else // Nothing matches
|
|
{
|
|
locInfoString = String.Format("SELECT * FROM [dbo].[Location] WHERE LocationID = {0}", ("" + locationId).Replace("'", "''"));
|
|
}
|
|
|
|
// Find the location in Location table
|
|
await using var queryCmd = new SqlCommand(locInfoString, cn);
|
|
await using var rd = await queryCmd.ExecuteReaderAsync();
|
|
|
|
// Extract loc id
|
|
List<Location> locations = new List<Location>();
|
|
while (await rd.ReadAsync())
|
|
{
|
|
var locID = rd.GetInt32(0);
|
|
var rootID = rd.GetInt32(1);
|
|
var locName = rd.GetString(2);
|
|
var lastSelected = rd.GetDateTime(3);
|
|
var needSelection = rd.GetInt32(4);
|
|
var selectionJson = rd.GetString(5);
|
|
var enabled = rd.GetInt32(6);
|
|
|
|
Location current = new Location(locID, rootID, locName, lastSelected, needSelection, selectionJson, enabled);
|
|
locations.Add(current);
|
|
}
|
|
|
|
|
|
cn.Close();
|
|
return locations;
|
|
}
|
|
}
|
|
catch (Exception ex) {
|
|
Console.WriteLine(ex.Message);
|
|
}
|
|
return new List<Location>();
|
|
}
|
|
|
|
|
|
|
|
public static async Task<(DateTime, DateTime)> GetSelectionTimes()
|
|
{
|
|
using (var cn = new SqlConnection(_connectionString))
|
|
{
|
|
await cn.OpenAsync();
|
|
await using var cmd = new SqlCommand("SELECT * FROM [cfg].[Selection]", cn);
|
|
await using var rd = await cmd.ExecuteReaderAsync();
|
|
|
|
(DateTime, DateTime) selectionTime = (default, default);
|
|
while (await rd.ReadAsync())
|
|
{
|
|
selectionTime.Item1 = rd.GetDateTime(0);
|
|
selectionTime.Item2 = rd.GetDateTime(1);
|
|
}
|
|
|
|
return selectionTime;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public static async Task<List<(int,bool)>> DoesLocationNeedSelection()
|
|
{
|
|
// Determine if offers need to be selected
|
|
var locInfo = await GetLocationInfoForUser(Layout.MainLayout.Session["id"], Layout.MainLayout.Session["login_method"]);
|
|
var selectionTime = await GetSelectionTimes();
|
|
|
|
List<(int, bool)> results = new List<(int, bool)> ();
|
|
foreach (Location current in locInfo)
|
|
{
|
|
// Location NeedSelection is effectively an override, forcing them to re-select for the flagged location(s)
|
|
if (current.NeedSelection == 1 || (current.LastSelected < selectionTime.Item1 && DateTime.Now < selectionTime.Item2))
|
|
{
|
|
results.Add((current.LocationID, true));
|
|
}
|
|
else
|
|
{
|
|
results.Add((current.LocationID, false));
|
|
}
|
|
}
|
|
return results;
|
|
}
|
|
|
|
|
|
|
|
public static async Task<bool> DoesUserHaveLocation(string id, string platform)
|
|
{
|
|
using (var cn = new SqlConnection(_connectionString))
|
|
{
|
|
await cn.OpenAsync();
|
|
|
|
string queryString = "";
|
|
if (platform == "Google")
|
|
queryString = String.Format("SELECT [LocationID] FROM [dbo].[User] WHERE [GoogleID] = '{0}'", id.Replace("'", "''"));
|
|
else if (platform == "FB")
|
|
queryString = String.Format("SELECT [LocationID] FROM [dbo].[User] WHERE [FBID] = '{0}'", id.Replace("'", "''"));
|
|
|
|
await using var cmd = new SqlCommand(queryString, cn);
|
|
await using var rd = await cmd.ExecuteReaderAsync();
|
|
|
|
while (await rd.ReadAsync())
|
|
{
|
|
if (rd.IsDBNull(0) || rd.GetInt32(0) == -1)
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public static async Task<bool> UpdateSelection(Dictionary<int, string> locSelections)
|
|
{
|
|
using (var cn = new SqlConnection(_connectionString))
|
|
{
|
|
await cn.OpenAsync();
|
|
|
|
foreach (var current in locSelections)
|
|
{
|
|
var query = String.Format("UPDATE [dbo].[Location] SET [SelectionJson] = '{0}', [LastSelected] = GETDATE() WHERE LocationID = {1}", current.Value, current.Key);
|
|
await using var cmd = new SqlCommand(query, cn);
|
|
cmd.ExecuteNonQuery();
|
|
}
|
|
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
public class Location
|
|
{
|
|
public Location(int locID, int rootID, string locName, DateTime lastSelect, int needSelection, string selectionJson, int enabled)
|
|
{
|
|
LocationID = locID;
|
|
RootID = rootID;
|
|
LocationName = locName;
|
|
LastSelected = lastSelect;
|
|
NeedSelection = needSelection;
|
|
SelectionJson = selectionJson;
|
|
Enabled = enabled;
|
|
}
|
|
|
|
|
|
|
|
public int LocationID { get; set; }
|
|
public int RootID { get; set; }
|
|
public string LocationName { get; set; }
|
|
public DateTime LastSelected { get; set; }
|
|
public int NeedSelection { get; set; }
|
|
public string SelectionJson { get; set; }
|
|
public int Enabled { get; set; }
|
|
}
|
|
}
|
|
}
|