Files
MoShiro/backend/src/MoShiro.Backend.Storage.Sqlite/Sql.cs
T
2026-10-07 16:57:34 +08:00

62 lines
2.7 KiB
C#

using Microsoft.Data.Sqlite;
namespace MoShiro.Backend.Storage.Sqlite;
/// <summary>手写的参数化 SQL 的小帮手:禁止字符串拼接值,所有值都经过参数。</summary>
internal static class Sql
{
public static SqliteCommand Cmd(this SqliteConnection connection, string sql, params (string Name, object? Value)[] parameters)
{
SqliteCommand command = connection.CreateCommand();
command.CommandText = sql;
foreach ((string name, object? value) in parameters)
{
command.Parameters.AddWithValue(name, value ?? DBNull.Value);
}
return command;
}
public static int Exec(this SqliteConnection connection, string sql, params (string Name, object? Value)[] parameters)
{
using SqliteCommand command = connection.Cmd(sql, parameters);
return command.ExecuteNonQuery();
}
public static T? Scalar<T>(this SqliteConnection connection, string sql, params (string Name, object? Value)[] parameters)
{
using SqliteCommand command = connection.Cmd(sql, parameters);
object? value = command.ExecuteScalar();
return value is null or DBNull ? default : (T)Convert.ChangeType(value, Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T), System.Globalization.CultureInfo.InvariantCulture);
}
public static List<T> Query<T>(this SqliteConnection connection, string sql, Func<SqliteDataReader, T> map, params (string Name, object? Value)[] parameters)
{
using SqliteCommand command = connection.Cmd(sql, parameters);
using SqliteDataReader reader = command.ExecuteReader();
var rows = new List<T>();
while (reader.Read())
{
rows.Add(map(reader));
}
return rows;
}
public static T? QueryOne<T>(this SqliteConnection connection, string sql, Func<SqliteDataReader, T> map, params (string Name, object? Value)[] parameters)
where T : class
{
using SqliteCommand command = connection.Cmd(sql, parameters);
using SqliteDataReader reader = command.ExecuteReader();
return reader.Read() ? map(reader) : null;
}
public static long? NullableLong(this SqliteDataReader reader, int ordinal) => reader.IsDBNull(ordinal) ? null : reader.GetInt64(ordinal);
public static string? NullableString(this SqliteDataReader reader, int ordinal) => reader.IsDBNull(ordinal) ? null : reader.GetString(ordinal);
public static byte[] Bytes(this SqliteDataReader reader, int ordinal) => (byte[])reader.GetValue(ordinal);
public static byte[]? NullableBytes(this SqliteDataReader reader, int ordinal) => reader.IsDBNull(ordinal) ? null : (byte[])reader.GetValue(ordinal);
}