feat(backend): initial data export support

obviously it's missing things that haven't been added yet
This commit is contained in:
sam 2024-12-02 18:06:19 +01:00
parent f0ae648492
commit 903be2709c
Signed by: sam
GPG key ID: B4EF20DDE721CAA1
15 changed files with 502 additions and 24 deletions

View file

@ -46,17 +46,18 @@ public class DatabaseContext(DbContextOptions options) : DbContext(options)
.UseSnakeCaseNamingConvention()
.UseExceptionProcessor();
public DbSet<User> Users { get; set; }
public DbSet<Member> Members { get; set; }
public DbSet<AuthMethod> AuthMethods { get; set; }
public DbSet<FediverseApplication> FediverseApplications { get; set; }
public DbSet<Token> Tokens { get; set; }
public DbSet<Application> Applications { get; set; }
public DbSet<TemporaryKey> TemporaryKeys { get; set; }
public DbSet<User> Users { get; init; }
public DbSet<Member> Members { get; init; }
public DbSet<AuthMethod> AuthMethods { get; init; }
public DbSet<FediverseApplication> FediverseApplications { get; init; }
public DbSet<Token> Tokens { get; init; }
public DbSet<Application> Applications { get; init; }
public DbSet<TemporaryKey> TemporaryKeys { get; init; }
public DbSet<DataExport> DataExports { get; init; }
public DbSet<PrideFlag> PrideFlags { get; set; }
public DbSet<UserFlag> UserFlags { get; set; }
public DbSet<MemberFlag> MemberFlags { get; set; }
public DbSet<PrideFlag> PrideFlags { get; init; }
public DbSet<UserFlag> UserFlags { get; init; }
public DbSet<MemberFlag> MemberFlags { get; init; }
protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
{
@ -81,6 +82,7 @@ public class DatabaseContext(DbContextOptions options) : DbContext(options)
})
.HasFilter("fediverse_application_id IS NOT NULL")
.IsUnique();
modelBuilder.Entity<DataExport>().HasIndex(d => d.Filename).IsUnique();
modelBuilder
.Entity<AuthMethod>()

View file

@ -0,0 +1,57 @@
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Foxnouns.Backend.Database.Migrations
{
/// <inheritdoc />
[DbContext(typeof(DatabaseContext))]
[Migration("20241202153736_AddDataExports")]
public partial class AddDataExports : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "data_exports",
columns: table => new
{
id = table.Column<long>(type: "bigint", nullable: false),
user_id = table.Column<long>(type: "bigint", nullable: false),
filename = table.Column<string>(type: "text", nullable: false),
},
constraints: table =>
{
table.PrimaryKey("pk_data_exports", x => x.id);
table.ForeignKey(
name: "fk_data_exports_users_user_id",
column: x => x.user_id,
principalTable: "users",
principalColumn: "id",
onDelete: ReferentialAction.Cascade
);
}
);
migrationBuilder.CreateIndex(
name: "ix_data_exports_filename",
table: "data_exports",
column: "filename",
unique: true
);
migrationBuilder.CreateIndex(
name: "ix_data_exports_user_id",
table: "data_exports",
column: "user_id"
);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(name: "data_exports");
}
}
}

View file

@ -111,6 +111,34 @@ namespace Foxnouns.Backend.Database.Migrations
b.ToTable("auth_methods", (string)null);
});
modelBuilder.Entity("Foxnouns.Backend.Database.Models.DataExport", b =>
{
b.Property<long>("Id")
.HasColumnType("bigint")
.HasColumnName("id");
b.Property<string>("Filename")
.IsRequired()
.HasColumnType("text")
.HasColumnName("filename");
b.Property<long>("UserId")
.HasColumnType("bigint")
.HasColumnName("user_id");
b.HasKey("Id")
.HasName("pk_data_exports");
b.HasIndex("Filename")
.IsUnique()
.HasDatabaseName("ix_data_exports_filename");
b.HasIndex("UserId")
.HasDatabaseName("ix_data_exports_user_id");
b.ToTable("data_exports", (string)null);
});
modelBuilder.Entity("Foxnouns.Backend.Database.Models.FediverseApplication", b =>
{
b.Property<long>("Id")
@ -515,6 +543,18 @@ namespace Foxnouns.Backend.Database.Migrations
b.Navigation("User");
});
modelBuilder.Entity("Foxnouns.Backend.Database.Models.DataExport", b =>
{
b.HasOne("Foxnouns.Backend.Database.Models.User", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_data_exports_users_user_id");
b.Navigation("User");
});
modelBuilder.Entity("Foxnouns.Backend.Database.Models.Member", b =>
{
b.HasOne("Foxnouns.Backend.Database.Models.User", "User")

View file

@ -0,0 +1,14 @@
using System.ComponentModel.DataAnnotations.Schema;
using NodaTime;
namespace Foxnouns.Backend.Database.Models;
public class DataExport : BaseModel
{
public Snowflake UserId { get; init; }
public User User { get; init; } = null!;
public required string Filename { get; init; }
[NotMapped]
public static readonly Duration Expiration = Duration.FromDays(15);
}

View file

@ -65,6 +65,9 @@ public readonly struct Snowflake(ulong value) : IEquatable<Snowflake>
return true;
}
public static Snowflake FromInstant(Instant instant) =>
new((ulong)(instant.ToUnixTimeMilliseconds() - Epoch) << 22);
public override bool Equals(object? obj) => obj is Snowflake other && Value == other.Value;
public bool Equals(Snowflake other)