using System;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using HotPocket;
using System.Linq;
namespace ToDoContract
{
/*
* This is a simple multi-user ToDo list contract which uses sqlite database as storage.
* In order to run this .Net Core should be installed on the system. If using docker,
* mcr.microsoft.com/dotnet/core/sdk:3.1 docker image must be used.
*
* Produce deployable output with: dotnet publish -c Release
*
* User inputs can be submitted in the following format.
* Insert a new ToDo record: add
* Retrieve all records owned by user: get all
* Retrieve record by ID: get
* Delete all records owned by user: delete all
* Delete record by ID: delete
*/
public class Program
{
static async Task Main(string[] args)
{
Console.WriteLine("Starting .Net ToDo contract");
using (var dataContext = new DataContext())
{
dataContext.Database.Migrate();
}
ContractArgs contractArgs = await HotPocketHelper.GetContractArgsAsync();
foreach (var user in contractArgs.UserPipes)
{
var pubkey = user.Key;
var pipe = user.Value;
var input = HotPocketHelper.ReadStringFromFD(pipe.ReadFD);
if (string.IsNullOrEmpty(input))
continue;
var output = await HandleUserInputAsync(pubkey, input);
HotPocketHelper.WriteStringToFD(pipe.WriteFD, output);
}
}
static async Task HandleUserInputAsync(string userId, string input)
{
var parts = input.Trim().Split(' ', 2);
if (parts.Length < 2)
return "Invalid input format";
var command = parts[0].ToLower();
var param = parts[1];
using (var dataContext = new DataContext())
{
if (command == "add") // add new record.
{
var entry = new ToDoEntry
{
Content = param,
CreatedBy = userId
};
dataContext.ToDoEntries.Add(entry);
await dataContext.SaveChangesAsync();
return "Added entry with id " + entry.Id;
}
else if (command == "get" || command == "delete")
{
if (param == "all") // get/delete all records.
{
// Get all entries belonging to this user.
var entries = await dataContext.ToDoEntries.Where(e => e.CreatedBy == userId).OrderBy(e => e.Id).ToListAsync();
if (command == "get")
{
return JsonConvert.SerializeObject(entries.Select(e => $"ID-{e.Id}: {e.Content}"));
}
else
{
// Delete all records for this user.
dataContext.RemoveRange(entries);
await dataContext.SaveChangesAsync();
return $"{entries.Count} record(s) deleted";
}
}
else // get/delete by ID.
{
int id = 0;
if (int.TryParse(param, out id))
{
var entry = await dataContext.ToDoEntries.FirstOrDefaultAsync(e => e.Id == id);
if (entry == null)
{
return $"Record id {id} does not exist";
}
else if (entry.CreatedBy != userId)
{
return $"You do not have permission for record id {id}";
}
else
{
if (command == "get")
{
return entry.Content;
}
else
{
dataContext.Remove(entry);
await dataContext.SaveChangesAsync();
return $"Record id {id} deleted";
}
}
}
else
{
return "Invalid record id";
}
}
}
else
{
return "Invalid command";
}
}
}
}
}