Update EsentDatabase specs

This commit is contained in:
Namhyeon Go 2025-06-26 10:22:07 +09:00
parent 91ce125c7f
commit 82df8c5605
13 changed files with 248 additions and 23 deletions

View File

@ -1,6 +1,6 @@
// Column.cs (WelsonJS.Esent)
// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: 2025 Namhyeon Go, Catswords OSS and WelsonJS Contributors
// SPDX-FileCopyrightText: 2025 Namhyeon Go <gnh1201@catswords.re.kr>, Catswords OSS and WelsonJS Contributors
// https://github.com/gnh1201/welsonjs
//
using System;

View File

@ -1,6 +1,6 @@
// DataStore.cs (WelsonJS.Esent)
// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: 2025 Namhyeon Go, Catswords OSS and WelsonJS Contributors
// SPDX-FileCopyrightText: 2025 Namhyeon Go <gnh1201@catswords.re.kr>, Catswords OSS and WelsonJS Contributors
// https://github.com/gnh1201/welsonjs
//
using System;
@ -13,11 +13,13 @@ using Microsoft.Isam.Esent.Interop;
namespace WelsonJS.Esent
{
public class DataStore : IDisposable
public class EsentDatabase : IDisposable
{
private const string _primaryKeyindexName = "primary";
private const string _indexNamePrefix = "idx_";
private const string _databaseName = "metadata.edb";
private readonly ICompatibleLogger _logger;
private static readonly object _lock = new object();
private static bool _initialized = false;
private static Instance _instance;
@ -30,8 +32,10 @@ namespace WelsonJS.Esent
private readonly Column _primaryKey;
private readonly Dictionary<string, JET_COLUMNID> _columnIds;
public DataStore(Schema schema, string workingDirectory)
public EsentDatabase(Schema schema, string workingDirectory, ICompatibleLogger logger = null)
{
_logger = logger ?? new TraceLogger();
_primaryKey = schema.PrimaryKey;
if (schema == null)
@ -74,10 +78,10 @@ namespace WelsonJS.Esent
if (_initialized) return;
// set the file path
_filePath = Path.Combine(_workingDirectory, "metadata.edb");
_filePath = Path.Combine(_workingDirectory, _databaseName);
// config the instance
_instance = new Instance("WelsonJS.Launcher.MetadataStore");
_instance = new Instance(typeof(EsentDatabase).Namespace);
_instance.Parameters.SystemDirectory = _workingDirectory;
_instance.Parameters.LogFileDirectory = _workingDirectory;
_instance.Parameters.TempDirectory = _workingDirectory;
@ -160,7 +164,7 @@ namespace WelsonJS.Esent
}
catch (EsentColumnNotFoundException)
{
Trace.TraceWarning($"Column '{col.Name}' not found.");
_logger.Warn($"Column '{col.Name}' not found.");
}
}
}
@ -201,7 +205,7 @@ namespace WelsonJS.Esent
if (expectSeek != found)
{
Trace.TraceWarning($"[ESENT] Operation skipped. Seek result = {found}, expected = {expectSeek}");
_logger.Warn($"[ESENT] Operation skipped. Seek result = {found}, expected = {expectSeek}");
Api.JetRollback(_session, RollbackTransactionGrbit.None);
return false;
}
@ -312,7 +316,7 @@ namespace WelsonJS.Esent
case JET_coltyp.LongBinary:
return Api.RetrieveColumn(session, table, columnId);
default:
Trace.TraceWarning($"[ESENT] Unsupported RetrieveColumn type: {type}");
_logger.Warn($"[ESENT] Unsupported RetrieveColumn type: {type}");
return null;
}
}
@ -323,13 +327,13 @@ namespace WelsonJS.Esent
if (!values.TryGetValue(_primaryKey.Name, out keyValue))
{
Trace.TraceWarning($"[ESENT] Missing primary key '{_primaryKey.Name}'.");
_logger.Warn($"[ESENT] Missing primary key '{_primaryKey.Name}'.");
return false;
}
if (keyValue == null)
{
Trace.TraceWarning("[ESENT] Primary key value cannot be null.");
_logger.Warn("[ESENT] Primary key value cannot be null.");
return false;
}
@ -351,7 +355,7 @@ namespace WelsonJS.Esent
{
if (!_columnIds.TryGetValue(kv.Key, out var colid))
{
Trace.TraceWarning($"[ESENT] Column '{kv.Key}' not found in cache.");
_logger.Warn($"[ESENT] Column '{kv.Key}' not found in cache.");
continue;
}
@ -384,7 +388,7 @@ namespace WelsonJS.Esent
Api.SetColumn(session, table, columnId, (byte[])value);
break;
default:
Trace.TraceWarning($"[ESENT] Unsupported SetColumn type: {type}");
_logger.Warn($"[ESENT] Unsupported SetColumn type: {type}");
break;
}
}
@ -410,7 +414,7 @@ namespace WelsonJS.Esent
Api.MakeKey(session, table, (byte[])value, MakeKeyGrbit.NewKey);
break;
default:
Trace.TraceWarning($"[ESENT] Unsupported MakeKey type: {type}");
_logger.Warn($"[ESENT] Unsupported MakeKey type: {type}");
break;
}
}

