mirror of https://bitbucket.org/anguist/ntpa
175 lines
5.9 KiB
C#
175 lines
5.9 KiB
C#
//
|
||
// Copyright (c) 2013-2016 Carsten Sonne Larsen <cs@innolan.dk>
|
||
//
|
||
// 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;
|
||
using System.Data;
|
||
using System.Diagnostics.CodeAnalysis;
|
||
using System.Text;
|
||
using Npgsql;
|
||
|
||
/**
|
||
*
|
||
* Npqsql Connection String Parameters:
|
||
* Ref: http://www.npgsql.org/doc/connection-string-parameters.html
|
||
*
|
||
* Note that by default, Npgsql will verify that your server’s certificate is valid.
|
||
* If you’re using a self-signed certificate this will fail. You can instruct Npgsql
|
||
* to ignore this by specifying Trust Server Certificate=true in the connection string.
|
||
* To precisely control how the server’s certificate is validated, you can register
|
||
* UserCertificateValidationCallback on NpgsqlConnection (this works just like on
|
||
* .NET’s SSLStream).
|
||
*
|
||
* You can also have Npgsql provide client certificates to the server by registering
|
||
* the ProvideClientCertificatesCallback on NpgsqlConnection (this works just like on
|
||
* .NET’s SSLStream).
|
||
*
|
||
* Ref: http://www.npgsql.org/doc/security.html
|
||
*
|
||
*/
|
||
|
||
namespace Ntp.Data.Provider
|
||
{
|
||
public sealed class PostgreSqlFactory : SqlDatabaseFactory
|
||
{
|
||
internal PostgreSqlFactory()
|
||
{
|
||
}
|
||
|
||
private const string CreateDatabaseSql1 =
|
||
"SELECT COUNT(*) FROM pg_database WHERE datname = lower('{0}');";
|
||
|
||
private const string CreateDatabaseSql2 =
|
||
"CREATE DATABASE {0};";
|
||
|
||
private const string CheckTableSql =
|
||
"SELECT * " +
|
||
"FROM information_schema.tables " +
|
||
"WHERE table_catalog = lower('{0}') " +
|
||
"AND table_name = lower('{1}');";
|
||
|
||
public override IDbCommand CreateCommand()
|
||
{
|
||
return new NpgsqlCommand();
|
||
}
|
||
|
||
public override IDbConnection CreateConnection()
|
||
{
|
||
return new NpgsqlConnection(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(CreateDatabaseSql1, Config.Name);
|
||
command.Prepare();
|
||
int count = Convert.ToInt32(command.ExecuteScalar());
|
||
|
||
if (count == 0)
|
||
{
|
||
command.CommandText = string.Format(CreateDatabaseSql2, Config.Name);
|
||
command.Prepare();
|
||
command.ExecuteNonQuery();
|
||
}
|
||
|
||
connection.Close();
|
||
}
|
||
|
||
public override IDbConnection CreateGenericConnection()
|
||
{
|
||
return new NpgsqlConnection(BuildConnectionString(false));
|
||
}
|
||
|
||
public override IDbDataParameter CreateParameter()
|
||
{
|
||
return new NpgsqlParameter();
|
||
}
|
||
|
||
public override IDbDataParameter CreateParameter(string name, object value)
|
||
{
|
||
return new NpgsqlParameter(name, value);
|
||
}
|
||
|
||
public override string PrepareCheckTableSql(string table)
|
||
{
|
||
return PrepareSql(string.Format(CheckTableSql, Config.Name, table));
|
||
}
|
||
|
||
public override string PrepareCreateTableSql(string sql)
|
||
{
|
||
string sql2 = sql.
|
||
Replace("UNIQUE KEY", "UNIQUE").
|
||
Replace("BIT(1)", "BOOL");
|
||
|
||
return PrepareSql(string.Format(sql2, "SERIAL", string.Empty));
|
||
}
|
||
|
||
public override string PrepareInsertSql(string sql)
|
||
{
|
||
return PrepareSql(string.Format(sql, "SELECT LASTVAL();"));
|
||
}
|
||
|
||
public override string PrepareSql(string sql)
|
||
{
|
||
return sql.Replace('[', '\"').Replace(']', '\"');
|
||
}
|
||
|
||
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};");
|
||
|
||
b.Append(includeName ? $"Database={Config.Name};" : @"Database=postgres;");
|
||
|
||
b.Append($"User Id={Config.User};");
|
||
b.Append($"Password={Config.Pass};");
|
||
|
||
if (Config.ConnectionTimeout.HasValue)
|
||
b.Append($"Timeout={Config.ConnectionTimeout.Value};");
|
||
|
||
if (Config.EnableSsl)
|
||
{
|
||
b.Append(@"SSL=true;");
|
||
b.Append(@"SslMode=Require;");
|
||
}
|
||
else
|
||
{
|
||
b.Append(@"SSL=false;");
|
||
b.Append(@"SslMode=Disable;");
|
||
}
|
||
|
||
if (Config.Protocol.HasValue)
|
||
b.Append($"Protocol={Config.Protocol.Value};");
|
||
|
||
return b.ToString();
|
||
}
|
||
}
|
||
} |