flower-story/FlowerApp/Data/FlowerDatabase.cs
2023-07-27 22:07:24 +08:00

176 lines
5.0 KiB
C#

using Blahblah.FlowerApp.Data.Model;
using Microsoft.Extensions.Logging;
using SQLite;
namespace Blahblah.FlowerApp.Data;
public class FlowerDatabase
{
private SQLiteAsyncConnection database = null!;
private readonly ILogger logger;
public FlowerDatabase(ILogger<FlowerDatabase> logger)
{
this.logger = logger;
Task.Run(async () =>
{
try
{
await Setup();
}
catch (Exception ex)
{
logger.LogError("error occurs on setup, {error}", ex);
}
});
}
private Dictionary<int, NamedItem>? categories;
private Dictionary<int, EventItem>? events;
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 Setup()
{
await Init();
#if DEBUG
Constants.SetAuthorization("RF4mfoUur0vHtWzHwD42ka0FhIfGaPnBxoQgrXOYEDg=");
#else
var token = await database.Table<ParamItem>().FirstOrDefaultAsync(p => p.Code == Constants.LastTokenName);
if (token != null)
{
Constants.SetAuthorization(token.Value);
}
#endif
var version = await database.Table<ParamItem>().FirstOrDefaultAsync(p => p.Code == Constants.ApiVersionName);
var definition = await Constants.Initialize(logger, version?.Value);
if (definition != null)
{
categories = definition.Categories;
events = definition.Events;
logger.LogInformation("new version founded, from ({from}) to ({to})", version?.Value, 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);
logger.LogInformation("{count} definitions, {rows} rows inserted", defs.Count, rows);
}
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;
}
}
private async Task Init()
{
if (database is not null)
{
return;
}
database = new SQLiteAsyncConnection(Constants.DatabasePath, Constants.SQLiteFlags);
#if DEBUG
var result =
#endif
await database.CreateTablesAsync(CreateFlags.None,
typeof(FlowerItem),
typeof(RecordItem),
typeof(PhotoItem),
typeof(UserItem),
typeof(DefinitionItem),
typeof(ParamItem));
#if DEBUG
foreach (var item in result.Results)
{
logger.LogInformation("create table {table}, result: {result}", item.Key, item.Value);
}
#endif
}
public async Task<FlowerItem[]> GetFlowers()
{
await Init();
return await database.Table<FlowerItem>().ToArrayAsync();
}
}