// // Copyright (c) 2013-2016 Carsten Sonne Larsen // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using System.Data; using System.Diagnostics.CodeAnalysis; using System.Text; using MySql.Data.MySqlClient; namespace Ntp.Data.Provider { public sealed class MySqlFactory : SqlDatabaseFactory { internal MySqlFactory() { } private const string CreateDatabaseSql = "CREATE DATABASE IF NOT EXISTS {0};"; private const string CheckTableSql = "SELECT table_name " + "FROM information_schema.tables " + "WHERE table_schema = '{0}' " + "AND table_name = '{1}';"; public override IDbCommand CreateCommand() { return new MySqlCommand(); } public override IDbConnection CreateConnection() { return new MySqlConnection(BuildConnectionString()); } [SuppressMessage("Microsoft.Security", "CA2100:Review SQL queries for security vulnerabilities")] public override void CreateDatabase() { var connection = CreateGenericConnection(); connection.Open(); var command = Instance.CreateCommand(); command.Connection = connection; command.CommandText = string.Format(CreateDatabaseSql, Config.Name); command.Prepare(); connection.Close(); } public override IDbConnection CreateGenericConnection() { return new MySqlConnection(BuildConnectionString(false)); } public override IDbDataParameter CreateParameter(string name, object value) { return new MySqlParameter(name, value); } public override string DateAddMinutes(string dateColumn, string minuteColumn) { return $"{dateColumn} - interval {minuteColumn} minute"; } public override string PrepareCheckTableSql(string table) { return PrepareSql(string.Format(CheckTableSql, Config.Name, table)); } public override string PrepareCreateTableSql(string sql) { return PrepareSql(string.Format(sql, "INT NOT NULL AUTO_INCREMENT", " ENGINE=INNODB")); } public override string PrepareInsertSql(string sql) { return PrepareSql(string.Format(sql, "SELECT LAST_INSERT_ID()")); } public override string PrepareSql(string sql) { return sql.Replace("[", string.Empty).Replace("]", string.Empty); } private static string BuildConnectionString(bool includeName = true) { if (Config.ConnectionString != null) return Config.ConnectionString; var b = new StringBuilder(); b.Append($"Server={Config.Host};"); if (Config.Port != null) b.Append($"Port={Config.Port};"); if (includeName) b.Append($"Database={Config.Name};"); b.Append($"Uid={Config.User};"); b.Append($"Pwd={Config.Pass};"); if (Config.EnableSsl) b.Append(@"SSL Mode=Required;"); if (Config.CertificateFile != null) b.Append($"CertificateFile={Config.CertificateFile};"); if (Config.CertificatePassword != null) b.Append($"CertificatePassword={Config.CertificatePassword};"); if (Config.ConnectionTimeout.HasValue) b.Append($"Connection Timeout={Config.ConnectionTimeout.Value};"); return b.ToString(); } } }