View File

@ -0,0 +1,17 @@
// ICompatibleLogger.cs (WelsonJS.Esent)
// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: 2025 Namhyeon Go <gnh1201@catswords.re.kr>, Catswords OSS and WelsonJS Contributors
// https://github.com/gnh1201/welsonjs
//
// We use the ICompatibleLogger interface to maintain a BCL-first style.
// This allows for later replacement with logging libraries such as ILogger or Log4Net.
//
namespace WelsonJS.Esent
{
public interface ICompatibleLogger
{
void Info(string message);
void Warn(string message);
void Error(string message);
}
}

View File

@ -0,0 +1,58 @@
# WelsonJS.Esent
WelsonJS.Esent is a library that enables the use of the [ESENT](https://learn.microsoft.com/en-us/windows/win32/extensible-storage-engine/extensible-storage-engine) database (also known as the Extensible Storage Engine or JET Blue).
Although it was developed to support the WelsonJS framework, it can be used in any .NET-based project.
For more details, refer to the [WelsonJS Documentation](https://catswords-oss.rdbl.io/5719744820/5330609327).
## Example code
```csharp
using WelsonJS.Esent;
// connect the database to manage an instances
Schema schema = new Schema("Instances", new List<Column>
{
new Column("InstanceId", typeof(string), 255),
new Column("FirstDeployTime", typeof(DateTime), 1)
});
schema.SetPrimaryKey("InstanceId");
_db = new EsentDatabase(schema, Path.GetTempPath());
// Insert row
try
{
_db.Insert(new Dictionary<string, object>
{
["InstanceId"] = instanceId,
["FirstDeployTime"] = now
}, out _);
}
catch (Exception ex)
{
// Handle exception
}
// find all
var instances = _db.FindAll();
foreach (var instance in instances)
{
try
{
string instanceId = instance["InstanceId"].ToString();
string firstDeployTime = instance.ContainsKey("FirstDeployTime")
? ((DateTime)instance["FirstDeployTime"]).ToString(_dateTimeFormat)
: "Unknown";
Console.WriteLine($"{firstDeployTime}, {instanceId}");
}
catch (Exception ex)
{
// Handle exception
}
}
```
Source code available: https://github.com/gnh1201/welsonjs

View File

@ -1,6 +1,6 @@
// Schema.cs (WelsonJS.Esent)
// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: 2025 Namhyeon Go, Catswords OSS and WelsonJS Contributors
// SPDX-FileCopyrightText: 2025 Namhyeon Go <gnh1201@catswords.re.kr>, Catswords OSS and WelsonJS Contributors
// https://github.com/gnh1201/welsonjs
//
using System;

View File

@ -0,0 +1,19 @@
// TraceLogger.cs (WelsonJS.Esent)
// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: 2025 Namhyeon Go <gnh1201@catswords.re.kr>, Catswords OSS and WelsonJS Contributors
// https://github.com/gnh1201/welsonjs
//
// We use the ICompatibleLogger interface to maintain a BCL-first style.
// This allows for later replacement with logging libraries such as ILogger or Log4Net.
//
using System.Diagnostics;
namespace WelsonJS.Esent
{
public class TraceLogger : ICompatibleLogger
{
public void Info(string message) => Trace.TraceInformation(message);
public void Warn(string message) => Trace.TraceWarning(message);
public void Error(string message) => Trace.TraceError(message);
}
}

View File

@ -0,0 +1,39 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<Platforms>AnyCPU;x86</Platforms>
<Title>WelsonJS.Esent</Title>
<PackageProjectUrl>https://github.com/gnh1201/welsonjs</PackageProjectUrl>
<RepositoryUrl>https://github.com/gnh1201/welsonjs</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>nosql,esent,database</PackageTags>
<AssemblyVersion>0.2.7.55</AssemblyVersion>
<FileVersion>0.2.7.55</FileVersion>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<Copyright>2025 Namhyeon Go, Catswords OSS and WelsonJS Contributors</Copyright>
<Description>Enable ESENT database engine</Description>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Authors>Namhyeon Go,Catswords OSS</Authors>
<PackageIcon></PackageIcon>
<PackageReadmeFile></PackageReadmeFile>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\EsentInterop\EsentInterop.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="assets\docs\README.md">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</None>
<None Update="assets\img\logo.png">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@ -4,10 +4,40 @@
<TargetFramework>netstandard2.0</TargetFramework>
<Platforms>AnyCPU;x86</Platforms>
<Title>WelsonJS.Esent</Title>
<PackageProjectUrl>https://github.com/gnh1201/welsonjs</PackageProjectUrl>
<RepositoryUrl>https://github.com/gnh1201/welsonjs</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>nosql,esent,database</PackageTags>
<AssemblyVersion>0.2.7.55</AssemblyVersion>
<FileVersion>0.2.7.55</FileVersion>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<Copyright>2025 Namhyeon Go, Catswords OSS and WelsonJS Contributors</Copyright>
<Description>Enable ESENT database engine</Description>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Authors>Namhyeon Go,Catswords OSS</Authors>
<PackageIcon></PackageIcon>
<PackageReadmeFile></PackageReadmeFile>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\EsentInterop\EsentInterop.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="assets\docs\README.md">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</None>
<None Update="assets\img\logo.png">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</None>
<None Update="README.md">
<PackagePath>\</PackagePath>
<Pack>True</Pack>
</None>
</ItemGroup>
</Project>

View File

@ -0,0 +1,58 @@
# WelsonJS.Esent
WelsonJS.Esent is a library that enables the use of the [ESENT](https://learn.microsoft.com/en-us/windows/win32/extensible-storage-engine/extensible-storage-engine) database (also known as the Extensible Storage Engine or JET Blue).
Although it was developed to support the WelsonJS framework, it can be used in any .NET-based project.
For more details, refer to the [WelsonJS Documentation](https://catswords-oss.rdbl.io/5719744820/5330609327).
## Example code
```csharp
using WelsonJS.Esent;
// connect the database to manage an instances
Schema schema = new Schema("Instances", new List<Column>
{
new Column("InstanceId", typeof(string), 255),
new Column("FirstDeployTime", typeof(DateTime), 1)
});
schema.SetPrimaryKey("InstanceId");
_db = new EsentDatabase(schema, Path.GetTempPath());
// Insert row
try
{
_db.Insert(new Dictionary<string, object>
{
["InstanceId"] = instanceId,
["FirstDeployTime"] = now
}, out _);
}
catch (Exception ex)
{
// Handle exception
}
// find all
var instances = _db.FindAll();
foreach (var instance in instances)
{
try
{
string instanceId = instance["InstanceId"].ToString();
string firstDeployTime = instance.ContainsKey("FirstDeployTime")
? ((DateTime)instance["FirstDeployTime"]).ToString(_dateTimeFormat)
: "Unknown";
Console.WriteLine($"{firstDeployTime}, {instanceId}");
}
catch (Exception ex)
{
// Handle exception
}
}
```
Source code available: https://github.com/gnh1201/welsonjs

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -15,7 +15,7 @@
{
if (disposing && (components != null))
{
_dataStore?.Dispose(); // dispose the database session
_db?.Dispose(); // dispose the database session
components.Dispose();
}
base.Dispose(disposing);

View File

@ -18,7 +18,7 @@ namespace WelsonJS.Launcher
private string _entryFileName;
private string _scriptName;
private readonly string _dateTimeFormat;
private readonly DataStore _dataStore;
private readonly EsentDatabase _db;
public InstancesForm()
{
@ -37,12 +37,12 @@ namespace WelsonJS.Launcher
new Column("FirstDeployTime", typeof(DateTime), 1)
});
schema.SetPrimaryKey("InstanceId");
_dataStore = new DataStore(schema, Program.GetAppDataPath());
_db = new EsentDatabase(schema, Program.GetAppDataPath());
}
public DataStore GetDataStore()
public EsentDatabase GetDatabaseInstance()
{
return _dataStore;
return _db;
}
private void InstancesForm_Load(object sender, EventArgs e)
@ -53,7 +53,7 @@ namespace WelsonJS.Launcher
private void LoadInstances()
{
var instances = _dataStore.FindAll();
var instances = _db.FindAll();
foreach (var instance in instances)
{
try
@ -135,7 +135,7 @@ namespace WelsonJS.Launcher
try
{
Directory.Delete(workingDirectory, true);
_dataStore.DeleteById(instanceId);
_db.DeleteById(instanceId);
}
catch (Exception ex)
{

View File

@ -169,7 +169,7 @@ namespace WelsonJS.Launcher
InstancesForm instancesForm = new InstancesForm();
try
{
instancesForm.GetDataStore().Insert(new Dictionary<string, object>
instancesForm.GetDatabaseInstance().Insert(new Dictionary<string, object>
{
["InstanceId"] = instanceId,
["FirstDeployTime"] = now