mycroforge/MycroForge.CLI/Features/Orm.cs
2024-04-23 08:56:01 +02:00

97 lines
3.1 KiB
C#

using MycroForge.CLI.CodeGen;
namespace MycroForge.CLI.Features;
public sealed class Orm : IFeature
{
#region Defaults
private static readonly string[] Settings =
[
"connectionstring = \"mysql+asyncmy://root:root@localhost:3306/example\"",
"",
"class OrmSettings:",
"\tdef get_connectionstring() -> str:",
"\t\treturn connectionstring"
];
private static readonly string[] AsyncSession =
[
"from sqlalchemy.ext.asyncio import create_async_engine, AsyncEngine, AsyncSession",
"from orm.settings import OrmSettings",
"",
"async_engine: AsyncEngine = create_async_engine(OrmSettings.get_connectionstring())",
"",
"def async_session():",
"\treturn AsyncSession(async_engine, expire_on_commit=False)"
];
private static readonly string[] EntityBase =
[
"from sqlalchemy.orm import DeclarativeBase",
"",
"class EntityBase(DeclarativeBase):",
"\tpass"
];
private static readonly string[] User =
[
"from sqlalchemy import String",
"from sqlalchemy.orm import Mapped, mapped_column",
"from orm.entities.entity_base import EntityBase",
"",
"class User(EntityBase):",
"\t__tablename__ = \"users\"",
"\tid: Mapped[int] = mapped_column(primary_key=True)",
"\tfirstname: Mapped[str] = mapped_column(String(255))",
"\tlastname: Mapped[str] = mapped_column(String(255))",
"",
"\tdef __repr__(self) -> str:",
"\t\treturn f\"User(id={self.id!r}, firstname={self.firstname!r}, lastname={self.lastname!r})\""
];
#endregion
public const string FeatureName = "orm";
public string Name => FeatureName;
public async Task ExecuteAsync(ProjectContext context)
{
if (context.Config.Features.Contains(FeatureName))
{
Console.WriteLine($"Feature {FeatureName} has already been initialized.");
return;
}
Console.WriteLine(string.Join("\n", [
$"Adding feature {FeatureName}",
"Requirements:",
" - asyncmy",
" - sqlalchemy",
" - alembic",
]));
await Bash.ExecuteAsync(
"source .venv/bin/activate",
"python3 -m pip install asyncmy sqlalchemy alembic",
"python3 -m pip freeze > requirements.txt",
"alembic init -t async orm"
);
var env = await context.ReadFile("orm/env.py");
env = new OrmEnvInitializer(env).Rewrite();
env = new OrmEnvUpdater(env, "user", "User").Rewrite();
await context.WriteFile("orm/env.py", env);
await context.CreateFile("orm/settings.py", Settings);
await context.CreateFile("orm/engine/async_session.py", AsyncSession);
await context.CreateFile("orm/entities/entity_base.py", EntityBase);
await context.CreateFile("orm/entities/user.py", User);
context.Config.Features.Add(FeatureName);
}
}