Skip to content
Draft
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
23 changes: 16 additions & 7 deletions LiteDB.Shell/Shell/Display.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,26 +46,35 @@ public void WriteError(Exception ex)

public void WriteResult(IBsonDataReader result, Env env)
{
if (result == null) throw new ArgumentNullException(nameof(result));

var index = 0;
var writer = new JsonWriter(Console.Out)
{
Pretty = this.Pretty,
Indent = 2
};

foreach (var item in result.ToEnumerable())
try
{
if (env.Running == false) return;
while (result.Read())
{
if (env.Running == false) return;

this.Write(ConsoleColor.Cyan, string.Format("[{0}]: ", ++index));
this.Write(ConsoleColor.Cyan, string.Format("[{0}]: ", ++index));

if (this.Pretty) Console.WriteLine();
if (this.Pretty) Console.WriteLine();

Console.ForegroundColor = ConsoleColor.DarkCyan;
Console.ForegroundColor = ConsoleColor.DarkCyan;

writer.Serialize(item);
writer.Serialize(result.Current);

Console.WriteLine();
Console.WriteLine();
}
}
finally
{
result.Dispose();
}
}

Expand Down
68 changes: 42 additions & 26 deletions LiteDB.Tests/Database/Storage_Tests.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Threading.Tasks;
using FluentAssertions;
using LiteDB.Tests.Utils;
using Xunit;
Expand Down Expand Up @@ -29,49 +30,64 @@ public Storage_Tests()
}

[Fact]
public void Storage_Upload_Download()
public async Task Storage_Upload_Download()
{
using (var db = DatabaseFactory.Create())
//using (var db = new LiteDatabase(@"c:\temp\file.db"))
await using (var db = DatabaseFactory.Create())
{
var fs = db.GetStorage<int>("_files", "_chunks");

var small = fs.Upload(10, "photo_small.png", new MemoryStream(_smallFile));
var big = fs.Upload(100, "photo_big.png", new MemoryStream(_bigFile));
var small = await fs.UploadAsync(10, "photo_small.png", new MemoryStream(_smallFile));
var big = await fs.UploadAsync(100, "photo_big.png", new MemoryStream(_bigFile));

_smallFile.Length.Should().Be((int) small.Length);
_bigFile.Length.Should().Be((int) big.Length);
_smallFile.Length.Should().Be((int)small.Length);
_bigFile.Length.Should().Be((int)big.Length);

var f0 = fs.Find(x => x.Filename == "photo_small.png").First();
var f1 = fs.Find(x => x.Filename == "photo_big.png").First();
var f0 = await FirstAsync(fs.FindAsync(x => x.Filename == "photo_small.png"));
var f1 = await FirstAsync(fs.FindAsync(x => x.Filename == "photo_big.png"));

this.HashFile(f0.OpenRead()).Should().Be(_smallHash);
this.HashFile(f1.OpenRead()).Should().Be(_bigHash);
await using (var reader0 = await f0.OpenReadAsync())
{
var hash = await this.HashFileAsync(reader0);
hash.Should().Be(_smallHash);
}

// now replace small content with big-content
var repl = fs.Upload(10, "new_photo.jpg", new MemoryStream(_bigFile));
await using (var reader1 = await f1.OpenReadAsync())
{
var hash = await this.HashFileAsync(reader1);
hash.Should().Be(_bigHash);
}

fs.Exists(10).Should().BeTrue();
var repl = await fs.UploadAsync(10, "new_photo.jpg", new MemoryStream(_bigFile));

var nrepl = fs.FindById(10);
(await fs.ExistsAsync(10)).Should().BeTrue();

var nrepl = await fs.FindByIdAsync(10);

nrepl.Chunks.Should().Be(repl.Chunks);

// update metadata
fs.SetMetadata(100, new BsonDocument {["x"] = 100, ["y"] = 99});
await fs.SetMetadataAsync(100, new BsonDocument { ["x"] = 100, ["y"] = 99 });

// find using metadata
var md = fs.Find(x => x.Metadata["x"] == 100).FirstOrDefault();
var md = await FirstAsync(fs.FindAsync(x => x.Metadata["x"] == 100));

md.Metadata["y"].AsInt32.Should().Be(99);
}
}

private string HashFile(Stream stream)
private static async Task<LiteFileInfo<int>> FirstAsync(IAsyncEnumerable<LiteFileInfo<int>> source)
{
await foreach (var item in source)
{
return item;
}

return null;
}

private async Task<string> HashFileAsync(Stream stream)
{
var m = new MemoryStream();
stream.CopyTo(m);
return this.HashFile(m.ToArray());
await using var memory = new MemoryStream();
await stream.CopyToAsync(memory);
return this.HashFile(memory.ToArray());
}

private string HashFile(byte[] input)
Expand All @@ -83,4 +99,4 @@ private string HashFile(byte[] input)
}
}
}
}
}
2 changes: 1 addition & 1 deletion LiteDB.Tests/Issues/Issue2112_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public void Deserialize_covariant_collection_succeed()

var deserialized = _mapper.Deserialize<IA>(serialized);

Assert.Equal(1, deserialized.Bs.Count);
Assert.Single(deserialized.Bs);
}

interface IA
Expand Down
2 changes: 2 additions & 0 deletions LiteDB.Tests/Issues/Issue2265_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using LiteDB.Tests.Utils;
using Xunit;

#nullable enable

namespace LiteDB.Tests.Issues;

