Skip to content

Commit 05cc60c

Browse files
authored
Merge pull request #6 from tvandinther/xmldoc
Add XML Documentation to public members
2 parents 4e5a02c + c91bce8 commit 05cc60c

18 files changed

+275
-115
lines changed

Demo/Program.cs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using Libsql.Client;
22

3-
var dbClient = DatabaseClient.Create();
3+
var dbClient = DatabaseClient.Create(opts => {
4+
opts.Url = ":memory:";
5+
});
46

57
var rs = await dbClient.Execute("CREATE TABLE IF NOT EXISTS `users` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` TEXT NOT NULL, `height` REAL, `data` BLOB)");
68

@@ -12,16 +14,20 @@
1214
Console.WriteLine(string.Join("\n", rs2.Rows.Select(row => string.Join(", ", row.Select(x => x.ToString())))));
1315
Console.WriteLine(string.Join("\n", rs2.Rows.Select(row => string.Join(", ", row.Select(x => x.ToString())))));
1416

15-
var user = ToUser(rs2.Rows.First().ToArray());
17+
var user = ToUser(rs2.Rows.First());
1618
Console.WriteLine(user);
1719

18-
User ToUser(Value[] row)
20+
var users = rs2.Rows.Select(ToUser);
21+
22+
User ToUser(IEnumerable<Value> row)
1923
{
24+
var rowArray = row.ToArray();
25+
2026
if (
21-
row[0] is Integer { Value: var id } &&
22-
row[1] is Text { Value: var name } &&
23-
row[2] is Real { Value: var height } &&
24-
row[3] is Blob { Value: var data })
27+
rowArray[0] is Integer { Value: var id } &&
28+
rowArray[1] is Text { Value: var name } &&
29+
rowArray[2] is Real { Value: var height } &&
30+
rowArray[3] is Blob { Value: var data })
2531
{
2632
return new User(id, name, height, data);
2733
}

Libsql.Client/DatabaseClient.cs

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,26 @@
22

33
namespace Libsql.Client
44
{
5+
/// <summary>
6+
/// Provides a static method to create an instance of <see cref="IDatabaseClient"/>.
7+
/// </summary>
58
public static class DatabaseClient
69
{
10+
/// <summary>
11+
/// Creates a new instance of the <see cref="IDatabaseClient"/> interface.
12+
/// </summary>
13+
/// <param name="configure">An optional action to configure the <see cref="DatabaseClientOptions"/>.</param>
14+
/// <returns>A new instance of the <see cref="IDatabaseClient"/> interface.</returns>
15+
/// <remarks>A client constitutes a connection to the database.</remarks>
16+
/// <exception cref="ArgumentNullException">Thrown when <paramref name="configure"/> is null.</exception>
17+
/// <exception cref="LibsqlException">Thrown when the database fails to open and/or connect.</exception>
718
public static IDatabaseClient Create(Action<DatabaseClientOptions> configure = default)
819
{
920
var options = DatabaseClientOptions.Default;
1021
configure?.Invoke(options);
1122
if (options.Url is null) throw new ArgumentNullException(nameof(options.Url));
1223

13-
return new DatabaseWrapper(options.Url);
14-
15-
// if (IsInMemory(options.Url))
16-
// {
17-
// return new DatabaseWrapper(":memory:");
18-
// }
19-
//
20-
// var uri = new Uri(options.Url);
21-
// return uri.Scheme switch
22-
// {
23-
// "http" or "https" => throw new ArgumentException($"{uri.Scheme}:// is not yet supported"),
24-
// "ws" or "wss" => throw new ArgumentException($"{uri.Scheme}:// is not yet supported"),
25-
// "file" => throw new ArgumentException(options.Url),
26-
// _ => throw new ArgumentException("Invalid scheme")
27-
// };
24+
return new DatabaseWrapper(options);
2825
}
29-
30-
private static bool IsInMemory(string url) => url is "" || url is ":memory:";
3126
}
3227
}

Libsql.Client/DatabaseClientOptions.cs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
namespace Libsql.Client
22
{
3+
/// <summary>
4+
/// Represents the options for configuring <see cref="IDatabaseClient"/>.
5+
/// </summary>
36
public class DatabaseClientOptions
47
{
58
private DatabaseClientOptions(string url, string authToken = null, bool useHttps = false)
@@ -10,16 +13,21 @@ private DatabaseClientOptions(string url, string authToken = null, bool useHttps
1013
}
1114

1215
internal static DatabaseClientOptions Default => new DatabaseClientOptions("");
16+
17+
/// <summary>
18+
/// Gets or sets the URL of the database server.
19+
/// </summary>
20+
/// <remarks>Default: <c>""</c>. <c>""</c> or <c>":memory:"</c> will create an in-memory database.</remarks>
1321
public string Url { get; set; }
22+
23+
/// <summary>
24+
/// Gets or sets the authentication token used to connect to the database.
25+
/// </summary>
1426
public string AuthToken { get; set; }
27+
28+
/// <summary>
29+
/// Gets or sets a value indicating whether to use HTTPS protocol for database connections.
30+
/// </summary>
1531
public bool UseHttps { get; set; }
16-
17-
public void Deconstruct(out string url, out string token, out bool useHttps)
18-
{
19-
url = Url;
20-
token = AuthToken;
21-
useHttps = UseHttps;
22-
}
2332
}
2433
}
25-

