comments, feature | Added new methods and comments that describe work of DatabaseWrapper

This commit is contained in:
Max Chaev 2025-02-09 12:42:07 +03:00
parent cad3b2ae0a
commit 4bdf5e6d41
3 changed files with 131 additions and 35 deletions

View File

@ -2,10 +2,23 @@ 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>
**/
public struct Parameter
{
public string Name;
// Dynamic allows passing any type in db. Warning! type must be supported by db.
public dynamic Value;
public Parameter(string name, dynamic value)
@ -14,12 +27,21 @@ namespace RestySqlite
Value = value;
}
}
/**
<summary>
Class that wraps around database with automatic connection managment and handy tools.
</summary>
*/
public class DatabaseWrapper
{
public SqliteConnection Connection {get; set;}
public SqliteConnection Connection {get;}
public string DatabaseName {get; set; }
/**
<summary>
Construct a database wrapper around provided database.
</summary>
**/
public DatabaseWrapper(string databaseName)
{
string connectionString = $"Data Source={databaseName}.db;";
@ -30,11 +52,16 @@ namespace RestySqlite
}
/**
<summary>
Execute SQL command with provided parameters.
</summary>
**/
public void ExecuteCommand(string sqlCommand, params Parameter[] parameters)
{
Connection.Open();
SqliteCommand comm = new(sqlCommand, Connection);
// Handling parameters by passing each in command.
if (parameters.Length != 0)
{
foreach (Parameter param in parameters)
@ -44,8 +71,15 @@ namespace RestySqlite
}
comm.ExecuteNonQuery();
Connection.Close();
}
/**
<summary>
Execute SQL command with provided parameters and get reader from database.
</summary>
**/
public SqliteDataReader? GetReader(string sqlCommand, params Parameter[] parameters)
{
Connection.Open();
@ -60,16 +94,36 @@ namespace RestySqlite
}
var reader = comm.ExecuteReader();
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>
**/
public List<string> MapTables()
{
var reader = this.GetReader(@"
var reader = GetReader(@"
SELECT *
FROM sqlite_master
WHERE type='table'
");
if (reader == null) throw new NullReferenceException("Reader is null");
List<string> tables = new();
using (reader)
@ -83,14 +137,35 @@ namespace RestySqlite
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>
**/
public Dictionary<string, List<string>> MapColumns()
{
Dictionary<string, List<string>> columnMap = new();
var tables = this.MapTables();
var tables = MapTables();
foreach (string table in tables)
{
var reader = this.GetReader($"pragma table_info({table});");
var reader = GetReader($"pragma table_info({table});");
if (reader == null) throw new NullReferenceException("Reader is null");
using (reader)
{
@ -106,35 +181,53 @@ namespace RestySqlite
}
}
}
return columnMap;
}
foreach (var table in columnMap)
/**
<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");
using (reader)
{
Console.WriteLine($"{table.Key}\n--------");
foreach (var column in table.Value)
while (reader.Read())
{
var reader = this.GetReader($"SELECT {column} FROM {table.Key}");
Console.WriteLine(column);
try
{
while (reader.Read())
{
Console.WriteLine(reader.GetString(0));
}
Console.WriteLine("---------");
}
catch (Exception e)
{
Console.WriteLine($"Something broken: {e.Message}");
}
result.Add(reader.GetString(0));
}
}
return columnMap;
return result;
}
~DatabaseWrapper()
{
// Making sure that connection is closed.
Connection.Close();
Console.WriteLine($"Disconected from {DatabaseName}");
}

View File

@ -6,16 +6,19 @@ namespace RestySqlite
{
DatabaseWrapper db = new("test");
/* string createTableSql = "CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)";
string insertSql = "INSERT INTO users (name, email) VALUES (@name, @email)";
//string createTableSql = "CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)";
/* string insertSql = "INSERT INTO users (name, email) VALUES (@name, @email)";
db.ExecuteCommand(createTableSql);
db.ExecuteCommand(insertSql, new Parameter("@name", "John Doe"),
db.ExecuteCommand(insertSql, new Parameter("@name", "Max Nullov"),
new Parameter("@email", "[not specified]"));
*/
db.MapColumns();
var usersnames = db.MapColumn("name", "users");
usersnames.ForEach(name => Console.WriteLine(name));
}
}
}

BIN
test.db

Binary file not shown.