2025-02-08 22:41:26 +03:00
|
|
|
using Microsoft.Data.Sqlite;
|
|
|
|
|
|
|
|
namespace RestySqlite
|
|
|
|
{
|
2025-02-09 12:42:07 +03:00
|
|
|
/**
|
|
|
|
<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;
|
2025-02-09 12:42:07 +03:00
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
}
|
2025-02-09 12:42:07 +03:00
|
|
|
/**
|
|
|
|
<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
|
|
|
|
{
|
2025-02-09 12:42:07 +03:00
|
|
|
public SqliteConnection Connection {get;}
|
2025-02-08 22:41:26 +03:00
|
|
|
public string DatabaseName {get; set; }
|
|
|
|
|
2025-02-09 12:42:07 +03:00
|
|
|
/**
|
|
|
|
<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}");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2025-02-09 12:42:07 +03:00
|
|
|
/**
|
|
|
|
<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);
|
2025-02-09 12:42:07 +03:00
|
|
|
// 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();
|
2025-02-09 12:42:07 +03:00
|
|
|
|
|
|
|
Connection.Close();
|
2025-02-08 22:41:26 +03:00
|
|
|
}
|
|
|
|
|
2025-02-09 12:42:07 +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-09 12:42:07 +03:00
|
|
|
|
2025-02-08 22:41:26 +03:00
|
|
|
return reader;
|
|
|
|
}
|
|
|
|
|
2025-02-09 12:42:07 +03:00
|
|
|
/**
|
|
|
|
<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()
|
|
|
|
{
|
2025-02-09 12:42:07 +03:00
|
|
|
var reader = GetReader(@"
|
2025-02-08 22:41:26 +03:00
|
|
|
SELECT *
|
|
|
|
FROM sqlite_master
|
|
|
|
WHERE type='table'
|
|
|
|
");
|
2025-02-09 12:42:07 +03:00
|
|
|
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;
|
|
|
|
}
|
2025-02-09 12:42:07 +03:00
|
|
|
/**
|
|
|
|
<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();
|
2025-02-09 12:42:07 +03:00
|
|
|
var tables = MapTables();
|
2025-02-08 22:41:26 +03:00
|
|
|
foreach (string table in tables)
|
|
|
|
{
|
2025-02-09 12:42:07 +03:00
|
|
|
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});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2025-02-09 12:42:07 +03:00
|
|
|
return columnMap;
|
|
|
|
}
|
2025-02-08 22:41:26 +03:00
|
|
|
|
2025-02-09 12:42:07 +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
|
|
|
|
2025-02-09 12:42:07 +03:00
|
|
|
using (reader)
|
|
|
|
{
|
|
|
|
while (reader.Read())
|
2025-02-08 22:41:26 +03:00
|
|
|
{
|
2025-02-09 12:42:07 +03:00
|
|
|
result.Add(reader.GetString(0));
|
2025-02-08 22:41:26 +03:00
|
|
|
}
|
|
|
|
}
|
2025-02-09 12:42:07 +03:00
|
|
|
|
|
|
|
return result;
|
2025-02-08 22:41:26 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
~DatabaseWrapper()
|
2025-02-09 12:42:07 +03:00
|
|
|
{
|
|
|
|
// Making sure that connection is closed.
|
2025-02-08 22:41:26 +03:00
|
|
|
Connection.Close();
|
|
|
|
Console.WriteLine($"Disconected from {DatabaseName}");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|