diff --git a/APITemplate/APITemplate.csproj b/APITemplate/APITemplate.csproj
new file mode 100644
index 0000000..fe24709
--- /dev/null
+++ b/APITemplate/APITemplate.csproj
@@ -0,0 +1,14 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+
+
+
+
+
+
+
diff --git a/APITemplate/APITemplate.sln b/APITemplate/APITemplate.sln
new file mode 100644
index 0000000..bca50f7
--- /dev/null
+++ b/APITemplate/APITemplate.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.7.34031.279
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "APITemplate", "APITemplate.csproj", "{EEF75926-CF27-4C86-9827-55D8605EF328}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {EEF75926-CF27-4C86-9827-55D8605EF328}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EEF75926-CF27-4C86-9827-55D8605EF328}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EEF75926-CF27-4C86-9827-55D8605EF328}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EEF75926-CF27-4C86-9827-55D8605EF328}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {4E1FFA94-449A-40F3-AE62-A2D1AC80634A}
+ EndGlobalSection
+EndGlobal
diff --git a/APITemplate/Contexts/IDBContext.cs b/APITemplate/Contexts/IDBContext.cs
new file mode 100644
index 0000000..10b14d8
--- /dev/null
+++ b/APITemplate/Contexts/IDBContext.cs
@@ -0,0 +1,8 @@
+namespace APITemplate.Contexts
+{
+ public interface IDBContext
+ {
+ Object GetWriteConn();
+ Object GetReadConn();
+ }
+}
diff --git a/APITemplate/Contexts/MysqlDBContext.cs b/APITemplate/Contexts/MysqlDBContext.cs
new file mode 100644
index 0000000..2505794
--- /dev/null
+++ b/APITemplate/Contexts/MysqlDBContext.cs
@@ -0,0 +1,31 @@
+using MySqlConnector;
+
+namespace APITemplate.Contexts
+{
+ public class MysqlDBContext : IDBContext
+ {
+ private IConfiguration _config;
+ private MySqlConnection _connection;
+ private string _connectionStringRead;
+ private string _connectionStringWrite;
+
+ public MysqlDBContext(IConfiguration configuration)
+ {
+ _config = configuration;
+ _connectionStringRead = _config.GetConnectionString("ReadDB").ToString();
+ _connectionStringWrite = _config.GetConnectionString("WriteDB").ToString();
+ }
+
+ public Object GetReadConn()
+ {
+ _connection = new MySqlConnection(_connectionStringWrite);
+ return _connection;
+ }
+
+ public Object GetWriteConn()
+ {
+ _connection = new MySqlConnection(_connectionStringRead);
+ return _connection;
+ }
+ }
+}
diff --git a/APITemplate/Controllers/ExampleController.cs b/APITemplate/Controllers/ExampleController.cs
new file mode 100644
index 0000000..8fda192
--- /dev/null
+++ b/APITemplate/Controllers/ExampleController.cs
@@ -0,0 +1,32 @@
+using APITemplate.Models;
+using APITemplate.Services;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+
+namespace APITemplate.Controllers
+{
+ public class ExampleController : Controller
+ {
+ private ExampleService _svc;
+ public ExampleController(ExampleService svc)
+ {
+ _svc = svc;
+ }
+
+ // POST: ExampleController/Create
+ [HttpPost]
+ [ValidateAntiForgeryToken]
+ public ActionResult Create(Example e)
+ {
+ try
+ {
+ _svc.Insert(e);
+ return Created("",e);
+ }
+ catch
+ {
+ throw;
+ }
+ }
+ }
+}
diff --git a/APITemplate/Models/Example.cs b/APITemplate/Models/Example.cs
new file mode 100644
index 0000000..831b506
--- /dev/null
+++ b/APITemplate/Models/Example.cs
@@ -0,0 +1,7 @@
+namespace APITemplate.Models
+{
+ public class Example
+ {
+ public string ExampleProp { get; set; }
+ }
+}
diff --git a/APITemplate/Program.cs b/APITemplate/Program.cs
new file mode 100644
index 0000000..c0c4351
--- /dev/null
+++ b/APITemplate/Program.cs
@@ -0,0 +1,44 @@
+using APITemplate.Contexts;
+using APITemplate.Repositories;
+using APITemplate.Services;
+
+namespace APITemplate
+{
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+ var builder = WebApplication.CreateBuilder(args);
+
+ // Add services to the container.
+
+ builder.Services.AddControllers();
+ // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
+ builder.Services.AddEndpointsApiExplorer();
+ builder.Services.AddSwaggerGen();
+
+ builder.Services.AddSingleton();
+ builder.Services.AddScoped();
+ builder.Services.AddScoped();
+ builder.Services.AddScoped();
+
+ var app = builder.Build();
+
+ // Configure the HTTP request pipeline.
+ if (app.Environment.IsDevelopment())
+ {
+ app.UseSwagger();
+ app.UseSwaggerUI();
+ }
+
+ app.UseHttpsRedirection();
+
+ app.UseAuthorization();
+
+
+ app.MapControllers();
+
+ app.Run();
+ }
+ }
+}
\ No newline at end of file
diff --git a/APITemplate/Properties/launchSettings.json b/APITemplate/Properties/launchSettings.json
new file mode 100644
index 0000000..5c90268
--- /dev/null
+++ b/APITemplate/Properties/launchSettings.json
@@ -0,0 +1,31 @@
+{
+ "$schema": "https://json.schemastore.org/launchsettings.json",
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:58714",
+ "sslPort": 44336
+ }
+ },
+ "profiles": {
+ "APITemplate": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "launchBrowser": true,
+ "launchUrl": "swagger",
+ "applicationUrl": "https://localhost:7069;http://localhost:5230",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "IIS Express": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "launchUrl": "swagger",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ }
+ }
+}
diff --git a/APITemplate/Repositories/ExampleRepository.cs b/APITemplate/Repositories/ExampleRepository.cs
new file mode 100644
index 0000000..3806b29
--- /dev/null
+++ b/APITemplate/Repositories/ExampleRepository.cs
@@ -0,0 +1,12 @@
+using APITemplate.Models;
+
+namespace APITemplate.Repositories
+{
+ public class ExampleRepository : IExampleRepository
+ {
+ public void Insert(Example e)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/APITemplate/Repositories/IExampleRepository.cs b/APITemplate/Repositories/IExampleRepository.cs
new file mode 100644
index 0000000..098e5df
--- /dev/null
+++ b/APITemplate/Repositories/IExampleRepository.cs
@@ -0,0 +1,9 @@
+using APITemplate.Models;
+
+namespace APITemplate.Repositories
+{
+ public interface IExampleRepository
+ {
+ void Insert(Example e);
+ }
+}
diff --git a/APITemplate/Services/ExampleService.cs b/APITemplate/Services/ExampleService.cs
new file mode 100644
index 0000000..acbc67b
--- /dev/null
+++ b/APITemplate/Services/ExampleService.cs
@@ -0,0 +1,21 @@
+using APITemplate.Models;
+using APITemplate.Repositories;
+
+namespace APITemplate.Services
+{
+ public class ExampleService
+ {
+ private IExampleRepository _repo;
+ private LogService _log;
+ public ExampleService(IExampleRepository repo, LogService log)
+ {
+ _log = log;
+ _repo = repo;
+ }
+
+ public void Insert(Example example)
+ {
+ _repo.Insert(example);
+ }
+ }
+}
diff --git a/APITemplate/Services/LogService.cs b/APITemplate/Services/LogService.cs
new file mode 100644
index 0000000..af63c2f
--- /dev/null
+++ b/APITemplate/Services/LogService.cs
@@ -0,0 +1,260 @@
+using APITemplate.Contexts;
+using System.Text.Json;
+
+namespace APITemplate.Services
+{
+ public class LogService
+ {
+ private LogType[] _logtype;
+ private IDBContext _db;
+ public LogService(IConfiguration config, IDBContext dbcontext)
+ {
+ _db = dbcontext;
+ _logtype = config.GetSection("Logger").Get();
+ }
+
+ public LogService(LogType[] logtype)
+ {
+ _logtype = logtype;
+ }
+
+ public void Debug(string s, string trace = "", string cmd = "")
+ {
+ WriteLog("Debug", s, "", trace, cmd);
+ }
+
+ public void Debug(string s, string toko, string trace = "", string cmd = "")
+ {
+ WriteLog("Debug", s, toko, trace, cmd);
+ }
+
+ public void Info(string s, string trace = "", string cmd = "")
+ {
+ WriteLog("Info", s, "", trace, cmd);
+ }
+
+ public void Info(string s, string toko, string trace = "", string cmd = "")
+ {
+ WriteLog("Info", s, toko, trace, cmd);
+ }
+
+ public void Warning(string s, string trace = "", string cmd = "")
+ {
+ WriteLog("Warn", s, "", trace, cmd);
+ }
+
+ public void Warning(string s, string toko, string trace = "", string cmd = "")
+ {
+ WriteLog("Warn", s, toko, trace, cmd);
+ }
+
+ public void Error(string s, string trace = "", string cmd = "")
+ {
+ WriteLog("Error", s, "", trace, cmd);
+ }
+
+ public void Error(string s, string toko, string trace = "", string cmd = "")
+ {
+ WriteLog("Error", s, toko, trace, cmd);
+ }
+
+ private void WriteLog(string tipe, string s, string toko, string trace = "", string cmd = "")
+ {
+ foreach (LogType l in _logtype)
+ {
+ if (
+ (l.MinimumLevel.ToLower() == "error" && tipe.ToLower() == "error") ||
+ (l.MinimumLevel.ToLower() == "warn" && (tipe.ToLower() == "warn" || tipe.ToLower() == "warn")) ||
+ (l.MinimumLevel.ToLower() == "info" && tipe.ToLower() != "debug") ||
+ (l.MinimumLevel.ToLower() == "debug")
+ )
+ {
+ switch (l.Name.ToLower())
+ {
+ case "console":
+ ConsoleLog(s, toko, tipe, trace);
+ break;
+
+ case "text":
+ TextLog(l.Path, s, toko, tipe, trace, cmd);
+ break;
+
+ case "json":
+ JsonLog(l.Path, s, toko, tipe, trace, cmd);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ }
+ }
+
+ private static void ConsoleLog(string s, string toko, string tipe, string trace = "")
+ {
+ Console.Write($"{DateTime.Now:yyyy-MM-dd HH:mm:ss} ");
+ if (tipe.ToLower() == "info")
+ {
+ Console.BackgroundColor = ConsoleColor.Green;
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.Write($"[INFO ]");
+ Console.ResetColor();
+ if (toko == "")
+ Console.WriteLine($" {s}");
+ else
+ Console.WriteLine($" ({toko}) {s}");
+ }
+ else if (tipe.ToLower() == "warn")
+ {
+ Console.BackgroundColor = ConsoleColor.Yellow;
+ Console.ForegroundColor = ConsoleColor.Black;
+ Console.Write($"[WARN ]");
+ Console.ResetColor();
+ if (toko == "")
+ Console.WriteLine($" {s}");
+ else
+ Console.WriteLine($" ({toko}) {s}");
+ }
+ else if (tipe.ToLower() == "error")
+ {
+ Console.BackgroundColor = ConsoleColor.Red;
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.Write($"[ERROR]");
+ Console.ResetColor();
+ if (toko == "")
+ Console.WriteLine($" {s}");
+ else
+ Console.WriteLine($" ({toko}) {s}");
+ if (trace != "")
+ Console.WriteLine(Environment.NewLine + trace);
+ }
+ else
+ {
+ Console.WriteLine($"[DEBUG] {s}");
+ }
+ }
+
+ private static void TextLog(string path, string s, string toko, string level, string trace = "", string cmd = "")
+ {
+ if (path is null)
+ {
+ path = Environment.CurrentDirectory + "\\logs";
+ }
+
+ string filename;
+ if (toko == "")
+ {
+ filename = @$"{path}\log-{DateTime.Now:MMM-yyyy}.log";
+ }
+ else
+ {
+ filename = @$"{path}\toko\{toko} log-{DateTime.Now:MMM-yyyy}.log";
+ }
+
+ bool written = false;
+
+ Directory.CreateDirectory(path);
+ Directory.CreateDirectory(path + "\\toko");
+
+ s = System.Text.RegularExpressions.Regex.Replace(s, @"\p{C}+", ">").Replace(Environment.NewLine, ">");
+ trace = System.Text.RegularExpressions.Regex.Replace(trace, @"\p{C}+", ">").Replace(Environment.NewLine, ">");
+ cmd = System.Text.RegularExpressions.Regex.Replace(cmd, @"\p{C}+", ">").Replace(Environment.NewLine, ">");
+
+ level = level.PadRight(5).ToUpper();
+
+ while (!written)
+ {
+ try
+ {
+ using (StreamWriter sw = System.IO.File.AppendText(filename))
+ {
+ sw.WriteLine(@$"{DateTime.Now:dd-MM-yy HH:mm:ss}|[{level}]|{s}|{trace}|{cmd}");
+ }
+ written = true;
+ }
+ catch (Exception)
+ {
+
+ }
+ }
+ }
+
+ private static void DBLog(string s, string toko, string level, string trace = "", string cmd = "")
+ {
+
+ }
+
+ private static void JsonLog(string path, string s, string toko, string level, string trace = "", string cmd = "")
+ {
+ if (path is null)
+ {
+ path = Environment.CurrentDirectory + "\\logs";
+ }
+
+ string filename;
+ if (toko == "")
+ {
+ filename = @$"{path}\log-{DateTime.Now:MMM-yyyy}.json";
+ }
+ else
+ {
+ filename = @$"{path}\toko\{toko} log-{DateTime.Now:MMM-yyyy}.json";
+ }
+ bool written = false;
+
+ Directory.CreateDirectory(path);
+ Directory.CreateDirectory(path + "\\toko");
+
+ while (!written)
+ {
+ try
+ {
+ List loglist;
+ if (File.Exists(filename))
+ {
+ string jsondata = System.IO.File.ReadAllText(filename);
+ loglist = JsonSerializer.Deserialize>(jsondata);
+ }
+ else
+ {
+ loglist = new List();
+ }
+
+ loglist.Add(new JsonLog()
+ {
+ Time = DateTime.Now,
+ Mesage = s,
+ Toko = toko,
+ Level = level,
+ Trace = trace,
+ Cmd = cmd,
+ });
+ File.WriteAllText(filename, JsonSerializer.Serialize(loglist));
+ written = true;
+ }
+ catch (Exception)
+ {
+
+ }
+ }
+ }
+ }
+
+ public class LogType
+ {
+ public string Name { get; set; }
+ public string MinimumLevel { get; set; }
+ public string Path { get; set; }
+ }
+
+ public class JsonLog
+ {
+ public DateTime Time { get; set; }
+ public string Toko { get; set; }
+ public string Level { get; set; }
+ public string Mesage { get; set; }
+ public string Trace { get; set; }
+ public string Cmd { get; set; }
+ }
+}
diff --git a/APITemplate/appsettings.Development.json b/APITemplate/appsettings.Development.json
new file mode 100644
index 0000000..0c208ae
--- /dev/null
+++ b/APITemplate/appsettings.Development.json
@@ -0,0 +1,8 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ }
+}
diff --git a/APITemplate/appsettings.json b/APITemplate/appsettings.json
new file mode 100644
index 0000000..ce48dad
--- /dev/null
+++ b/APITemplate/appsettings.json
@@ -0,0 +1,17 @@
+{
+ "Logger": [
+ {
+ "Name": "Console",
+ "MinimumLevel": "Info"
+ },
+ {
+ "Name": "Text",
+ "MinimumLevel": "Debug"
+ }
+ ],
+ "ConnectionStrings": {
+ "ReadDB": "server=localhost;port=3306;user id=root; password=root1234;Persist Security Info=True;pooling=false;connection timeout=500;allow user variables=True;Allow Zero DateTime=True;Convert Zero Datetime=True;SslMode:none",
+ "WriteDB": "server=localhost;port=3306;user id=root; password=root1234;Persist Security Info=True;pooling=false;connection timeout=500;allow user variables=True;Allow Zero DateTime=True;Convert Zero Datetime=True;SslMode:none"
+ },
+ "AllowedHosts": "*"
+}
diff --git a/ConsoleTemplate/Conf.cs b/ConsoleTemplate/Conf.cs
new file mode 100644
index 0000000..caab6e8
--- /dev/null
+++ b/ConsoleTemplate/Conf.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using ConsoleTemplate.Repositories;
+using Microsoft.Extensions.Configuration;
+
+namespace ConsoleTemplate
+{
+ internal static class Conf
+ {
+ public static string DB_SCHEME = "testdb";
+ public static string OTHER_CONF = "";
+
+ public static void Load(IRepository rorepository, IConfiguration config)
+ {
+ // Read config
+ if (config.GetValue("Const:db_scheme") != null)
+ DB_SCHEME = config.GetValue("Const:db_scheme");
+
+ //Read DB
+ // OTHER_CONF = _repo.GetConf("other");
+ }
+ }
+}
diff --git a/ConsoleTemplate/ConsoleTemplate.config.json b/ConsoleTemplate/ConsoleTemplate.config.json
new file mode 100644
index 0000000..ad7a6cb
--- /dev/null
+++ b/ConsoleTemplate/ConsoleTemplate.config.json
@@ -0,0 +1,16 @@
+{
+ "Logger": [
+ {
+ "Name": "Console",
+ "MinimumLevel": "Info"
+ },
+ {
+ "Name": "Text",
+ "MinimumLevel": "Debug"
+ }
+ ],
+ "ConnectionStrings": {
+ "ReadDB": "server=localhost;port=3306;user id=root; password=root1234;Persist Security Info=True;pooling=false;connection timeout=500;allow user variables=True;Allow Zero DateTime=True;Convert Zero Datetime=True;SslMode:none",
+ "WriteDB": "server=localhost;port=3306;user id=root; password=root1234;Persist Security Info=True;pooling=false;connection timeout=500;allow user variables=True;Allow Zero DateTime=True;Convert Zero Datetime=True;SslMode:none"
+ }
+}
diff --git a/ConsoleTemplate/ConsoleTemplate.csproj b/ConsoleTemplate/ConsoleTemplate.csproj
new file mode 100644
index 0000000..d7219b6
--- /dev/null
+++ b/ConsoleTemplate/ConsoleTemplate.csproj
@@ -0,0 +1,43 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ disable
+
+
+
+ embedded
+
+
+
+ embedded
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Always
+ true
+
+
+ Always
+ true
+
+
+
+
diff --git a/ConsoleTemplate/ConsoleTemplate.sln b/ConsoleTemplate/ConsoleTemplate.sln
new file mode 100644
index 0000000..ca42d45
--- /dev/null
+++ b/ConsoleTemplate/ConsoleTemplate.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.7.34031.279
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleTemplate", "ConsoleTemplate.csproj", "{FB15BFF9-C749-43D3-B571-F6A16E94E731}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {FB15BFF9-C749-43D3-B571-F6A16E94E731}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FB15BFF9-C749-43D3-B571-F6A16E94E731}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FB15BFF9-C749-43D3-B571-F6A16E94E731}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FB15BFF9-C749-43D3-B571-F6A16E94E731}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {939171FE-D5DB-4034-B198-43FDDFAC2D32}
+ EndGlobalSection
+EndGlobal
diff --git a/ConsoleTemplate/Contexts/IDBContext.cs b/ConsoleTemplate/Contexts/IDBContext.cs
new file mode 100644
index 0000000..450e878
--- /dev/null
+++ b/ConsoleTemplate/Contexts/IDBContext.cs
@@ -0,0 +1,10 @@
+using MySqlConnector;
+
+namespace ConsoleTemplate.Contexts
+{
+ internal interface IDBContext
+ {
+ Object GetWriteConn();
+ Object GetReadConn();
+ }
+}
diff --git a/ConsoleTemplate/Contexts/MysqlDBContext.cs b/ConsoleTemplate/Contexts/MysqlDBContext.cs
new file mode 100644
index 0000000..d8c14a0
--- /dev/null
+++ b/ConsoleTemplate/Contexts/MysqlDBContext.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Configuration;
+using MySqlConnector;
+
+namespace ConsoleTemplate.Contexts
+{
+ internal class MysqlDBContext : IDBContext
+ {
+ private IConfiguration _config;
+ private MySqlConnection _connection;
+ private MySqlCommand _cmd;
+ private string _connectionStringRead;
+ private string _connectionStringWrite;
+
+ public MysqlDBContext(IConfiguration configuration)
+ {
+ _config = configuration;
+ _connectionStringRead = _config.GetConnectionString("ReadDB").ToString();
+ _connectionStringWrite = _config.GetConnectionString("WriteDB").ToString();
+ }
+
+ public Object GetReadConn()
+ {
+ _connection = new MySqlConnection(_connectionStringWrite);
+ return _connection;
+ }
+
+ public Object GetWriteConn()
+ {
+ _connection = new MySqlConnection(_connectionStringRead);
+ return _connection;
+ }
+ }
+}
diff --git a/ConsoleTemplate/Program.cs b/ConsoleTemplate/Program.cs
new file mode 100644
index 0000000..4e4430e
--- /dev/null
+++ b/ConsoleTemplate/Program.cs
@@ -0,0 +1,95 @@
+using ConsoleTemplate.Contexts;
+using ConsoleTemplate.Repositories;
+using ConsoleTemplate.Services;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using System.CommandLine;
+using System.Globalization;
+
+namespace ConsoleTemplate
+{
+ internal class Program
+ {
+ static int Main(string[] args)
+ {
+ Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
+
+ var serviceCollection = new ServiceCollection();
+ ConfigureServices(serviceCollection);
+ var serviceProvider = serviceCollection.BuildServiceProvider();
+
+
+ var timerSvc = serviceProvider.GetRequiredService();
+
+ // Option
+ var dateOption = new Option
+ (
+ name: "--date",
+ description: "Tangal Proses",
+ isDefault: true,
+ parseArgument: result =>
+ {
+ if (result.Tokens.Count == 0)
+ {
+ return DateTime.Now;
+ }
+
+ string strtgl = result.Tokens.Single().Value;
+ if (DateTime.TryParseExact(strtgl, "yyMMdd", null, DateTimeStyles.None, out DateTime tgl))
+ {
+ return tgl;
+ }
+ else
+ {
+ result.ErrorMessage = "Format tanggal salah";
+ return DateTime.Now;
+ }
+ }
+ );
+ dateOption.AddAlias("-d");
+
+ var threadOption = new Option
+ (
+ name: "--thread",
+ description: "Jumlah Thread",
+ getDefaultValue: () => 8
+ );
+ threadOption.AddAlias("-t");
+
+ // Command
+
+ // == Timer
+ var rootCommand = new RootCommand("Proses RO PB");
+ rootCommand.AddOption(dateOption);
+ rootCommand.AddOption(threadOption);
+ rootCommand.SetHandler
+ (
+ (ctx) =>
+ {
+ timerSvc.Start(
+ ctx.ParseResult.GetValueForOption(dateOption),
+ ctx.ParseResult.GetValueForOption(threadOption)
+ );
+ }
+ );
+
+ return rootCommand.Invoke(args);
+ }
+
+ private static void ConfigureServices(ServiceCollection service)
+ {
+ // Build Configuration
+ IConfiguration configuration = new ConfigurationBuilder()
+ .SetBasePath(Directory.GetCurrentDirectory())
+ //.SetBasePath(Environment.CurrentDirectory)
+ .AddJsonFile("$safeprojectname$.config.json")
+ .Build();
+
+ service.AddSingleton(configuration);
+ service.AddSingleton();
+ service.AddSingleton();
+ service.AddSingleton();
+ service.AddScoped();
+ }
+ }
+}
\ No newline at end of file
diff --git a/ConsoleTemplate/Repositories/IRepository.cs b/ConsoleTemplate/Repositories/IRepository.cs
new file mode 100644
index 0000000..82624be
--- /dev/null
+++ b/ConsoleTemplate/Repositories/IRepository.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ConsoleTemplate.Repositories
+{
+ internal interface IRepository
+ {
+ bool InitDB();
+ }
+}
diff --git a/ConsoleTemplate/Repositories/MysqlRepository.cs b/ConsoleTemplate/Repositories/MysqlRepository.cs
new file mode 100644
index 0000000..d64f938
--- /dev/null
+++ b/ConsoleTemplate/Repositories/MysqlRepository.cs
@@ -0,0 +1,33 @@
+using ConsoleTemplate.Contexts;
+using ConsoleTemplate.Services;
+using MySqlConnector;
+
+namespace ConsoleTemplate.Repositories
+{
+ internal class MysqlRepository : IRepository
+ {
+ private IDBContext _dbContext;
+ private LogService _log;
+
+ public MysqlRepository(IDBContext dbContext, LogService logger)
+ {
+ _dbContext = dbContext;
+ _log = logger;
+ }
+
+ public bool InitDB()
+ {
+ using (MySqlConnection con = (MySqlConnection)_dbContext.GetWriteConn())
+ {
+ _log.Info("Init DB");
+
+ con.Open();
+ MySqlCommand cmd = con.CreateCommand();
+
+ cmd.CommandText = $"CREATE DATABASE IF NOT EXISTS `{Conf.DB_SCHEME}`";
+ cmd.ExecuteNonQuery();
+ return true;
+ }
+ }
+ }
+}
diff --git a/ConsoleTemplate/Services/LogService.cs b/ConsoleTemplate/Services/LogService.cs
new file mode 100644
index 0000000..09e3007
--- /dev/null
+++ b/ConsoleTemplate/Services/LogService.cs
@@ -0,0 +1,266 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.Json;
+using System.Threading.Tasks;
+using ConsoleTemplate.Contexts;
+using Microsoft.Extensions.Configuration;
+
+namespace ConsoleTemplate.Services
+{
+ internal class LogService
+ {
+ private LogType[] _logtype;
+ private IDBContext _db;
+ public LogService(IConfiguration config, IDBContext dbcontext)
+ {
+ _db = dbcontext;
+ _logtype = config.GetSection("Logger").Get();
+ }
+
+ public LogService(LogType[] logtype)
+ {
+ _logtype = logtype;
+ }
+
+ public void Debug(string s, string trace = "", string cmd = "")
+ {
+ WriteLog("Debug", s, "", trace, cmd);
+ }
+
+ public void Debug(string s, string toko, string trace = "", string cmd = "")
+ {
+ WriteLog("Debug", s, toko, trace, cmd);
+ }
+
+ public void Info(string s, string trace = "", string cmd = "")
+ {
+ WriteLog("Info", s, "", trace, cmd);
+ }
+
+ public void Info(string s, string toko, string trace = "", string cmd = "")
+ {
+ WriteLog("Info", s, toko, trace, cmd);
+ }
+
+ public void Warning(string s, string trace = "", string cmd = "")
+ {
+ WriteLog("Warn", s, "", trace, cmd);
+ }
+
+ public void Warning(string s, string toko, string trace = "", string cmd = "")
+ {
+ WriteLog("Warn", s, toko, trace, cmd);
+ }
+
+ public void Error(string s, string trace = "", string cmd = "")
+ {
+ WriteLog("Error", s, "", trace, cmd);
+ }
+
+ public void Error(string s, string toko, string trace = "", string cmd = "")
+ {
+ WriteLog("Error", s, toko, trace, cmd);
+ }
+
+ private void WriteLog(string tipe, string s, string toko, string trace = "", string cmd = "")
+ {
+ foreach (LogType l in _logtype)
+ {
+ if (
+ (l.MinimumLevel.ToLower() == "error" && tipe.ToLower() == "error") ||
+ (l.MinimumLevel.ToLower() == "warn" && (tipe.ToLower() == "warn" || tipe.ToLower() == "warn")) ||
+ (l.MinimumLevel.ToLower() == "info" && tipe.ToLower() != "debug") ||
+ (l.MinimumLevel.ToLower() == "debug")
+ )
+ {
+ switch (l.Name.ToLower())
+ {
+ case "console":
+ ConsoleLog(s, toko, tipe, trace);
+ break;
+
+ case "text":
+ TextLog(l.Path, s, toko, tipe, trace, cmd);
+ break;
+
+ case "json":
+ JsonLog(l.Path, s, toko, tipe, trace, cmd);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ }
+ }
+
+ private static void ConsoleLog(string s, string toko, string tipe, string trace = "")
+ {
+ Console.Write($"{DateTime.Now:yyyy-MM-dd HH:mm:ss} ");
+ if (tipe.ToLower() == "info")
+ {
+ Console.BackgroundColor = ConsoleColor.Green;
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.Write($"[INFO ]");
+ Console.ResetColor();
+ if (toko == "")
+ Console.WriteLine($" {s}");
+ else
+ Console.WriteLine($" ({toko}) {s}");
+ }
+ else if (tipe.ToLower() == "warn")
+ {
+ Console.BackgroundColor = ConsoleColor.Yellow;
+ Console.ForegroundColor = ConsoleColor.Black;
+ Console.Write($"[WARN ]");
+ Console.ResetColor();
+ if (toko == "")
+ Console.WriteLine($" {s}");
+ else
+ Console.WriteLine($" ({toko}) {s}");
+ }
+ else if (tipe.ToLower() == "error")
+ {
+ Console.BackgroundColor = ConsoleColor.Red;
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.Write($"[ERROR]");
+ Console.ResetColor();
+ if (toko == "")
+ Console.WriteLine($" {s}");
+ else
+ Console.WriteLine($" ({toko}) {s}");
+ if (trace != "")
+ Console.WriteLine(Environment.NewLine + trace);
+ }
+ else
+ {
+ Console.WriteLine($"[DEBUG] {s}");
+ }
+ }
+
+ private static void TextLog(string path, string s, string toko, string level, string trace = "", string cmd = "")
+ {
+ if (path is null)
+ {
+ path = Environment.CurrentDirectory + "\\logs";
+ }
+
+ string filename;
+ if (toko == "")
+ {
+ filename = @$"{path}\log-{DateTime.Now:MMM-yyyy}.log";
+ }
+ else
+ {
+ filename = @$"{path}\toko\{toko} log-{DateTime.Now:MMM-yyyy}.log";
+ }
+
+ bool written = false;
+
+ Directory.CreateDirectory(path);
+ Directory.CreateDirectory(path + "\\toko");
+
+ s = System.Text.RegularExpressions.Regex.Replace(s, @"\p{C}+", ">").Replace(Environment.NewLine, ">");
+ trace = System.Text.RegularExpressions.Regex.Replace(trace, @"\p{C}+", ">").Replace(Environment.NewLine, ">");
+ cmd = System.Text.RegularExpressions.Regex.Replace(cmd, @"\p{C}+", ">").Replace(Environment.NewLine, ">");
+
+ level = level.PadRight(5).ToUpper();
+
+ while (!written)
+ {
+ try
+ {
+ using (StreamWriter sw = System.IO.File.AppendText(filename))
+ {
+ sw.WriteLine(@$"{DateTime.Now:dd-MM-yy HH:mm:ss}|[{level}]|{s}|{trace}|{cmd}");
+ }
+ written = true;
+ }
+ catch (Exception)
+ {
+
+ }
+ }
+ }
+
+ private static void DBLog(string s, string toko, string level, string trace = "", string cmd = "")
+ {
+
+ }
+
+ private static void JsonLog(string path, string s, string toko, string level, string trace = "", string cmd = "")
+ {
+ if (path is null)
+ {
+ path = Environment.CurrentDirectory + "\\logs";
+ }
+
+ string filename;
+ if (toko == "")
+ {
+ filename = @$"{path}\log-{DateTime.Now:MMM-yyyy}.json";
+ }
+ else
+ {
+ filename = @$"{path}\toko\{toko} log-{DateTime.Now:MMM-yyyy}.json";
+ }
+ bool written = false;
+
+ Directory.CreateDirectory(path);
+ Directory.CreateDirectory(path + "\\toko");
+
+ while (!written)
+ {
+ try
+ {
+ List loglist;
+ if (File.Exists(filename))
+ {
+ string jsondata = System.IO.File.ReadAllText(filename);
+ loglist = JsonSerializer.Deserialize>(jsondata);
+ }
+ else
+ {
+ loglist = new List();
+ }
+
+ loglist.Add(new JsonLog()
+ {
+ Time = DateTime.Now,
+ Mesage = s,
+ Toko = toko,
+ Level = level,
+ Trace = trace,
+ Cmd = cmd,
+ });
+ File.WriteAllText(filename, JsonSerializer.Serialize(loglist));
+ written = true;
+ }
+ catch (Exception)
+ {
+
+ }
+ }
+ }
+ }
+
+ class LogType
+ {
+ public string Name { get; set; }
+ public string MinimumLevel { get; set; }
+ public string Path { get; set; }
+ }
+
+ class JsonLog
+ {
+ public DateTime Time { get; set; }
+ public string Toko { get; set; }
+ public string Level { get; set; }
+ public string Mesage { get; set; }
+ public string Trace { get; set; }
+ public string Cmd { get; set; }
+ }
+}
diff --git a/ConsoleTemplate/Services/TimerService.cs b/ConsoleTemplate/Services/TimerService.cs
new file mode 100644
index 0000000..84615e3
--- /dev/null
+++ b/ConsoleTemplate/Services/TimerService.cs
@@ -0,0 +1,115 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Threading.Tasks;
+using System.Timers;
+using ConsoleTemplate.Repositories;
+using Microsoft.Extensions.Configuration;
+
+namespace ConsoleTemplate.Services
+{
+ internal class TimerService
+ {
+ private LogService _log;
+ private IRepository _repo;
+ private IConfiguration _config;
+ private System.Timers.Timer _tmr;
+
+ private DateTime _tglRequest;
+ private int _jumlahTread;
+
+ public TimerService(LogService logger, IRepository rorepository, IConfiguration config)
+ {
+ _log = logger;
+ _repo = rorepository;
+ _config = config;
+ }
+
+ public void Start(DateTime tanggalProses, int jmlthread)
+ {
+ _repo.InitDB();
+
+ _tglRequest = tanggalProses;
+ _jumlahTread = jmlthread;
+
+ Conf.Load(_repo, _config);
+
+ _log.Info("Timer Start");
+ _tmr = new System.Timers.Timer(5000);
+ _tmr.Elapsed += CekRequest;
+ _tmr.Start();
+
+ Console.ReadLine();
+ }
+
+ private void CekRequest(object sender, ElapsedEventArgs e)
+ {
+ _tmr.Stop();
+ try
+ {
+ long totalRequest = 0; // _repo.GetTotalRequest(_tglRequest);
+ if (totalRequest > 0)
+ {
+ //List _requestList = _repo.GetRequests(_tglRequest);
+ ProceedRequest();
+ }
+ else if (true)
+ {
+
+ }
+ }
+ catch (Exception ex)
+ {
+ _log.Error("Error CekRequest : " + ex.Message);
+ }
+
+ _tmr.Start();
+ }
+
+ private void ProceedRequest()
+ {
+ try
+ {
+ List ThreadList = new List();
+ for (int i = 0; i < _jumlahTread; i++)
+ {
+ ThreadList.Add(new Thread(DummyProcess));
+ ThreadList[i].Name = "Thread" + i;
+ }
+
+ for (int i = 0; i < 10; i++)
+ {
+ int k = Array.FindIndex(ThreadList.ToArray(), IsThreadAvailable);
+ if (k >= 0)
+ {
+ ThreadList[k] = new Thread(() => DummyProcess());
+ ThreadList[k].Start();
+ }
+
+ while (Array.FindAll(ThreadList.ToArray(), IsThreadAvailable).Length == 0 ||
+ (i == 10 & Array.FindAll(ThreadList.ToArray(), IsThreadRunning).Length > 0))
+ Thread.Sleep(5000);
+ }
+ }
+ catch (Exception ex)
+ {
+ _log.Error("Error ProceedRequest : " + ex.Message);
+ }
+
+ }
+
+ private void DummyProcess() { }
+
+ private bool IsThreadAvailable(Thread t)
+ {
+ return t.ThreadState != ThreadState.Running && t.ThreadState != ThreadState.WaitSleepJoin;
+ }
+
+ private bool IsThreadRunning(Thread t)
+ {
+ return t.ThreadState == ThreadState.Running || t.ThreadState == ThreadState.WaitSleepJoin;
+ }
+ }
+}
diff --git a/ConsoleTemplate/changelog.txt b/ConsoleTemplate/changelog.txt
new file mode 100644
index 0000000..b355acb
--- /dev/null
+++ b/ConsoleTemplate/changelog.txt
@@ -0,0 +1,8 @@
+#emailby alazhar@indomaret.co.id
+#emailto alazhar@indomaret.co.id
+#emailcc alazhar@indomaret.co.id
+#location http://localhost:21/
+#line 8
+
+v 1.0.0.0
+- Test
\ No newline at end of file
diff --git a/Template.sln b/Template.sln
new file mode 100644
index 0000000..fb0571d
--- /dev/null
+++ b/Template.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.7.34031.279
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleTemplate", "ConsoleTemplate\ConsoleTemplate.csproj", "{B0E438EF-3AE4-416A-9793-C8B032BF2AB3}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "APITemplate", "APITemplate\APITemplate.csproj", "{CF0A06DF-50E8-42A6-8D67-19520D14E347}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B0E438EF-3AE4-416A-9793-C8B032BF2AB3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B0E438EF-3AE4-416A-9793-C8B032BF2AB3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B0E438EF-3AE4-416A-9793-C8B032BF2AB3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B0E438EF-3AE4-416A-9793-C8B032BF2AB3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CF0A06DF-50E8-42A6-8D67-19520D14E347}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CF0A06DF-50E8-42A6-8D67-19520D14E347}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CF0A06DF-50E8-42A6-8D67-19520D14E347}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CF0A06DF-50E8-42A6-8D67-19520D14E347}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {C3401901-366A-47F2-93FC-7AD9FA345B4D}
+ EndGlobalSection
+EndGlobal