Init Commit
Works: -Databases --MySql/Mariadb --MongoDB --Postgres -Formatting -JSON -XML -HTML Todo: -Databases --SQLite --Firebird
This commit is contained in:
25
src/RestAPI/RestAPI.sln
Normal file
25
src/RestAPI/RestAPI.sln
Normal file
@@ -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
|
||||||
7
src/RestAPI/RestAPI/.env.default
Normal file
7
src/RestAPI/RestAPI/.env.default
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
DATASOURCE=
|
||||||
|
HOST=
|
||||||
|
HOSTPORT=
|
||||||
|
USERNAME=
|
||||||
|
PASSWORD=
|
||||||
|
DATABASE=
|
||||||
|
BLACKLISTEDFIELDS=
|
||||||
115
src/RestAPI/RestAPI/Clients/FirebirdClient.cs
Normal file
115
src/RestAPI/RestAPI/Clients/FirebirdClient.cs
Normal file
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
109
src/RestAPI/RestAPI/Clients/MongoDbClient.cs
Normal file
109
src/RestAPI/RestAPI/Clients/MongoDbClient.cs
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
114
src/RestAPI/RestAPI/Clients/MySqlClient.cs
Normal file
114
src/RestAPI/RestAPI/Clients/MySqlClient.cs
Normal file
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
117
src/RestAPI/RestAPI/Clients/NpgsqlClient.cs
Normal file
117
src/RestAPI/RestAPI/Clients/NpgsqlClient.cs
Normal file
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
115
src/RestAPI/RestAPI/Clients/SQLiteClient.cs
Normal file
115
src/RestAPI/RestAPI/Clients/SQLiteClient.cs
Normal file
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
227
src/RestAPI/RestAPI/Controllers/TableController.cs
Normal file
227
src/RestAPI/RestAPI/Controllers/TableController.cs
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
23
src/RestAPI/RestAPI/Exceptions/HttpResponseException.cs
Normal file
23
src/RestAPI/RestAPI/Exceptions/HttpResponseException.cs
Normal file
@@ -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)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
18
src/RestAPI/RestAPI/Interfaces/IDatabaseClient.cs
Normal file
18
src/RestAPI/RestAPI/Interfaces/IDatabaseClient.cs
Normal file
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/RestAPI/RestAPI/OutputFormatters/HtmlOutputFormatter.cs
Normal file
12
src/RestAPI/RestAPI/OutputFormatters/HtmlOutputFormatter.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc.Formatters;
|
||||||
|
|
||||||
|
namespace RestAPI.OutputFormatters
|
||||||
|
{
|
||||||
|
public class HtmlOutputFormatter : StringOutputFormatter
|
||||||
|
{
|
||||||
|
public HtmlOutputFormatter()
|
||||||
|
{
|
||||||
|
SupportedMediaTypes.Add("text/html");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
27
src/RestAPI/RestAPI/Program.cs
Normal file
27
src/RestAPI/RestAPI/Program.cs
Normal file
@@ -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>();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
30
src/RestAPI/RestAPI/Properties/launchSettings.json
Normal file
30
src/RestAPI/RestAPI/Properties/launchSettings.json
Normal file
@@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
18
src/RestAPI/RestAPI/RestAPI.csproj
Normal file
18
src/RestAPI/RestAPI/RestAPI.csproj
Normal file
@@ -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>
|
||||||
205
src/RestAPI/RestAPI/Startup.cs
Normal file
205
src/RestAPI/RestAPI/Startup.cs
Normal file
@@ -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();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
9
src/RestAPI/RestAPI/appsettings.Development.json
Normal file
9
src/RestAPI/RestAPI/appsettings.Development.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft": "Warning",
|
||||||
|
"Microsoft.Hosting.Lifetime": "Information"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
10
src/RestAPI/RestAPI/appsettings.json
Normal file
10
src/RestAPI/RestAPI/appsettings.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft": "Warning",
|
||||||
|
"Microsoft.Hosting.Lifetime": "Information"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user