private readonly int AbuseCount        = 3;  // max number of requests from the same IP within the AbuseTimeInterval

        public DbStorageManager(ILogger <DbStorageManager> logger, IConfiguration conf)
        {
            Configuration   = conf;
            Logger          = (Logger <DbStorageManager>)logger;
            this.DbProvider = conf.GetValue <DbLayerProvider>("DBLayerProvider");
            var    DbConnStr = conf.GetValue <string>("SqlDbConnStr");
            string connStr;

            //HashFunction = hashprovider;

            if (DbProvider == DbLayerProvider.Sqlite)
            {
                connStr = "Data Source=" + Program.SqliteDbLayerDataSource();
            }
            else
            {
                connStr = DbConnStr;
            }

            DbConnection DbConn; // Common DbConnection interface

            if (DbProvider == DbLayerProvider.Sqlite)
            {
                DbConn = new SqliteConnection(connStr);
            }
            else
            {
                DbConn = new MySqlConnection(connStr);
            }

            DBConnection = DbConn;
            Logger.LogInformation("DB Storage initiated and ready... Using {DbProvider.ToString()}, source: {DBConnection.DataSource}", DbProvider.ToString(), DBConnection.DataSource);
        }
        private static bool InitDB(DbConnection connection, DbLayerProvider provider)
        {
            string initscript;

            if (provider == DbLayerProvider.Sqlite)
            {
                initscript =
                    @"DROP TABLE IF EXISTS task_pipeline;
CREATE TABLE task_pipeline (
  timestamp bigint NOT NULL
, task text NOT NULL
, input text NULL
, result text NULL
, performed int  NOT NULL
, performed_when bigint NULL
, ip text NULL
, guid text NULL);
";
            }
            else
            {
                initscript =
                    @"DROP TABLE IF EXISTS task_pipeline;
CREATE TABLE task_pipeline (
  timestamp BIGINT NOT NULL
, task VARCHAR(50) NOT NULL
, input TEXT NULL
, result VARCHAR(255) NULL
, performed INT NOT NULL
, performed_when BIGINT NULL
, ip VARCHAR(100) NULL
, guid VARCHAR(100) NULL);
";
            }

            var c = connection.CreateCommand();

            c.CommandText = initscript;
            var res = false;

            connection.Open();
            try
            {
                c.ExecuteNonQuery();
                res = true;
            }
            catch (Exception)
            {
                res = false;
            }
            finally
            {
                connection.Close();
            }

            Console.WriteLine($"DB CREATED from scratch... Location: {connection.DataSource}");
            return(res);
        }
        public static bool IsDBLayerReady(string connectionstring = null, DbLayerProvider provider = DbLayerProvider.Sqlite)
        {
            var res = false;
            var SqliteDbBasePath = Program.SqliteDbLayerDataSource();
            var CacheFolderPath  = Program.CacheBasePath();

            var connStr = connectionstring;
            var initDB  = false;

            // Preparing cache folder
            if (!System.IO.Directory.Exists(CacheFolderPath))
            {
                try
                {
                    System.IO.Directory.CreateDirectory(CacheFolderPath);
                }
                catch (Exception e)
                {
                    Console.WriteLine($"Cache directory can't be created! Error: {e.Message}");
                    return(false);
                }
            }

            // Trying write access to that folder
            try
            {
                var TestFile = System.IO.Path.Combine(CacheFolderPath, "writable.test");
                System.IO.File.WriteAllText(TestFile, "test");
            }
            catch (Exception e)
            {
                Console.WriteLine($"It seems cache directory is not writable! Error: {e.Message}");
                return(false);
            }

            // Preparing cache folders

            if (provider == DbLayerProvider.Sqlite)
            {
                connStr = "Data Source=" + SqliteDbBasePath;
                if (!System.IO.File.Exists(SqliteDbBasePath)) // Sqlite DB file does not exist
                {
                    initDB = true;
                    Console.WriteLine($"Sqlite DB file not found! Location: {SqliteDbBasePath}");
                }
            }
            else // Other than Sqlite Provider
            {
                if (connStr is null)
                {
                    Console.WriteLine($"Connection string is missing for non-Sqlite DB! provider: {provider}");
                    return(false); // Connection string is missing for non Sqlite DB
                }
            }

            DbConnection DbConn; // Common DbConnection interface

            if (provider == DbLayerProvider.Sqlite)
            {
                DbConn = new SqliteConnection(connStr);
            }
            else
            {
                DbConn = new MySqlConnection(connStr);
            }

            using (DbConn)
            {
                var validDB = false;

                if (initDB == false)
                {
                    validDB = IsValidDBLayer(DbConn);
                }

                if (initDB || !validDB)           // some basic checks whether the DB is ok in terms of structure
                {
                    if (InitDB(DbConn, provider)) // let's create new DB from scratch
                    {
                        res = true;
                    }
                    else
                    {
                        res = false;
                    }
                }
                else
                {
                    res = true;
                }
            }
            return(res);
        }