博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SharpFileDB - a file database for small apps
阅读量:7218 次
发布时间:2019-06-29

本文共 9847 字,大约阅读时间需要 32 分钟。

SharpFileDB - a file database for small apps

本文中文版在。

I'm not an expert of database. Please feel free to corect my mistakes.

This article () helpes a lot. Thank you!

目标(Goal)

I've decided to write a micro database library that spports 10 thousand level applications.

It's better not to rely on other drives or tools in case of high difficulty in deployment. After all, it's a small database for a small application.

It's a DLL from totally C# codes. It's easy for reading and using.

It supports CRUD of course.

It doesn't use any SQL. I'm not familiar with SQL and I don't like it. And it's not necessary to use SQL here.

It saves data via plain text files or binary files. It's convenient to use plain text files when developing and debugging codes. And it's safer to use binary files at deployment time.

So, simply, it's a micro database library that uses no SQL, files as storage form and totally C# to implement a CRUD system. Let's name the library SharpFileDB.

I've put the newest project on . All codes in the library are noted in both chinese and engilsh. I hope that will help to communicate.

设计草图(sketch)

使用场景(User Scene)

The typical user scene of SharpFileDB is as follows.

1                 // common cases to use SharpFileDB. 2                 FileDBContext db = new FileDBContext(); 3  4                 Cat cat = new Cat(); 5                 cat.Name = "xiao xiao bai"; 6                 db.Create(cat); 7  8                 Predicate
pre = new Predicate
(x => x.Name == "xiao xiao bai"); 9 IList
cats = db.Retrieve(pre);10 11 cat.Name = "xiao bai";12 db.Update(cat);13 14 db.Delete(cat);

This routine contains lines that create a database and uses CRUD operations.

Let's start the first version of SharpFileDB according to this user scene.

表vs类型(Table vs Type)

Let's take the type 'Cat' as an example.

1     ///  2     /// demo file object 3     ///  4     public class Cat : FileObject 5     { 6         public string Name { get; set; } 7         public int Legs { get; set; } 8  9         public override string ToString()10         {11             return string.Format("{0}, Name: {1}, Legs: {2}", base.ToString(), Name, Legs);12         }13     }

The type 'Cat' is equivalent to a 'Table' in a relational database.

An instance of 'Cat' is equivalent to a record of a 'Table'.

Lets' call types like 'Cat' a table-type.

全局唯一的主键(global unique main key)

We need a global unique main key for every instance of a table-type to diffentiate them. So let's do this in an abstract class.

1     ///  2     /// 可在文件数据库中使用CRUD操作的所有类型的基类。 3     /// Base class for all classed that can use CRUD in SharpFileDB. 4     ///  5     [Serializable] 6     public abstract class FileObject 7     { 8         ///  9         /// 主键.10         /// main key.11         /// 12         public Guid Id { get; set; }13 14         /// 15         /// 创建一个文件对象,并自动为其生成一个全局唯一的Id。16         /// 
Create a
and generate a global unique id for it.
17 ///
18 public FileObject()19 {20 this.Id = Guid.NewGuid();21 }22 23 public override string ToString()24 {25 return string.Format("Id: {0}", this.Id);26 }27 }

 

数据库(FileDBContext)

All table-types' CRUD operations are done in a FileDBContext.