Libsql.Client/DatabaseWrapper.cs

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,33 @@ internal class DatabaseWrapper : IDatabaseClient, IDisposable
1111
private libsql_database_t _db;
1212
private libsql_connection_t _connection;
1313

14-
public unsafe DatabaseWrapper(string url)
14+
public unsafe DatabaseWrapper(DatabaseClientOptions options)
1515
{
16-
Debug.Assert(url != null, "url is null");
16+
Debug.Assert(options.Url != null, "url is null");
17+
18+
if (!(options.Url == "" || options.Url == ":memory:"))
19+
{
20+
try
21+
{
22+
var uri = new Uri(options.Url);
23+
switch (uri.Scheme)
24+
{
25+
case "http":
26+
case "https":
27+
case "ws":
28+
case "wss":
29+
throw new LibsqlException($"{uri.Scheme}:// is not yet supported");
30+
}
31+
}
32+
catch (UriFormatException) { }
33+
}
34+
35+
// C# empty strings have null pointers, so we need to give the url some meat.
36+
var url = options.Url is "" ? "\0" : options.Url;
37+
1738
var error = new Error();
1839
int exitCode;
1940

20-
// C# empty strings have null pointers, so we need to give the urln it some meat.
21-
if (url is "") url = "\0";
22-
2341
fixed (libsql_database_t* dbPtr = &_db)
2442
{
2543
fixed (byte* urlPtr = Encoding.UTF8.GetBytes(url))
@@ -46,31 +64,34 @@ private unsafe void Connect()
4664
error.ThrowIfNonZero(exitCode, "Failed to connect to database");
4765
}
4866

49-
public unsafe Task<ResultSet> Execute(string sql)
67+
public async Task<IResultSet> Execute(string sql)
5068
{
51-
return Task.Run(() =>
69+
return await Task.Run(() =>
5270
{
53-
var error = new Error();
54-
var rows = new libsql_rows_t();
55-
int exitCode;
56-
57-
fixed (byte* sqlPtr = Encoding.UTF8.GetBytes(sql))
71+
unsafe
5872
{
59-
exitCode = Bindings.libsql_execute(_connection, sqlPtr, &rows, &error.Ptr);
60-
}
73+
var error = new Error();
74+
var rows = new libsql_rows_t();
75+
int exitCode;
76+
77+
fixed (byte* sqlPtr = Encoding.UTF8.GetBytes(sql))
78+
{
79+
exitCode = Bindings.libsql_execute(_connection, sqlPtr, &rows, &error.Ptr);
80+
}
6181

62-
error.ThrowIfNonZero(exitCode, "Failed to execute query");
82+
error.ThrowIfNonZero(exitCode, "Failed to execute query");
6383

64-
return new ResultSet(
65-
0,
66-
0,
67-
rows.GetColumnNames(),
68-
new Rows(rows)
69-
);
84+
return new ResultSet(
85+
0,
86+
0,
87+
rows.GetColumnNames(),
88+
new Rows(rows)
89+
);
90+
}
7091
});
7192
}
7293

73-
public Task<ResultSet> Execute(string sql, params object[] args)
94+
public Task<IResultSet> Execute(string sql, params object[] args)
7495
{
7596
throw new NotImplementedException();
7697
}

Libsql.Client/Error.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public unsafe void ThrowIfNonZero(int exitCode, string message)
1313

1414
var text = Marshal.PtrToStringAuto((IntPtr)Ptr);
1515

16-
throw new Exception($"{message}: {text}");
16+
throw new LibsqlException($"{message}: {text}");
1717
}
1818
}
1919
}

Libsql.Client/IDatabaseClient.cs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,26 @@
22

33
namespace Libsql.Client
44
{
5+
/// <summary>
6+
/// Interface for a Libsql database client.
7+
/// </summary>
58
public interface IDatabaseClient
69
{
7-
Task<ResultSet> Execute(string sql);
8-
Task<ResultSet> Execute(string sql, params object[] args);
10+
/// <summary>
11+
/// Executes the given SQL query and returns the result set.
12+
/// </summary>
13+
/// <param name="sql">The SQL query to execute.</param>
14+
/// <returns>The result set returned by the query.</returns>
15+
/// <exception cref="LibsqlException">Thrown when the query fails to execute.</exception>
16+
Task<IResultSet> Execute(string sql);
17+
18+
/// <summary>
19+
/// Executes the given SQL query with the specified parameters and returns the result set.
20+
/// </summary>
21+
/// <param name="sql">The SQL query to execute.</param>
22+
/// <param name="args">The parameters to use in the query.</param>
23+
/// <returns>The result set returned by the query.</returns>
24+
/// <exception cref="LibsqlException">Thrown when the query fails to execute.</exception>
25+
Task<IResultSet> Execute(string sql, params object[] args);
926
}
1027
}

