diff --git a/Cocotte/Cocotte.csproj b/Cocotte/Cocotte.csproj index 9399762..efa8231 100644 --- a/Cocotte/Cocotte.csproj +++ b/Cocotte/Cocotte.csproj @@ -8,6 +8,7 @@ + all @@ -15,6 +16,10 @@ + + + + diff --git a/Cocotte/Migrations/20230326095220_AddQuartz.Designer.cs b/Cocotte/Migrations/20230326095220_AddQuartz.Designer.cs new file mode 100644 index 0000000..154d52b --- /dev/null +++ b/Cocotte/Migrations/20230326095220_AddQuartz.Designer.cs @@ -0,0 +1,673 @@ +// +using System; +using Cocotte.Services; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Cocotte.Migrations +{ + [DbContext(typeof(CocotteDbContext))] + [Migration("20230326095220_AddQuartz")] + partial class AddQuartz + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "7.0.4"); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzBlobTrigger", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("TriggerName") + .HasColumnType("text") + .HasColumnName("TRIGGER_NAME"); + + b.Property("TriggerGroup") + .HasColumnType("text") + .HasColumnName("TRIGGER_GROUP"); + + b.Property("BlobData") + .HasColumnType("bytea") + .HasColumnName("BLOB_DATA"); + + b.HasKey("SchedulerName", "TriggerName", "TriggerGroup"); + + b.ToTable("QRTZ_BLOB_TRIGGERS", (string)null); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzCalendar", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("CalendarName") + .HasColumnType("text") + .HasColumnName("CALENDAR_NAME"); + + b.Property("Calendar") + .IsRequired() + .HasColumnType("bytea") + .HasColumnName("CALENDAR"); + + b.HasKey("SchedulerName", "CalendarName"); + + b.ToTable("QRTZ_CALENDARS", (string)null); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzCronTrigger", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("TriggerName") + .HasColumnType("text") + .HasColumnName("TRIGGER_NAME"); + + b.Property("TriggerGroup") + .HasColumnType("text") + .HasColumnName("TRIGGER_GROUP"); + + b.Property("CronExpression") + .IsRequired() + .HasColumnType("text") + .HasColumnName("CRON_EXPRESSION"); + + b.Property("TimeZoneId") + .HasColumnType("text") + .HasColumnName("TIME_ZONE_ID"); + + b.HasKey("SchedulerName", "TriggerName", "TriggerGroup"); + + b.ToTable("QRTZ_CRON_TRIGGERS", (string)null); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzFiredTrigger", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("EntryId") + .HasColumnType("text") + .HasColumnName("ENTRY_ID"); + + b.Property("FiredTime") + .HasColumnType("bigint") + .HasColumnName("FIRED_TIME"); + + b.Property("InstanceName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("INSTANCE_NAME"); + + b.Property("IsNonConcurrent") + .HasColumnType("bool") + .HasColumnName("IS_NONCONCURRENT"); + + b.Property("JobGroup") + .HasColumnType("text") + .HasColumnName("JOB_GROUP"); + + b.Property("JobName") + .HasColumnType("text") + .HasColumnName("JOB_NAME"); + + b.Property("Priority") + .HasColumnType("integer") + .HasColumnName("PRIORITY"); + + b.Property("RequestsRecovery") + .HasColumnType("bool") + .HasColumnName("REQUESTS_RECOVERY"); + + b.Property("ScheduledTime") + .HasColumnType("bigint") + .HasColumnName("SCHED_TIME"); + + b.Property("State") + .IsRequired() + .HasColumnType("text") + .HasColumnName("STATE"); + + b.Property("TriggerGroup") + .IsRequired() + .HasColumnType("text") + .HasColumnName("TRIGGER_GROUP"); + + b.Property("TriggerName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("TRIGGER_NAME"); + + b.HasKey("SchedulerName", "EntryId"); + + b.HasIndex("InstanceName") + .HasDatabaseName("IDX_QRTZ_FT_TRIG_INST_NAME"); + + b.HasIndex("JobGroup") + .HasDatabaseName("IDX_QRTZ_FT_JOB_GROUP"); + + b.HasIndex("JobName") + .HasDatabaseName("IDX_QRTZ_FT_JOB_NAME"); + + b.HasIndex("RequestsRecovery") + .HasDatabaseName("IDX_QRTZ_FT_JOB_REQ_RECOVERY"); + + b.HasIndex("TriggerGroup") + .HasDatabaseName("IDX_QRTZ_FT_TRIG_GROUP"); + + b.HasIndex("TriggerName") + .HasDatabaseName("IDX_QRTZ_FT_TRIG_NAME"); + + b.HasIndex("SchedulerName", "TriggerName", "TriggerGroup") + .HasDatabaseName("IDX_QRTZ_FT_TRIG_NM_GP"); + + b.ToTable("QRTZ_FIRED_TRIGGERS", (string)null); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzJobDetail", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("JobName") + .HasColumnType("text") + .HasColumnName("JOB_NAME"); + + b.Property("JobGroup") + .HasColumnType("text") + .HasColumnName("JOB_GROUP"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("DESCRIPTION"); + + b.Property("IsDurable") + .HasColumnType("bool") + .HasColumnName("IS_DURABLE"); + + b.Property("IsNonConcurrent") + .HasColumnType("bool") + .HasColumnName("IS_NONCONCURRENT"); + + b.Property("IsUpdateData") + .HasColumnType("bool") + .HasColumnName("IS_UPDATE_DATA"); + + b.Property("JobClassName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("JOB_CLASS_NAME"); + + b.Property("JobData") + .HasColumnType("bytea") + .HasColumnName("JOB_DATA"); + + b.Property("RequestsRecovery") + .HasColumnType("bool") + .HasColumnName("REQUESTS_RECOVERY"); + + b.HasKey("SchedulerName", "JobName", "JobGroup"); + + b.HasIndex("RequestsRecovery") + .HasDatabaseName("IDX_QRTZ_J_REQ_RECOVERY"); + + b.ToTable("QRTZ_JOB_DETAILS", (string)null); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzLock", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("LockName") + .HasColumnType("text") + .HasColumnName("LOCK_NAME"); + + b.HasKey("SchedulerName", "LockName"); + + b.ToTable("QRTZ_LOCKS", (string)null); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzPausedTriggerGroup", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("TriggerGroup") + .HasColumnType("text") + .HasColumnName("TRIGGER_GROUP"); + + b.HasKey("SchedulerName", "TriggerGroup"); + + b.ToTable("QRTZ_PAUSED_TRIGGER_GRPS", (string)null); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzSchedulerState", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("InstanceName") + .HasColumnType("text") + .HasColumnName("INSTANCE_NAME"); + + b.Property("CheckInInterval") + .HasColumnType("bigint") + .HasColumnName("CHECKIN_INTERVAL"); + + b.Property("LastCheckInTime") + .HasColumnType("bigint") + .HasColumnName("LAST_CHECKIN_TIME"); + + b.HasKey("SchedulerName", "InstanceName"); + + b.ToTable("QRTZ_SCHEDULER_STATE", (string)null); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzSimplePropertyTrigger", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("TriggerName") + .HasColumnType("text") + .HasColumnName("TRIGGER_NAME"); + + b.Property("TriggerGroup") + .HasColumnType("text") + .HasColumnName("TRIGGER_GROUP"); + + b.Property("BooleanProperty1") + .HasColumnType("bool") + .HasColumnName("BOOL_PROP_1"); + + b.Property("BooleanProperty2") + .HasColumnType("bool") + .HasColumnName("BOOL_PROP_2"); + + b.Property("DecimalProperty1") + .HasColumnType("numeric") + .HasColumnName("DEC_PROP_1"); + + b.Property("DecimalProperty2") + .HasColumnType("numeric") + .HasColumnName("DEC_PROP_2"); + + b.Property("IntegerProperty1") + .HasColumnType("integer") + .HasColumnName("INT_PROP_1"); + + b.Property("IntegerProperty2") + .HasColumnType("integer") + .HasColumnName("INT_PROP_2"); + + b.Property("LongProperty1") + .HasColumnType("bigint") + .HasColumnName("LONG_PROP_1"); + + b.Property("LongProperty2") + .HasColumnType("bigint") + .HasColumnName("LONG_PROP_2"); + + b.Property("StringProperty1") + .HasColumnType("text") + .HasColumnName("STR_PROP_1"); + + b.Property("StringProperty2") + .HasColumnType("text") + .HasColumnName("STR_PROP_2"); + + b.Property("StringProperty3") + .HasColumnType("text") + .HasColumnName("STR_PROP_3"); + + b.Property("TimeZoneId") + .HasColumnType("text") + .HasColumnName("TIME_ZONE_ID"); + + b.HasKey("SchedulerName", "TriggerName", "TriggerGroup"); + + b.ToTable("QRTZ_SIMPROP_TRIGGERS", (string)null); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzSimpleTrigger", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("TriggerName") + .HasColumnType("text") + .HasColumnName("TRIGGER_NAME"); + + b.Property("TriggerGroup") + .HasColumnType("text") + .HasColumnName("TRIGGER_GROUP"); + + b.Property("RepeatCount") + .HasColumnType("bigint") + .HasColumnName("REPEAT_COUNT"); + + b.Property("RepeatInterval") + .HasColumnType("bigint") + .HasColumnName("REPEAT_INTERVAL"); + + b.Property("TimesTriggered") + .HasColumnType("bigint") + .HasColumnName("TIMES_TRIGGERED"); + + b.HasKey("SchedulerName", "TriggerName", "TriggerGroup"); + + b.ToTable("QRTZ_SIMPLE_TRIGGERS", (string)null); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzTrigger", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("TriggerName") + .HasColumnType("text") + .HasColumnName("TRIGGER_NAME"); + + b.Property("TriggerGroup") + .HasColumnType("text") + .HasColumnName("TRIGGER_GROUP"); + + b.Property("CalendarName") + .HasColumnType("text") + .HasColumnName("CALENDAR_NAME"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("DESCRIPTION"); + + b.Property("EndTime") + .HasColumnType("bigint") + .HasColumnName("END_TIME"); + + b.Property("JobData") + .HasColumnType("bytea") + .HasColumnName("JOB_DATA"); + + b.Property("JobGroup") + .IsRequired() + .HasColumnType("text") + .HasColumnName("JOB_GROUP"); + + b.Property("JobName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("JOB_NAME"); + + b.Property("MisfireInstruction") + .HasColumnType("smallint") + .HasColumnName("MISFIRE_INSTR"); + + b.Property("NextFireTime") + .HasColumnType("bigint") + .HasColumnName("NEXT_FIRE_TIME"); + + b.Property("PreviousFireTime") + .HasColumnType("bigint") + .HasColumnName("PREV_FIRE_TIME"); + + b.Property("Priority") + .HasColumnType("integer") + .HasColumnName("PRIORITY"); + + b.Property("StartTime") + .HasColumnType("bigint") + .HasColumnName("START_TIME"); + + b.Property("TriggerState") + .IsRequired() + .HasColumnType("text") + .HasColumnName("TRIGGER_STATE"); + + b.Property("TriggerType") + .IsRequired() + .HasColumnType("text") + .HasColumnName("TRIGGER_TYPE"); + + b.HasKey("SchedulerName", "TriggerName", "TriggerGroup"); + + b.HasIndex("NextFireTime") + .HasDatabaseName("IDX_QRTZ_T_NEXT_FIRE_TIME"); + + b.HasIndex("TriggerState") + .HasDatabaseName("IDX_QRTZ_T_STATE"); + + b.HasIndex("NextFireTime", "TriggerState") + .HasDatabaseName("IDX_QRTZ_T_NFT_ST"); + + b.HasIndex("SchedulerName", "JobName", "JobGroup"); + + b.ToTable("QRTZ_TRIGGERS", (string)null); + }); + + modelBuilder.Entity("Cocotte.Modules.Activities.Models.Activity", b => + { + b.Property("GuildId") + .HasColumnType("INTEGER"); + + b.Property("ChannelId") + .HasColumnType("INTEGER"); + + b.Property("MessageId") + .HasColumnType("INTEGER"); + + b.Property("AreRolesEnabled") + .HasColumnType("INTEGER"); + + b.Property("CreationDate") + .HasColumnType("TEXT"); + + b.Property("CreatorDisplayName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatorUserId") + .HasColumnType("INTEGER"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("DueDateTime") + .HasColumnType("TEXT"); + + b.Property("MaxPlayers") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("INTEGER"); + + b.Property("ThreadId") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("GuildId", "ChannelId", "MessageId"); + + b.HasIndex("ThreadId"); + + b.ToTable("Activities"); + + b.HasDiscriminator("Discriminator").HasValue("Activity"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("Cocotte.Modules.Activities.Models.ActivityPlayer", b => + { + b.Property("GuildId") + .HasColumnType("INTEGER"); + + b.Property("ChannelId") + .HasColumnType("INTEGER"); + + b.Property("MessageId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("GuildId", "ChannelId", "MessageId", "UserId"); + + b.ToTable("ActivityPlayers"); + + b.HasDiscriminator("Discriminator").HasValue("ActivityPlayer"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("Cocotte.Modules.Activities.Models.InterstellarActivity", b => + { + b.HasBaseType("Cocotte.Modules.Activities.Models.Activity"); + + b.Property("Color") + .HasColumnType("INTEGER"); + + b.HasDiscriminator().HasValue("InterstellarActivity"); + }); + + modelBuilder.Entity("Cocotte.Modules.Activities.Models.StagedActivity", b => + { + b.HasBaseType("Cocotte.Modules.Activities.Models.Activity"); + + b.Property("Stage") + .HasColumnType("INTEGER"); + + b.HasDiscriminator().HasValue("StagedActivity"); + }); + + modelBuilder.Entity("Cocotte.Modules.Activities.Models.ActivityRolePlayer", b => + { + b.HasBaseType("Cocotte.Modules.Activities.Models.ActivityPlayer"); + + b.Property("Roles") + .HasColumnType("INTEGER"); + + b.HasDiscriminator().HasValue("ActivityRolePlayer"); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzBlobTrigger", b => + { + b.HasOne("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzTrigger", "Trigger") + .WithMany("BlobTriggers") + .HasForeignKey("SchedulerName", "TriggerName", "TriggerGroup") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Trigger"); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzCronTrigger", b => + { + b.HasOne("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzTrigger", "Trigger") + .WithMany("CronTriggers") + .HasForeignKey("SchedulerName", "TriggerName", "TriggerGroup") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Trigger"); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzSimplePropertyTrigger", b => + { + b.HasOne("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzTrigger", "Trigger") + .WithMany("SimplePropertyTriggers") + .HasForeignKey("SchedulerName", "TriggerName", "TriggerGroup") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Trigger"); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzSimpleTrigger", b => + { + b.HasOne("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzTrigger", "Trigger") + .WithMany("SimpleTriggers") + .HasForeignKey("SchedulerName", "TriggerName", "TriggerGroup") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Trigger"); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzTrigger", b => + { + b.HasOne("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzJobDetail", "JobDetail") + .WithMany("Triggers") + .HasForeignKey("SchedulerName", "JobName", "JobGroup") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("JobDetail"); + }); + + modelBuilder.Entity("Cocotte.Modules.Activities.Models.ActivityPlayer", b => + { + b.HasOne("Cocotte.Modules.Activities.Models.Activity", "Activity") + .WithMany("ActivityPlayers") + .HasForeignKey("GuildId", "ChannelId", "MessageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Activity"); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzJobDetail", b => + { + b.Navigation("Triggers"); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzTrigger", b => + { + b.Navigation("BlobTriggers"); + + b.Navigation("CronTriggers"); + + b.Navigation("SimplePropertyTriggers"); + + b.Navigation("SimpleTriggers"); + }); + + modelBuilder.Entity("Cocotte.Modules.Activities.Models.Activity", b => + { + b.Navigation("ActivityPlayers"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Cocotte/Migrations/20230326095220_AddQuartz.cs b/Cocotte/Migrations/20230326095220_AddQuartz.cs new file mode 100644 index 0000000..040a157 --- /dev/null +++ b/Cocotte/Migrations/20230326095220_AddQuartz.cs @@ -0,0 +1,331 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Cocotte.Migrations +{ + /// + public partial class AddQuartz : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "QRTZ_CALENDARS", + columns: table => new + { + SCHED_NAME = table.Column(type: "text", nullable: false), + CALENDAR_NAME = table.Column(type: "text", nullable: false), + CALENDAR = table.Column(type: "bytea", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_QRTZ_CALENDARS", x => new { x.SCHED_NAME, x.CALENDAR_NAME }); + }); + + migrationBuilder.CreateTable( + name: "QRTZ_FIRED_TRIGGERS", + columns: table => new + { + SCHED_NAME = table.Column(type: "text", nullable: false), + ENTRY_ID = table.Column(type: "text", nullable: false), + TRIGGER_NAME = table.Column(type: "text", nullable: false), + TRIGGER_GROUP = table.Column(type: "text", nullable: false), + INSTANCE_NAME = table.Column(type: "text", nullable: false), + FIRED_TIME = table.Column(type: "bigint", nullable: false), + SCHED_TIME = table.Column(type: "bigint", nullable: false), + PRIORITY = table.Column(type: "integer", nullable: false), + STATE = table.Column(type: "text", nullable: false), + JOB_NAME = table.Column(type: "text", nullable: true), + JOB_GROUP = table.Column(type: "text", nullable: true), + IS_NONCONCURRENT = table.Column(type: "bool", nullable: false), + REQUESTS_RECOVERY = table.Column(type: "bool", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_QRTZ_FIRED_TRIGGERS", x => new { x.SCHED_NAME, x.ENTRY_ID }); + }); + + migrationBuilder.CreateTable( + name: "QRTZ_JOB_DETAILS", + columns: table => new + { + SCHED_NAME = table.Column(type: "text", nullable: false), + JOB_NAME = table.Column(type: "text", nullable: false), + JOB_GROUP = table.Column(type: "text", nullable: false), + DESCRIPTION = table.Column(type: "text", nullable: true), + JOB_CLASS_NAME = table.Column(type: "text", nullable: false), + IS_DURABLE = table.Column(type: "bool", nullable: false), + IS_NONCONCURRENT = table.Column(type: "bool", nullable: false), + IS_UPDATE_DATA = table.Column(type: "bool", nullable: false), + REQUESTS_RECOVERY = table.Column(type: "bool", nullable: false), + JOB_DATA = table.Column(type: "bytea", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_QRTZ_JOB_DETAILS", x => new { x.SCHED_NAME, x.JOB_NAME, x.JOB_GROUP }); + }); + + migrationBuilder.CreateTable( + name: "QRTZ_LOCKS", + columns: table => new + { + SCHED_NAME = table.Column(type: "text", nullable: false), + LOCK_NAME = table.Column(type: "text", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_QRTZ_LOCKS", x => new { x.SCHED_NAME, x.LOCK_NAME }); + }); + + migrationBuilder.CreateTable( + name: "QRTZ_PAUSED_TRIGGER_GRPS", + columns: table => new + { + SCHED_NAME = table.Column(type: "text", nullable: false), + TRIGGER_GROUP = table.Column(type: "text", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_QRTZ_PAUSED_TRIGGER_GRPS", x => new { x.SCHED_NAME, x.TRIGGER_GROUP }); + }); + + migrationBuilder.CreateTable( + name: "QRTZ_SCHEDULER_STATE", + columns: table => new + { + SCHED_NAME = table.Column(type: "text", nullable: false), + INSTANCE_NAME = table.Column(type: "text", nullable: false), + LAST_CHECKIN_TIME = table.Column(type: "bigint", nullable: false), + CHECKIN_INTERVAL = table.Column(type: "bigint", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_QRTZ_SCHEDULER_STATE", x => new { x.SCHED_NAME, x.INSTANCE_NAME }); + }); + + migrationBuilder.CreateTable( + name: "QRTZ_TRIGGERS", + columns: table => new + { + SCHED_NAME = table.Column(type: "text", nullable: false), + TRIGGER_NAME = table.Column(type: "text", nullable: false), + TRIGGER_GROUP = table.Column(type: "text", nullable: false), + JOB_NAME = table.Column(type: "text", nullable: false), + JOB_GROUP = table.Column(type: "text", nullable: false), + DESCRIPTION = table.Column(type: "text", nullable: true), + NEXT_FIRE_TIME = table.Column(type: "bigint", nullable: true), + PREV_FIRE_TIME = table.Column(type: "bigint", nullable: true), + PRIORITY = table.Column(type: "integer", nullable: true), + TRIGGER_STATE = table.Column(type: "text", nullable: false), + TRIGGER_TYPE = table.Column(type: "text", nullable: false), + START_TIME = table.Column(type: "bigint", nullable: false), + END_TIME = table.Column(type: "bigint", nullable: true), + CALENDAR_NAME = table.Column(type: "text", nullable: true), + MISFIRE_INSTR = table.Column(type: "smallint", nullable: true), + JOB_DATA = table.Column(type: "bytea", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_QRTZ_TRIGGERS", x => new { x.SCHED_NAME, x.TRIGGER_NAME, x.TRIGGER_GROUP }); + table.ForeignKey( + name: "FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS_SCHED_NAME_JOB_NAME_JOB_GROUP", + columns: x => new { x.SCHED_NAME, x.JOB_NAME, x.JOB_GROUP }, + principalTable: "QRTZ_JOB_DETAILS", + principalColumns: new[] { "SCHED_NAME", "JOB_NAME", "JOB_GROUP" }, + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "QRTZ_BLOB_TRIGGERS", + columns: table => new + { + SCHED_NAME = table.Column(type: "text", nullable: false), + TRIGGER_NAME = table.Column(type: "text", nullable: false), + TRIGGER_GROUP = table.Column(type: "text", nullable: false), + BLOB_DATA = table.Column(type: "bytea", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_QRTZ_BLOB_TRIGGERS", x => new { x.SCHED_NAME, x.TRIGGER_NAME, x.TRIGGER_GROUP }); + table.ForeignKey( + name: "FK_QRTZ_BLOB_TRIGGERS_QRTZ_TRIGGERS_SCHED_NAME_TRIGGER_NAME_TRIGGER_GROUP", + columns: x => new { x.SCHED_NAME, x.TRIGGER_NAME, x.TRIGGER_GROUP }, + principalTable: "QRTZ_TRIGGERS", + principalColumns: new[] { "SCHED_NAME", "TRIGGER_NAME", "TRIGGER_GROUP" }, + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "QRTZ_CRON_TRIGGERS", + columns: table => new + { + SCHED_NAME = table.Column(type: "text", nullable: false), + TRIGGER_NAME = table.Column(type: "text", nullable: false), + TRIGGER_GROUP = table.Column(type: "text", nullable: false), + CRON_EXPRESSION = table.Column(type: "text", nullable: false), + TIME_ZONE_ID = table.Column(type: "text", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_QRTZ_CRON_TRIGGERS", x => new { x.SCHED_NAME, x.TRIGGER_NAME, x.TRIGGER_GROUP }); + table.ForeignKey( + name: "FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS_SCHED_NAME_TRIGGER_NAME_TRIGGER_GROUP", + columns: x => new { x.SCHED_NAME, x.TRIGGER_NAME, x.TRIGGER_GROUP }, + principalTable: "QRTZ_TRIGGERS", + principalColumns: new[] { "SCHED_NAME", "TRIGGER_NAME", "TRIGGER_GROUP" }, + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "QRTZ_SIMPLE_TRIGGERS", + columns: table => new + { + SCHED_NAME = table.Column(type: "text", nullable: false), + TRIGGER_NAME = table.Column(type: "text", nullable: false), + TRIGGER_GROUP = table.Column(type: "text", nullable: false), + REPEAT_COUNT = table.Column(type: "bigint", nullable: false), + REPEAT_INTERVAL = table.Column(type: "bigint", nullable: false), + TIMES_TRIGGERED = table.Column(type: "bigint", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_QRTZ_SIMPLE_TRIGGERS", x => new { x.SCHED_NAME, x.TRIGGER_NAME, x.TRIGGER_GROUP }); + table.ForeignKey( + name: "FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS_SCHED_NAME_TRIGGER_NAME_TRIGGER_GROUP", + columns: x => new { x.SCHED_NAME, x.TRIGGER_NAME, x.TRIGGER_GROUP }, + principalTable: "QRTZ_TRIGGERS", + principalColumns: new[] { "SCHED_NAME", "TRIGGER_NAME", "TRIGGER_GROUP" }, + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "QRTZ_SIMPROP_TRIGGERS", + columns: table => new + { + SCHED_NAME = table.Column(type: "text", nullable: false), + TRIGGER_NAME = table.Column(type: "text", nullable: false), + TRIGGER_GROUP = table.Column(type: "text", nullable: false), + STR_PROP_1 = table.Column(type: "text", nullable: true), + STR_PROP_2 = table.Column(type: "text", nullable: true), + STR_PROP_3 = table.Column(type: "text", nullable: true), + INT_PROP_1 = table.Column(type: "integer", nullable: true), + INT_PROP_2 = table.Column(type: "integer", nullable: true), + LONG_PROP_1 = table.Column(type: "bigint", nullable: true), + LONG_PROP_2 = table.Column(type: "bigint", nullable: true), + DEC_PROP_1 = table.Column(type: "numeric", nullable: true), + DEC_PROP_2 = table.Column(type: "numeric", nullable: true), + BOOL_PROP_1 = table.Column(type: "bool", nullable: true), + BOOL_PROP_2 = table.Column(type: "bool", nullable: true), + TIME_ZONE_ID = table.Column(type: "text", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_QRTZ_SIMPROP_TRIGGERS", x => new { x.SCHED_NAME, x.TRIGGER_NAME, x.TRIGGER_GROUP }); + table.ForeignKey( + name: "FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS_SCHED_NAME_TRIGGER_NAME_TRIGGER_GROUP", + columns: x => new { x.SCHED_NAME, x.TRIGGER_NAME, x.TRIGGER_GROUP }, + principalTable: "QRTZ_TRIGGERS", + principalColumns: new[] { "SCHED_NAME", "TRIGGER_NAME", "TRIGGER_GROUP" }, + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IDX_QRTZ_FT_JOB_GROUP", + table: "QRTZ_FIRED_TRIGGERS", + column: "JOB_GROUP"); + + migrationBuilder.CreateIndex( + name: "IDX_QRTZ_FT_JOB_NAME", + table: "QRTZ_FIRED_TRIGGERS", + column: "JOB_NAME"); + + migrationBuilder.CreateIndex( + name: "IDX_QRTZ_FT_JOB_REQ_RECOVERY", + table: "QRTZ_FIRED_TRIGGERS", + column: "REQUESTS_RECOVERY"); + + migrationBuilder.CreateIndex( + name: "IDX_QRTZ_FT_TRIG_GROUP", + table: "QRTZ_FIRED_TRIGGERS", + column: "TRIGGER_GROUP"); + + migrationBuilder.CreateIndex( + name: "IDX_QRTZ_FT_TRIG_INST_NAME", + table: "QRTZ_FIRED_TRIGGERS", + column: "INSTANCE_NAME"); + + migrationBuilder.CreateIndex( + name: "IDX_QRTZ_FT_TRIG_NAME", + table: "QRTZ_FIRED_TRIGGERS", + column: "TRIGGER_NAME"); + + migrationBuilder.CreateIndex( + name: "IDX_QRTZ_FT_TRIG_NM_GP", + table: "QRTZ_FIRED_TRIGGERS", + columns: new[] { "SCHED_NAME", "TRIGGER_NAME", "TRIGGER_GROUP" }); + + migrationBuilder.CreateIndex( + name: "IDX_QRTZ_J_REQ_RECOVERY", + table: "QRTZ_JOB_DETAILS", + column: "REQUESTS_RECOVERY"); + + migrationBuilder.CreateIndex( + name: "IDX_QRTZ_T_NEXT_FIRE_TIME", + table: "QRTZ_TRIGGERS", + column: "NEXT_FIRE_TIME"); + + migrationBuilder.CreateIndex( + name: "IDX_QRTZ_T_NFT_ST", + table: "QRTZ_TRIGGERS", + columns: new[] { "NEXT_FIRE_TIME", "TRIGGER_STATE" }); + + migrationBuilder.CreateIndex( + name: "IDX_QRTZ_T_STATE", + table: "QRTZ_TRIGGERS", + column: "TRIGGER_STATE"); + + migrationBuilder.CreateIndex( + name: "IX_QRTZ_TRIGGERS_SCHED_NAME_JOB_NAME_JOB_GROUP", + table: "QRTZ_TRIGGERS", + columns: new[] { "SCHED_NAME", "JOB_NAME", "JOB_GROUP" }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "QRTZ_BLOB_TRIGGERS"); + + migrationBuilder.DropTable( + name: "QRTZ_CALENDARS"); + + migrationBuilder.DropTable( + name: "QRTZ_CRON_TRIGGERS"); + + migrationBuilder.DropTable( + name: "QRTZ_FIRED_TRIGGERS"); + + migrationBuilder.DropTable( + name: "QRTZ_LOCKS"); + + migrationBuilder.DropTable( + name: "QRTZ_PAUSED_TRIGGER_GRPS"); + + migrationBuilder.DropTable( + name: "QRTZ_SCHEDULER_STATE"); + + migrationBuilder.DropTable( + name: "QRTZ_SIMPLE_TRIGGERS"); + + migrationBuilder.DropTable( + name: "QRTZ_SIMPROP_TRIGGERS"); + + migrationBuilder.DropTable( + name: "QRTZ_TRIGGERS"); + + migrationBuilder.DropTable( + name: "QRTZ_JOB_DETAILS"); + } + } +} diff --git a/Cocotte/Migrations/CocotteDbContextModelSnapshot.cs b/Cocotte/Migrations/CocotteDbContextModelSnapshot.cs index ceae3fe..4d9376c 100644 --- a/Cocotte/Migrations/CocotteDbContextModelSnapshot.cs +++ b/Cocotte/Migrations/CocotteDbContextModelSnapshot.cs @@ -17,6 +17,449 @@ namespace Cocotte.Migrations #pragma warning disable 612, 618 modelBuilder.HasAnnotation("ProductVersion", "7.0.4"); + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzBlobTrigger", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("TriggerName") + .HasColumnType("text") + .HasColumnName("TRIGGER_NAME"); + + b.Property("TriggerGroup") + .HasColumnType("text") + .HasColumnName("TRIGGER_GROUP"); + + b.Property("BlobData") + .HasColumnType("bytea") + .HasColumnName("BLOB_DATA"); + + b.HasKey("SchedulerName", "TriggerName", "TriggerGroup"); + + b.ToTable("QRTZ_BLOB_TRIGGERS", (string)null); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzCalendar", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("CalendarName") + .HasColumnType("text") + .HasColumnName("CALENDAR_NAME"); + + b.Property("Calendar") + .IsRequired() + .HasColumnType("bytea") + .HasColumnName("CALENDAR"); + + b.HasKey("SchedulerName", "CalendarName"); + + b.ToTable("QRTZ_CALENDARS", (string)null); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzCronTrigger", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("TriggerName") + .HasColumnType("text") + .HasColumnName("TRIGGER_NAME"); + + b.Property("TriggerGroup") + .HasColumnType("text") + .HasColumnName("TRIGGER_GROUP"); + + b.Property("CronExpression") + .IsRequired() + .HasColumnType("text") + .HasColumnName("CRON_EXPRESSION"); + + b.Property("TimeZoneId") + .HasColumnType("text") + .HasColumnName("TIME_ZONE_ID"); + + b.HasKey("SchedulerName", "TriggerName", "TriggerGroup"); + + b.ToTable("QRTZ_CRON_TRIGGERS", (string)null); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzFiredTrigger", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("EntryId") + .HasColumnType("text") + .HasColumnName("ENTRY_ID"); + + b.Property("FiredTime") + .HasColumnType("bigint") + .HasColumnName("FIRED_TIME"); + + b.Property("InstanceName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("INSTANCE_NAME"); + + b.Property("IsNonConcurrent") + .HasColumnType("bool") + .HasColumnName("IS_NONCONCURRENT"); + + b.Property("JobGroup") + .HasColumnType("text") + .HasColumnName("JOB_GROUP"); + + b.Property("JobName") + .HasColumnType("text") + .HasColumnName("JOB_NAME"); + + b.Property("Priority") + .HasColumnType("integer") + .HasColumnName("PRIORITY"); + + b.Property("RequestsRecovery") + .HasColumnType("bool") + .HasColumnName("REQUESTS_RECOVERY"); + + b.Property("ScheduledTime") + .HasColumnType("bigint") + .HasColumnName("SCHED_TIME"); + + b.Property("State") + .IsRequired() + .HasColumnType("text") + .HasColumnName("STATE"); + + b.Property("TriggerGroup") + .IsRequired() + .HasColumnType("text") + .HasColumnName("TRIGGER_GROUP"); + + b.Property("TriggerName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("TRIGGER_NAME"); + + b.HasKey("SchedulerName", "EntryId"); + + b.HasIndex("InstanceName") + .HasDatabaseName("IDX_QRTZ_FT_TRIG_INST_NAME"); + + b.HasIndex("JobGroup") + .HasDatabaseName("IDX_QRTZ_FT_JOB_GROUP"); + + b.HasIndex("JobName") + .HasDatabaseName("IDX_QRTZ_FT_JOB_NAME"); + + b.HasIndex("RequestsRecovery") + .HasDatabaseName("IDX_QRTZ_FT_JOB_REQ_RECOVERY"); + + b.HasIndex("TriggerGroup") + .HasDatabaseName("IDX_QRTZ_FT_TRIG_GROUP"); + + b.HasIndex("TriggerName") + .HasDatabaseName("IDX_QRTZ_FT_TRIG_NAME"); + + b.HasIndex("SchedulerName", "TriggerName", "TriggerGroup") + .HasDatabaseName("IDX_QRTZ_FT_TRIG_NM_GP"); + + b.ToTable("QRTZ_FIRED_TRIGGERS", (string)null); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzJobDetail", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("JobName") + .HasColumnType("text") + .HasColumnName("JOB_NAME"); + + b.Property("JobGroup") + .HasColumnType("text") + .HasColumnName("JOB_GROUP"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("DESCRIPTION"); + + b.Property("IsDurable") + .HasColumnType("bool") + .HasColumnName("IS_DURABLE"); + + b.Property("IsNonConcurrent") + .HasColumnType("bool") + .HasColumnName("IS_NONCONCURRENT"); + + b.Property("IsUpdateData") + .HasColumnType("bool") + .HasColumnName("IS_UPDATE_DATA"); + + b.Property("JobClassName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("JOB_CLASS_NAME"); + + b.Property("JobData") + .HasColumnType("bytea") + .HasColumnName("JOB_DATA"); + + b.Property("RequestsRecovery") + .HasColumnType("bool") + .HasColumnName("REQUESTS_RECOVERY"); + + b.HasKey("SchedulerName", "JobName", "JobGroup"); + + b.HasIndex("RequestsRecovery") + .HasDatabaseName("IDX_QRTZ_J_REQ_RECOVERY"); + + b.ToTable("QRTZ_JOB_DETAILS", (string)null); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzLock", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("LockName") + .HasColumnType("text") + .HasColumnName("LOCK_NAME"); + + b.HasKey("SchedulerName", "LockName"); + + b.ToTable("QRTZ_LOCKS", (string)null); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzPausedTriggerGroup", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("TriggerGroup") + .HasColumnType("text") + .HasColumnName("TRIGGER_GROUP"); + + b.HasKey("SchedulerName", "TriggerGroup"); + + b.ToTable("QRTZ_PAUSED_TRIGGER_GRPS", (string)null); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzSchedulerState", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("InstanceName") + .HasColumnType("text") + .HasColumnName("INSTANCE_NAME"); + + b.Property("CheckInInterval") + .HasColumnType("bigint") + .HasColumnName("CHECKIN_INTERVAL"); + + b.Property("LastCheckInTime") + .HasColumnType("bigint") + .HasColumnName("LAST_CHECKIN_TIME"); + + b.HasKey("SchedulerName", "InstanceName"); + + b.ToTable("QRTZ_SCHEDULER_STATE", (string)null); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzSimplePropertyTrigger", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("TriggerName") + .HasColumnType("text") + .HasColumnName("TRIGGER_NAME"); + + b.Property("TriggerGroup") + .HasColumnType("text") + .HasColumnName("TRIGGER_GROUP"); + + b.Property("BooleanProperty1") + .HasColumnType("bool") + .HasColumnName("BOOL_PROP_1"); + + b.Property("BooleanProperty2") + .HasColumnType("bool") + .HasColumnName("BOOL_PROP_2"); + + b.Property("DecimalProperty1") + .HasColumnType("numeric") + .HasColumnName("DEC_PROP_1"); + + b.Property("DecimalProperty2") + .HasColumnType("numeric") + .HasColumnName("DEC_PROP_2"); + + b.Property("IntegerProperty1") + .HasColumnType("integer") + .HasColumnName("INT_PROP_1"); + + b.Property("IntegerProperty2") + .HasColumnType("integer") + .HasColumnName("INT_PROP_2"); + + b.Property("LongProperty1") + .HasColumnType("bigint") + .HasColumnName("LONG_PROP_1"); + + b.Property("LongProperty2") + .HasColumnType("bigint") + .HasColumnName("LONG_PROP_2"); + + b.Property("StringProperty1") + .HasColumnType("text") + .HasColumnName("STR_PROP_1"); + + b.Property("StringProperty2") + .HasColumnType("text") + .HasColumnName("STR_PROP_2"); + + b.Property("StringProperty3") + .HasColumnType("text") + .HasColumnName("STR_PROP_3"); + + b.Property("TimeZoneId") + .HasColumnType("text") + .HasColumnName("TIME_ZONE_ID"); + + b.HasKey("SchedulerName", "TriggerName", "TriggerGroup"); + + b.ToTable("QRTZ_SIMPROP_TRIGGERS", (string)null); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzSimpleTrigger", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("TriggerName") + .HasColumnType("text") + .HasColumnName("TRIGGER_NAME"); + + b.Property("TriggerGroup") + .HasColumnType("text") + .HasColumnName("TRIGGER_GROUP"); + + b.Property("RepeatCount") + .HasColumnType("bigint") + .HasColumnName("REPEAT_COUNT"); + + b.Property("RepeatInterval") + .HasColumnType("bigint") + .HasColumnName("REPEAT_INTERVAL"); + + b.Property("TimesTriggered") + .HasColumnType("bigint") + .HasColumnName("TIMES_TRIGGERED"); + + b.HasKey("SchedulerName", "TriggerName", "TriggerGroup"); + + b.ToTable("QRTZ_SIMPLE_TRIGGERS", (string)null); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzTrigger", b => + { + b.Property("SchedulerName") + .HasColumnType("text") + .HasColumnName("SCHED_NAME"); + + b.Property("TriggerName") + .HasColumnType("text") + .HasColumnName("TRIGGER_NAME"); + + b.Property("TriggerGroup") + .HasColumnType("text") + .HasColumnName("TRIGGER_GROUP"); + + b.Property("CalendarName") + .HasColumnType("text") + .HasColumnName("CALENDAR_NAME"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("DESCRIPTION"); + + b.Property("EndTime") + .HasColumnType("bigint") + .HasColumnName("END_TIME"); + + b.Property("JobData") + .HasColumnType("bytea") + .HasColumnName("JOB_DATA"); + + b.Property("JobGroup") + .IsRequired() + .HasColumnType("text") + .HasColumnName("JOB_GROUP"); + + b.Property("JobName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("JOB_NAME"); + + b.Property("MisfireInstruction") + .HasColumnType("smallint") + .HasColumnName("MISFIRE_INSTR"); + + b.Property("NextFireTime") + .HasColumnType("bigint") + .HasColumnName("NEXT_FIRE_TIME"); + + b.Property("PreviousFireTime") + .HasColumnType("bigint") + .HasColumnName("PREV_FIRE_TIME"); + + b.Property("Priority") + .HasColumnType("integer") + .HasColumnName("PRIORITY"); + + b.Property("StartTime") + .HasColumnType("bigint") + .HasColumnName("START_TIME"); + + b.Property("TriggerState") + .IsRequired() + .HasColumnType("text") + .HasColumnName("TRIGGER_STATE"); + + b.Property("TriggerType") + .IsRequired() + .HasColumnType("text") + .HasColumnName("TRIGGER_TYPE"); + + b.HasKey("SchedulerName", "TriggerName", "TriggerGroup"); + + b.HasIndex("NextFireTime") + .HasDatabaseName("IDX_QRTZ_T_NEXT_FIRE_TIME"); + + b.HasIndex("TriggerState") + .HasDatabaseName("IDX_QRTZ_T_STATE"); + + b.HasIndex("NextFireTime", "TriggerState") + .HasDatabaseName("IDX_QRTZ_T_NFT_ST"); + + b.HasIndex("SchedulerName", "JobName", "JobGroup"); + + b.ToTable("QRTZ_TRIGGERS", (string)null); + }); + modelBuilder.Entity("Cocotte.Modules.Activities.Models.Activity", b => { b.Property("GuildId") @@ -135,6 +578,61 @@ namespace Cocotte.Migrations b.HasDiscriminator().HasValue("ActivityRolePlayer"); }); + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzBlobTrigger", b => + { + b.HasOne("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzTrigger", "Trigger") + .WithMany("BlobTriggers") + .HasForeignKey("SchedulerName", "TriggerName", "TriggerGroup") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Trigger"); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzCronTrigger", b => + { + b.HasOne("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzTrigger", "Trigger") + .WithMany("CronTriggers") + .HasForeignKey("SchedulerName", "TriggerName", "TriggerGroup") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Trigger"); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzSimplePropertyTrigger", b => + { + b.HasOne("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzTrigger", "Trigger") + .WithMany("SimplePropertyTriggers") + .HasForeignKey("SchedulerName", "TriggerName", "TriggerGroup") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Trigger"); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzSimpleTrigger", b => + { + b.HasOne("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzTrigger", "Trigger") + .WithMany("SimpleTriggers") + .HasForeignKey("SchedulerName", "TriggerName", "TriggerGroup") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Trigger"); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzTrigger", b => + { + b.HasOne("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzJobDetail", "JobDetail") + .WithMany("Triggers") + .HasForeignKey("SchedulerName", "JobName", "JobGroup") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("JobDetail"); + }); + modelBuilder.Entity("Cocotte.Modules.Activities.Models.ActivityPlayer", b => { b.HasOne("Cocotte.Modules.Activities.Models.Activity", "Activity") @@ -146,6 +644,22 @@ namespace Cocotte.Migrations b.Navigation("Activity"); }); + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzJobDetail", b => + { + b.Navigation("Triggers"); + }); + + modelBuilder.Entity("AppAny.Quartz.EntityFrameworkCore.Migrations.QuartzTrigger", b => + { + b.Navigation("BlobTriggers"); + + b.Navigation("CronTriggers"); + + b.Navigation("SimplePropertyTriggers"); + + b.Navigation("SimpleTriggers"); + }); + modelBuilder.Entity("Cocotte.Modules.Activities.Models.Activity", b => { b.Navigation("ActivityPlayers"); diff --git a/Cocotte/Modules/Activities/ActivityCloseJob.cs b/Cocotte/Modules/Activities/ActivityCloseJob.cs new file mode 100644 index 0000000..2526ac8 --- /dev/null +++ b/Cocotte/Modules/Activities/ActivityCloseJob.cs @@ -0,0 +1,52 @@ +using Cocotte.Modules.Activities.Models; +using Discord.WebSocket; +using Quartz; + +namespace Cocotte.Modules.Activities; + +public class ActivityCloseJob : IJob +{ + public long GuildId { private get; set; } + public long ChannelId { private get; set; } + public long MessageId { private get; set; } + + private readonly ILogger _logger; + private readonly ActivitiesRepository _activitiesRepository; + private readonly ActivityHelper _activityHelper; + private readonly DiscordSocketClient _discordClient; + + public ActivityCloseJob(ILogger logger, ActivitiesRepository activitiesRepository, ActivityHelper activityHelper, DiscordSocketClient discordClient) + { + _logger = logger; + _activitiesRepository = activitiesRepository; + _activityHelper = activityHelper; + _discordClient = discordClient; + } + + public async Task Execute(IJobExecutionContext context) + { + // Get associated activity + if (await _activitiesRepository.FindActivity((ulong)GuildId, (ulong)ChannelId, (ulong)MessageId) is not { } activity) + { + _logger.LogTrace("Activity {MessageId} does not exist anymore", MessageId); + + return; + } + + // Close activity + activity.IsClosed = true; + await _activitiesRepository.SaveChanges(); + + _logger.LogInformation("Closed activity {Activity}", activity); + + // Get channel + if (_discordClient.GetChannel(activity.ChannelId) is not SocketTextChannel channel) + { + return; + } + + // Update embed + await _activityHelper.UpdateActivityEmbed(channel, activity, ActivityUpdateReason.Update); + + } +} \ No newline at end of file diff --git a/Cocotte/Modules/Activities/ActivityFormatter.cs b/Cocotte/Modules/Activities/ActivityFormatter.cs index 7e93fef..98de424 100644 --- a/Cocotte/Modules/Activities/ActivityFormatter.cs +++ b/Cocotte/Modules/Activities/ActivityFormatter.cs @@ -72,7 +72,7 @@ public class ActivityFormatter // Add time if specified if (activity.DueDateTime is { } dueDateTime) { - descriptionBuilder.AppendLine($"**:clock2: {TimestampTag.FormatFromDateTime(dueDateTime, TimestampTagStyles.ShortTime)} ― {TimestampTag.FormatFromDateTime(dueDateTime, TimestampTagStyles.Relative)}**"); + descriptionBuilder.AppendLine($"**:clock2: {TimestampTag.FormatFromDateTime(dueDateTime, TimestampTagStyles.ShortTime)} ― {(activity.IsClosed ? "Fermée" : TimestampTag.FormatFromDateTime(dueDateTime, TimestampTagStyles.Relative))}**"); } else { @@ -92,7 +92,7 @@ public class ActivityFormatter string bannerUrl = GetActivityBanner(activity.Name); - var color = activityFull ? Colors.CocotteOrange : Colors.CocotteBlue; + var color = activity.IsClosed ? Colors.CocotteRed : (activityFull ? Colors.CocotteOrange : Colors.CocotteBlue); var builder = new EmbedBuilder() .WithColor(color) diff --git a/Cocotte/Modules/Activities/ActivityHelper.cs b/Cocotte/Modules/Activities/ActivityHelper.cs index 70c0307..7f52ea5 100644 --- a/Cocotte/Modules/Activities/ActivityHelper.cs +++ b/Cocotte/Modules/Activities/ActivityHelper.cs @@ -1,4 +1,7 @@ -using Cocotte.Options; +using Cocotte.Modules.Activities.Models; +using Cocotte.Options; +using Cocotte.Utils; +using Discord; using Discord.WebSocket; using Microsoft.Extensions.Options; @@ -9,9 +12,13 @@ public class ActivityHelper private const uint UnlimitedPlayers = uint.MaxValue; private readonly ActivityOptions _options; + private readonly ActivitiesRepository _activitiesRepository; + private readonly ActivityFormatter _activityFormatter; - public ActivityHelper(IOptions options) + public ActivityHelper(IOptions options, ActivitiesRepository activitiesRepository, ActivityFormatter activityFormatter) { + _activitiesRepository = activitiesRepository; + _activityFormatter = activityFormatter; _options = options.Value; } @@ -72,4 +79,50 @@ public class ActivityHelper _ => 0 }; + + public async Task UpdateActivityEmbed(IMessageChannel channel, Activity activity, ActivityUpdateReason updateReason) + { + // Fetch players + var players = await _activitiesRepository.LoadActivityPlayers(activity); + + await channel.ModifyMessageAsync(activity.MessageId, properties => + { + properties.Embed = _activityFormatter.ActivityEmbed(activity, players).Build(); + + // Disable join button if the activity is full on join, enable it on leave if activity is not full anymore + var isActivityFull = players.Count >= activity.MaxPlayers; + properties.Components = updateReason switch + { + ActivityUpdateReason.PlayerJoin when isActivityFull => ActivityComponents(activity.MessageId, disabled: true).Build(), + ActivityUpdateReason.PlayerLeave when !isActivityFull => ActivityComponents(activity.MessageId, disabled: false).Build(), + _ => Optional.Unspecified + }; + }); + } + + public ComponentBuilder ActivityComponents(ulong activityId, bool disabled = false) + { + return new ComponentBuilder() + .AddRow(new ActionRowBuilder() + .WithButton(new ButtonBuilder() + .WithLabel("Rejoindre") + .WithCustomId($"activity join:{activityId}") + .WithEmote(":white_check_mark:".ToEmote()) + .WithStyle(ButtonStyle.Primary) + .WithDisabled(disabled) + ) + .WithButton(new ButtonBuilder() + .WithLabel("Se désinscrire") + .WithCustomId($"activity leave:{activityId}") + .WithEmote(":x:".ToEmote()) + .WithStyle(ButtonStyle.Secondary) + ) + .WithButton(new ButtonBuilder() + .WithLabel("Supprimer") + .WithCustomId($"activity delete:{activityId}") + .WithEmote(":wastebasket:".ToEmote()) + .WithStyle(ButtonStyle.Danger) + ) + ); + } } \ No newline at end of file diff --git a/Cocotte/Modules/Activities/ActivityModule.cs b/Cocotte/Modules/Activities/ActivityModule.cs index d1ea3d7..9330fcc 100644 --- a/Cocotte/Modules/Activities/ActivityModule.cs +++ b/Cocotte/Modules/Activities/ActivityModule.cs @@ -7,6 +7,7 @@ using Discord; using Discord.Interactions; using Discord.WebSocket; using Microsoft.Extensions.Options; +using Quartz; using Alias = Discord.Commands.AliasAttribute; namespace Cocotte.Modules.Activities; @@ -23,15 +24,19 @@ public partial class ActivityModule : InteractionModuleBase (SocketGuildUser) Context.User; - public ActivityModule(ILogger logger, IOptions options, ActivityHelper activityHelper, ActivitiesRepository activitiesRepository, ActivityFormatter activityFormatter) + public ActivityModule(ILogger logger, IOptions options, + ActivityHelper activityHelper, ActivitiesRepository activitiesRepository, + ActivityFormatter activityFormatter, ISchedulerFactory schedulerFactory) { _logger = logger; _activityHelper = activityHelper; _activitiesRepository = activitiesRepository; _activityFormatter = activityFormatter; + _schedulerFactory = schedulerFactory; _options = options.Value; } @@ -53,90 +58,122 @@ public partial class ActivityModule : InteractionModuleBase { m.Content = ""; m.Components = components.Build(); - m.Embed = _activityFormatter.ActivityEmbed(activity, Enumerable.Repeat(rolePlayer, 1).ToImmutableList()).Build(); + m.Embed = _activityFormatter.ActivityEmbed(activity, Enumerable.Repeat(rolePlayer, 1).ToImmutableList()) + .Build(); }); + + // Add job to close this activity in scheduler if due date is specified + if (dueDate is { } dueDateTime) + { + var scheduler = await _schedulerFactory.GetScheduler(); + + var job = JobBuilder.Create() + .WithIdentity(activity.JobKey, "activity-close") + .WithDescription("Automatically close an activity after due date has passed") + .UsingJobData(nameof(ActivityCloseJob.GuildId), (long) activity.GuildId) + .UsingJobData(nameof(ActivityCloseJob.ChannelId), (long) activity.ChannelId) + .UsingJobData(nameof(ActivityCloseJob.MessageId), (long) activity.MessageId) + .Build(); + + var trigger = TriggerBuilder.Create() + .WithIdentity($"{activity.JobKey}-trigger", "activity-close") + .StartAt(dueDateTime) + .ForJob(job) + .Build(); + + await scheduler.ScheduleJob(job, trigger); + } } private ActivityPlayer CreateActivityPlayer(Activity activity, SocketGuildUser user, bool areRolesEnabled) { - return areRolesEnabled ? new ActivityRolePlayer - { - Activity = activity, - UserId = user.Id, - Name = user.DisplayName, - Roles = _activityHelper.GetPlayerRoles(user.Roles) - } : new ActivityPlayer - { - Activity = activity, - UserId = user.Id, - Name = user.DisplayName - }; + return areRolesEnabled + ? new ActivityRolePlayer + { + Activity = activity, + UserId = user.Id, + Name = user.DisplayName, + Roles = _activityHelper.GetPlayerRoles(user.Roles) + } + : new ActivityPlayer + { + Activity = activity, + UserId = user.Id, + Name = user.DisplayName + }; } [ComponentInteraction("activity join:*", ignoreGroupNames: true)] public async Task JoinActivity(ulong messageId) { // Check if activity exists - if (await _activitiesRepository.FindActivity(Context.Guild.Id, Context.Channel.Id, messageId) is not { } activity) + if (await _activitiesRepository.FindActivity(Context.Guild.Id, Context.Channel.Id, messageId) is not + { } activity) { await RespondAsync( ephemeral: true, @@ -292,7 +358,8 @@ public partial class ActivityModule : InteractionModuleBase AddUserToActivity(Activity activity, SocketGuildUser user, bool self) { // If player is already registered - if (await _activitiesRepository.FindActivityPlayer(activity.GuildId, activity.ChannelId, activity.MessageId, user.Id) is not + if (await _activitiesRepository.FindActivityPlayer(activity.GuildId, activity.ChannelId, activity.MessageId, + user.Id) is not null) { await RespondAsync( ephemeral: true, - embed: EmbedUtils.ErrorEmbed(self ? "Vous êtes **déjà inscrit** à cette activité" : $"{user.DisplayName} est **déjà inscrit** à cette activité").Build() + embed: EmbedUtils + .ErrorEmbed(self + ? "Vous êtes **déjà inscrit** à cette activité" + : $"{user.DisplayName} est **déjà inscrit** à cette activité").Build() + ); + + return false; + } + + // Check if activity is closed + if (activity.IsClosed) + { + await RespondAsync( + ephemeral: true, + embed: EmbedUtils.ErrorEmbed("Cette activité est fermée").Build() ); return false; @@ -410,11 +493,15 @@ public partial class ActivityModule : InteractionModuleBase RemovePlayerFromActivity(Activity activity, SocketGuildUser user, bool self) { // Check if player is in activity - if (await _activitiesRepository.FindActivityPlayer(activity.GuildId, activity.ChannelId, activity.MessageId, user.Id) is not { } activityPlayer) + if (await _activitiesRepository.FindActivityPlayer(activity.GuildId, activity.ChannelId, activity.MessageId, + user.Id) is not { } activityPlayer) { await RespondAsync( ephemeral: true, - embed: EmbedUtils.ErrorEmbed(self ? "Vous n'êtes **pas inscrit** à cette activité" : $"{user.DisplayName} n'est **pas inscrit** à cette activité").Build() + embed: EmbedUtils + .ErrorEmbed(self + ? "Vous n'êtes **pas inscrit** à cette activité" + : $"{user.DisplayName} n'est **pas inscrit** à cette activité").Build() ); return false; @@ -458,47 +545,6 @@ public partial class ActivityModule : InteractionModuleBase - { - properties.Embed = _activityFormatter.ActivityEmbed(activity, players).Build(); - - // Disable join button if the activity is full on join, enable it on leave if activity is not full anymore - var isActivityFull = players.Count >= activity.MaxPlayers; - properties.Components = updateReason switch - { - ActivityUpdateReason.PlayerJoin when isActivityFull => ActivityComponents(activity.MessageId, disabled: true).Build(), - ActivityUpdateReason.PlayerLeave when !isActivityFull => ActivityComponents(activity.MessageId, disabled: false).Build(), - _ => Optional.Unspecified - }; - }); + await _activityHelper.UpdateActivityEmbed(channel, activity, updateReason); } - - private static ComponentBuilder ActivityComponents(ulong activityId, bool disabled = false) - { - return new ComponentBuilder() - .AddRow(new ActionRowBuilder() - .WithButton(new ButtonBuilder() - .WithLabel("Rejoindre") - .WithCustomId($"activity join:{activityId}") - .WithEmote(":white_check_mark:".ToEmote()) - .WithStyle(ButtonStyle.Primary) - .WithDisabled(disabled) - ) - .WithButton(new ButtonBuilder() - .WithLabel("Se désinscrire") - .WithCustomId($"activity leave:{activityId}") - .WithEmote(":x:".ToEmote()) - .WithStyle(ButtonStyle.Secondary) - ) - .WithButton(new ButtonBuilder() - .WithLabel("Supprimer") - .WithCustomId($"activity delete:{activityId}") - .WithEmote(":wastebasket:".ToEmote()) - .WithStyle(ButtonStyle.Danger) - ) - ); - } -} +} \ No newline at end of file diff --git a/Cocotte/Modules/Activities/Models/Activity.cs b/Cocotte/Modules/Activities/Models/Activity.cs index 2ee4b93..1783280 100644 --- a/Cocotte/Modules/Activities/Models/Activity.cs +++ b/Cocotte/Modules/Activities/Models/Activity.cs @@ -25,9 +25,12 @@ public class Activity public required uint MaxPlayers { get; set; } public DateTime CreationDate { get; init; } = DateTime.Now; + public bool IsClosed { get; set; } public List ActivityPlayers { get; init; } = new(); + public string JobKey => $"{GuildId}/{ChannelId}/{MessageId}"; + public override string ToString() { return $"{nameof(MessageId)}: {MessageId}, {nameof(CreatorUserId)}: {CreatorUserId}, {nameof(Description)}: {Description}, {nameof(Type)}: {Type}, {nameof(Name)}: {Name}, {nameof(MaxPlayers)}: {MaxPlayers}"; diff --git a/Cocotte/Program.cs b/Cocotte/Program.cs index 1a2a36f..8df348a 100644 --- a/Cocotte/Program.cs +++ b/Cocotte/Program.cs @@ -8,6 +8,7 @@ using Discord.Commands; using Discord.Interactions; using Discord.WebSocket; using Microsoft.EntityFrameworkCore; +using Quartz; DiscordSocketConfig discordSocketConfig = new() { @@ -25,6 +26,18 @@ IHost host = Host.CreateDefaultBuilder(args) }) .ConfigureServices((context, services) => { + // Quartz service + services.AddQuartz(q => + { + q.UseMicrosoftDependencyInjectionJobFactory(); + q.UsePersistentStore(options => + { + options.UseJsonSerializer(); + options.UseMicrosoftSQLite("Data Source=cocotte.db"); + }); + }); + services.AddQuartzHostedService(options => options.WaitForJobsToComplete = true); + // Options services.Configure(context.Configuration.GetSection(DiscordOptions.SectionName)); services.Configure(context.Configuration.GetSection(ActivityOptions.SectionName)); @@ -32,8 +45,8 @@ IHost host = Host.CreateDefaultBuilder(args) // Database services.AddDbContext(options => - options.UseSqlite(context.Configuration.GetConnectionString("CocotteContext")), ServiceLifetime.Transient, ServiceLifetime.Transient); - services.AddTransient(); + options.UseSqlite(context.Configuration.GetConnectionString("CocotteContext"))); + services.AddScoped(); // Discord.Net services.AddHostedService(); @@ -53,19 +66,16 @@ IHost host = Host.CreateDefaultBuilder(args) // Activities services.AddTransient(); services.AddTransient(); - services.AddTransient(); + services.AddScoped(); + services.AddScoped(); // Composite roles services.AddSingleton(); // Raids - services.AddTransient(); - services.AddSingleton(); - services.AddTransient(); - - // Custom - services.AddSingleton(); - services.AddTransient(); + // services.AddTransient(); + // services.AddSingleton(); + // services.AddTransient(); }) .Build(); diff --git a/Cocotte/Services/CocotteDbContext.cs b/Cocotte/Services/CocotteDbContext.cs index e2d2124..89f05e7 100644 --- a/Cocotte/Services/CocotteDbContext.cs +++ b/Cocotte/Services/CocotteDbContext.cs @@ -1,4 +1,6 @@ -using Cocotte.Modules.Activities.Models; +using AppAny.Quartz.EntityFrameworkCore.Migrations; +using AppAny.Quartz.EntityFrameworkCore.Migrations.SQLite; +using Cocotte.Modules.Activities.Models; using Microsoft.EntityFrameworkCore; namespace Cocotte.Services; @@ -16,4 +18,12 @@ public class CocotteDbContext : DbContext { } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + // Adds Quartz.NET SQLite schema to EntityFrameworkCore + modelBuilder.AddQuartz(builder => builder.UseSqlite()); + } } \ No newline at end of file diff --git a/Cocotte/Services/CocotteService.cs b/Cocotte/Services/CocotteService.cs index 0c22a9b..651a9d5 100644 --- a/Cocotte/Services/CocotteService.cs +++ b/Cocotte/Services/CocotteService.cs @@ -52,11 +52,11 @@ public class CocotteService : BackgroundService } // Initialize modules and commands - // await _interactionService.AddModulesAsync(Assembly.GetEntryAssembly(), _serviceProvider); + using var scope = _serviceProvider.CreateScope(); #if DEBUG - await _interactionService.AddModuleAsync(typeof(Modules.Ping.PingModule), _serviceProvider); + await _interactionService.AddModuleAsync(typeof(Modules.Ping.PingModule), scope.ServiceProvider); #endif - await _interactionService.AddModuleAsync(typeof(ActivityModule), _serviceProvider); + await _interactionService.AddModuleAsync(typeof(ActivityModule), scope.ServiceProvider); _client.Ready += ClientOnReady; _client.InteractionCreated += HandleInteraction; diff --git a/Cocotte/Services/SharedCounter.cs b/Cocotte/Services/SharedCounter.cs deleted file mode 100644 index e96803f..0000000 --- a/Cocotte/Services/SharedCounter.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Cocotte.Services; - -public class SharedCounter -{ - public int Count { get; set; } = 0; -} \ No newline at end of file diff --git a/Cocotte/Services/TransientCounter.cs b/Cocotte/Services/TransientCounter.cs deleted file mode 100644 index edb477f..0000000 --- a/Cocotte/Services/TransientCounter.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Cocotte.Services; - -public class TransientCounter -{ - public int Count { get; set; } = 0; -} \ No newline at end of file diff --git a/Cocotte/appsettings.Development.json b/Cocotte/appsettings.Development.json index b4be21e..220b0f7 100644 --- a/Cocotte/appsettings.Development.json +++ b/Cocotte/appsettings.Development.json @@ -3,7 +3,10 @@ "LogLevel": { "Default": "Information", "Microsoft.Hosting.Lifetime": "Information", - "Cocotte": "Trace" + "Cocotte": "Trace", + "Quartz": "Information", + "Quartz.Core.QuartzSchedulerThread": "Information", + "Quartz.Core.JobRunShell": "Information" } } }