From 1e0a39272a1908aa0c9b9713eed1ba8d170e8320 Mon Sep 17 00:00:00 2001 From: miyaji255 <84168445+miyaji255@users.noreply.github.com> Date: Wed, 1 Oct 2025 00:32:06 +0900 Subject: [PATCH 1/2] Support executing sql with template literal --- .gitignore | 3 +- sandbox/ConsoleApp1/Program.cs | 6 + .../CsSqlite.Unity/Runtime/CsSqlite.dll | Bin 15872 -> 16384 bytes .../ExecuteInterporatedStringHandler.cs | 128 ++++++++++++++++++ ...erpolatedStringHandlerArgumentAttribute.cs | 11 ++ .../InterpolatedStringHandlerAttribute.cs | 6 + src/CsSqlite/SpliteParameters.cs | 6 + src/CsSqlite/SqliteConnection.cs | 65 ++++++++- 8 files changed, 223 insertions(+), 2 deletions(-) create mode 100644 src/CsSqlite/ExecuteInterporatedStringHandler.cs create mode 100644 src/CsSqlite/InterpolatedStringHandlerArgumentAttribute.cs create mode 100644 src/CsSqlite/InterpolatedStringHandlerAttribute.cs diff --git a/.gitignore b/.gitignore index 496ee2c..7375804 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -.DS_Store \ No newline at end of file +.DS_Store +.vs diff --git a/sandbox/ConsoleApp1/Program.cs b/sandbox/ConsoleApp1/Program.cs index 50957ca..c147596 100644 --- a/sandbox/ConsoleApp1/Program.cs +++ b/sandbox/ConsoleApp1/Program.cs @@ -18,11 +18,17 @@ INSERT INTO user (id, name, age) (3, 'Charlie', 25); """); +connection.ExecuteNonQuery(stackalloc char[1024], $""" + INSERT INTO user (id, name, age) + VALUES ({4}, {"Darwin"}, {80}); + """); + using var reader = connection.ExecuteReader(""" SELECT name FROM user """); + while (reader.Read()) { Console.WriteLine($"{reader.GetString(0)}!"); diff --git a/src/CsSqlite.Unity/Assets/CsSqlite.Unity/Runtime/CsSqlite.dll b/src/CsSqlite.Unity/Assets/CsSqlite.Unity/Runtime/CsSqlite.dll index b0aa0b5cd7f28723ffa94b236fdb825c9513905e..4fd21a1242ea575efe3394c47c2264040b6329c1 100644 GIT binary patch literal 16384 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 commandText; + public readonly ReadOnlySpan CommandText => commandText[..textWritten]; + int textWritten; + SqliteParam[]? sqliteParams; + Span parameters; + int parameterWritten; + public readonly ReadOnlySpan Parameter => parameters[..parameterWritten]; + + public ExecuteInterporatedStringHandler(int literalLength, int formattedCount) + { + if (literalLength > 0) + { + this.commandText = this.chars = ArrayPool.Shared.Rent(literalLength + formattedCount * 3); + } + + if (formattedCount > 0) + { + this.parameters = this.sqliteParams = ArrayPool.Shared.Rent(formattedCount); + } + } + + public ExecuteInterporatedStringHandler(int literalLength, int formattedCount, Span commandText) + { + this.commandText = literalLength > commandText.Length ? this.chars = ArrayPool.Shared.Rent(literalLength + formattedCount * 3) : commandText; + + if (formattedCount > 0) + { + this.parameters = this.sqliteParams = ArrayPool.Shared.Rent(formattedCount); + } + } + + public void AppendLiteral(string s) + { + s.AsSpan().CopyTo(commandText[textWritten..]); + textWritten += s.Length; + } + + public void AppendFormatted(string? s) + { + parameters[parameterWritten++] = new(SqlitePramKind.String, new(s?.AsMemory() ?? "".AsMemory())); + WriteParameterPlaceholder(); + } + + public void AppendFormatted(ReadOnlyMemory s) + { + parameters[parameterWritten++] = new(SqlitePramKind.String, new(s)); + WriteParameterPlaceholder(); + } + + public void AppendFormatted(ReadOnlyMemory s) + { + parameters[parameterWritten++] = new(SqlitePramKind.Utf8String, new(s)); + WriteParameterPlaceholder(); + } + + public void AppendFormatted(long value) + { + parameters[parameterWritten++] = new(SqlitePramKind.Integer, new(value)); + WriteParameterPlaceholder(); + } + + public void AppendFormatted(double value) + { + parameters[parameterWritten++] = new(SqlitePramKind.Double, new(value)); + WriteParameterPlaceholder(); + } + + void WriteParameterPlaceholder() + { + commandText[textWritten++] = ' '; + commandText[textWritten++] = '?'; + commandText[textWritten++] = ' '; + } + + public void Dispose() + { + if (chars != null) + { + ArrayPool.Shared.Return(chars); + chars = null; + } + + if (sqliteParams != null) + { + ArrayPool.Shared.Return(sqliteParams); + sqliteParams = null; + } + } +} + +public readonly struct SqliteParam(SqlitePramKind kind, SqlitePramPayload payload) +{ + public readonly SqlitePramKind Kind = kind; + public readonly SqlitePramPayload Payload = payload; + +} + +public enum SqlitePramKind : byte +{ + Integer, + Double, + String, + Utf8String, +} + +[StructLayout(LayoutKind.Explicit)] +public struct SqlitePramPayload +{ + [FieldOffset(0)] public readonly long Long; + [FieldOffset(0)] public readonly double Double; + [FieldOffset(8)] public readonly ReadOnlyMemory String; + [FieldOffset(8)] public readonly ReadOnlyMemory Utf8String; + + public SqlitePramPayload(long l) { this.Long = l; } + public SqlitePramPayload(double d) { this.Double = d; } + public SqlitePramPayload(ReadOnlyMemory t) { this.String = t; } + public SqlitePramPayload(ReadOnlyMemory b) { this.Utf8String = b; } +} diff --git a/src/CsSqlite/InterpolatedStringHandlerArgumentAttribute.cs b/src/CsSqlite/InterpolatedStringHandlerArgumentAttribute.cs new file mode 100644 index 0000000..9a02a39 --- /dev/null +++ b/src/CsSqlite/InterpolatedStringHandlerArgumentAttribute.cs @@ -0,0 +1,11 @@ +namespace CsSqlite; + +#if NETSTANDARD2_1 +[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] +internal sealed class InterpolatedStringHandlerArgumentAttribute : Attribute +{ + public InterpolatedStringHandlerArgumentAttribute(string argument) => Arguments = [argument]; + public InterpolatedStringHandlerArgumentAttribute(params string[] arguments) => Arguments = arguments; + public string[] Arguments { get; } +} +#endif diff --git a/src/CsSqlite/InterpolatedStringHandlerAttribute.cs b/src/CsSqlite/InterpolatedStringHandlerAttribute.cs new file mode 100644 index 0000000..abf151a --- /dev/null +++ b/src/CsSqlite/InterpolatedStringHandlerAttribute.cs @@ -0,0 +1,6 @@ +namespace CsSqlite; + +#if NETSTANDARD2_1 +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] +internal sealed class InterpolatedStringHandlerAttribute : Attribute { } +#endif diff --git a/src/CsSqlite/SpliteParameters.cs b/src/CsSqlite/SpliteParameters.cs index 3eb4cd4..61d1fe2 100644 --- a/src/CsSqlite/SpliteParameters.cs +++ b/src/CsSqlite/SpliteParameters.cs @@ -43,6 +43,12 @@ public void Add(int index, long value) BindParameter(index, value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Add(int index, double value) + { + BindParameter(index, value); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Add(int index, ReadOnlySpan text) { diff --git a/src/CsSqlite/SqliteConnection.cs b/src/CsSqlite/SqliteConnection.cs index 1e370b7..9e2ef83 100644 --- a/src/CsSqlite/SqliteConnection.cs +++ b/src/CsSqlite/SqliteConnection.cs @@ -23,7 +23,8 @@ enum State : byte public void Open() { ThrowIfDisposed(); - if (state == State.Open) return; + if (state == State.Open) + return; var buffer = ArrayPool.Shared.Rent(path.Length * 3); try @@ -111,6 +112,36 @@ public int ExecuteNonQuery(ReadOnlySpan commandText) return command.ExecuteNonQuery(); } + public int ExecuteNonQuery(ref ExecuteInterporatedStringHandler commandHandler) + { + using var command = CreateCommand(commandHandler.CommandText); + for (int i = 0; i < commandHandler.Parameter.Length; i++) + { + var p = commandHandler.Parameter[i]; + switch (p.Kind) + { + case SqlitePramKind.String: + command.Parameters.Add(i + 1, p.Payload.String.Span); + break; + case SqlitePramKind.Utf8String: + command.Parameters.Add(i + 1, p.Payload.Utf8String.Span); + break; + case SqlitePramKind.Integer: + command.Parameters.Add(i + 1, p.Payload.Long); + break; + case SqlitePramKind.Double: + command.Parameters.Add(i + 1, p.Payload.Double); + break; + } + } + return command.ExecuteNonQuery(); + } + + public int ExecuteNonQuery(Span commandText, [InterpolatedStringHandlerArgument("commandText")] ref ExecuteInterporatedStringHandler commandHandler) + { + return ExecuteNonQuery(ref commandHandler); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public SqliteReader ExecuteReader(ReadOnlySpan utf8CommandText) { @@ -127,6 +158,38 @@ public SqliteReader ExecuteReader(ReadOnlySpan commandText) return new(this, Prepare(commandText), true); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public SqliteReader ExecuteReader(ref ExecuteInterporatedStringHandler commandHandler) + { + var command = CreateCommand(commandHandler.CommandText); + for (int i = 0; i < commandHandler.Parameter.Length; i++) + { + var p = commandHandler.Parameter[i]; + switch (p.Kind) + { + case SqlitePramKind.String: + command.Parameters.Add(i + 1, p.Payload.String.Span); + break; + case SqlitePramKind.Utf8String: + command.Parameters.Add(i + 1, p.Payload.Utf8String.Span); + break; + case SqlitePramKind.Integer: + command.Parameters.Add(i + 1, p.Payload.Long); + break; + case SqlitePramKind.Double: + command.Parameters.Add(i + 1, p.Payload.Double); + break; + } + } + return command.ExecuteReader(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public SqliteReader ExecuteReader(Span commandText, [InterpolatedStringHandlerArgument("commandText")] ref ExecuteInterporatedStringHandler commandHandler) + { + return ExecuteReader(ref commandHandler); + } + internal void ThrowIfDisposed() { if (IsDisposed) From b3a85001261b064d57d92c6408aef90fb8470326 Mon Sep 17 00:00:00 2001 From: miyaji255 <84168445+miyaji255@users.noreply.github.com> Date: Wed, 1 Oct 2025 23:17:49 +0900 Subject: [PATCH 2/2] Add AppendFormatted for Blob --- sandbox/ConsoleApp1/Program.cs | 2 +- .../CsSqlite.Unity/Runtime/CsSqlite.dll | Bin 16384 -> 21504 bytes .../ExecuteInterporatedStringHandler.cs | 61 ++++++++++-------- src/CsSqlite/SpliteParameters.cs | 5 ++ src/CsSqlite/SqliteConnection.cs | 42 +++++++----- 5 files changed, 66 insertions(+), 44 deletions(-) diff --git a/sandbox/ConsoleApp1/Program.cs b/sandbox/ConsoleApp1/Program.cs index c147596..a15d83f 100644 --- a/sandbox/ConsoleApp1/Program.cs +++ b/sandbox/ConsoleApp1/Program.cs @@ -20,7 +20,7 @@ INSERT INTO user (id, name, age) connection.ExecuteNonQuery(stackalloc char[1024], $""" INSERT INTO user (id, name, age) - VALUES ({4}, {"Darwin"}, {80}); + VALUES ({4}, {"Darwin"u8.ToArray():text}, {80}); """); using var reader = connection.ExecuteReader(""" diff --git a/src/CsSqlite.Unity/Assets/CsSqlite.Unity/Runtime/CsSqlite.dll b/src/CsSqlite.Unity/Assets/CsSqlite.Unity/Runtime/CsSqlite.dll index 4fd21a1242ea575efe3394c47c2264040b6329c1..3379819ee510ee3de31f5e4154bbe981017f8ccc 100644 GIT binary patch literal 21504 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 commandText; public readonly ReadOnlySpan CommandText => commandText[..textWritten]; int textWritten; - SqliteParam[]? sqliteParams; - Span parameters; + SqliteParam[] parameters; int parameterWritten; - public readonly ReadOnlySpan Parameter => parameters[..parameterWritten]; + public readonly ReadOnlySpan Parameters => parameters[..parameterWritten]; public ExecuteInterporatedStringHandler(int literalLength, int formattedCount) { @@ -23,20 +22,13 @@ public ExecuteInterporatedStringHandler(int literalLength, int formattedCount) this.commandText = this.chars = ArrayPool.Shared.Rent(literalLength + formattedCount * 3); } - if (formattedCount > 0) - { - this.parameters = this.sqliteParams = ArrayPool.Shared.Rent(formattedCount); - } + this.parameters = formattedCount > 0 ? ArrayPool.Shared.Rent(formattedCount) : []; } public ExecuteInterporatedStringHandler(int literalLength, int formattedCount, Span commandText) { - this.commandText = literalLength > commandText.Length ? this.chars = ArrayPool.Shared.Rent(literalLength + formattedCount * 3) : commandText; - - if (formattedCount > 0) - { - this.parameters = this.sqliteParams = ArrayPool.Shared.Rent(formattedCount); - } + this.commandText = literalLength + formattedCount * 3 > commandText.Length ? this.chars = ArrayPool.Shared.Rent(literalLength + formattedCount * 3) : commandText; + this.parameters = formattedCount > 0 ? ArrayPool.Shared.Rent(formattedCount) : []; } public void AppendLiteral(string s) @@ -57,9 +49,14 @@ public void AppendFormatted(ReadOnlyMemory s) WriteParameterPlaceholder(); } - public void AppendFormatted(ReadOnlyMemory s) + public void AppendFormatted(ReadOnlyMemory s) => AppendFormatted(s, default); + + public void AppendFormatted(ReadOnlyMemory s, ReadOnlySpan format) { - parameters[parameterWritten++] = new(SqlitePramKind.Utf8String, new(s)); + parameters[parameterWritten++] = + format.Length == 0 || format.SequenceEqual("text") ? new(SqlitePramKind.Utf8String, new(s)) : + format.SequenceEqual("blob") ? new(SqlitePramKind.Blob, new(s)) : + throw new ArgumentException($"The {nameof(format)} must be text or blob.", nameof(format)); WriteParameterPlaceholder(); } @@ -90,10 +87,11 @@ public void Dispose() chars = null; } - if (sqliteParams != null) + if (parameters != null) { - ArrayPool.Shared.Return(sqliteParams); - sqliteParams = null; + // Clear because SqliteParam can contain managed objects + ArrayPool.Shared.Return(parameters, true); + parameters = null!; } } } @@ -111,18 +109,27 @@ public enum SqlitePramKind : byte Double, String, Utf8String, + Blob, } [StructLayout(LayoutKind.Explicit)] -public struct SqlitePramPayload +public readonly struct SqlitePramPayload { - [FieldOffset(0)] public readonly long Long; - [FieldOffset(0)] public readonly double Double; - [FieldOffset(8)] public readonly ReadOnlyMemory String; - [FieldOffset(8)] public readonly ReadOnlyMemory Utf8String; - - public SqlitePramPayload(long l) { this.Long = l; } - public SqlitePramPayload(double d) { this.Double = d; } + [FieldOffset(0)] readonly MemoryLike memoryLikeLong; + public readonly long Long => memoryLikeLong.Long; + [FieldOffset(0)] readonly MemoryLike memoryLikeDouble; + public readonly double Double => memoryLikeDouble.Long; + [FieldOffset(0)] public readonly ReadOnlyMemory String; + [FieldOffset(0)] public readonly ReadOnlyMemory BlobOrUtf8String; + + public SqlitePramPayload(long l) { this.memoryLikeLong = new(l); } + public SqlitePramPayload(double d) { this.memoryLikeDouble = new(d); } public SqlitePramPayload(ReadOnlyMemory t) { this.String = t; } - public SqlitePramPayload(ReadOnlyMemory b) { this.Utf8String = b; } + public SqlitePramPayload(ReadOnlyMemory b) { this.BlobOrUtf8String = b; } + + private readonly struct MemoryLike(T l) + { + public readonly T Long = l; + private readonly object? dummy = null; + } } diff --git a/src/CsSqlite/SpliteParameters.cs b/src/CsSqlite/SpliteParameters.cs index 61d1fe2..f113b19 100644 --- a/src/CsSqlite/SpliteParameters.cs +++ b/src/CsSqlite/SpliteParameters.cs @@ -82,6 +82,11 @@ public void AddLiteral(int index, BindText(index, utf8Text, true); } + public void AddBytes(int index, ReadOnlySpan blob) + { + BindBlob(index, blob); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Add(ReadOnlySpan name, int value) { diff --git a/src/CsSqlite/SqliteConnection.cs b/src/CsSqlite/SqliteConnection.cs index 9e2ef83..8a65588 100644 --- a/src/CsSqlite/SqliteConnection.cs +++ b/src/CsSqlite/SqliteConnection.cs @@ -115,22 +115,27 @@ public int ExecuteNonQuery(ReadOnlySpan commandText) public int ExecuteNonQuery(ref ExecuteInterporatedStringHandler commandHandler) { using var command = CreateCommand(commandHandler.CommandText); - for (int i = 0; i < commandHandler.Parameter.Length; i++) + var handlerParameters = commandHandler.Parameters; + var commandParameters = command.Parameters; + for (int i = 0; i < handlerParameters.Length; i++) { - var p = commandHandler.Parameter[i]; + var p = handlerParameters[i]; switch (p.Kind) { + case SqlitePramKind.Integer: + commandParameters.Add(i + 1, p.Payload.Long); + break; + case SqlitePramKind.Double: + commandParameters.Add(i + 1, p.Payload.Double); + break; case SqlitePramKind.String: - command.Parameters.Add(i + 1, p.Payload.String.Span); + commandParameters.Add(i + 1, p.Payload.String.Span); break; case SqlitePramKind.Utf8String: - command.Parameters.Add(i + 1, p.Payload.Utf8String.Span); + commandParameters.Add(i + 1, p.Payload.BlobOrUtf8String.Span); break; - case SqlitePramKind.Integer: - command.Parameters.Add(i + 1, p.Payload.Long); - break; - case SqlitePramKind.Double: - command.Parameters.Add(i + 1, p.Payload.Double); + case SqlitePramKind.Blob: + commandParameters.AddBytes(i + 1, p.Payload.BlobOrUtf8String.Span); break; } } @@ -161,23 +166,28 @@ public SqliteReader ExecuteReader(ReadOnlySpan commandText) [MethodImpl(MethodImplOptions.AggressiveInlining)] public SqliteReader ExecuteReader(ref ExecuteInterporatedStringHandler commandHandler) { - var command = CreateCommand(commandHandler.CommandText); - for (int i = 0; i < commandHandler.Parameter.Length; i++) + using var command = CreateCommand(commandHandler.CommandText); + var handlerParameters = commandHandler.Parameters; + var commandParameters = command.Parameters; + for (int i = 0; i < handlerParameters.Length; i++) { - var p = commandHandler.Parameter[i]; + var p = handlerParameters[i]; switch (p.Kind) { case SqlitePramKind.String: - command.Parameters.Add(i + 1, p.Payload.String.Span); + commandParameters.Add(i + 1, p.Payload.String.Span); break; case SqlitePramKind.Utf8String: - command.Parameters.Add(i + 1, p.Payload.Utf8String.Span); + commandParameters.Add(i + 1, p.Payload.BlobOrUtf8String.Span); break; case SqlitePramKind.Integer: - command.Parameters.Add(i + 1, p.Payload.Long); + commandParameters.Add(i + 1, p.Payload.Long); break; case SqlitePramKind.Double: - command.Parameters.Add(i + 1, p.Payload.Double); + commandParameters.Add(i + 1, p.Payload.Double); + break; + case SqlitePramKind.Blob: + commandParameters.AddBytes(i + 1, p.Payload.BlobOrUtf8String.Span); break; } }