1     ///   2 /// 文件数据库。  3     /// Represents a file database.  4     ///   5     public class FileDBContext  6     {  7         #region Fields  8   9         ///  10         /// 文件数据库操作锁 11         /// 
database operation lock.
12 ///
13 protected static readonly object operationLock = new object(); 14 15 /// 16 /// 文件数据库 17 ///
Represents a file database.
18 ///
19 /// 数据库文件所在目录
Directory for all files of database.
20 public FileDBContext(string directory = null) 21 { 22 if (directory == null) 23 { 24 this.Directory = Environment.CurrentDirectory; 25 } 26 else 27 { 28 Directory = directory; 29 } 30 } 31 32 #endregion 33 34 public override string ToString() 35 { 36 return string.Format("@: {0}", Directory); 37 } 38 39 #region Properties 40 41 /// 42 /// 数据库文件所在目录 43 ///
Directory of database files.
44 ///
45 public virtual string Directory { get; protected set; } 46 47 #endregion 48 49 50 protected string Serialize(FileObject item) 51 { 52 using (StringWriterWithEncoding sw = new StringWriterWithEncoding(Encoding.UTF8)) 53 { 54 XmlSerializer serializer = new XmlSerializer(item.GetType()); 55 serializer.Serialize(sw, item); 56 string serializedString = sw.ToString(); 57 58 return serializedString; 59 } 60 } 61 62 /// 63 /// 将字符串反序列化成文档对象 64 /// 65 ///
文档类型
66 /// 字符串 67 ///
68 /// 文档对象 69 ///
70 protected TFileObject Deserialize
(string serializedFileObject) 71 where TFileObject : FileObject 72 { 73 if (string.IsNullOrEmpty(serializedFileObject)) 74 throw new ArgumentNullException("data"); 75 76 using (StringReader sr = new StringReader(serializedFileObject)) 77 { 78 XmlSerializer serializer = new XmlSerializer(typeof(TFileObject)); 79 object deserializedObj = serializer.Deserialize(sr); 80 TFileObject fileObject = deserializedObj as TFileObject; 81 return fileObject; 82 } 83 } 84 85 protected string GenerateFileFullPath(FileObject item) 86 { 87 string path = GenerateFilePath(item.GetType()); 88 string name = item.GenerateFileName(); 89 string fullname = Path.Combine(path, name); 90 return fullname; 91 } 92 93 ///
94 /// 生成文件路径 95 /// 96 ///
文档类型
97 ///
文件路径
98 protected string GenerateFilePath(Type type) 99 {100 string path = Path.Combine(this.Directory, type.Name);101 return path;102 }103 104 #region CRUD105 106 ///
107 /// 增加一个
到数据库。这实际上创建了一个文件。108 ///
Create a new
into database. This operation will create a new file.
109 ///
110 ///
111 public virtual void Create(FileObject item)112 {113 string fileName = GenerateFileFullPath(item);114 string output = Serialize(item);115 116 lock (operationLock)117 {118 System.IO.FileInfo info = new System.IO.FileInfo(fileName);119 System.IO.Directory.CreateDirectory(info.Directory.FullName);120 System.IO.File.WriteAllText(fileName, output);121 }122 }123 124 ///
125 /// 检索符合给定条件的所有
。126 ///
Retrives all
that satisfies the specified condition.
127 ///
128 ///
129 ///
检索出的对象应满足的条件。
THe condition that should be satisfied by retrived object.
130 ///
131 public virtual IList
Retrieve
(Predicate
predicate)132 where TFileObject : FileObject133 {134 IList
result = new List
();135 if (predicate != null)136 {137 string path = GenerateFilePath(typeof(TFileObject));138 string[] files = System.IO.Directory.GetFiles(path, "*.xml", SearchOption.AllDirectories);139 foreach (var item in files)140 {141 string fileContent = File.ReadAllText(item);142 TFileObject deserializedFileObject = Deserialize
(fileContent);143 if (predicate(deserializedFileObject))144 {145 result.Add(deserializedFileObject);146 }147 }148 }149 150 return result;151 }152 153 ///
154 /// 更新给定的对象。155 ///
Update specified
.
156 ///
157 ///
要被更新的对象。
The object to be updated.
158 public virtual void Update(FileObject item)159 {160 string fileName = GenerateFileFullPath(item);161 string output = Serialize(item);162 163 lock (operationLock)164 {165 System.IO.FileInfo info = new System.IO.FileInfo(fileName);166 System.IO.Directory.CreateDirectory(info.Directory.FullName);167 System.IO.File.WriteAllText(fileName, output);168 }169 }170 171 ///
172 /// 删除指定的对象。173 ///
Delete specified
.
174 ///
175 ///
要被删除的对象。
The object to be deleted.
176 public virtual void Delete(FileObject item)177 {178 if (item == null)179 {180 throw new ArgumentNullException(item.ToString());181 }182 183 string filename = GenerateFileFullPath(item);184 if (File.Exists(filename))185 {186 lock (operationLock)187 {188 File.Delete(filename);189 }190 }191 }192 193 #endregion CRUD194 195 }
FileDBContext

 

文件存储方式(Way to store files)

SharpFileDB creates a directory for every table-types in the database's folder. Every instance of a table-type are stored in its respective directory as a single XML file. The file's name is same with the instance's Id.

 

 

下载(Download)

I've put the project on github() and you are welcom to try, create issues and fork it.

 

PS: I think this small file database library can help some people. It's where we are that needs us.

转载地址:http://cotym.baihongyu.com/

你可能感兴趣的文章
Lucene基础(2)
查看>>
Oracle 存储过程
查看>>
java基础 静态 static 问在多态中,子类静态方法覆盖父类静态方法时,父类引用调用的是哪个方法?...
查看>>
FlasCC发布说明
查看>>
如何在macOS Sierra中运行CORE Keygen破解程序
查看>>
终极解决方案:windows10资源管理器假死
查看>>
【java】一维数组循环位移方阵
查看>>
Essential Studio for mobile MVC中创建Razor应用程序平台教程
查看>>
java主函数的含义
查看>>
中国大学MOOC —— 学习笔记(四)
查看>>
访问,ringbtn,
查看>>
致橡树
查看>>
一段测试代码,哦哦哦,
查看>>
uiimagepickercontroller,中文,--》摘
查看>>
第四次作业
查看>>
在python中调用js或者nodejs
查看>>
【年终总结】2年计划还是要有的,万一实现了呢?(转自叶小钗)
查看>>
数字图像处理学习笔记(1.1)---位图的读写、几何变换、傅里叶变换、直方图均衡...
查看>>
javascript数组顺序-----1冒泡的另一种比较好理解的写法
查看>>
数据结构-栈的实现之行编译器核心实现
查看>>