初始化 monorepo: Go后端(7微服务) + Unity客户端(9模块) + 启动器 HTML5原型: Three.js 3D体素世界, Perlin噪声地形, 原版材质, 22种方块 Minecraft创造模式背包: 双栏布局, 拖拽移动物品, 方向性元件引脚 AI助搭策划文档 + 客户端/服务端骨架 + Docker Compose + CI
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using LiteDB;
|
||||
|
||||
namespace PCL.Core.App.Database;
|
||||
|
||||
/// <summary>
|
||||
/// Base database connention entry.
|
||||
/// </summary>
|
||||
public abstract class DatabaseEntry : IDisposable
|
||||
{
|
||||
protected readonly LiteDatabase Db;
|
||||
private bool _disposed = false;
|
||||
|
||||
/// <exception cref="ArgumentNullException">Throw if connection path is invalid.</exception>
|
||||
protected DatabaseEntry(string connPath)
|
||||
{
|
||||
var db = DatabaseService.GetConnection(connPath);
|
||||
Db = db ?? throw new ArgumentNullException(nameof(db), "Database variable can not be null.");
|
||||
}
|
||||
|
||||
/// <exception cref="ArgumentNullException">Throw if connection path is invalid.</exception>
|
||||
protected DatabaseEntry(LiteDatabase database)
|
||||
{
|
||||
Db = database ?? throw new ArgumentNullException(nameof(database), "Database variable can not be null.");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
// NOTE: do not dispose Db, because it is managed by DatabaseService
|
||||
}
|
||||
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using LiteDB;
|
||||
using PCL.Core.App.IoC;
|
||||
|
||||
namespace PCL.Core.App.Database;
|
||||
|
||||
[LifecycleService(LifecycleState.Loading)]
|
||||
public class DatabaseService() : GeneralService("database", "数据库管理")
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, LiteDatabase> _Instances = new();
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Stop()
|
||||
{
|
||||
foreach (var instance in _Instances.Values)
|
||||
{
|
||||
instance.Dispose();
|
||||
}
|
||||
|
||||
_Instances.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the database connenction from specified connection path.<br/>
|
||||
/// If not exists, a new connection will be created and cached.
|
||||
/// </summary>
|
||||
/// <returns>Getted connenction instance.</returns>
|
||||
/// <exception cref="ArgumentException">Throw if connection path is invalid.</exception>
|
||||
public static LiteDatabase GetConnection(string connectionPath)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(connectionPath))
|
||||
{
|
||||
throw new ArgumentException("Connection string canot be null or whitespace.", nameof(connectionPath));
|
||||
}
|
||||
|
||||
return _Instances.GetOrAdd(connectionPath, cp => new LiteDatabase(cp));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
# Database Guildline
|
||||
This is a light database management guildline for PCL.Core. It is not a strict rule, but a recommendation to follow.
|
||||
## How to create a new database
|
||||
1. You need create a class that inheritance from `DatabaseEntry`.
|
||||
2. Then make a ctor that call `base(<connPath>)` with the connection path.
|
||||
3. Now this class is ready to use. (Yes it is that simple, and will automatically create the database file if not exists)
|
||||
|
||||
## DatabaseEntry
|
||||
The `DatabaseEntry` class is the entrance to use the database.
|
||||
User must implement a class that inheritance from `DatabaseEntry` to use it.
|
||||
And the child class should implement there own method to provide some ways to interact with the database.
|
||||
|
||||
## A Normal Example
|
||||
```charp
|
||||
public class UserDatabase : DatabaseEntry
|
||||
{
|
||||
public UserDatabase() : base("example.db")
|
||||
{
|
||||
// You can do some initialization here.
|
||||
// Like create table if not exists,
|
||||
// or anything else.
|
||||
}
|
||||
|
||||
|
||||
public List<(int Id, string Name, int Age)> GetAllUsers()
|
||||
{
|
||||
// In your method, you shoul provide some way to interact with the database.
|
||||
}
|
||||
}
|
||||
```
|
||||
Then, you can use it like this:
|
||||
```charp
|
||||
var db = new UserDatabase();
|
||||
var users = db.GetAlUsers();
|
||||
```
|
||||
Reference in New Issue
Block a user