240 lines
7.0 KiB
C#
240 lines
7.0 KiB
C#
using Blahblah.FlowerApp.Data.Model;
|
|
using Microsoft.Extensions.Logging;
|
|
using SQLite;
|
|
|
|
namespace Blahblah.FlowerApp.Data;
|
|
|
|
public class FlowerDatabase : ILoggerContent
|
|
{
|
|
public ILogger Logger { get; }
|
|
|
|
public FlowerDatabase Database => this;
|
|
|
|
private SQLiteAsyncConnection database = null!;
|
|
|
|
public FlowerDatabase(ILogger<FlowerDatabase> logger)
|
|
{
|
|
Logger = logger;
|
|
}
|
|
|
|
private Dictionary<int, NamedItem>? categories;
|
|
|
|
private Dictionary<int, EventItem>? events;
|
|
|
|
public Dictionary<int, NamedItem>? Categories => categories;
|
|
|
|
public string Category(int categoryId)
|
|
{
|
|
if (categories?.TryGetValue(categoryId, out var category) == true)
|
|
{
|
|
return category.Name;
|
|
}
|
|
return Constants.CategoryOther;
|
|
}
|
|
|
|
public string Event(int eventId)
|
|
{
|
|
if (events?.TryGetValue(eventId, out var @event) == true)
|
|
{
|
|
return @event.Name;
|
|
}
|
|
return Constants.EventUnknown;
|
|
}
|
|
|
|
private async Task Init()
|
|
{
|
|
if (database is not null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
#if DEBUG
|
|
Logger.LogInformation("database path: {path}", Constants.DatabasePath);
|
|
#endif
|
|
|
|
database = new SQLiteAsyncConnection(Constants.DatabasePath, Constants.SQLiteFlags);
|
|
|
|
#if DEBUG1
|
|
var result =
|
|
#endif
|
|
await database.CreateTablesAsync(CreateFlags.None,
|
|
typeof(FlowerItem),
|
|
typeof(RecordItem),
|
|
typeof(PhotoItem),
|
|
typeof(UserItem),
|
|
typeof(DefinitionItem),
|
|
typeof(ParamItem),
|
|
typeof(LogItem));
|
|
|
|
#if DEBUG1
|
|
foreach (var item in result.Results)
|
|
{
|
|
this.LogInformation($"create table {item.Key}, result: {item.Value}");
|
|
}
|
|
#endif
|
|
}
|
|
|
|
public async Task Setup()
|
|
{
|
|
await Init();
|
|
|
|
#if DEBUG1
|
|
var token = "RF4mfoUur0vHtWzHwD42ka0FhIfGaPnBxoQgrXOYEDg=";
|
|
#else
|
|
var tk = await database.Table<ParamItem>().FirstOrDefaultAsync(p => p.Code == Constants.LastTokenName);
|
|
var token = tk?.Value;
|
|
#endif
|
|
if (token is string t)
|
|
{
|
|
Constants.SetAuthorization(t);
|
|
var user = await database.Table<UserItem>().FirstOrDefaultAsync(u => u.Token == t);
|
|
if (user != null)
|
|
{
|
|
AppResources.SetUser(user);
|
|
}
|
|
}
|
|
|
|
var version = await database.Table<ParamItem>().FirstOrDefaultAsync(p => p.Code == Constants.ApiVersionName);
|
|
var definition = await Constants.Initialize(this, version?.Value);
|
|
|
|
if (definition != null)
|
|
{
|
|
categories = definition.Categories;
|
|
events = definition.Events;
|
|
|
|
this.LogInformation($"new version founded, from ({version?.Value}) to ({definition.ApiVersion})");
|
|
|
|
if (version == null)
|
|
{
|
|
version = new ParamItem
|
|
{
|
|
Code = Constants.ApiVersionName,
|
|
Value = definition.ApiVersion
|
|
};
|
|
}
|
|
else
|
|
{
|
|
version.Value = definition.ApiVersion;
|
|
}
|
|
await database.InsertOrReplaceAsync(version);
|
|
|
|
// replace local definitions
|
|
await database.DeleteAllAsync<DefinitionItem>();
|
|
|
|
var defs = new List<DefinitionItem>();
|
|
foreach (var category in definition.Categories)
|
|
{
|
|
defs.Add(new DefinitionItem
|
|
{
|
|
DefinitionType = 0,
|
|
DefinitionId = category.Key,
|
|
Name = category.Value.Name,
|
|
Description = category.Value.Description
|
|
});
|
|
}
|
|
foreach (var @event in definition.Events)
|
|
{
|
|
defs.Add(new DefinitionItem
|
|
{
|
|
DefinitionType = 1,
|
|
DefinitionId = @event.Key,
|
|
Name = @event.Value.Name,
|
|
Description = @event.Value.Description,
|
|
Unique = @event.Value.Unique
|
|
});
|
|
}
|
|
var rows = await database.InsertAllAsync(defs);
|
|
this.LogInformation($"{defs.Count} definitions, {rows} rows inserted");
|
|
}
|
|
else
|
|
{
|
|
// use local definitions
|
|
var defs = await database.Table<DefinitionItem>().ToListAsync();
|
|
var cates = new Dictionary<int, NamedItem>();
|
|
var evts = new Dictionary<int, EventItem>();
|
|
foreach (var d in defs)
|
|
{
|
|
if (d.DefinitionType == 0)
|
|
{
|
|
// category
|
|
cates[d.DefinitionId] = new NamedItem(d.Name, d.Description);
|
|
}
|
|
else if (d.DefinitionType == 1)
|
|
{
|
|
// event
|
|
evts[d.DefinitionId] = new EventItem(d.Name, d.Description, d.Unique ?? false);
|
|
}
|
|
}
|
|
categories = cates;
|
|
events = evts;
|
|
}
|
|
}
|
|
|
|
public async Task<int> GetLogCount()
|
|
{
|
|
await Init();
|
|
return await database.Table<LogItem>().Where(l => l.OwnerId < 0 || l.OwnerId == AppResources.User.Id).CountAsync();
|
|
}
|
|
|
|
public async Task<LogItem[]> GetLogs()
|
|
{
|
|
await Init();
|
|
return await database.Table<LogItem>().Where(l => l.OwnerId < 0 || l.OwnerId == AppResources.User.Id).OrderByDescending(l => l.LogUnixTime).ToArrayAsync();
|
|
}
|
|
|
|
public async Task<int> AddLog(LogItem log)
|
|
{
|
|
await Init();
|
|
return await database.InsertAsync(log);
|
|
}
|
|
|
|
public async Task<FlowerItem[]> GetFlowers()
|
|
{
|
|
await Init();
|
|
return await database.Table<FlowerItem>().ToArrayAsync();
|
|
}
|
|
|
|
public async Task<int> UpdateFlowers(IEnumerable<FlowerItem> flowers)
|
|
{
|
|
await Init();
|
|
|
|
var ids = flowers.Select(f => f.Id).ToList();
|
|
var count = await database.Table<FlowerItem>().DeleteAsync(f => ids.Contains(f.Id));
|
|
await database.Table<PhotoItem>().DeleteAsync(p => p.RecordId == null && ids.Contains(p.FlowerId));
|
|
|
|
await database.InsertAllAsync(flowers);
|
|
foreach (var flower in flowers)
|
|
{
|
|
if (flower.Photos?.Length > 0)
|
|
{
|
|
await database.InsertAllAsync(flower.Photos);
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
|
|
public async Task<int> SetUser(UserItem user)
|
|
{
|
|
await Init();
|
|
var count = user.Id > 0 ?
|
|
await database.Table<UserItem>().CountAsync(u => u.Id == user.Id) :
|
|
0;
|
|
if (count > 0)
|
|
{
|
|
count = await database.UpdateAsync(user);
|
|
}
|
|
else
|
|
{
|
|
count = await database.InsertAsync(user);
|
|
}
|
|
if (count > 0)
|
|
{
|
|
var c = await database.Table<ParamItem>().FirstOrDefaultAsync(p => p.Code == Constants.LastTokenName);
|
|
c ??= new ParamItem { Code = Constants.LastTokenName };
|
|
c.Value = user.Token;
|
|
await database.InsertOrReplaceAsync(c);
|
|
}
|
|
return count;
|
|
}
|
|
}
|