Libsql.Client/IResultSet.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using System.Collections.Generic;
2+
3+
namespace Libsql.Client
4+
{
5+
/// <summary>
6+
/// Represents the result set of a SQL query.
7+
/// </summary>
8+
public interface IResultSet
9+
{
10+
/// <summary>
11+
/// The ID of the last row inserted by the connection.
12+
/// </summary>
13+
/// <returns>The ID of the last row inserted.</returns>
14+
long LastInsertRowId { get; }
15+
16+
/// <summary>
17+
/// The number of rows affected by the last query executed by the connection.
18+
/// </summary>
19+
/// <returns>The number of rows affected.</returns>
20+
ulong RowsAffected { get; }
21+
22+
/// <summary>
23+
/// The names of the columns in the result set.
24+
/// </summary>
25+
/// <returns>An enumerable of column names.</returns>
26+
IEnumerable<string> Columns { get; }
27+
28+
/// <summary>
29+
/// The rows in the result set.
30+
/// </summary>
31+
/// <returns>An enumerable of enumerable rows. Rows are enumerated by column.</returns>
32+
IEnumerable<IEnumerable<Value>> Rows { get; }
33+
}
34+
}

Libsql.Client/Libsql.Client.csproj

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<Title>Libsql.Client</Title>
55
<Authors>Tom van Dinther</Authors>
66
<Description>A client library for Libsql</Description>
7-
<PackageVersion>0.2.0</PackageVersion>
7+
<PackageVersion>0.2.1</PackageVersion>
88
<Copyright>Copyright (c) Tom van Dinther 2023</Copyright>
99
<PackageProjectUrl>https://github.com/tvandinther/libsql-client-dotnet</PackageProjectUrl>
1010
<PackageLicense>https://raw.githubusercontent.com/tvandinther/libsql-client-dotnet/master/LICENSE</PackageLicense>
@@ -50,13 +50,6 @@
5050
<Compile Include="..\rust-bindings\csharp-bindings\bindings\Libsql.g.cs" Link="Libsql.g.cs" />
5151
</ItemGroup>
5252

53-
<ItemGroup>
54-
<PackageReference Include="csbindgen" Version="1.8.3">
55-
<PrivateAssets>all</PrivateAssets>
56-
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
57-
</PackageReference>
58-
</ItemGroup>
59-
6053
<ItemGroup>
6154
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
6255
<_Parameter1>$(AssemblyName).Tests</_Parameter1>

Libsql.Client/LibsqlException.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System;
2+
3+
namespace Libsql.Client
4+
{
5+
/// <summary>
6+
/// Represents an exception that is thrown when an error occurs in the Libsql.Client library.
7+
/// </summary>
8+
public class LibsqlException : ApplicationException
9+
{
10+
internal LibsqlException()
11+
{
12+
}
13+
14+
internal LibsqlException(string message)
15+
: base(message)
16+
{
17+
}
18+
19+
internal LibsqlException(string message, Exception inner)
20+
: base(message, inner)
21+
{
22+
}
23+
}
24+
}

Libsql.Client/ResultSet.cs

Lines changed: 6 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
using System;
2-
using System.Collections.Generic;
1+
using System.Collections.Generic;
32

43
namespace Libsql.Client
54
{
6-
public class ResultSet : IEquatable<ResultSet>
5+
internal class ResultSet : IResultSet
76
{
87
public long LastInsertRowId { get; }
8+
99
public ulong RowsAffected { get; }
10+
1011
public IEnumerable<string> Columns { get; }
12+
1113
public IEnumerable<IEnumerable<Value>> Rows { get; }
1214

1315
public ResultSet(long lastInsertRowId, ulong rowsAffected, IEnumerable<string> columns, IEnumerable<IEnumerable<Value>> rows)
@@ -17,33 +19,5 @@ public ResultSet(long lastInsertRowId, ulong rowsAffected, IEnumerable<string> c
1719
Columns = columns;
1820
Rows = rows;
1921
}
20-
21-
public bool Equals(ResultSet other)
22-
{
23-
if (ReferenceEquals(null, other)) return false;
24-
if (ReferenceEquals(this, other)) return true;
25-
return LastInsertRowId == other.LastInsertRowId && RowsAffected == other.RowsAffected &&
26-
Equals(Columns, other.Columns) && Equals(Rows, other.Rows);
27-
}
28-
29-
public override bool Equals(object obj)
30-
{
31-
if (ReferenceEquals(null, obj)) return false;
32-
if (ReferenceEquals(this, obj)) return true;
33-
if (obj.GetType() != this.GetType()) return false;
34-
return Equals((ResultSet)obj);
35-
}
36-
37-
public override int GetHashCode()
38-
{
39-
unchecked
40-
{
41-
var hashCode = LastInsertRowId.GetHashCode();
42-
hashCode = (hashCode * 397) ^ RowsAffected.GetHashCode();
43-
hashCode = (hashCode * 397) ^ (Columns != null ? Columns.GetHashCode() : 0);
44-
hashCode = (hashCode * 397) ^ (Rows != null ? Rows.GetHashCode() : 0);
45-
return hashCode;
46-
}
47-
}
48-
}
22+
}
4923
}

0 commit comments

Comments
 (0)