Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/LightningDB.Tests/DatabaseTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ public void can_get_database_flags()
// Test default database (should have no special flags)
using (var txn = env.BeginTransaction())
{
using var db = txn.OpenDatabase(null, new DatabaseConfiguration { Flags = DatabaseOpenFlags.Create });
using var db = txn.OpenDatabase(new DatabaseConfiguration { Flags = DatabaseOpenFlags.Create });

var flags = db.GetFlags(txn);
flags.ShouldBe(DatabaseOpenFlags.None);
Expand Down
16 changes: 8 additions & 8 deletions src/LightningDB.Tests/EnvironmentTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public void can_put_multiple_key_value_pairs_and_flush_successfully()
env.Open();

using var tx = env.BeginTransaction();
using var db = tx.OpenDatabase(null, new DatabaseConfiguration { Flags = DatabaseOpenFlags.Create });
using var db = tx.OpenDatabase(new DatabaseConfiguration { Flags = DatabaseOpenFlags.Create });

for (int i = 0; i < 5; i++)
{
Expand Down Expand Up @@ -250,7 +250,7 @@ public void can_copy_to_file_stream()

// Add some data to the source environment
using (var tx = sourceEnv.BeginTransaction())
using (var db = tx.OpenDatabase(null, new DatabaseConfiguration { Flags = DatabaseOpenFlags.Create }))
using (var db = tx.OpenDatabase(new DatabaseConfiguration { Flags = DatabaseOpenFlags.Create }))
{
for (int i = 0; i < 5; i++)
{
Expand All @@ -263,7 +263,7 @@ public void can_copy_to_file_stream()
var tempFilePath = Path.Combine(TempPath(), "env_copy.mdb");

// Ensure directory exists
Directory.CreateDirectory(Path.GetDirectoryName(tempFilePath));
Directory.CreateDirectory(Path.GetDirectoryName(tempFilePath)!);

// Create a FileStream to the destination file
using (var fileStream = new FileStream(tempFilePath, FileMode.Create, FileAccess.ReadWrite))
Expand All @@ -286,7 +286,7 @@ public void can_copy_with_compaction_to_file_stream()

// Add some data to the source environment and then delete half of it to create free space
using (var tx = sourceEnv.BeginTransaction())
using (var db = tx.OpenDatabase(null, new DatabaseConfiguration { Flags = DatabaseOpenFlags.Create }))
using (var db = tx.OpenDatabase(new DatabaseConfiguration { Flags = DatabaseOpenFlags.Create }))
{
for (int i = 0; i < 10; i++)
{
Expand All @@ -310,7 +310,7 @@ public void can_copy_with_compaction_to_file_stream()
var tempFilePath = Path.Combine(TempPath(), "env_copy_compact.mdb");

// Ensure directory exists
Directory.CreateDirectory(Path.GetDirectoryName(tempFilePath));
Directory.CreateDirectory(Path.GetDirectoryName(tempFilePath)!);

// Create a FileStream to the destination file
using (var fileStream = new FileStream(tempFilePath, FileMode.Create, FileAccess.ReadWrite))
Expand All @@ -333,7 +333,7 @@ public void can_get_environment_file_stream()

// Add some data to make sure the file has content
using (var tx = env.BeginTransaction())
using (var db = tx.OpenDatabase(null, new DatabaseConfiguration { Flags = DatabaseOpenFlags.Create }))
using (var db = tx.OpenDatabase(new DatabaseConfiguration { Flags = DatabaseOpenFlags.Create }))
{
tx.Put(db, "testkey", "testvalue");
tx.Commit();
Expand All @@ -360,8 +360,8 @@ public void stream_throws_exception_for_null_argument()
using var env = CreateEnvironment();
env.Open();

// Null FileStream
Should.Throw<ArgumentNullException>(() => env.CopyToStream(null));
// Null FileStream - intentionally passing null to verify exception behavior
Should.Throw<ArgumentNullException>(() => env.CopyToStream(null!));
}

public void stream_throws_exception_for_read_only_file_stream()
Expand Down
1 change: 1 addition & 0 deletions src/LightningDB.Tests/LightningDB.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<PropertyGroup>
<TargetFrameworks>net8.0;net9.0;net10.0</TargetFrameworks>
<LangVersion>13</LangVersion>
<Nullable>enable</Nullable>
<AssemblyName>LightningDB.Tests</AssemblyName>
<PackageId>LightningDB.Tests</PackageId>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
Expand Down
4 changes: 2 additions & 2 deletions src/LightningDB.Tests/TestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ protected string TempPath(string seed = "")
Directory.CreateDirectory(path);
return path;
}
protected LightningEnvironment CreateEnvironment(string path = null, EnvironmentConfiguration config = null) =>
new(path ?? TempPath(), config);
protected LightningEnvironment CreateEnvironment(string? path = null, EnvironmentConfiguration? config = null) =>
config is null ? new(path ?? TempPath()) : new(path ?? TempPath(), config);

public static void CleanupSession()
{
Expand Down
8 changes: 4 additions & 4 deletions src/LightningDB.Tests/TestHelperExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ public static bool ContainsKey(this LightningTransaction tx, LightningDatabase d
return tx.ContainsKey(db, enc.GetBytes(key));
}

public static bool TryGet(this LightningTransaction tx, LightningDatabase db, string key, out string value)
public static bool TryGet(this LightningTransaction tx, LightningDatabase db, string key, out string? value)
{
var enc = System.Text.Encoding.UTF8;
var found = tx.TryGet(db, enc.GetBytes(key), out var result);
value = enc.GetString(result);
value = result is not null ? enc.GetString(result) : null;
return found;
}

Expand All @@ -52,7 +52,7 @@ public static void RunCursorScenario(this LightningEnvironment env,
DatabaseOpenFlags flags = DatabaseOpenFlags.Create, TransactionBeginFlags transactionFlags = TransactionBeginFlags.None)
{
using var tx = env.BeginTransaction(transactionFlags);
using var db = tx.OpenDatabase(configuration: new DatabaseConfiguration { Flags = flags });
using var db = tx.OpenDatabase(new DatabaseConfiguration { Flags = flags });
using var cursor = tx.CreateCursor(db);
scenario(tx, db, cursor);
}
Expand All @@ -62,7 +62,7 @@ public static void RunTransactionScenario(this LightningEnvironment env,
DatabaseOpenFlags flags = DatabaseOpenFlags.Create, TransactionBeginFlags transactionFlags = TransactionBeginFlags.None)
{
using var tx = env.BeginTransaction(transactionFlags);
using var db = tx.OpenDatabase(configuration: new DatabaseConfiguration { Flags = flags });
using var db = tx.OpenDatabase(new DatabaseConfiguration { Flags = flags });
scenario(tx, db);
}
}
8 changes: 4 additions & 4 deletions src/LightningDB/DatabaseConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ namespace LightningDB;
/// </summary>
public class DatabaseConfiguration
{
private IComparer<MDBValue> _comparer;
private IComparer<MDBValue> _duplicatesComparer;
private IComparer<MDBValue>? _comparer;
private IComparer<MDBValue>? _duplicatesComparer;

public DatabaseConfiguration()
{
Expand Down Expand Up @@ -51,12 +51,12 @@ internal IDisposable ConfigureDatabase(LightningTransaction tx, LightningDatabas

private int Compare(ref MDBValue left, ref MDBValue right)
{
return _comparer.Compare(left, right);
return _comparer!.Compare(left, right);
}

private int IsDuplicate(ref MDBValue left, ref MDBValue right)
{
return _duplicatesComparer.Compare(left, right);
return _duplicatesComparer!.Compare(left, right);
}

/// <summary>
Expand Down
2 changes: 2 additions & 0 deletions src/LightningDB/LightningDB.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<Authors>Ilya Lukyanov;Corey Kaylor</Authors>
<TargetFrameworks>netstandard2.0;net8.0;net9.0;net10.0</TargetFrameworks>
<LangVersion>14</LangVersion>
<Nullable>enable</Nullable>
<AssemblyName>LightningDB</AssemblyName>
<PackageId>LightningDB</PackageId>
<PackageIcon>lightningdb.png</PackageIcon>
Expand Down Expand Up @@ -34,5 +35,6 @@

<ItemGroup>
<PackageReference Include="System.Memory" Version="4.6.0" Condition="'$(TargetFramework)' == 'netstandard2.0'" />
<PackageReference Include="PolySharp" Version="1.14.1" PrivateAssets="all" Condition="'$(TargetFramework)' == 'netstandard2.0'" />
</ItemGroup>
</Project>
4 changes: 2 additions & 2 deletions src/LightningDB/LightningDatabase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public sealed class LightningDatabase : IDisposable
/// <param name="transaction">Active transaction.</param>
/// <param name="configuration">Options for the database, like encoding, option flags, and comparison logic.</param>
/// <param name="closeOnDispose">Close database handle on dispose</param>
internal LightningDatabase(string name, LightningTransaction transaction, DatabaseConfiguration configuration,
internal LightningDatabase(string? name, LightningTransaction transaction, DatabaseConfiguration configuration,
bool closeOnDispose)
{
if (transaction == null)
Expand Down Expand Up @@ -55,7 +55,7 @@ internal LightningDatabase(string name, LightningTransaction transaction, Databa
/// <summary>
/// Database name.
/// </summary>
public string Name { get; }
public string? Name { get; }

/// <summary>
/// Environment in which the database was opened.
Expand Down
61 changes: 40 additions & 21 deletions src/LightningDB/LightningEnvironment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,38 @@ public sealed class LightningEnvironment : IDisposable

internal nint _handle;

/// <summary>
/// Creates a new instance of LightningEnvironment with default configuration.
/// </summary>
/// <param name="path">Directory for storing database files.</param>
public LightningEnvironment(string path)
{
if (string.IsNullOrWhiteSpace(path))
throw new ArgumentException("Invalid directory name");

mdb_env_create(out _handle).ThrowOnError();
_config.Configure(this);

Path = path;
}

/// <summary>
/// Creates a new instance of LightningEnvironment.
/// </summary>
/// <param name="path">Directory for storing database files.</param>
/// <param name="configuration">Configuration for the environment.</param>
public LightningEnvironment(string path, EnvironmentConfiguration configuration = null)
public LightningEnvironment(string path, EnvironmentConfiguration configuration)
{
if (string.IsNullOrWhiteSpace(path))
throw new ArgumentException("Invalid directory name");

var config = configuration ?? _config;
if (configuration == null)
throw new ArgumentNullException(nameof(configuration));

mdb_env_create(out _handle).ThrowOnError();
config.Configure(this);
_config = config;
configuration.Configure(this);
_config = configuration;

Path = path;

}

/// <summary>
Expand Down Expand Up @@ -218,47 +232,52 @@ public void Open(EnvironmentOpenFlags openFlags = EnvironmentOpenFlags.None, Uni
}

/// <summary>
/// Create a transaction for use with the environment.
/// Create a top-level transaction for use with the environment.
/// The transaction handle may be discarded using Abort() or Commit().
/// Note:
/// Transactions may not span threads; a transaction must only be used by a single thread. Also, a thread may only have a single transaction.
/// Cursors may not span transactions; each cursor must be opened and closed within a single transaction.
/// </summary>
/// <param name="parent">
/// If this parameter is non-NULL, the new transaction will be a nested transaction, with the transaction indicated by parent as its parent.
/// Transactions may be nested to any level.
/// A parent transaction may not issue any other operations besides BeginTransaction, Abort, or Commit while it has active child transactions.
/// </param>
/// <param name="beginFlags">
/// Special options for this transaction.
/// </param>
/// <returns>
/// New LightningTransaction
/// </returns>
public LightningTransaction BeginTransaction(LightningTransaction parent = null, TransactionBeginFlags beginFlags = LightningTransaction.DefaultTransactionBeginFlags)
public LightningTransaction BeginTransaction(TransactionBeginFlags beginFlags = LightningTransaction.DefaultTransactionBeginFlags)
{
if (!IsOpened)
throw new InvalidOperationException("Environment must be opened before starting a transaction");

return new LightningTransaction(this, parent, beginFlags);
return BeginTransactionImpl(null, beginFlags);
}

/// <summary>
/// Create a transaction for use with the environment.
/// The transaction handle may be discarded usingAbort() or Commit().
/// Create a nested transaction for use with the environment.
/// The transaction handle may be discarded using Abort() or Commit().
/// Note:
/// Transactions may not span threads; a transaction must only be used by a single thread. Also, a thread may only have a single transaction.
/// Cursors may not span transactions; each cursor must be opened and closed within a single transaction.
/// </summary>
/// <param name="parent">
/// The parent transaction. The new transaction will be a nested transaction.
/// Transactions may be nested to any level.
/// A parent transaction may not issue any other operations besides BeginTransaction, Abort, or Commit while it has active child transactions.
/// </param>
/// <param name="beginFlags">
/// Special options for this transaction.
/// </param>
/// <returns>
/// New LightningTransaction
/// </returns>
public LightningTransaction BeginTransaction(TransactionBeginFlags beginFlags)
public LightningTransaction BeginTransaction(LightningTransaction parent, TransactionBeginFlags beginFlags = LightningTransaction.DefaultTransactionBeginFlags)
{
return BeginTransactionImpl(parent, beginFlags);
}

private LightningTransaction BeginTransactionImpl(LightningTransaction? parent, TransactionBeginFlags beginFlags)
{
return BeginTransaction(null, beginFlags);
if (!IsOpened)
throw new InvalidOperationException("Environment must be opened before starting a transaction");

return new LightningTransaction(this, parent, beginFlags);
}

/// <summary>
Expand Down
8 changes: 4 additions & 4 deletions src/LightningDB/LightningExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public static (MDBResultCode resultCode, MDBValue key, MDBValue value) ThrowOnRe
private static string mdb_strerror(int err)
{
var ptr = Lmdb.mdb_strerror(err);
return Marshal.PtrToStringAnsi(ptr);
return Marshal.PtrToStringAnsi(ptr) ?? $"Unknown error {err}";
}

/// <summary>
Expand Down Expand Up @@ -124,11 +124,11 @@ private static IEnumerable<MDBValue> AllValuesForImpl(this LightningCursor curso
/// <param name="value">A byte array containing the value found in the database, if it exists.</param>
/// <returns>True if key exists, false if not.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryGet(this LightningTransaction tx, LightningDatabase db, byte[] key, out byte[] value)
public static bool TryGet(this LightningTransaction tx, LightningDatabase db, byte[] key, out byte[]? value)
{
return TryGet(tx, db, key.AsSpan(), out value);
}

/// <summary>
/// Tries to get a value by its key.
/// </summary>
Expand All @@ -138,7 +138,7 @@ public static bool TryGet(this LightningTransaction tx, LightningDatabase db, by
/// <param name="value">A byte array containing the value found in the database, if it exists.</param>
/// <returns>True if key exists, false if not.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryGet(this LightningTransaction tx, LightningDatabase db, ReadOnlySpan<byte> key, out byte[] value)
public static bool TryGet(this LightningTransaction tx, LightningDatabase db, ReadOnlySpan<byte> key, out byte[]? value)
{
var (resultCode, _, mdbValue) = tx.Get(db, key);
if (resultCode == MDBResultCode.Success)
Expand Down
Loading