update db usage and init db files
This commit is contained in:
@@ -5,14 +5,22 @@
|
|||||||
<TargetFramework>net10.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
<UserSecretsId>a768c8b7-60e5-4914-8594-db709ad9929c</UserSecretsId>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="appsettings.json" CopyToOutputDirectory="PreserveNewest" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="EFCore.NamingConventions" Version="10.0.1" />
|
<PackageReference Include="EFCore.NamingConventions" Version="10.0.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.8">
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.8">
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="10.0.8" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.8" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="10.0.8" />
|
||||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.2" />
|
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -28,8 +28,13 @@ public class SkinTrackerDbContext : DbContext
|
|||||||
public DbSet<TradeItem> TradeItems => Set<TradeItem>();
|
public DbSet<TradeItem> TradeItems => Set<TradeItem>();
|
||||||
public DbSet<PriceHistory> PriceHistories => Set<PriceHistory>();
|
public DbSet<PriceHistory> PriceHistories => Set<PriceHistory>();
|
||||||
|
|
||||||
|
/// <summary>The PostgreSQL schema that owns all of this context's tables.</summary>
|
||||||
|
public const string Schema = "skintracker";
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
{
|
{
|
||||||
|
modelBuilder.HasDefaultSchema(Schema);
|
||||||
|
|
||||||
modelBuilder.ApplyConfiguration(new SkinConfiguration());
|
modelBuilder.ApplyConfiguration(new SkinConfiguration());
|
||||||
modelBuilder.ApplyConfiguration(new SkinConditionConfiguration());
|
modelBuilder.ApplyConfiguration(new SkinConditionConfiguration());
|
||||||
modelBuilder.ApplyConfiguration(new SteamUserConfiguration());
|
modelBuilder.ApplyConfiguration(new SteamUserConfiguration());
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Design;
|
using Microsoft.EntityFrameworkCore.Design;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
|
||||||
namespace BlueLaminate.EFCore.Data;
|
namespace BlueLaminate.EFCore.Data;
|
||||||
|
|
||||||
@@ -7,15 +8,25 @@ public class SkinTrackerDbContextFactory : IDesignTimeDbContextFactory<SkinTrack
|
|||||||
{
|
{
|
||||||
public SkinTrackerDbContext CreateDbContext(string[] args)
|
public SkinTrackerDbContext CreateDbContext(string[] args)
|
||||||
{
|
{
|
||||||
var connectionString =
|
var connectionString = BuildConfiguration().GetConnectionString("SkinTracker")
|
||||||
Environment.GetEnvironmentVariable("SKINTRACKER_CONNECTION")
|
?? throw new InvalidOperationException(
|
||||||
?? "Host=localhost;Port=5432;Database=skintracker;Username=postgres;Password=postgres";
|
"Connection string 'SkinTracker' is not configured. "
|
||||||
|
+ "Set it via user secrets (dev) or the ConnectionStrings__SkinTracker environment variable (prod).");
|
||||||
|
|
||||||
var options = new DbContextOptionsBuilder<SkinTrackerDbContext>()
|
var options = new DbContextOptionsBuilder<SkinTrackerDbContext>()
|
||||||
.UseNpgsql(connectionString)
|
.UseNpgsql(connectionString, npgsql =>
|
||||||
|
npgsql.MigrationsHistoryTable("__EFMigrationsHistory", SkinTrackerDbContext.Schema))
|
||||||
.UseSnakeCaseNamingConvention()
|
.UseSnakeCaseNamingConvention()
|
||||||
.Options;
|
.Options;
|
||||||
|
|
||||||
return new SkinTrackerDbContext(options);
|
return new SkinTrackerDbContext(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IConfiguration BuildConfiguration() =>
|
||||||
|
new ConfigurationBuilder()
|
||||||
|
.SetBasePath(AppContext.BaseDirectory)
|
||||||
|
.AddJsonFile("appsettings.json", optional: true)
|
||||||
|
.AddUserSecrets<SkinTrackerDbContextFactory>(optional: true)
|
||||||
|
.AddEnvironmentVariables()
|
||||||
|
.Build();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ public static class ServiceCollectionExtensions
|
|||||||
{
|
{
|
||||||
services.AddDbContext<SkinTrackerDbContext>(options =>
|
services.AddDbContext<SkinTrackerDbContext>(options =>
|
||||||
options
|
options
|
||||||
.UseNpgsql(connectionString)
|
.UseNpgsql(connectionString, npgsql =>
|
||||||
|
npgsql.MigrationsHistoryTable("__EFMigrationsHistory", SkinTrackerDbContext.Schema))
|
||||||
.UseSnakeCaseNamingConvention());
|
.UseSnakeCaseNamingConvention());
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
|||||||
namespace BlueLaminate.EFCore.Migrations
|
namespace BlueLaminate.EFCore.Migrations
|
||||||
{
|
{
|
||||||
[DbContext(typeof(SkinTrackerDbContext))]
|
[DbContext(typeof(SkinTrackerDbContext))]
|
||||||
[Migration("20260529170710_InitialCreate")]
|
[Migration("20260529180200_InitialCreate")]
|
||||||
partial class InitialCreate
|
partial class InitialCreate
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -20,6 +20,7 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
{
|
{
|
||||||
#pragma warning disable 612, 618
|
#pragma warning disable 612, 618
|
||||||
modelBuilder
|
modelBuilder
|
||||||
|
.HasDefaultSchema("skintracker")
|
||||||
.HasAnnotation("ProductVersion", "10.0.8")
|
.HasAnnotation("ProductVersion", "10.0.8")
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||||
|
|
||||||
@@ -63,7 +64,7 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
b.HasIndex("UserId")
|
b.HasIndex("UserId")
|
||||||
.HasDatabaseName("ix_inventory_items_user_id");
|
.HasDatabaseName("ix_inventory_items_user_id");
|
||||||
|
|
||||||
b.ToTable("inventory_items", (string)null);
|
b.ToTable("inventory_items", "skintracker");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("BlueLaminate.EFCore.Entities.PriceHistory", b =>
|
modelBuilder.Entity("BlueLaminate.EFCore.Entities.PriceHistory", b =>
|
||||||
@@ -111,7 +112,7 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
b.HasIndex("SkinId", "ConditionId", "RecordedAt")
|
b.HasIndex("SkinId", "ConditionId", "RecordedAt")
|
||||||
.HasDatabaseName("ix_price_histories_skin_id_condition_id_recorded_at");
|
.HasDatabaseName("ix_price_histories_skin_id_condition_id_recorded_at");
|
||||||
|
|
||||||
b.ToTable("price_histories", (string)null);
|
b.ToTable("price_histories", "skintracker");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("BlueLaminate.EFCore.Entities.Skin", b =>
|
modelBuilder.Entity("BlueLaminate.EFCore.Entities.Skin", b =>
|
||||||
@@ -172,7 +173,7 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
b.HasIndex("WeaponId")
|
b.HasIndex("WeaponId")
|
||||||
.HasDatabaseName("ix_skins_weapon_id");
|
.HasDatabaseName("ix_skins_weapon_id");
|
||||||
|
|
||||||
b.ToTable("skins", (string)null);
|
b.ToTable("skins", "skintracker");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("BlueLaminate.EFCore.Entities.SkinCondition", b =>
|
modelBuilder.Entity("BlueLaminate.EFCore.Entities.SkinCondition", b =>
|
||||||
@@ -207,7 +208,7 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
b.HasIndex("SkinId")
|
b.HasIndex("SkinId")
|
||||||
.HasDatabaseName("ix_skin_conditions_skin_id");
|
.HasDatabaseName("ix_skin_conditions_skin_id");
|
||||||
|
|
||||||
b.ToTable("skin_conditions", (string)null);
|
b.ToTable("skin_conditions", "skintracker");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("BlueLaminate.EFCore.Entities.SkinInstance", b =>
|
modelBuilder.Entity("BlueLaminate.EFCore.Entities.SkinInstance", b =>
|
||||||
@@ -263,7 +264,7 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
b.HasIndex("SkinId")
|
b.HasIndex("SkinId")
|
||||||
.HasDatabaseName("ix_skin_instances_skin_id");
|
.HasDatabaseName("ix_skin_instances_skin_id");
|
||||||
|
|
||||||
b.ToTable("skin_instances", (string)null);
|
b.ToTable("skin_instances", "skintracker");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("BlueLaminate.EFCore.Entities.SteamUser", b =>
|
modelBuilder.Entity("BlueLaminate.EFCore.Entities.SteamUser", b =>
|
||||||
@@ -295,7 +296,7 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
.IsUnique()
|
.IsUnique()
|
||||||
.HasDatabaseName("ix_steam_users_steam_id");
|
.HasDatabaseName("ix_steam_users_steam_id");
|
||||||
|
|
||||||
b.ToTable("steam_users", (string)null);
|
b.ToTable("steam_users", "skintracker");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("BlueLaminate.EFCore.Entities.Trade", b =>
|
modelBuilder.Entity("BlueLaminate.EFCore.Entities.Trade", b =>
|
||||||
@@ -332,7 +333,7 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
b.HasIndex("ToUserId")
|
b.HasIndex("ToUserId")
|
||||||
.HasDatabaseName("ix_trades_to_user_id");
|
.HasDatabaseName("ix_trades_to_user_id");
|
||||||
|
|
||||||
b.ToTable("trades", (string)null);
|
b.ToTable("trades", "skintracker");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("BlueLaminate.EFCore.Entities.TradeItem", b =>
|
modelBuilder.Entity("BlueLaminate.EFCore.Entities.TradeItem", b =>
|
||||||
@@ -361,7 +362,7 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
b.HasIndex("TradeId")
|
b.HasIndex("TradeId")
|
||||||
.HasDatabaseName("ix_trade_items_trade_id");
|
.HasDatabaseName("ix_trade_items_trade_id");
|
||||||
|
|
||||||
b.ToTable("trade_items", (string)null);
|
b.ToTable("trade_items", "skintracker");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("BlueLaminate.EFCore.Entities.Weapon", b =>
|
modelBuilder.Entity("BlueLaminate.EFCore.Entities.Weapon", b =>
|
||||||
@@ -391,7 +392,7 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
b.HasKey("Id")
|
b.HasKey("Id")
|
||||||
.HasName("pk_weapons");
|
.HasName("pk_weapons");
|
||||||
|
|
||||||
b.ToTable("weapons", (string)null);
|
b.ToTable("weapons", "skintracker");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("BlueLaminate.EFCore.Entities.InventoryItem", b =>
|
modelBuilder.Entity("BlueLaminate.EFCore.Entities.InventoryItem", b =>
|
||||||
@@ -12,8 +12,12 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
{
|
{
|
||||||
|
migrationBuilder.EnsureSchema(
|
||||||
|
name: "skintracker");
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "steam_users",
|
name: "steam_users",
|
||||||
|
schema: "skintracker",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
id = table.Column<int>(type: "integer", nullable: false)
|
id = table.Column<int>(type: "integer", nullable: false)
|
||||||
@@ -29,6 +33,7 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "weapons",
|
name: "weapons",
|
||||||
|
schema: "skintracker",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
id = table.Column<int>(type: "integer", nullable: false)
|
id = table.Column<int>(type: "integer", nullable: false)
|
||||||
@@ -44,6 +49,7 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "trades",
|
name: "trades",
|
||||||
|
schema: "skintracker",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
id = table.Column<int>(type: "integer", nullable: false)
|
id = table.Column<int>(type: "integer", nullable: false)
|
||||||
@@ -59,12 +65,14 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
table.ForeignKey(
|
table.ForeignKey(
|
||||||
name: "fk_trades_steam_users_from_user_id",
|
name: "fk_trades_steam_users_from_user_id",
|
||||||
column: x => x.from_user_id,
|
column: x => x.from_user_id,
|
||||||
|
principalSchema: "skintracker",
|
||||||
principalTable: "steam_users",
|
principalTable: "steam_users",
|
||||||
principalColumn: "id",
|
principalColumn: "id",
|
||||||
onDelete: ReferentialAction.Restrict);
|
onDelete: ReferentialAction.Restrict);
|
||||||
table.ForeignKey(
|
table.ForeignKey(
|
||||||
name: "fk_trades_steam_users_to_user_id",
|
name: "fk_trades_steam_users_to_user_id",
|
||||||
column: x => x.to_user_id,
|
column: x => x.to_user_id,
|
||||||
|
principalSchema: "skintracker",
|
||||||
principalTable: "steam_users",
|
principalTable: "steam_users",
|
||||||
principalColumn: "id",
|
principalColumn: "id",
|
||||||
onDelete: ReferentialAction.Restrict);
|
onDelete: ReferentialAction.Restrict);
|
||||||
@@ -72,6 +80,7 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "skins",
|
name: "skins",
|
||||||
|
schema: "skintracker",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
id = table.Column<int>(type: "integer", nullable: false)
|
id = table.Column<int>(type: "integer", nullable: false)
|
||||||
@@ -91,6 +100,7 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
table.ForeignKey(
|
table.ForeignKey(
|
||||||
name: "fk_skins_weapons_weapon_id",
|
name: "fk_skins_weapons_weapon_id",
|
||||||
column: x => x.weapon_id,
|
column: x => x.weapon_id,
|
||||||
|
principalSchema: "skintracker",
|
||||||
principalTable: "weapons",
|
principalTable: "weapons",
|
||||||
principalColumn: "id",
|
principalColumn: "id",
|
||||||
onDelete: ReferentialAction.Cascade);
|
onDelete: ReferentialAction.Cascade);
|
||||||
@@ -98,6 +108,7 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "skin_conditions",
|
name: "skin_conditions",
|
||||||
|
schema: "skintracker",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
id = table.Column<int>(type: "integer", nullable: false)
|
id = table.Column<int>(type: "integer", nullable: false)
|
||||||
@@ -113,6 +124,7 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
table.ForeignKey(
|
table.ForeignKey(
|
||||||
name: "fk_skin_conditions_skins_skin_id",
|
name: "fk_skin_conditions_skins_skin_id",
|
||||||
column: x => x.skin_id,
|
column: x => x.skin_id,
|
||||||
|
principalSchema: "skintracker",
|
||||||
principalTable: "skins",
|
principalTable: "skins",
|
||||||
principalColumn: "id",
|
principalColumn: "id",
|
||||||
onDelete: ReferentialAction.Cascade);
|
onDelete: ReferentialAction.Cascade);
|
||||||
@@ -120,6 +132,7 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "price_histories",
|
name: "price_histories",
|
||||||
|
schema: "skintracker",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
id = table.Column<int>(type: "integer", nullable: false)
|
id = table.Column<int>(type: "integer", nullable: false)
|
||||||
@@ -137,12 +150,14 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
table.ForeignKey(
|
table.ForeignKey(
|
||||||
name: "fk_price_histories_skin_conditions_condition_id",
|
name: "fk_price_histories_skin_conditions_condition_id",
|
||||||
column: x => x.condition_id,
|
column: x => x.condition_id,
|
||||||
|
principalSchema: "skintracker",
|
||||||
principalTable: "skin_conditions",
|
principalTable: "skin_conditions",
|
||||||
principalColumn: "id",
|
principalColumn: "id",
|
||||||
onDelete: ReferentialAction.Restrict);
|
onDelete: ReferentialAction.Restrict);
|
||||||
table.ForeignKey(
|
table.ForeignKey(
|
||||||
name: "fk_price_histories_skins_skin_id",
|
name: "fk_price_histories_skins_skin_id",
|
||||||
column: x => x.skin_id,
|
column: x => x.skin_id,
|
||||||
|
principalSchema: "skintracker",
|
||||||
principalTable: "skins",
|
principalTable: "skins",
|
||||||
principalColumn: "id",
|
principalColumn: "id",
|
||||||
onDelete: ReferentialAction.Cascade);
|
onDelete: ReferentialAction.Cascade);
|
||||||
@@ -150,6 +165,7 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "skin_instances",
|
name: "skin_instances",
|
||||||
|
schema: "skintracker",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
id = table.Column<int>(type: "integer", nullable: false)
|
id = table.Column<int>(type: "integer", nullable: false)
|
||||||
@@ -168,12 +184,14 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
table.ForeignKey(
|
table.ForeignKey(
|
||||||
name: "fk_skin_instances_skin_conditions_condition_id",
|
name: "fk_skin_instances_skin_conditions_condition_id",
|
||||||
column: x => x.condition_id,
|
column: x => x.condition_id,
|
||||||
|
principalSchema: "skintracker",
|
||||||
principalTable: "skin_conditions",
|
principalTable: "skin_conditions",
|
||||||
principalColumn: "id",
|
principalColumn: "id",
|
||||||
onDelete: ReferentialAction.Restrict);
|
onDelete: ReferentialAction.Restrict);
|
||||||
table.ForeignKey(
|
table.ForeignKey(
|
||||||
name: "fk_skin_instances_skins_skin_id",
|
name: "fk_skin_instances_skins_skin_id",
|
||||||
column: x => x.skin_id,
|
column: x => x.skin_id,
|
||||||
|
principalSchema: "skintracker",
|
||||||
principalTable: "skins",
|
principalTable: "skins",
|
||||||
principalColumn: "id",
|
principalColumn: "id",
|
||||||
onDelete: ReferentialAction.Cascade);
|
onDelete: ReferentialAction.Cascade);
|
||||||
@@ -181,6 +199,7 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "inventory_items",
|
name: "inventory_items",
|
||||||
|
schema: "skintracker",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
id = table.Column<int>(type: "integer", nullable: false)
|
id = table.Column<int>(type: "integer", nullable: false)
|
||||||
@@ -196,12 +215,14 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
table.ForeignKey(
|
table.ForeignKey(
|
||||||
name: "fk_inventory_items_skin_instances_skin_instance_id",
|
name: "fk_inventory_items_skin_instances_skin_instance_id",
|
||||||
column: x => x.skin_instance_id,
|
column: x => x.skin_instance_id,
|
||||||
|
principalSchema: "skintracker",
|
||||||
principalTable: "skin_instances",
|
principalTable: "skin_instances",
|
||||||
principalColumn: "id",
|
principalColumn: "id",
|
||||||
onDelete: ReferentialAction.Cascade);
|
onDelete: ReferentialAction.Cascade);
|
||||||
table.ForeignKey(
|
table.ForeignKey(
|
||||||
name: "fk_inventory_items_steam_users_user_id",
|
name: "fk_inventory_items_steam_users_user_id",
|
||||||
column: x => x.user_id,
|
column: x => x.user_id,
|
||||||
|
principalSchema: "skintracker",
|
||||||
principalTable: "steam_users",
|
principalTable: "steam_users",
|
||||||
principalColumn: "id",
|
principalColumn: "id",
|
||||||
onDelete: ReferentialAction.Cascade);
|
onDelete: ReferentialAction.Cascade);
|
||||||
@@ -209,6 +230,7 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "trade_items",
|
name: "trade_items",
|
||||||
|
schema: "skintracker",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
id = table.Column<int>(type: "integer", nullable: false)
|
id = table.Column<int>(type: "integer", nullable: false)
|
||||||
@@ -222,12 +244,14 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
table.ForeignKey(
|
table.ForeignKey(
|
||||||
name: "fk_trade_items_inventory_items_inventory_item_id",
|
name: "fk_trade_items_inventory_items_inventory_item_id",
|
||||||
column: x => x.inventory_item_id,
|
column: x => x.inventory_item_id,
|
||||||
|
principalSchema: "skintracker",
|
||||||
principalTable: "inventory_items",
|
principalTable: "inventory_items",
|
||||||
principalColumn: "id",
|
principalColumn: "id",
|
||||||
onDelete: ReferentialAction.Cascade);
|
onDelete: ReferentialAction.Cascade);
|
||||||
table.ForeignKey(
|
table.ForeignKey(
|
||||||
name: "fk_trade_items_trades_trade_id",
|
name: "fk_trade_items_trades_trade_id",
|
||||||
column: x => x.trade_id,
|
column: x => x.trade_id,
|
||||||
|
principalSchema: "skintracker",
|
||||||
principalTable: "trades",
|
principalTable: "trades",
|
||||||
principalColumn: "id",
|
principalColumn: "id",
|
||||||
onDelete: ReferentialAction.Cascade);
|
onDelete: ReferentialAction.Cascade);
|
||||||
@@ -235,87 +259,104 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "ix_inventory_items_asset_id",
|
name: "ix_inventory_items_asset_id",
|
||||||
|
schema: "skintracker",
|
||||||
table: "inventory_items",
|
table: "inventory_items",
|
||||||
column: "asset_id");
|
column: "asset_id");
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "ix_inventory_items_skin_instance_id",
|
name: "ix_inventory_items_skin_instance_id",
|
||||||
|
schema: "skintracker",
|
||||||
table: "inventory_items",
|
table: "inventory_items",
|
||||||
column: "skin_instance_id");
|
column: "skin_instance_id");
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "ix_inventory_items_user_id",
|
name: "ix_inventory_items_user_id",
|
||||||
|
schema: "skintracker",
|
||||||
table: "inventory_items",
|
table: "inventory_items",
|
||||||
column: "user_id");
|
column: "user_id");
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "ix_price_histories_condition_id",
|
name: "ix_price_histories_condition_id",
|
||||||
|
schema: "skintracker",
|
||||||
table: "price_histories",
|
table: "price_histories",
|
||||||
column: "condition_id");
|
column: "condition_id");
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "ix_price_histories_skin_id_condition_id_recorded_at",
|
name: "ix_price_histories_skin_id_condition_id_recorded_at",
|
||||||
|
schema: "skintracker",
|
||||||
table: "price_histories",
|
table: "price_histories",
|
||||||
columns: new[] { "skin_id", "condition_id", "recorded_at" });
|
columns: new[] { "skin_id", "condition_id", "recorded_at" });
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "ix_skin_conditions_skin_id",
|
name: "ix_skin_conditions_skin_id",
|
||||||
|
schema: "skintracker",
|
||||||
table: "skin_conditions",
|
table: "skin_conditions",
|
||||||
column: "skin_id");
|
column: "skin_id");
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "ix_skin_instances_condition_id",
|
name: "ix_skin_instances_condition_id",
|
||||||
|
schema: "skintracker",
|
||||||
table: "skin_instances",
|
table: "skin_instances",
|
||||||
column: "condition_id");
|
column: "condition_id");
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "ix_skin_instances_float_value",
|
name: "ix_skin_instances_float_value",
|
||||||
|
schema: "skintracker",
|
||||||
table: "skin_instances",
|
table: "skin_instances",
|
||||||
column: "float_value");
|
column: "float_value");
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "ix_skin_instances_paint_seed",
|
name: "ix_skin_instances_paint_seed",
|
||||||
|
schema: "skintracker",
|
||||||
table: "skin_instances",
|
table: "skin_instances",
|
||||||
column: "paint_seed");
|
column: "paint_seed");
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "ix_skin_instances_skin_id",
|
name: "ix_skin_instances_skin_id",
|
||||||
|
schema: "skintracker",
|
||||||
table: "skin_instances",
|
table: "skin_instances",
|
||||||
column: "skin_id");
|
column: "skin_id");
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "ix_skins_true_float",
|
name: "ix_skins_true_float",
|
||||||
|
schema: "skintracker",
|
||||||
table: "skins",
|
table: "skins",
|
||||||
column: "true_float");
|
column: "true_float");
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "ix_skins_weapon_id",
|
name: "ix_skins_weapon_id",
|
||||||
|
schema: "skintracker",
|
||||||
table: "skins",
|
table: "skins",
|
||||||
column: "weapon_id");
|
column: "weapon_id");
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "ix_steam_users_steam_id",
|
name: "ix_steam_users_steam_id",
|
||||||
|
schema: "skintracker",
|
||||||
table: "steam_users",
|
table: "steam_users",
|
||||||
column: "steam_id",
|
column: "steam_id",
|
||||||
unique: true);
|
unique: true);
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "ix_trade_items_inventory_item_id",
|
name: "ix_trade_items_inventory_item_id",
|
||||||
|
schema: "skintracker",
|
||||||
table: "trade_items",
|
table: "trade_items",
|
||||||
column: "inventory_item_id");
|
column: "inventory_item_id");
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "ix_trade_items_trade_id",
|
name: "ix_trade_items_trade_id",
|
||||||
|
schema: "skintracker",
|
||||||
table: "trade_items",
|
table: "trade_items",
|
||||||
column: "trade_id");
|
column: "trade_id");
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "ix_trades_from_user_id",
|
name: "ix_trades_from_user_id",
|
||||||
|
schema: "skintracker",
|
||||||
table: "trades",
|
table: "trades",
|
||||||
column: "from_user_id");
|
column: "from_user_id");
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "ix_trades_to_user_id",
|
name: "ix_trades_to_user_id",
|
||||||
|
schema: "skintracker",
|
||||||
table: "trades",
|
table: "trades",
|
||||||
column: "to_user_id");
|
column: "to_user_id");
|
||||||
}
|
}
|
||||||
@@ -324,31 +365,40 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
{
|
{
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "price_histories");
|
name: "price_histories",
|
||||||
|
schema: "skintracker");
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "trade_items");
|
name: "trade_items",
|
||||||
|
schema: "skintracker");
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "inventory_items");
|
name: "inventory_items",
|
||||||
|
schema: "skintracker");
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "trades");
|
name: "trades",
|
||||||
|
schema: "skintracker");
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "skin_instances");
|
name: "skin_instances",
|
||||||
|
schema: "skintracker");
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "steam_users");
|
name: "steam_users",
|
||||||
|
schema: "skintracker");
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "skin_conditions");
|
name: "skin_conditions",
|
||||||
|
schema: "skintracker");
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "skins");
|
name: "skins",
|
||||||
|
schema: "skintracker");
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "weapons");
|
name: "weapons",
|
||||||
|
schema: "skintracker");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -17,6 +17,7 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
{
|
{
|
||||||
#pragma warning disable 612, 618
|
#pragma warning disable 612, 618
|
||||||
modelBuilder
|
modelBuilder
|
||||||
|
.HasDefaultSchema("skintracker")
|
||||||
.HasAnnotation("ProductVersion", "10.0.8")
|
.HasAnnotation("ProductVersion", "10.0.8")
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||||
|
|
||||||
@@ -60,7 +61,7 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
b.HasIndex("UserId")
|
b.HasIndex("UserId")
|
||||||
.HasDatabaseName("ix_inventory_items_user_id");
|
.HasDatabaseName("ix_inventory_items_user_id");
|
||||||
|
|
||||||
b.ToTable("inventory_items", (string)null);
|
b.ToTable("inventory_items", "skintracker");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("BlueLaminate.EFCore.Entities.PriceHistory", b =>
|
modelBuilder.Entity("BlueLaminate.EFCore.Entities.PriceHistory", b =>
|
||||||
@@ -108,7 +109,7 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
b.HasIndex("SkinId", "ConditionId", "RecordedAt")
|
b.HasIndex("SkinId", "ConditionId", "RecordedAt")
|
||||||
.HasDatabaseName("ix_price_histories_skin_id_condition_id_recorded_at");
|
.HasDatabaseName("ix_price_histories_skin_id_condition_id_recorded_at");
|
||||||
|
|
||||||
b.ToTable("price_histories", (string)null);
|
b.ToTable("price_histories", "skintracker");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("BlueLaminate.EFCore.Entities.Skin", b =>
|
modelBuilder.Entity("BlueLaminate.EFCore.Entities.Skin", b =>
|
||||||
@@ -169,7 +170,7 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
b.HasIndex("WeaponId")
|
b.HasIndex("WeaponId")
|
||||||
.HasDatabaseName("ix_skins_weapon_id");
|
.HasDatabaseName("ix_skins_weapon_id");
|
||||||
|
|
||||||
b.ToTable("skins", (string)null);
|
b.ToTable("skins", "skintracker");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("BlueLaminate.EFCore.Entities.SkinCondition", b =>
|
modelBuilder.Entity("BlueLaminate.EFCore.Entities.SkinCondition", b =>
|
||||||
@@ -204,7 +205,7 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
b.HasIndex("SkinId")
|
b.HasIndex("SkinId")
|
||||||
.HasDatabaseName("ix_skin_conditions_skin_id");
|
.HasDatabaseName("ix_skin_conditions_skin_id");
|
||||||
|
|
||||||
b.ToTable("skin_conditions", (string)null);
|
b.ToTable("skin_conditions", "skintracker");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("BlueLaminate.EFCore.Entities.SkinInstance", b =>
|
modelBuilder.Entity("BlueLaminate.EFCore.Entities.SkinInstance", b =>
|
||||||
@@ -260,7 +261,7 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
b.HasIndex("SkinId")
|
b.HasIndex("SkinId")
|
||||||
.HasDatabaseName("ix_skin_instances_skin_id");
|
.HasDatabaseName("ix_skin_instances_skin_id");
|
||||||
|
|
||||||
b.ToTable("skin_instances", (string)null);
|
b.ToTable("skin_instances", "skintracker");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("BlueLaminate.EFCore.Entities.SteamUser", b =>
|
modelBuilder.Entity("BlueLaminate.EFCore.Entities.SteamUser", b =>
|
||||||
@@ -292,7 +293,7 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
.IsUnique()
|
.IsUnique()
|
||||||
.HasDatabaseName("ix_steam_users_steam_id");
|
.HasDatabaseName("ix_steam_users_steam_id");
|
||||||
|
|
||||||
b.ToTable("steam_users", (string)null);
|
b.ToTable("steam_users", "skintracker");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("BlueLaminate.EFCore.Entities.Trade", b =>
|
modelBuilder.Entity("BlueLaminate.EFCore.Entities.Trade", b =>
|
||||||
@@ -329,7 +330,7 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
b.HasIndex("ToUserId")
|
b.HasIndex("ToUserId")
|
||||||
.HasDatabaseName("ix_trades_to_user_id");
|
.HasDatabaseName("ix_trades_to_user_id");
|
||||||
|
|
||||||
b.ToTable("trades", (string)null);
|
b.ToTable("trades", "skintracker");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("BlueLaminate.EFCore.Entities.TradeItem", b =>
|
modelBuilder.Entity("BlueLaminate.EFCore.Entities.TradeItem", b =>
|
||||||
@@ -358,7 +359,7 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
b.HasIndex("TradeId")
|
b.HasIndex("TradeId")
|
||||||
.HasDatabaseName("ix_trade_items_trade_id");
|
.HasDatabaseName("ix_trade_items_trade_id");
|
||||||
|
|
||||||
b.ToTable("trade_items", (string)null);
|
b.ToTable("trade_items", "skintracker");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("BlueLaminate.EFCore.Entities.Weapon", b =>
|
modelBuilder.Entity("BlueLaminate.EFCore.Entities.Weapon", b =>
|
||||||
@@ -388,7 +389,7 @@ namespace BlueLaminate.EFCore.Migrations
|
|||||||
b.HasKey("Id")
|
b.HasKey("Id")
|
||||||
.HasName("pk_weapons");
|
.HasName("pk_weapons");
|
||||||
|
|
||||||
b.ToTable("weapons", (string)null);
|
b.ToTable("weapons", "skintracker");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("BlueLaminate.EFCore.Entities.InventoryItem", b =>
|
modelBuilder.Entity("BlueLaminate.EFCore.Entities.InventoryItem", b =>
|
||||||
|
|||||||
5
BlueLaminate/BlueLaminate.EFCore/appsettings.json
Normal file
5
BlueLaminate/BlueLaminate.EFCore/appsettings.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"ConnectionStrings": {
|
||||||
|
"SkinTracker": "Host=localhost;Port=5432;Database=skintracker;Username=postgres"
|
||||||
|
}
|
||||||
|
}
|
||||||
40
db/00_drop_legacy_role.sql
Normal file
40
db/00_drop_legacy_role.sql
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
-- ============================================================
|
||||||
|
-- CS2 Skin Tracker — drop a pre-existing skintracker_app role
|
||||||
|
-- Run ONCE as a superuser (e.g. postgres) BEFORE
|
||||||
|
-- 01_schema_and_roles.sql, to remove an older role and
|
||||||
|
-- everything it owns so the creation script starts clean.
|
||||||
|
--
|
||||||
|
-- IMPORTANT:
|
||||||
|
-- * Connect to the SAME database that contains the old
|
||||||
|
-- skintracker schema/tables. DROP OWNED only affects the
|
||||||
|
-- current database, so if the role owns objects in more
|
||||||
|
-- than one database, run this in each of them.
|
||||||
|
-- * This is DESTRUCTIVE: it drops the schema, tables, and any
|
||||||
|
-- data the role owns. Back up first if you need the data.
|
||||||
|
-- ============================================================
|
||||||
|
|
||||||
|
-- 1. (Optional) Terminate any live sessions still using the role,
|
||||||
|
-- otherwise the DROP ROLE can fail with "role is being used".
|
||||||
|
SELECT pg_terminate_backend(pid)
|
||||||
|
FROM pg_stat_activity
|
||||||
|
WHERE usename = 'skintracker_app'
|
||||||
|
AND pid <> pg_backend_pid();
|
||||||
|
|
||||||
|
-- 2. Reassign ownership of the DATABASE away from the role.
|
||||||
|
-- DROP OWNED BY does NOT cover database ownership (a database is a
|
||||||
|
-- cluster-level object), so the role must hand off the database
|
||||||
|
-- first or DROP ROLE fails with "owner of database skintracker".
|
||||||
|
-- Run this while connected as the target owner (e.g. postgres).
|
||||||
|
ALTER DATABASE skintracker OWNER TO CURRENT_USER;
|
||||||
|
|
||||||
|
-- 3. Drop everything the role owns (schema, tables, indexes, etc.)
|
||||||
|
-- and revoke any privileges granted to it, then drop the role.
|
||||||
|
-- Guarded so the script is safe to run even if the role is gone.
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'skintracker_app') THEN
|
||||||
|
EXECUTE 'DROP OWNED BY skintracker_app CASCADE';
|
||||||
|
EXECUTE 'DROP ROLE skintracker_app';
|
||||||
|
END IF;
|
||||||
|
END
|
||||||
|
$$;
|
||||||
40
db/01_schema_and_roles.sql
Normal file
40
db/01_schema_and_roles.sql
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
-- ============================================================
|
||||||
|
-- CS2 Skin Tracker — schema & role hardening
|
||||||
|
-- Run ONCE as a superuser (e.g. postgres), connected to the
|
||||||
|
-- skintracker database, before the app's first migration.
|
||||||
|
--
|
||||||
|
-- Replace the password placeholders before running.
|
||||||
|
-- The application/migration connection should authenticate as
|
||||||
|
-- the skintracker_app role.
|
||||||
|
-- ============================================================
|
||||||
|
|
||||||
|
-- 1. Application login role (least-privilege; not a superuser).
|
||||||
|
-- Skip the CREATE if the role already exists.
|
||||||
|
CREATE ROLE skintracker_app WITH LOGIN PASSWORD 'change-me-strong-password';
|
||||||
|
|
||||||
|
-- 2. Create the schema and make the app role its owner.
|
||||||
|
-- Because the app owns it, EF's `EnsureSchema` (CREATE SCHEMA IF
|
||||||
|
-- NOT EXISTS) becomes a no-op and the app can create/alter tables
|
||||||
|
-- here during `database update` without any rights on `public`.
|
||||||
|
CREATE SCHEMA IF NOT EXISTS skintracker AUTHORIZATION skintracker_app;
|
||||||
|
|
||||||
|
-- 3. Lock down the default `public` schema.
|
||||||
|
-- Historically every role had CREATE on public; revoke it so no
|
||||||
|
-- objects can be created there by accident. (PG15+ already removed
|
||||||
|
-- this by default, but being explicit is harmless and portable.)
|
||||||
|
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
|
||||||
|
|
||||||
|
-- 4. Make the app role use its own schema by default (so unqualified
|
||||||
|
-- object names resolve to skintracker, not public).
|
||||||
|
ALTER ROLE skintracker_app SET search_path = skintracker;
|
||||||
|
|
||||||
|
-- ------------------------------------------------------------
|
||||||
|
-- Optional: a read-only role for reporting / BI.
|
||||||
|
-- Uncomment if you need separate read-only access.
|
||||||
|
-- ------------------------------------------------------------
|
||||||
|
-- CREATE ROLE skintracker_readonly WITH LOGIN PASSWORD 'change-me-too';
|
||||||
|
-- GRANT USAGE ON SCHEMA skintracker TO skintracker_readonly;
|
||||||
|
-- GRANT SELECT ON ALL TABLES IN SCHEMA skintracker TO skintracker_readonly;
|
||||||
|
-- -- Apply automatically to tables created LATER by the app role:
|
||||||
|
-- ALTER DEFAULT PRIVILEGES FOR ROLE skintracker_app IN SCHEMA skintracker
|
||||||
|
-- GRANT SELECT ON TABLES TO skintracker_readonly;
|
||||||
Reference in New Issue
Block a user