// issue 2265
Expand Down
51 changes: 26 additions & 25 deletions LiteDB.Tests/Issues/Issue2458_Tests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System;
using System.IO;
using System.Threading.Tasks;
using LiteDB.Tests.Utils;
using Xunit;

Expand All @@ -8,48 +9,48 @@ namespace LiteDB.Tests.Issues;
public class Issue2458_Tests
{
[Fact]
public void NegativeSeekFails()
public async Task NegativeSeekFails()
{
using var db = DatabaseFactory.Create();
await using var db = DatabaseFactory.Create();
var fs = db.FileStorage;
AddTestFile("test", 1, fs);
using Stream stream = fs.OpenRead("test");
await AddTestFileAsync("test", 1, fs);
await using var stream = await fs.OpenReadAsync("test");
Assert.Throws<ArgumentOutOfRangeException>(() => stream.Position = -1);
}

//https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.position?view=net-8.0 says seeking to a position
//beyond the end of a stream is supported, so implementations should support it (error on read).
[Fact]
public void SeekPastFileSucceds()
public async Task SeekPastFileSucceds()
{
using var db = DatabaseFactory.Create();
await using var db = DatabaseFactory.Create();
var fs = db.FileStorage;
AddTestFile("test", 1, fs);
using Stream stream = fs.OpenRead("test");
stream.Position = Int32.MaxValue;
await AddTestFileAsync("test", 1, fs);
await using var stream = await fs.OpenReadAsync("test");
stream.Position = int.MaxValue;
}

[Fact]
public void SeekShortChunks()
public async Task SeekShortChunks()
{
using var db = DatabaseFactory.Create();
await using var db = DatabaseFactory.Create();
var fs = db.FileStorage;
using(Stream writeStream = fs.OpenWrite("test", "test"))
await using (var writeStream = await fs.OpenWriteAsync("test", "test"))
{
writeStream.WriteByte(0);
writeStream.Flush(); //Create single-byte chunk just containing a 0
writeStream.WriteByte(1);
writeStream.Flush();
writeStream.WriteByte(2);
await writeStream.WriteAsync(new byte[] { 0 }, 0, 1);
await writeStream.FlushAsync();
await writeStream.WriteAsync(new byte[] { 1 }, 0, 1);
await writeStream.FlushAsync();
await writeStream.WriteAsync(new byte[] { 2 }, 0, 1);
}
using Stream readStream = fs.OpenRead("test");

await using var readStream = await fs.OpenReadAsync("test");
readStream.Position = 2;
Assert.Equal(2, readStream.ReadByte());
}

private void AddTestFile(string id, long length, ILiteStorage<string> fs)
private static async Task AddTestFileAsync(string id, long length, ILiteStorage<string> fs)
{
using Stream writeStream = fs.OpenWrite(id, id);
writeStream.Write(new byte[length]);
await using var writeStream = await fs.OpenWriteAsync(id, id);
var buffer = new byte[length];
await writeStream.WriteAsync(buffer, 0, buffer.Length);
}
}
}
3 changes: 2 additions & 1 deletion LiteDB.Tests/Issues/Issue2487_Tests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using FluentAssertions;
using LiteDB.Engine;

using System.Diagnostics;

Expand Down Expand Up @@ -42,4 +43,4 @@ public void Test_Contains_EmptyStrings()
var shouldExecute = () => engine.Query("data", Query.All(Query.Contains("Foo", " ")));
shouldExecute.Should().NotThrow();
}
}
}
37 changes: 21 additions & 16 deletions LiteDB.Tests/Issues/Issue2506_Tests.cs
Original file line number Diff line number Diff line change
@@ -1,36 +1,41 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Xunit;

namespace LiteDB.Tests.Issues;

public class Issue2506_Tests
{
[Fact]
public void Test()
public async Task Test()
{
// Open database connection
using LiteDatabase dataBase = new("demo.db");
await using LiteDatabase dataBase = new("demo.db");

// Get the file metadata/chunks storage
ILiteStorage<string> fileStorage = dataBase.GetStorage<string>("myFiles", "myChunks");

// Upload empty test file to file storage
using MemoryStream emptyStream = new();
fileStorage.Upload("photos/2014/picture-01.jpg", "picture-01.jpg", emptyStream);
await fileStorage.UploadAsync("photos/2014/picture-01.jpg", "picture-01.jpg", emptyStream);

// Find file reference by its ID (returns null if not found)
LiteFileInfo<string> file = fileStorage.FindById("photos/2014/picture-01.jpg");
LiteFileInfo<string> file = await fileStorage.FindByIdAsync("photos/2014/picture-01.jpg");
Assert.NotNull(file);

// Load and save file bytes to hard drive
file.SaveAs(Path.Combine(Path.GetTempPath(), "new-picture.jpg"));
await file.SaveAsAsync(Path.Combine(Path.GetTempPath(), "new-picture.jpg"));

List<LiteFileInfo<string>> files = new();
await foreach (var info in fileStorage.FindAsync("_id LIKE 'photos/2014/%'"))
{
files.Add(info);
}

// Find all files matching pattern
IEnumerable<LiteFileInfo<string>> files = fileStorage.Find("_id LIKE 'photos/2014/%'");
Assert.Single(files);
// Find all files matching pattern using parameters
IEnumerable<LiteFileInfo<string>> files2 = fileStorage.Find("_id LIKE @0", "photos/2014/%");

List<LiteFileInfo<string>> files2 = new();
await foreach (var info in fileStorage.FindAsync("_id LIKE @0", cancellationToken: default, "photos/2014/%"))
{
files2.Add(info);
}

Assert.Single(files2);
}
}
}
Loading
Loading