From 4a22f3ca058191e2099ad06c2398915d0ee0007c Mon Sep 17 00:00:00 2001 From: Juan Castellanos Date: Thu, 28 Aug 2025 11:06:55 -0300 Subject: [PATCH 1/2] fix [#31]: add explicit 'file:' case and update URL docs - Added explicit handling for URLs prefixed with 'file:' in DatabaseWrapper. - Updated DatabaseClientOptions.Url documentation with examples for: - In-memory database - Local file database - Connection string --- Libsql.Client.Tests/DatabaseClientTests.cs | 32 ++++++++++++++++++++++ Libsql.Client/DatabaseClientOptions.cs | 16 ++++++++++- Libsql.Client/DatabaseWrapper.cs | 3 ++ README.md | 19 +++++++++++++ 4 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 Libsql.Client.Tests/DatabaseClientTests.cs diff --git a/Libsql.Client.Tests/DatabaseClientTests.cs b/Libsql.Client.Tests/DatabaseClientTests.cs new file mode 100644 index 0000000..1b9dff6 --- /dev/null +++ b/Libsql.Client.Tests/DatabaseClientTests.cs @@ -0,0 +1,32 @@ +namespace Libsql.Client.Tests; + +public class DatabaseClientTests +{ + [Theory] + [InlineData("file:testdb.sqlite")] + [InlineData(":memory:")] + public async Task Create_WithValidPaths_ShouldCreateDatabaseClient(string path) + { + var client = await DatabaseClient.Create(path); + + Assert.NotNull(client); + Assert.IsAssignableFrom(client); + } + + [Fact] + public async Task Create_WithLocalPath_ShouldCreateDatabaseClient() + { + var filePath = Path.GetFullPath("testdb.sqlite"); + + var client = await DatabaseClient.Create(filePath); + + Assert.NotNull(client); + Assert.IsAssignableFrom(client); + } + + [Fact] + public async Task Create_WithNullPath_ShouldThrowArgumentNullException() + { + await Assert.ThrowsAsync(() => DatabaseClient.Create((string)null!)); + } +} \ No newline at end of file diff --git a/Libsql.Client/DatabaseClientOptions.cs b/Libsql.Client/DatabaseClientOptions.cs index 2cd0714..d4fd8a7 100644 --- a/Libsql.Client/DatabaseClientOptions.cs +++ b/Libsql.Client/DatabaseClientOptions.cs @@ -18,7 +18,21 @@ private DatabaseClientOptions(string url, string authToken = null, string replic /// /// Gets or sets the URL of the database server. /// - /// Default: "". "" or ":memory:" will create an in-memory database. + /// + /// Supported values: + /// + /// + /// ":memory:" or "" - Creates an in-memory database. + /// + /// + /// Local file path (e.g. file:localdb.sqlite or C:\data\localdbs.sqlite) - Creates or opens a file-based database. + /// + /// + /// Remote URL (e.g. http://example.com/db) - For remote database support. + /// + /// + /// Default: "". + /// public string Url { get; set; } /// diff --git a/Libsql.Client/DatabaseWrapper.cs b/Libsql.Client/DatabaseWrapper.cs index c543b2f..68bb3d8 100644 --- a/Libsql.Client/DatabaseWrapper.cs +++ b/Libsql.Client/DatabaseWrapper.cs @@ -37,6 +37,9 @@ public unsafe DatabaseWrapper(DatabaseClientOptions options) case "wss": _type = _options.ReplicaPath != null ? DatabaseType.EmbeddedReplica : DatabaseType.Remote; break; + case "file": + _type = DatabaseType.File; + break; default: throw new InvalidOperationException($"Unsupported scheme: {uri.Scheme}"); } diff --git a/README.md b/README.md index 7c10f7b..82486b7 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,9 @@ For an example, see the Demo project in the repository. ### Creating a Database +You can open a database in different locations: + +1. In-Memory Database ```csharp // Create an in-memory database. var dbClient = await DatabaseClient.Create(opts => { @@ -36,6 +39,22 @@ var dbClient = await DatabaseClient.Create(opts => { }); ``` +2. From a File +```csharp +// Creates or opens a database stored in a local file. +var dbClient = await DatabaseClient.Create(opts => { + opts.Url = "file:./mydb.sqlite"; +}); +``` + +3. From a Connection String +```csharp +// Opens a database using a full connection string. +var dbClient = await DatabaseClient.Create(opts => { + opts.Url = "file:./mydb.sqlite?mode=rwc"; +}); +``` + ### Executing SQL Statements Using direct queries From 38fe90454e142cece75e5d93af4f7697e21c3fd4 Mon Sep 17 00:00:00 2001 From: Juan Castellanos Date: Sat, 30 Aug 2025 10:30:11 -0300 Subject: [PATCH 2/2] update README: add remote database examples and clarify connection options --- README.md | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 82486b7..099c4c5 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,32 @@ var dbClient = await DatabaseClient.Create(opts => { ```csharp // Opens a database using a full connection string. var dbClient = await DatabaseClient.Create(opts => { - opts.Url = "file:./mydb.sqlite?mode=rwc"; + opts.Url = "https://my-remote-db.example.com"; +}); +``` + +#### Provide Additional Connection Options +#### Remote Databases +For remote libSQL databases, use client options for authentication and secure connections: + +```csharp +// Connect to a remote database with authentication and HTTPS enabled +var dbClient = await DatabaseClient.Create(opts => +{ + opts.Url = "https://my-remote-db.example.com"; + opts.AuthToken = "MY_TOKEN"; + opts.UseHttps = true; +}); +``` + +#### Local File Databases +For local files, you can pass standard query parameters via the file URI: + +```csharp +// Open a local database with query parameters +var dbClient = await DatabaseClient.Create(opts => +{ + opts.Url = "file:mydb.sqlite?mode=rwc&cache=shared"; }); ```