ESENT: Add method CreateIndex

The index creation process has been separated into a dedicated method to improve readability and stability.
This commit is contained in:
Namhyeon Go 2025-06-24 11:30:27 +09:00
parent 3e4b6a73b5
commit 62d219f443

View File

@ -17,6 +17,9 @@ namespace WelsonJS.Launcher
{ {
public class MetadataStore : IDisposable public class MetadataStore : IDisposable
{ {
private const string _primaryKeyindexName = "primary";
private const string _indexNamePrefix = "idx_";
private static readonly object _lock = new object(); private static readonly object _lock = new object();
private static bool _initialized = false; private static bool _initialized = false;
private static Instance _instance; private static Instance _instance;
@ -105,23 +108,46 @@ namespace WelsonJS.Launcher
Api.JetAddColumn(_session, tableid, col.Name, coldef, null, 0, out _); Api.JetAddColumn(_session, tableid, col.Name, coldef, null, 0, out _);
} }
string indexName = "primary"; CreateIndex(tableid, new[] { _primaryKey }, CreateIndexGrbit.IndexPrimary | CreateIndexGrbit.IndexUnique);
string key = $"+{_primaryKey.Name}\0";
string keyDescription = key + "\0"; // double null-terminated Api.JetCloseTable(_session, tableid);
int keyDescriptionLength = Encoding.ASCII.GetByteCount(keyDescription); // in characters Api.JetCommitTransaction(_session, CommitTransactionGrbit.None);
}
public void CreateIndex(JET_TABLEID tableid, IEnumerable<Column> columns, CreateIndexGrbit grbit)
{
if (columns == null)
throw new ArgumentNullException(nameof(columns));
var columnList = columns.ToList();
if (columnList.Count == 0)
throw new ArgumentException("At least one column is required to create an index.", nameof(columns));
if (tableid == JET_TABLEID.Nil)
throw new ArgumentException("Invalid table ID.", nameof(tableid));
bool isPrimaryKeyIndex = (columnList.Count == 1 && columnList[0].IsPrimaryKey);
if (isPrimaryKeyIndex && (grbit & CreateIndexGrbit.IndexPrimary) == 0)
throw new ArgumentException("Primary key index must have the CreateIndexGrbit.IndexPrimary flag set.", nameof(grbit));
string indexName = isPrimaryKeyIndex
? _primaryKeyindexName
: _indexNamePrefix + string.Join("_", columnList.Select(c => c.Name));
string key = string.Concat(columnList.Select(c => "+" + c.Name));
string keyDescription = key + "\0\0"; // double null-terminated
int keyDescriptionLength = keyDescription.Length;
Api.JetCreateIndex( Api.JetCreateIndex(
_session, _session,
tableid, tableid,
indexName, indexName,
CreateIndexGrbit.IndexPrimary | CreateIndexGrbit.IndexUnique, grbit,
keyDescription, keyDescription,
keyDescriptionLength, keyDescriptionLength,
100 100
); );
Api.JetCloseTable(_session, tableid);
Api.JetCommitTransaction(_session, CommitTransactionGrbit.None);
} }
private void CacheColumns() private void CacheColumns()
@ -172,7 +198,7 @@ namespace WelsonJS.Launcher
{ {
Api.JetBeginTransaction(_session); Api.JetBeginTransaction(_session);
Api.JetSetCurrentIndex(_session, table, null); Api.JetSetCurrentIndex(_session, table, _primaryKeyindexName);
MakeKeyByType(keyValue, keyType, _session, table); MakeKeyByType(keyValue, keyType, _session, table);
bool found = Api.TrySeek(_session, table, SeekGrbit.SeekEQ); bool found = Api.TrySeek(_session, table, SeekGrbit.SeekEQ);
@ -197,8 +223,9 @@ namespace WelsonJS.Launcher
catch (Exception ex) catch (Exception ex)
{ {
Trace.TraceError($"[ESENT] Operation failed: {ex.Message}"); Trace.TraceError($"[ESENT] Operation failed: {ex.Message}");
MessageBox.Show($"[ESENT] Operation failed: {ex.Message}");
Api.JetRollback(_session, RollbackTransactionGrbit.None); Api.JetRollback(_session, RollbackTransactionGrbit.None);
MessageBox.Show($"[ESENT] Operation failed: {ex.Message}");
return false; return false;
} }
} }
@ -211,7 +238,7 @@ namespace WelsonJS.Launcher
using (var table = new Table(_session, _dbid, _schema.TableName, OpenTableGrbit.ReadOnly)) using (var table = new Table(_session, _dbid, _schema.TableName, OpenTableGrbit.ReadOnly))
{ {
Api.JetSetCurrentIndex(_session, table, null); Api.JetSetCurrentIndex(_session, table, _primaryKeyindexName);
MakeKeyByType(keyValue, keyType, _session, table); MakeKeyByType(keyValue, keyType, _session, table);
if (!Api.TrySeek(_session, table, SeekGrbit.SeekEQ)) if (!Api.TrySeek(_session, table, SeekGrbit.SeekEQ))
return null; return null;
@ -235,6 +262,8 @@ namespace WelsonJS.Launcher
using (var table = new Table(_session, _dbid, _schema.TableName, OpenTableGrbit.ReadOnly)) using (var table = new Table(_session, _dbid, _schema.TableName, OpenTableGrbit.ReadOnly))
{ {
Api.JetSetCurrentIndex(_session, table, _primaryKeyindexName);
if (!Api.TryMoveFirst(_session, table)) if (!Api.TryMoveFirst(_session, table))
return results; return results;
@ -263,7 +292,7 @@ namespace WelsonJS.Launcher
using (var table = new Table(_session, _dbid, _schema.TableName, OpenTableGrbit.Updatable)) using (var table = new Table(_session, _dbid, _schema.TableName, OpenTableGrbit.Updatable))
{ {
Api.JetSetCurrentIndex(_session, table, null); Api.JetSetCurrentIndex(_session, table, _primaryKeyindexName);
MakeKeyByType(keyValue, keyType, _session, table); MakeKeyByType(keyValue, keyType, _session, table);
if (!Api.TrySeek(_session, table, SeekGrbit.SeekEQ)) if (!Api.TrySeek(_session, table, SeekGrbit.SeekEQ))
return false; return false;