From 4bdf5e6d416a1f0acc6acba338fabcb767bc8962 Mon Sep 17 00:00:00 2001 From: Max Nullov Date: Sun, 9 Feb 2025 12:42:07 +0300 Subject: [PATCH] comments, feature | Added new methods and comments that describe work of DatabaseWrapper --- DatabaseWrapper.cs | 155 ++++++++++++++++++++++++++++++++++++--------- WebApi.cs | 11 ++-- test.db | Bin 8192 -> 8192 bytes 3 files changed, 131 insertions(+), 35 deletions(-) diff --git a/DatabaseWrapper.cs b/DatabaseWrapper.cs index 55b202c..aef34e0 100644 --- a/DatabaseWrapper.cs +++ b/DatabaseWrapper.cs @@ -2,10 +2,23 @@ using Microsoft.Data.Sqlite; namespace RestySqlite { + /** + + Structure that represents SQL command injection parameter + + + + string insertSql = "INSERT INTO users (name) VALUES (@name)"; + + db.ExecuteCommand(insertSql, new Parameter("@name", "John Doe"); + + + **/ 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; } } - + /** + + Class that wraps around database with automatic connection managment and handy tools. + + */ public class DatabaseWrapper { - public SqliteConnection Connection {get; set;} + public SqliteConnection Connection {get;} public string DatabaseName {get; set; } + /** + + Construct a database wrapper around provided database. + + **/ public DatabaseWrapper(string databaseName) { string connectionString = $"Data Source={databaseName}.db;"; @@ -30,11 +52,16 @@ namespace RestySqlite } + /** + + Execute SQL command with provided parameters. + + **/ 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(); } + /** + + Execute SQL command with provided parameters and get reader from database. + + **/ public SqliteDataReader? GetReader(string sqlCommand, params Parameter[] parameters) { Connection.Open(); @@ -60,16 +94,36 @@ namespace RestySqlite } var reader = comm.ExecuteReader(); + return reader; } + /** + + Tool that parses entire database and returns all tables inside it. + + + Throws NullReferenceException when reader is null for some reason. + + + + + // For example: + var db = new DatabaseWrapper("example"); + var tables = db.MapTables(); + tables.ForEach(table => Console.WriteLine(table)); + + + + **/ public List 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 tables = new(); using (reader) @@ -83,14 +137,35 @@ namespace RestySqlite return tables; } + /** + + Tool that parses entire database and returns dictionary. + Where table name is its Key and List of columns attached to this table is its Value. + + + Throws NullReferenceException when reader is null for some reason. + + + + + // For example: + var db = new DatabaseWrapper("example"); + var tableColumns = db.MapColumns(); + tables.ForEach(table => Console.WriteLine($"{table.Key} table {table.Value} list of collumns")); + + + + **/ public Dictionary> MapColumns() { Dictionary> 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 } } } - - foreach (var table in columnMap) - { - Console.WriteLine($"{table.Key}\n--------"); - - foreach (var column in table.Value) - { - 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}"); - } - - } - } return columnMap; } - ~DatabaseWrapper() + /** + + Tool that parses provided table and column. + + After execution it returns list of values inside provided column. + + + + Throws NullReferenceException when reader is null for some reason. + + + + + // For example: + var db = new DatabaseWrapper("example"); + var usersnames = db.MapColumn("name", "users"); + + usernames.ForEach(name => Console.WriteLine(name)); + + + + **/ + public List? 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 result = new(); + + if (reader == null) throw new NullReferenceException("Reader is null"); + + using (reader) + { + while (reader.Read()) + { + result.Add(reader.GetString(0)); + } + } + + return result; + } + + ~DatabaseWrapper() + { + // Making sure that connection is closed. Connection.Close(); Console.WriteLine($"Disconected from {DatabaseName}"); } diff --git a/WebApi.cs b/WebApi.cs index dd132a9..f16491d 100644 --- a/WebApi.cs +++ b/WebApi.cs @@ -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)); } } } \ No newline at end of file diff --git a/test.db b/test.db index 07a82f24fd5c521d3f8a8a38c58d511bd0e57e37..e2d340052f0b1e6fa1e9ea7a42ca0432aaf37b45 100644 GIT binary patch delta 159 zcmZp0XmFSy&B!`Y#+i|IW5N=C9v1#q2L8wVNBEcUw{8{`DCMt~Wnp1Z)b>rRQ1C0w z$;mH^&dV=RC@x4%&P>ZpO^KCbW?@j)b}da$%}Z7AC{52mlb2-zX?M-ZNzGI6N-Qr% Wla^*=VUX4K%FoDCaLG?alLP?pkukLZ delta 62 zcmZp0XmFSy&B!!S#+i|6W5N=CHb(x(4E&Eb3ksC*Pi#n)m1bmNkk$6e&&X47$xn^W S%P&zVE=WzzOv_A7i3I>EWD>ss