2024-08-12 12:02:12 +09:00
|
|
|
using System.Text;
|
|
|
|
using System.Text.Json;
|
|
|
|
|
|
|
|
namespace DevJsonDB.IO;
|
|
|
|
|
|
|
|
public class LocalStore<T> : IStore<T>
|
|
|
|
{
|
|
|
|
private static Encoding DefaultEncoding = Encoding.UTF8;
|
|
|
|
private string filePath;
|
|
|
|
private List<T> items;
|
2024-08-12 16:35:58 +09:00
|
|
|
private bool autoCommit;
|
2024-08-12 12:02:12 +09:00
|
|
|
|
2024-08-12 16:35:58 +09:00
|
|
|
public LocalStore(string filePath, bool autoCommit)
|
2024-08-12 12:02:12 +09:00
|
|
|
{
|
|
|
|
this.filePath = filePath;
|
|
|
|
this.items = new List<T>();
|
2024-08-12 16:35:58 +09:00
|
|
|
this.autoCommit = autoCommit;
|
2024-08-12 12:02:12 +09:00
|
|
|
|
|
|
|
this.InitDatabase();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
{
|
|
|
|
this.Commit();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Commit()
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
using (FileStream fs = new FileStream(this.filePath, FileMode.OpenOrCreate))
|
|
|
|
using (StreamWriter writer = new StreamWriter(fs, DefaultEncoding))
|
|
|
|
{
|
2024-08-12 12:46:55 +09:00
|
|
|
fs.Seek(0, SeekOrigin.Begin);
|
|
|
|
fs.SetLength(0);
|
|
|
|
|
2024-08-12 16:35:58 +09:00
|
|
|
for (int i = 0 ; i < items.Count; i++)
|
2024-08-12 12:02:12 +09:00
|
|
|
{
|
2024-08-12 16:35:58 +09:00
|
|
|
T item = items[i];
|
2024-08-12 12:02:12 +09:00
|
|
|
string json = JsonSerializer.Serialize<T>(item);
|
2024-08-12 16:35:58 +09:00
|
|
|
writer.Write(json);
|
|
|
|
if (i != items.Count - 1)
|
|
|
|
{
|
|
|
|
writer.Write("\n");
|
|
|
|
}
|
2024-08-12 12:02:12 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
throw new JsonDBException(ex.Message, ex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public bool Add(T item)
|
|
|
|
{
|
|
|
|
if (this.items.Contains(item))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.items.Add(item);
|
2024-08-12 16:35:58 +09:00
|
|
|
this.AutoCommit(FastMergeType.Add);
|
2024-08-12 12:02:12 +09:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2024-08-12 12:30:07 +09:00
|
|
|
public bool Has(T item)
|
|
|
|
{
|
|
|
|
return this.items.Contains(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
public bool Remove(T item)
|
|
|
|
{
|
2024-08-12 16:35:58 +09:00
|
|
|
bool ret = this.items.Remove(item);
|
|
|
|
this.AutoCommit(FastMergeType.Remove);
|
|
|
|
return ret;
|
2024-08-12 12:30:07 +09:00
|
|
|
}
|
|
|
|
|
2024-08-12 12:02:12 +09:00
|
|
|
public IEnumerable<T> GetValues()
|
|
|
|
{
|
|
|
|
return this.items.ToList();
|
|
|
|
}
|
|
|
|
|
2024-08-12 16:35:58 +09:00
|
|
|
private void AutoCommit(FastMergeType mergeType)
|
|
|
|
{
|
|
|
|
if (!this.autoCommit) return;
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
// Fast-Merge
|
|
|
|
switch (mergeType)
|
|
|
|
{
|
|
|
|
case FastMergeType.Add:
|
|
|
|
{
|
|
|
|
using (FileStream fs = new FileStream(this.filePath, FileMode.Append))
|
|
|
|
using (StreamWriter writer = new StreamWriter(fs, DefaultEncoding))
|
|
|
|
{
|
|
|
|
T lastItem = this.items.ElementAt(this.items.Count() - 1);
|
|
|
|
string json = JsonSerializer.Serialize<T>(lastItem);
|
|
|
|
if (fs.Length > 0)
|
|
|
|
{
|
|
|
|
writer.Write("\n");
|
|
|
|
}
|
|
|
|
writer.Write(json);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case FastMergeType.Remove:
|
|
|
|
{
|
|
|
|
this.Commit();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
throw new JsonDBException(ex.Message, ex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-12 12:02:12 +09:00
|
|
|
private void InitDatabase()
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
using (FileStream fs = new FileStream(this.filePath, FileMode.OpenOrCreate))
|
|
|
|
using (StreamReader reader = new StreamReader(fs, DefaultEncoding))
|
|
|
|
{
|
|
|
|
string? line = null;
|
|
|
|
while ((line = reader.ReadLine()) != null)
|
|
|
|
{
|
|
|
|
T? value = JsonSerializer.Deserialize<T>(line);
|
|
|
|
if (value is object)
|
|
|
|
{
|
|
|
|
this.items.Add(value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
throw new JsonDBException(ex.Message, ex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|