Init Commit

Works:

-Databases
--MySql/Mariadb
--MongoDB
--Postgres

-Formatting
-JSON
-XML
-HTML

Todo:
-Databases
--SQLite
--Firebird
master
exsersewo 4 years ago
parent 5b08eb5819
commit 0dd65e7f9a
  1. 25
      src/RestAPI/RestAPI.sln
  2. 7
      src/RestAPI/RestAPI/.env.default
  3. 115
      src/RestAPI/RestAPI/Clients/FirebirdClient.cs
  4. 109
      src/RestAPI/RestAPI/Clients/MongoDbClient.cs
  5. 114
      src/RestAPI/RestAPI/Clients/MySqlClient.cs
  6. 117
      src/RestAPI/RestAPI/Clients/NpgsqlClient.cs
  7. 115
      src/RestAPI/RestAPI/Clients/SQLiteClient.cs
  8. 227
      src/RestAPI/RestAPI/Controllers/TableController.cs
  9. 25
      src/RestAPI/RestAPI/ExceptionFilters/HttpResponseExceptionFilter.cs
  10. 23
      src/RestAPI/RestAPI/Exceptions/HttpResponseException.cs
  11. 18
      src/RestAPI/RestAPI/Interfaces/IDatabaseClient.cs
  12. 12
      src/RestAPI/RestAPI/OutputFormatters/HtmlOutputFormatter.cs
  13. 27
      src/RestAPI/RestAPI/Program.cs
  14. 30
      src/RestAPI/RestAPI/Properties/launchSettings.json
  15. 18
      src/RestAPI/RestAPI/RestAPI.csproj
  16. 205
      src/RestAPI/RestAPI/Startup.cs
  17. 9
      src/RestAPI/RestAPI/appsettings.Development.json
  18. 10
      src/RestAPI/RestAPI/appsettings.json

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30615.102
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RestAPI", "RestAPI\RestAPI.csproj", "{3929B199-3AEB-41BA-993B-DA1AF2A73CA3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3929B199-3AEB-41BA-993B-DA1AF2A73CA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3929B199-3AEB-41BA-993B-DA1AF2A73CA3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3929B199-3AEB-41BA-993B-DA1AF2A73CA3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3929B199-3AEB-41BA-993B-DA1AF2A73CA3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {972DCCF9-29C3-427D-82B0-1DA966964D24}
EndGlobalSection
EndGlobal

@ -0,0 +1,7 @@
DATASOURCE=
HOST=
HOSTPORT=
USERNAME=
PASSWORD=
DATABASE=
BLACKLISTEDFIELDS=

@ -0,0 +1,115 @@
using FirebirdSql.Data.FirebirdClient;
using RestAPI.Interfaces;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Threading.Tasks;
namespace RestAPI.Clients
{
public class FirebirdClient : IDatabaseClient
{
FbConnection connection;
IEnumerable<string> Tables;
public FirebirdClient(string connectionString)
{
connection = new FbConnection(connectionString);
}
public async Task CloseAsync()
{
if (connection.State != System.Data.ConnectionState.Closed)
{
await connection.CloseAsync();
}
}
public async Task<bool> DoesTableExistAsync(string tableName)
{
if (Tables == null || !Tables.Any())
{
await GetTablesAsync().ConfigureAwait(false);
}
return Tables.Select(x => x.ToLowerInvariant()).Contains(tableName.ToLowerInvariant());
}
public async Task<object> GetTableAsync(string tableName, string[] blacklistedFields = null)
{
if (blacklistedFields == null)
{
blacklistedFields = new string[0];
}
List<List<KeyValuePair<string, string>>> content = null;
FbCommand cmd = new FbCommand($"SELECT * FROM `{tableName}`", connection);
var reader = await cmd.ExecuteReaderAsync();
if (reader.HasRows)
{
content = new List<List<KeyValuePair<string, string>>>();
while (await reader.ReadAsync())
{
var colSchema = reader.GetColumnSchema();
List<KeyValuePair<string, string>> obj = new List<KeyValuePair<string, string>>();
for (int col = 0; col < colSchema.Count; col++)
{
if (!blacklistedFields.Contains(colSchema[col].ColumnName.ToLowerInvariant()))
{
obj.Add(
new KeyValuePair<string, string>(
colSchema[col].ColumnName,
Convert.ToString(reader[col])
)
);
}
}
content.Add(obj);
}
}
await reader.CloseAsync();
return content;
}
public async Task<IEnumerable<string>> GetTablesAsync()
{
if (Tables == null || !Tables.Any())
{
List<string> TableNames = new List<string>();
FbCommand command = new FbCommand($"SHOW TABLES FROM `{connection.Database}`", connection);
using (var reader = await command.ExecuteReaderAsync())
{
while (await reader.ReadAsync())
{
TableNames.Add(reader.GetString(0));
}
await reader.CloseAsync();
}
Tables = TableNames;
}
return Tables;
}
public async Task OpenAsync()
{
if (connection.State != System.Data.ConnectionState.Open)
{
await connection.OpenAsync();
}
}
}
}

@ -0,0 +1,109 @@
using Microsoft.AspNetCore.Routing;
using MongoDB.Driver;
using MongoDB.Driver.Core.Clusters;
using RestAPI.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace RestAPI.Clients
{
public class MongoDbClient : IDatabaseClient
{
string database;
string connectionString;
MongoClient connection;
IEnumerable<string> Tables;
public MongoDbClient(string connectionString, string database)
{
this.connectionString = connectionString;
this.database = database;
connection = new MongoClient(connectionString);
}
public Task CloseAsync()
{
connection.Cluster.Dispose();
return Task.CompletedTask;
}
public async Task<bool> DoesTableExistAsync(string tableName)
{
if (Tables == null || !Tables.Any())
{
await GetTablesAsync().ConfigureAwait(false);
}
return Tables.Select(x => x.ToLowerInvariant()).Contains(tableName.ToLowerInvariant());
}
public async Task<object> GetTableAsync(string tableName, string[] blacklistedFields = null)
{
if (blacklistedFields == null)
{
blacklistedFields = new string[0];
}
List<List<KeyValuePair<string, string>>> content = null;
var database = connection.GetDatabase(this.database);
var collection = database.GetCollection<dynamic>(tableName);
var entries = await (await collection.FindAsync(_ => true)).ToListAsync();
if (entries.Count > 0)
{
content = new List<List<KeyValuePair<string, string>>>();
foreach (dynamic entry in entries)
{
var res = new RouteValueDictionary(entry);
foreach (var blacklisted in blacklistedFields)
{
if (res.ContainsKey(blacklisted))
{
res.Remove(blacklisted);
}
}
List<KeyValuePair<string, string>> obj = new List<KeyValuePair<string, string>>();
foreach (var ent in res)
{
obj.Add(new KeyValuePair<string, string>(ent.Key, Convert.ToString(ent.Value)));
}
content.Add(obj);
}
}
return content;
}
public async Task<IEnumerable<string>> GetTablesAsync()
{
if (Tables == null || !Tables.Any())
{
var database = connection.GetDatabase(this.database);
Tables = await (await database.ListCollectionNamesAsync()).ToListAsync();
}
return Tables;
}
public Task OpenAsync()
{
if (connection.Cluster.Description.State != ClusterState.Connected)
{
connection = new MongoClient(connectionString);
}
return Task.CompletedTask;
}
}
}

@ -0,0 +1,114 @@
using MySqlConnector;
using RestAPI.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace RestAPI.Clients
{
public class MySqlClient : IDatabaseClient
{
MySqlConnection connection;
IEnumerable<string> Tables;
public MySqlClient(string connectionString)
{
connection = new MySqlConnection(connectionString);
}
public async Task CloseAsync()
{
if (connection.State != System.Data.ConnectionState.Closed)
{
await connection.CloseAsync();
}
}
public async Task<bool> DoesTableExistAsync(string tableName)
{
if (Tables == null || !Tables.Any())
{
await GetTablesAsync().ConfigureAwait(false);
}
return Tables.Select(x => x.ToLowerInvariant()).Contains(tableName.ToLowerInvariant());
}
public async Task<object> GetTableAsync(string tableName, string[] blacklistedFields = null)
{
if (blacklistedFields == null)
{
blacklistedFields = new string[0];
}
List<List<KeyValuePair<string, string>>> content = null;
MySqlCommand cmd = new MySqlCommand($"SELECT * FROM `{tableName}`", connection);
var reader = await cmd.ExecuteReaderAsync();
if (reader.HasRows)
{
content = new List<List<KeyValuePair<string, string>>>();
while (await reader.ReadAsync())
{
var colSchema = await reader.GetColumnSchemaAsync();
List<KeyValuePair<string, string>> obj = new List<KeyValuePair<string, string>>();
for (int col = 0; col < colSchema.Count; col++)
{
if (!blacklistedFields.Contains(colSchema[col].ColumnName.ToLowerInvariant()))
{
obj.Add(
new KeyValuePair<string, string>(
colSchema[col].ColumnName,
Convert.ToString(reader[col])
)
);
}
}
content.Add(obj);
}
}
await reader.CloseAsync();
return content;
}
public async Task<IEnumerable<string>> GetTablesAsync()
{
if (Tables == null || !Tables.Any())
{
List<string> TableNames = new List<string>();
MySqlCommand command = new MySqlCommand($"SHOW TABLES FROM `{connection.Database}`", connection);
using (var reader = await command.ExecuteReaderAsync())
{
while (await reader.ReadAsync())
{
TableNames.Add(reader.GetString(0));
}
await reader.CloseAsync();
}
Tables = TableNames;
}
return Tables;
}
public async Task OpenAsync()
{
if (connection.State != System.Data.ConnectionState.Open)
{
await connection.OpenAsync();
}
}
}
}

@ -0,0 +1,117 @@
using Npgsql;
using RestAPI.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace RestAPI.Clients
{
public class NpgsqlClient : IDatabaseClient
{
NpgsqlConnection connection;
IEnumerable<string> Tables;
public NpgsqlClient(string connectionString)
{
connection = new NpgsqlConnection(connectionString);
}
public async Task CloseAsync()
{
if (connection.State != System.Data.ConnectionState.Closed)
{
await connection.CloseAsync();
}
}
public async Task<bool> DoesTableExistAsync(string tableName)
{
if (Tables == null || !Tables.Any())
{
await GetTablesAsync().ConfigureAwait(false);
}
return Tables.Select(x => x.ToLowerInvariant()).Contains(tableName.ToLowerInvariant());
}
public async Task<object> GetTableAsync(string tableName, string[] blacklistedFields = null)
{
if (blacklistedFields == null)
{
blacklistedFields = new string[0];
}
List<List<KeyValuePair<string, string>>> content = null;
NpgsqlCommand cmd = new NpgsqlCommand($"SELECT * FROM {tableName}", connection);
var reader = await cmd.ExecuteReaderAsync();
if (reader.HasRows)
{
content = new List<List<KeyValuePair<string, string>>>();
while (await reader.ReadAsync())
{
var colSchema = await reader.GetColumnSchemaAsync();
List<KeyValuePair<string, string>> obj = new List<KeyValuePair<string, string>>();
for (int col = 0; col < colSchema.Count; col++)
{
if (!blacklistedFields.Contains(colSchema[col].ColumnName.ToLowerInvariant()))
{
obj.Add(
new KeyValuePair<string, string>(
colSchema[col].ColumnName,
Convert.ToString(reader[col])
)
);
}
}
content.Add(obj);
}
}
await reader.CloseAsync();
return content;
}
public async Task<IEnumerable<string>> GetTablesAsync()
{
if (Tables == null || !Tables.Any())
{
List<string> TableNames = new List<string>();
NpgsqlCommand command = new NpgsqlCommand("SELECT * FROM information_schema.tables", connection);
using (var reader = await command.ExecuteReaderAsync())
{
if (reader.HasRows)
{
while (await reader.ReadAsync())
{
TableNames.Add(Convert.ToString($"{reader["table_schema"]}.{reader["table_name"]}"));
}
}
await reader.CloseAsync();
}
Tables = TableNames;
}
return Tables;
}
public async Task OpenAsync()
{
if (connection.State != System.Data.ConnectionState.Open)
{
await connection.OpenAsync();
}
}
}
}

@ -0,0 +1,115 @@
using Microsoft.Data.Sqlite;
using RestAPI.Interfaces;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Threading.Tasks;
namespace RestAPI.Clients
{
public class SQLiteClient : IDatabaseClient
{
SqliteConnection connection;
IEnumerable<string> Tables;
public SQLiteClient(string connectionString)
{
connection = new SqliteConnection(connectionString);
}
public async Task CloseAsync()
{
if (connection.State != System.Data.ConnectionState.Closed)
{
await connection.CloseAsync();
}
}
public async Task<bool> DoesTableExistAsync(string tableName)
{
if (Tables == null || !Tables.Any())
{
await GetTablesAsync().ConfigureAwait(false);
}
return Tables.Select(x => x.ToLowerInvariant()).Contains(tableName.ToLowerInvariant());
}
public async Task<object> GetTableAsync(string tableName, string[] blacklistedFields = null)
{
if (blacklistedFields == null)
{
blacklistedFields = new string[0];
}
List<List<KeyValuePair<string, string>>> content = null;
SqliteCommand cmd = new SqliteCommand($"SELECT * FROM `{tableName}`", connection);
var reader = await cmd.ExecuteReaderAsync();
if (reader.HasRows)
{
content = new List<List<KeyValuePair<string, string>>>();
while (await reader.ReadAsync())
{
var colSchema = reader.GetColumnSchema();
List<KeyValuePair<string, string>> obj = new List<KeyValuePair<string, string>>();
for (int col = 0; col < colSchema.Count; col++)
{
if (!blacklistedFields.Contains(colSchema[col].ColumnName.ToLowerInvariant()))
{
obj.Add(
new KeyValuePair<string, string>(
colSchema[col].ColumnName,
Convert.ToString(reader[col])
)
);
}
}
content.Add(obj);
}
}
await reader.CloseAsync();
return content;
}
public async Task<IEnumerable<string>> GetTablesAsync()
{
if (Tables == null || !Tables.Any())
{
List<string> TableNames = new List<string>();
SqliteCommand command = new SqliteCommand($"SHOW TABLES FROM `{connection.Database}`", connection);
using (var reader = await command.ExecuteReaderAsync())
{
while (await reader.ReadAsync())
{
TableNames.Add(reader.GetString(0));
}
await reader.CloseAsync();
}
Tables = TableNames;
}
return Tables;
}
public async Task OpenAsync()
{
if (connection.State != System.Data.ConnectionState.Open)
{
await connection.OpenAsync();
}
}
}
}

@ -0,0 +1,227 @@
using HtmlAgilityPack;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using RestAPI.Clients;
using RestAPI.Exceptions;
using RestAPI.Interfaces;
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Net;
using System.Xml;
// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
namespace RestAPI.Controllers
{
[Route("table")]
[ApiController]
public class TableController : ControllerBase
{
private readonly IDatabaseClient database;
private readonly IEnumerable<string> BlacklistedFields;
public TableController(IDatabaseClient database)
{
this.database = database;
var fields = Environment.GetEnvironmentVariable("BLACKLISTEDFIELDS");
if (fields != null)
{
BlacklistedFields = fields.Split(",").Select(x => x.ToLowerInvariant());
}
else
{
BlacklistedFields = new List<string>();
}
}
private dynamic ConvertResponse(List<List<KeyValuePair<string, string>>> tableContent, string format, HttpResponse Response)
{
switch (format.ToLowerInvariant())
{
case "json":
{
Response.ContentType = "application/json";
List<dynamic> content = new List<dynamic>();
foreach (var result in tableContent)
{
dynamic item = new ExpandoObject();
var dItem = item as IDictionary<string, object>;
foreach (var attr in result)
{
dItem.Add(attr.Key, attr.Value);
}
content.Add(item);
}
return content;
}
case "xml":
{
Response.ContentType = "text/xml";
var doc = new XmlDocument();
var results = doc.CreateNode(XmlNodeType.Element, null, "results", null);
foreach (var result in tableContent)
{
var res = doc.CreateNode(XmlNodeType.Element, null, "result", null);
foreach (var attr in result)
{
var resEl = doc.CreateNode(XmlNodeType.Element, null, attr.Key, null);
resEl.InnerText = attr.Value;
res.AppendChild(resEl);
}
results.AppendChild(res);
doc.AppendChild(results);
}
return doc;
}
case "html":
{
Response.ContentType = "text/html";
var doc = new HtmlDocument();
var html = doc.CreateElement("html");
var body = doc.CreateElement("body");
var table = doc.CreateElement("table");
var thead = doc.CreateElement("thead");
var theadr = doc.CreateElement("tr");
doc.DocumentNode.AppendChild(html);
html.AppendChild(body);
body.AppendChild(table);
table.AppendChild(thead);
thead.AppendChild(theadr);
foreach (var attr in tableContent[0])
{
var th = doc.CreateElement("th");
th.InnerHtml = attr.Key;
theadr.AppendChild(th);
}
var tbody = doc.CreateElement("tbody");
table.AppendChild(tbody);
foreach (var result in tableContent)
{
var row = doc.CreateElement("tr");
foreach (var attr in result)
{
var resEl = doc.CreateElement("td");
resEl.InnerHtml = attr.Value;
row.AppendChild(resEl);
}
tbody.AppendChild(row);
}
return doc.DocumentNode.InnerHtml;
}
default:
return null;
}
}
[HttpGet]
public string Get()
{
throw new HttpResponseException(HttpStatusCode.BadRequest, "Must enter a valid table");
}
[HttpGet("{table}.{format}")]
public dynamic Get(string table, string format)
{
database.OpenAsync().GetAwaiter().GetResult();
string tableLocation = table;
if (database is NpgsqlClient)
{
tableLocation = $"public.{table}";
}
if (database.DoesTableExistAsync(tableLocation).GetAwaiter().GetResult())
{
var tableContent = database.GetTableAsync(tableLocation, BlacklistedFields.ToArray()).GetAwaiter().GetResult();
dynamic response = null;
if (tableContent != null)
{
response = ConvertResponse(tableContent as List<List<KeyValuePair<string, string>>>, format, Response);
}
if (response != null)
{
return response;
}
else
{
throw new HttpResponseException(HttpStatusCode.NotFound, $"Data within table \"{tableLocation}\" not found");
}
}
else
{
throw new HttpResponseException(HttpStatusCode.NotFound, $"Table \"{tableLocation}\" not found");
}
}
[HttpGet("{area}/{table}.{format}")]
public dynamic Get(string area, string table, string format)
{
database.OpenAsync().GetAwaiter().GetResult();
string tableLocation;
if (database is NpgsqlClient)
{
tableLocation = $"{area}.{table}";
}
else
{
tableLocation = $"{area}/{table}"; //default assumption for now
}
if (database.DoesTableExistAsync(tableLocation).GetAwaiter().GetResult())
{
var tableContent = database.GetTableAsync(tableLocation, BlacklistedFields.ToArray()).GetAwaiter().GetResult();
dynamic response = null;
if (tableContent != null)
{
response = ConvertResponse(tableContent as List<List<KeyValuePair<string, string>>>, format, Response);
}
if (response != null)
{
return response;
}
else
{
throw new HttpResponseException(HttpStatusCode.NotFound, $"Data within table \"{tableLocation}\" not found");
}
}
else
{
throw new HttpResponseException(HttpStatusCode.NotFound, $"Table \"{tableLocation}\" not found");
}
}
}
}

@ -0,0 +1,25 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using RestAPI.Exceptions;
namespace RestAPI.ExceptionFilters
{
public class HttpResponseExceptionFilter : IActionFilter, IOrderedFilter
{
public int Order { get; } = int.MaxValue - 10;
public void OnActionExecuting(ActionExecutingContext context) { }
public void OnActionExecuted(ActionExecutedContext context)
{
if (context.Exception is HttpResponseException exception)
{
context.Result = new ObjectResult(exception.Value)
{
StatusCode = exception.Status,
};
context.ExceptionHandled = true;
}
}
}
}

@ -0,0 +1,23 @@
using System;
using System.Net;
namespace RestAPI.Exceptions
{
public class HttpResponseException : Exception
{
public int Status { get; set; } = 500;
public object Value { get; set; }
public HttpResponseException(int statusCode, object val)
{
Status = statusCode;
Value = val;
}
public HttpResponseException(HttpStatusCode statusCode, object val) : this((int)statusCode, val)
{
}
}
}

@ -0,0 +1,18 @@
using System.Collections.Generic;
using System.Threading.Tasks;
namespace RestAPI.Interfaces
{
public interface IDatabaseClient
{
public Task OpenAsync();
public Task CloseAsync();
public Task<object> GetTableAsync(string tableName, string[] blacklistedFields = null);
public Task<bool> DoesTableExistAsync(string tableName);
public Task<IEnumerable<string>> GetTablesAsync();
}
}

@ -0,0 +1,12 @@
using Microsoft.AspNetCore.Mvc.Formatters;
namespace RestAPI.OutputFormatters
{
public class HtmlOutputFormatter : StringOutputFormatter
{
public HtmlOutputFormatter()
{
SupportedMediaTypes.Add("text/html");
}
}
}

@ -0,0 +1,27 @@
using dotenv.net;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using System;
using System.IO;
namespace RestAPI
{
public class Program
{
public static void Main(string[] args)
{
string envFile = Path.Combine(AppContext.BaseDirectory, ".env");
DotEnv.Config(false, filePath: envFile);
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}

@ -0,0 +1,30 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iis": {
"applicationUrl": "http://localhost/RestAPI",
"sslPort": 0
},
"iisExpress": {
"applicationUrl": "http://localhost:35486",
"sslPort": 44381
}
},
"$schema": "http://json.schemastore.org/launchsettings.json",
"profiles": {
"IIS Express": {
"commandName": "IIS",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"RestAPI": {
"commandName": "Project",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://0.0.0.0:5001;http://0.0.0.0:5000"
}
}
}

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="dotenv.net" Version="2.1.1" />
<PackageReference Include="FirebirdSql.Data.FirebirdClient" Version="7.10.1" />
<PackageReference Include="HtmlAgilityPack" Version="1.11.29" />
<PackageReference Include="Microsoft.Data.Sqlite.Core" Version="5.0.1" />
<PackageReference Include="MongoDB.Driver" Version="2.11.5" />
<PackageReference Include="MySqlConnector" Version="1.2.1" />
<PackageReference Include="Npgsql" Version="5.0.1.1" />
</ItemGroup>
</Project>

@ -0,0 +1,205 @@
using FirebirdSql.Data.FirebirdClient;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Data.Sqlite;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using MongoDB.Driver;
using MySqlConnector;
using Npgsql;
using RestAPI.Clients;
using RestAPI.ExceptionFilters;
using RestAPI.Interfaces;
using RestAPI.OutputFormatters;
using System;
using System.IO;
using System.Linq;
namespace RestAPI
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
string dataSource = Environment.GetEnvironmentVariable("DATASOURCE");
if (dataSource != null)
{
string serverHost = Environment.GetEnvironmentVariable("HOST");
string serverHostPort = Environment.GetEnvironmentVariable("HOSTPORT");
string username = Environment.GetEnvironmentVariable("USERNAME");
string password = Environment.GetEnvironmentVariable("PASSWORD");
string database = Environment.GetEnvironmentVariable("DATABASE");
ushort hostPort = 0;
if (!ushort.TryParse(serverHostPort, out hostPort))
{
}
switch (dataSource.ToLowerInvariant())
{
case "mysql":
case "mariadb":
{
if (hostPort == 0)
{
hostPort = 3306;
}
services.AddSingleton<IDatabaseClient>(new MySqlClient(new MySqlConnectionStringBuilder
{
Server = serverHost,
Port = hostPort,
UserID = username,
Password = password,
Database = database,
AllowUserVariables = true
}.ConnectionString));
}
break;
case "mongo":
case "mongodb":
{
if (hostPort == 0)
{
hostPort = 27017;
}
MongoClientSettings builder = new MongoClientSettings();
string prefix = "mongodb";
if (!System.Net.IPAddress.TryParse(serverHost, out _))
{
prefix += "+srv";
}
string connString;
if (!string.IsNullOrEmpty(username))
{
connString = string.Format(
"{0}://{1}:{2}@{3}:{4}/",
prefix,
username,
password,
serverHost,
hostPort
);
}
else
{
connString = string.Format(
"{0}://{1}:{2}/",
prefix,
serverHost,
hostPort
);
}
services.AddSingleton<IDatabaseClient>(new MongoDbClient(connString, database));
}
break;
case "firebird":
case "interbase":
{
//TODO: TEST FIREBASE
throw new NotImplementedException();
if (hostPort == 0)
{
hostPort = 3050;
}
services.AddSingleton<IDatabaseClient>(new FirebirdClient(new FbConnectionStringBuilder
{
DataSource = serverHost,
Port = hostPort,
UserID = username,
Password = password,
ServerType = FbServerType.Default
}.ConnectionString));
}
break;
case "pgsql":
case "postgresql":
{
if (hostPort == 0)
{
hostPort = 5432;
}
services.AddSingleton<IDatabaseClient>(new NpgsqlClient(new NpgsqlConnectionStringBuilder
{
Host = serverHost,
Port = hostPort,
Database = database,
Username = username,
Password = password
}.ConnectionString));
}
break;
case "sqlite":
{
//TODO: TEST SQLite
throw new NotImplementedException();
SqliteConnectionStringBuilder builder = new SqliteConnectionStringBuilder();
var sqliteFiles = Directory.GetFiles(AppContext.BaseDirectory, "*.sqlite", SearchOption.AllDirectories);
if (File.Exists(database))
{
builder.DataSource = database;
}
else if (!database.Contains(".sqlite"))
{
builder.DataSource = sqliteFiles.FirstOrDefault(x => x.Contains($"{database}.sqlite"));
}
services.AddSingleton<IDatabaseClient>(new SQLiteClient(builder.ConnectionString));
}
break;
}
}
services.AddControllers(options =>
{
options.Filters.Add(new HttpResponseExceptionFilter());
options.OutputFormatters.Add(new HtmlOutputFormatter());
})
.AddXmlSerializerFormatters();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}

@ -0,0 +1,10 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
Loading…
Cancel
Save