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) { Name = name; Value = value; } } /** Class that wraps around database with automatic connection managment and handy tools. */ public class DatabaseWrapper { 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;"; DatabaseName = databaseName; Connection = new(connectionString); Console.WriteLine($"Connected to {DatabaseName}"); } /** 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) { comm.Parameters.AddWithValue(param.Name, param.Value); } } 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(); 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(); 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 = GetReader(@" SELECT * FROM sqlite_master WHERE type='table' "); if (reader == null) throw new NullReferenceException("Reader is null"); List tables = new(); using (reader) { while (reader.Read()) { var table = reader.GetString(1); tables.Add(table); } } 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 = MapTables(); foreach (string table in tables) { var reader = GetReader($"pragma table_info({table});"); if (reader == null) throw new NullReferenceException("Reader is null"); using (reader) { while (reader.Read()) { var col = reader.GetString(1); if (columnMap.ContainsKey(table)) { columnMap[table].Add(col); continue; } columnMap.Add(table,new List{col}); } } } return columnMap; } /** 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}"); } } }