namespace Framework.Cli.Generate
{
using Framework.DataAccessLayer;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using static Framework.Cli.AppCli;
internal static class NamingConventionIntegrate
{
public static bool TableNameIsIntegrate(string tableNameCSharp)
{
return tableNameCSharp.EndsWith("Integrate");
}
}
internal class GenerateCSharpIntegrate
{
///
/// Generate CSharp namespace for every database schema.
///
/// If true, generate CSharp code for Framework library (internal use only) otherwise generate code for Application.
/// If false, generate CSharp code for cli. If true, generate code for Application or Framework.
private static void GenerateCSharpSchemaName(List integrateList, bool isFrameworkDb, bool isApplication, StringBuilder result)
{
integrateList = integrateList.Where(item => item.IsFrameworkDb == isFrameworkDb && item.IsApplication == isApplication).ToList();
var schemaNameCSharpList = integrateList.GroupBy(item => item.SchemaNameCSharp, (key, group) => key);
bool isFirst = true;
foreach (string schemaNameCSharp in schemaNameCSharpList)
{
if (isFirst)
{
isFirst = false;
}
else
{
result.AppendLine();
}
result.AppendLine(string.Format("namespace DatabaseIntegrate.{0}", schemaNameCSharp));
result.AppendLine(string.Format("{{"));
result.AppendLine(string.Format(" using System;")); // Used for method Guid.Parse();
result.AppendLine(string.Format(" using System.Collections.Generic;"));
result.AppendLine(string.Format(" using System.Globalization;")); // Used for property CultureInfo.InvariantCulture;
if (isApplication)
{
// See also class IdNameEnumAttribute
result.AppendLine(string.Format(" using System.Linq;"));
result.AppendLine(string.Format(" using System.Threading.Tasks;"));
result.AppendLine(string.Format(" using Framework.DataAccessLayer;"));
}
result.AppendLine(string.Format(" using Database.{0};", schemaNameCSharp));
result.AppendLine();
GenerateCSharpTableNameClass(integrateList.Where(item => item.SchemaNameCSharp == schemaNameCSharp).ToList(), isFrameworkDb, isApplication, result);
result.AppendLine(string.Format("}}"));
}
}
///
/// Generate static CSharp class for every database table.
///
private static void GenerateCSharpTableNameClass(List integrateList, bool isFrameworkDb, bool isApplication, StringBuilder result)
{
bool isFirst = true;
foreach (var integrate in integrateList)
{
if (isFirst)
{
isFirst = false;
}
else
{
result.AppendLine();
}
// Use one "Database" and "DatabaseIntegrate" namespace for Framework and Application
string classNameExtension = ""; // "Table"; // See also method CommandDeployDbIntegrateInternal();
// Framework, Application
if (isFrameworkDb)
{
classNameExtension += "Framework";
}
else
{
classNameExtension += "App";
}
// Cli, Application
if (isApplication)
{
classNameExtension += "";
}
else
{
classNameExtension += "Cli";
}
result.AppendLine(string.Format(" public static class {0}{1}", integrate.TableNameCSharp, classNameExtension));
result.AppendLine(string.Format(" {{"));
if (isApplication)
{
GenerateCSharpNameEnum(integrate, result);
}
result.AppendLine(string.Format(" public static List<{0}> RowList", integrate.TableNameCSharp));
result.AppendLine(string.Format(" {{"));
result.AppendLine(string.Format(" get"));
result.AppendLine(string.Format(" {{"));
result.AppendLine(string.Format(" var result = new List<{0}>", integrate.TableNameCSharp));
result.AppendLine(string.Format(" {{", integrate.TableNameCSharp));
GenerateCSharpRowIntegrate(integrate, result);
result.AppendLine(string.Format(" }};", integrate.TableNameCSharp));
result.AppendLine(string.Format(" return result;"));
result.AppendLine(string.Format(" }}"));
result.AppendLine(string.Format(" }}"));
result.AppendLine(string.Format(" }}"));
}
}
private static void GenerateCSharpNameEnum(GenerateIntegrateItem integrate, StringBuilder result)
{
var fieldList = UtilDalType.TypeRowToFieldList(integrate.TypeRow);
var fieldId = fieldList.SingleOrDefault(item => item.FieldNameCSharp == "Id"); // See also FieldIntegrate.IsKey
var fieldIdName = fieldList.SingleOrDefault(item => item.FieldNameCSharp == "IdName"); // See also FieldIntegrate.IsKey
if (fieldIdName != null)
{
result.Append(string.Format(" public enum IdEnum {{ [IdEnum(null)]None = 0"));
List nameExceptList = new List();
int count = 0;
foreach (Row row in integrate.RowList)
{
count += 1;
string idName = (string)fieldIdName.PropertyInfo.GetValue(row);
string nameCSharp = UtilGenerate.NameCSharp(idName, nameExceptList);
result.Append(string.Format(", [IdEnum(\"{0}\")]{1} = {2}", idName, nameCSharp, count * -1)); // Count * -1 to ensure there is no relation between enum id and database record id!
}
result.AppendLine(string.Format(" }}"));
result.AppendLine();
result.AppendLine(string.Format(" public static {0} Row(this IdEnum value)", integrate.TableNameCSharp));
result.AppendLine(string.Format(" {{"));
result.AppendLine(string.Format(" return RowList.Where(item => item.IdName == IdEnumAttribute.IdNameFromEnum(value)).SingleOrDefault();"));
result.AppendLine(string.Format(" }}"));
result.AppendLine();
result.AppendLine(string.Format(" public static IdEnum IdName(string value)"));
result.AppendLine(string.Format(" {{"));
result.AppendLine(string.Format(" return IdEnumAttribute.IdNameToEnum(value);"));
result.AppendLine(string.Format(" }}"));
result.AppendLine();
result.AppendLine(string.Format(" public static string IdName(this IdEnum value)"));
result.AppendLine(string.Format(" {{"));
result.AppendLine(string.Format(" return IdEnumAttribute.IdNameFromEnum(value);"));
result.AppendLine(string.Format(" }}"));
result.AppendLine();
result.AppendLine(string.Format(" public static async Task Id(this IdEnum value)"));
result.AppendLine(string.Format(" {{"));
result.AppendLine(string.Format(" return (await Data.Query<{0}>().Where(item => item.IdName == IdEnumAttribute.IdNameFromEnum(value)).QueryExecuteAsync()).Single().Id;", integrate.TableNameCSharp));
result.AppendLine(string.Format(" }}"));
result.AppendLine();
}
}
private static void GenerateCSharpRowIntegrate(GenerateIntegrateItem integrateItem, StringBuilder result)
{
var fieldNameIdCSharpReferenceList = integrateItem.Owner.ResultReference.Where(item => item.TypeRowIntegrate == integrateItem.TypeRow).Select(item => item.FieldNameIdCSharp).ToList();
var fieldList = UtilDalType.TypeRowToFieldList(integrateItem.TypeRow);
foreach (Row row in integrateItem.RowList)
{
result.Append(string.Format(" new {0} {{", integrateItem.TableNameCSharp));
bool isFirst = true;
foreach (var field in fieldList)
{
if (isFirst)
{
isFirst = false;
result.Append(" ");
}
else
{
result.Append(", ");
}
object value = field.PropertyInfo.GetValue(row);
if (fieldNameIdCSharpReferenceList.Contains(field.FieldNameCSharp) || field.FieldNameCSharp == "Id")
{
UtilFramework.Assert(value == null || value.GetType() == typeof(int));
// Unlike IdName, Id can change from database to database.
value = 0;
}
// Blob FileName
string fileName = null;
if (integrateItem.Owner.ResultBlob.ContainsKey(row.GetType()))
{
if (integrateItem.Owner.ResultBlob[row.GetType()].TryGetValue(field.FieldNameCSharp, out var fileNameFunc))
{
fileName = fileNameFunc(row);
fileName = string.Format("{0}.{1}.{2}", integrateItem.SchemaNameCSharp, integrateItem.TableNameCSharp, fileName);
}
}
// Generate field
GenerateCSharpRowIntegrateField(field, value, fileName, integrateItem.IsApplication, result);
}
result.Append(" },");
result.AppendLine();
}
}
///
/// Generate CSharp property with value.
///
private static void GenerateCSharpRowIntegrateField(UtilDalType.Field field, object value, string fileName, bool isApplication, StringBuilder result)
{
string fieldNameCSharp = field.FieldNameCSharp;
FrameworkType frameworkType = UtilDalType.FrameworkTypeFromEnum(field.FrameworkTypeEnum);
string valueCSharp;
if (value is string)
{
valueCSharp = UtilCliInternal.EscapeCSharpString(value.ToString());
}
else
{
valueCSharp = frameworkType.ValueToCSharp(value);
}
// Blob write
if (fileName != null && !isApplication && (value is byte[] || value is string))
{
var folderName = UtilFramework.FolderName + "Application.Cli/Database/Blob/";
UtilCliInternal.FolderCreate(folderName);
var fileNameFull = folderName + fileName;
if (value is byte[])
{
File.WriteAllBytes(fileNameFull, (byte[])value);
valueCSharp = $"Framework.Cli.UtilCli.BlobReadData(\"{ fileName }\")";
}
if (value is string)
{
File.WriteAllText(fileNameFull, (string)value);
valueCSharp = $"Framework.Cli.UtilCli.BlobReadText(\"{ fileName }\")";
}
}
result.Append(string.Format("{0} = {1}", fieldNameCSharp, valueCSharp));
}
///
/// Generate CSharp code for file DatabaseIntegrate.cs
///
/// If false, generate code for cli. If true, generate code for Application.
public void Run(out string cSharp, bool isFrameworkDb, bool isApplication, List integrateList)
{
StringBuilder result = new StringBuilder();
result.AppendLine("// Do not modify this file. It's generated by Framework.Cli generate command."); // File DatabaseIntegrate.cs
result.AppendLine();
GenerateCSharpSchemaName(integrateList, isFrameworkDb, isApplication, result);
cSharp = result.ToString();
}
}
}