RestySqlite/DatabaseWrapper.cs

235 lines
6.8 KiB
C#
Raw Normal View History

2025-02-08 22:41:26 +03:00
using Microsoft.Data.Sqlite;
namespace RestySqlite
{
/**
<summary>
Structure that represents SQL command injection parameter
</summary>
<example>
<code>
string insertSql = "INSERT INTO users (name) VALUES (@name)";
db.ExecuteCommand(insertSql, new Parameter("@name", "John Doe");
</code>
</example>
**/
2025-02-08 22:41:26 +03:00
public struct Parameter
{
public string Name;
// Dynamic allows passing any type in db. Warning! type must be supported by db.
2025-02-08 22:41:26 +03:00
public dynamic Value;
public Parameter(string name, dynamic value)
{
Name = name;
Value = value;
}
}
/**
<summary>
Class that wraps around database with automatic connection managment and handy tools.
</summary>
*/
2025-02-08 22:41:26 +03:00
public class DatabaseWrapper
{
public SqliteConnection Connection {get;}
2025-02-08 22:41:26 +03:00
public string DatabaseName {get; set; }
/**
<summary>
Construct a database wrapper around provided database.
</summary>
**/
2025-02-08 22:41:26 +03:00
public DatabaseWrapper(string databaseName)
{
string connectionString = $"Data Source={databaseName}.db;";
DatabaseName = databaseName;
Connection = new(connectionString);
Console.WriteLine($"Connected to {DatabaseName}");
}
/**
<summary>
Execute SQL command with provided parameters.
</summary>
**/
2025-02-08 22:41:26 +03:00
public void ExecuteCommand(string sqlCommand, params Parameter[] parameters)
{
Connection.Open();
SqliteCommand comm = new(sqlCommand, Connection);
// Handling parameters by passing each in command.
2025-02-08 22:41:26 +03:00
if (parameters.Length != 0)
{
foreach (Parameter param in parameters)
{
comm.Parameters.AddWithValue(param.Name, param.Value);
}
}
comm.ExecuteNonQuery();
Connection.Close();
2025-02-08 22:41:26 +03:00
}
/**
<summary>
Execute SQL command with provided parameters and get reader from database.
</summary>
**/
2025-02-08 22:41:26 +03:00
public SqliteDataReader? GetReader(string sqlCommand, params Parameter[] parameters)
{
Connection.Open();
SqliteCommand comm = new(sqlCommand, Connection);
if (parameters.Length != 0)
{
foreach (Parameter param in parameters)
{
comm.Parameters.AddWithValue(param.Name, param.Value);
}
}
var reader = comm.ExecuteReader();
2025-02-08 22:41:26 +03:00
return reader;
}
/**
<summary>
Tool that parses entire database and returns all tables inside it.
<exception cref="NullReferenceException">
Throws NullReferenceException when reader is null for some reason.
</exception>
<example>
<code>
// For example:
var db = new DatabaseWrapper("example");
var tables = db.MapTables();
tables.ForEach(table => Console.WriteLine(table));
</code>
</example>
</summary>
**/
2025-02-08 22:41:26 +03:00
public List<string> MapTables()
{
var reader = GetReader(@"
2025-02-08 22:41:26 +03:00
SELECT *
FROM sqlite_master
WHERE type='table'
");
if (reader == null) throw new NullReferenceException("Reader is null");
2025-02-08 22:41:26 +03:00
List<string> tables = new();
using (reader)
{
while (reader.Read())
{
var table = reader.GetString(1);
tables.Add(table);
}
}
return tables;
}
/**
<summary>
Tool that parses entire database and returns dictionary.
Where table name is its <c>Key</c> and List of columns attached to this table is its <c>Value</c>.
<exception cref="NullReferenceException">
Throws NullReferenceException when reader is null for some reason.
</exception>
<example>
<code>
// For example:
var db = new DatabaseWrapper("example");
var tableColumns = db.MapColumns();
tables.ForEach(table => Console.WriteLine($"{table.Key} table {table.Value} list of collumns"));
</code>
</example>
</summary>
**/
2025-02-08 22:41:26 +03:00
public Dictionary<string, List<string>> MapColumns()
{
Dictionary<string, List<string>> columnMap = new();
var tables = MapTables();
2025-02-08 22:41:26 +03:00
foreach (string table in tables)
{
var reader = GetReader($"pragma table_info({table});");
if (reader == null) throw new NullReferenceException("Reader is null");
2025-02-08 22:41:26 +03:00
using (reader)
{
while (reader.Read())
{
var col = reader.GetString(1);
if (columnMap.ContainsKey(table))
{
columnMap[table].Add(col);
continue;
}
columnMap.Add(table,new List<string>{col});
}
}
}
return columnMap;
}
2025-02-08 22:41:26 +03:00
/**
<summary>
Tool that parses provided table and column.
<returns>
After execution it returns list of values inside provided column.
</returns>
<exception cref="NullReferenceException">
Throws NullReferenceException when reader is null for some reason.
</exception>
<example>
<code>
// For example:
var db = new DatabaseWrapper("example");
var usersnames = db.MapColumn("name", "users");
usernames.ForEach(name => Console.WriteLine(name));
</code>
</example>
</summary>
**/
public List<string>? MapColumn(string columnName, string tableName)
{
var reader = GetReader($"SELECT {columnName} FROM {tableName}");
// Using string. Because I cant know exactly which datatype I will encounter.
List<string> result = new();
if (reader == null) throw new NullReferenceException("Reader is null");
2025-02-08 22:41:26 +03:00
using (reader)
{
while (reader.Read())
2025-02-08 22:41:26 +03:00
{
result.Add(reader.GetString(0));
2025-02-08 22:41:26 +03:00
}
}
return result;
2025-02-08 22:41:26 +03:00
}
~DatabaseWrapper()
{
// Making sure that connection is closed.
2025-02-08 22:41:26 +03:00
Connection.Close();
Console.WriteLine($"Disconected from {DatabaseName}");
}
}
}