using System.Text; using System.Text.Json; namespace DevJsonDB.IO; public class LocalStore : IStore { private static Encoding DefaultEncoding = Encoding.UTF8; private string filePath; private List items; private bool autoCommit; public LocalStore(string filePath, bool autoCommit) { this.filePath = filePath; this.items = new List(); this.autoCommit = autoCommit; 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)) { fs.Seek(0, SeekOrigin.Begin); fs.SetLength(0); for (int i = 0 ; i < items.Count; i++) { T item = items[i]; string json = JsonSerializer.Serialize(item); writer.Write(json); if (i != items.Count - 1) { writer.Write("\n"); } } } } 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); this.AutoCommit(FastMergeType.Add); return true; } public bool Has(T item) { return this.items.Contains(item); } public bool Remove(T item) { bool ret = this.items.Remove(item); this.AutoCommit(FastMergeType.Remove); return ret; } public IEnumerable GetValues() { return this.items.ToList(); } 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(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); } } 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(line); if (value is object) { this.items.Add(value); } } } } catch (Exception ex) { throw new JsonDBException(ex.Message, ex); } } }