using Microsoft.Data.Sqlite;
using YKanBan.Storage;
using YKanBan.Storage.Workspace;
namespace YKanBan.Tests.TestUtilities;
///
/// Shared helpers for the storage tests: small SQL conveniences plus opening a
/// workspace database with the real migration list.
///
public static class SqliteTestHelper
{
///
/// Executes a non-query SQL statement and returns the affected row count.
///
/// An open database connection.
/// The statement to execute.
/// Name/value pairs bound as SQL parameters.
/// The number of affected rows.
public static int Exec(SqliteConnection connection, string sql, params (string Name, object? Value)[] parameters)
{
using var command = connection.CreateCommand();
command.CommandText = sql;
foreach ((string name, object? value) in parameters)
{
command.Parameters.AddWithValue(name, value);
}
return command.ExecuteNonQuery();
}
///
/// Returns the scalar result of a SQL query as a string.
///
/// An open database connection.
/// The query to execute.
/// The scalar result cast to a string.
public static string ScalarString(SqliteConnection connection, string sql)
{
using var command = connection.CreateCommand();
command.CommandText = sql;
return (string)command.ExecuteScalar()!;
}
///
/// Returns the scalar result of a SQL query as a long.
///
/// An open database connection.
/// The query to execute.
/// The scalar result cast to a long.
public static long ScalarLong(SqliteConnection connection, string sql)
{
using var command = connection.CreateCommand();
command.CommandText = sql;
return (long)command.ExecuteScalar()!;
}
///
/// Returns whether a table with the given name exists in the database.
///
/// An open database connection.
/// The table name to look for.
/// when the table exists.
public static bool TableExists(SqliteConnection connection, string tableName)
{
using var command = connection.CreateCommand();
command.CommandText = "SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name=$name;";
command.Parameters.AddWithValue("$name", tableName);
return (long)command.ExecuteScalar()! == 1;
}
///
/// Returns the titles of all columns, ordered by id ascending.
///
/// An open database connection.
/// The column titles in id order.
public static List GetColumnTitles(SqliteConnection connection)
{
using var command = connection.CreateCommand();
command.CommandText = "SELECT title FROM columns ORDER BY id ASC;";
using var reader = command.ExecuteReader();
var titles = new List();
while (reader.Read())
{
titles.Add(reader.GetString(0));
}
return titles;
}
///
/// Returns the descriptions of all columns, ordered by id ascending.
///
/// An open database connection.
/// The column descriptions in id order.
public static List GetColumnDescriptions(SqliteConnection connection)
{
using var command = connection.CreateCommand();
command.CommandText = "SELECT description FROM columns ORDER BY id ASC;";
using var reader = command.ExecuteReader();
var descriptions = new List();
while (reader.Read())
{
descriptions.Add(reader.GetString(0));
}
return descriptions;
}
///
/// Returns all tags as name/color/description tuples, ordered by id ascending.
///
/// An open database connection.
/// The tags in id order.
public static List<(string Name, string Color, string Description)> GetTags(SqliteConnection connection)
{
using var command = connection.CreateCommand();
command.CommandText = "SELECT name, color, description FROM tags ORDER BY id ASC;";
using var reader = command.ExecuteReader();
var tags = new List<(string, string, string)>();
while (reader.Read())
{
tags.Add((reader.GetString(0), reader.GetString(1), reader.GetString(2)));
}
return tags;
}
///
/// Opens a workspace database with the real workspace migration list.
///
/// The workspace folder path.
/// An open, migrated connection.
public static SqliteConnection OpenWorkspace(string folderPath)
{
return SqliteDatabase.Open(WorkspacePaths.Database(folderPath), WorkspaceSchema.Migrations);
}
}