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 07a82f2..e2d3400 100644 Binary files a/test.db and b/test.db differ