feat: step 7's migration, with an index on spaceId
The first migration since the initial one, created with the CLI (serverpod create-migration --tag studysets), since no MCP bridge was set up yet. On the server it is one transaction that only adds: gen_random_uuid_v7(), the studyset table, the sync engine's tables (spaces, their members and nodes, the CRDT bookkeeping, the log of integrity violations) with their foreign keys, and, from Serverpod v4.0.3, the auth module's profile image foreign key re-created as DEFERRABLE INITIALLY DEFERRED, so that dumps restore. The server tests apply it to their Postgres. studyset gets an index on spaceId: deleting a space cascades into every synced table, and Postgres doesn't index foreign keys by itself, so account deletion and pruning would otherwise read whole tables. AGENTS.md makes it the rule for every synced table. The client migration creates each device's SQLite schema. The generator builds it from the whole definition, so it also contains the server's own tables; only the synced tables and the bookkeeping ever hold data on a device. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
7bd94a5bb8
commit
8f45b39c0e
8 changed files with 18154 additions and 6 deletions
|
|
@ -87,7 +87,21 @@ class Protocol extends _is.DatabaseSerializationManager {
|
|||
matchType: null,
|
||||
),
|
||||
],
|
||||
indexes: [],
|
||||
indexes: [
|
||||
_isp.IndexDefinition(
|
||||
indexName: 'studyset_space_idx',
|
||||
tableSpace: null,
|
||||
elements: [
|
||||
_isp.IndexElementDefinition(
|
||||
type: _isp.IndexElementDefinitionType.column,
|
||||
definition: 'spaceId',
|
||||
),
|
||||
],
|
||||
type: 'btree',
|
||||
isUnique: false,
|
||||
isPrimary: false,
|
||||
),
|
||||
],
|
||||
managed: true,
|
||||
),
|
||||
..._iais.Protocol.targetTableDefinitions,
|
||||
|
|
|
|||
|
|
@ -15,3 +15,9 @@ fields:
|
|||
payload: ByteData
|
||||
### The encryption nonce; always null, like keyId.
|
||||
nonce: ByteData?
|
||||
indexes:
|
||||
# Deleting a space (account deletion, pruning) finds its rows through this index
|
||||
# instead of reading the whole table: Postgres doesn't index foreign keys by itself.
|
||||
# Every synced table gets one.
|
||||
studyset_space_idx:
|
||||
fields: spaceId
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,113 @@
|
|||
{
|
||||
"__className__": "serverpod.DatabaseDefinition",
|
||||
"schemaVersion": 2,
|
||||
"moduleName": "halkyon_learn",
|
||||
"tables": [
|
||||
{
|
||||
"__className__": "serverpod.TableDefinition",
|
||||
"name": "studyset",
|
||||
"dartName": "Studyset",
|
||||
"module": "halkyon_learn",
|
||||
"schema": "public",
|
||||
"columns": [
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "id",
|
||||
"fieldName": "id",
|
||||
"columnType": 7,
|
||||
"isNullable": false,
|
||||
"columnDefault": "random_v7",
|
||||
"dartType": "UuidValue?"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "spaceId",
|
||||
"fieldName": "spaceId",
|
||||
"columnType": 6,
|
||||
"isNullable": true,
|
||||
"dartType": "int?"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "keyId",
|
||||
"fieldName": "keyId",
|
||||
"columnType": 0,
|
||||
"isNullable": true,
|
||||
"dartType": "String?"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "payload",
|
||||
"fieldName": "payload",
|
||||
"columnType": 5,
|
||||
"isNullable": false,
|
||||
"dartType": "dart:typed_data:ByteData"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "nonce",
|
||||
"fieldName": "nonce",
|
||||
"columnType": 5,
|
||||
"isNullable": true,
|
||||
"dartType": "dart:typed_data:ByteData?"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"__className__": "serverpod.ForeignKeyDefinition",
|
||||
"constraintName": "studyset_fk_0",
|
||||
"columns": [
|
||||
"spaceId"
|
||||
],
|
||||
"referenceTable": "offline_sync_spaces",
|
||||
"referenceTableSchema": "public",
|
||||
"referenceColumns": [
|
||||
"id"
|
||||
],
|
||||
"onUpdate": 3,
|
||||
"onDelete": 4
|
||||
}
|
||||
],
|
||||
"indexes": [
|
||||
{
|
||||
"__className__": "serverpod.IndexDefinition",
|
||||
"indexName": "studyset_space_idx",
|
||||
"elements": [
|
||||
{
|
||||
"__className__": "serverpod.IndexElementDefinition",
|
||||
"type": 0,
|
||||
"definition": "spaceId"
|
||||
}
|
||||
],
|
||||
"type": "btree",
|
||||
"isUnique": false,
|
||||
"isPrimary": false
|
||||
}
|
||||
],
|
||||
"managed": true
|
||||
}
|
||||
],
|
||||
"installedModules": [
|
||||
{
|
||||
"__className__": "serverpod.DatabaseMigrationVersion",
|
||||
"module": "serverpod",
|
||||
"version": "20260824182259319"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.DatabaseMigrationVersion",
|
||||
"module": "serverpod_auth_idp",
|
||||
"version": "20260924105404509"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.DatabaseMigrationVersion",
|
||||
"module": "serverpod_offline_sync",
|
||||
"version": "20260914143806119"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.DatabaseMigrationVersion",
|
||||
"module": "serverpod_auth_core",
|
||||
"version": "20260924105232991"
|
||||
}
|
||||
],
|
||||
"migrationApiVersion": 1
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,388 @@
|
|||
BEGIN;
|
||||
|
||||
--
|
||||
-- Function: gen_random_uuid_v7()
|
||||
-- Source: https://gist.github.com/kjmph/5bd772b2c2df145aa645b837da7eca74
|
||||
-- License: MIT (copyright notice included on the generator source code).
|
||||
--
|
||||
create or replace function gen_random_uuid_v7()
|
||||
returns uuid
|
||||
as $$
|
||||
begin
|
||||
-- use random v4 uuid as starting point (which has the same variant we need)
|
||||
-- then overlay timestamp
|
||||
-- then set version 7 by flipping the 2 and 1 bit in the version 4 string
|
||||
return encode(
|
||||
set_bit(
|
||||
set_bit(
|
||||
overlay(uuid_send(gen_random_uuid())
|
||||
placing substring(int8send(floor(extract(epoch from clock_timestamp()) * 1000)::bigint) from 3)
|
||||
from 1 for 6
|
||||
),
|
||||
52, 1
|
||||
),
|
||||
53, 1
|
||||
),
|
||||
'hex')::uuid;
|
||||
end
|
||||
$$
|
||||
language plpgsql
|
||||
volatile;
|
||||
|
||||
--
|
||||
-- ACTION CREATE TABLE
|
||||
--
|
||||
CREATE TABLE "studyset" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid_v7(),
|
||||
"spaceId" bigint,
|
||||
"keyId" text,
|
||||
"payload" bytea NOT NULL,
|
||||
"nonce" bytea
|
||||
);
|
||||
|
||||
-- Indexes
|
||||
CREATE INDEX "studyset_space_idx" ON "studyset" USING btree ("spaceId");
|
||||
|
||||
--
|
||||
-- ACTION CREATE TABLE
|
||||
--
|
||||
CREATE TABLE "crdt_data_attempted_value" (
|
||||
"id" bigserial PRIMARY KEY,
|
||||
"fieldId" bigint NOT NULL,
|
||||
"value" jsonb NOT NULL,
|
||||
"projectionReason" bigint NOT NULL
|
||||
);
|
||||
|
||||
-- Indexes
|
||||
CREATE UNIQUE INDEX "crdt_data_attempted_value__fieldId__unique_idx" ON "crdt_data_attempted_value" USING btree ("fieldId");
|
||||
|
||||
--
|
||||
-- ACTION CREATE TABLE
|
||||
--
|
||||
CREATE TABLE "crdt_data_fields" (
|
||||
"id" bigserial PRIMARY KEY,
|
||||
"hlcDatetime" timestamp without time zone NOT NULL,
|
||||
"hlcCounter" bigint NOT NULL,
|
||||
"rowId" bigint NOT NULL,
|
||||
"columnId" bigint NOT NULL,
|
||||
"nodeId" bigint NOT NULL
|
||||
);
|
||||
|
||||
-- Indexes
|
||||
CREATE UNIQUE INDEX "crdt_data_fields_row_column_idx" ON "crdt_data_fields" USING btree ("rowId", "columnId");
|
||||
|
||||
--
|
||||
-- ACTION CREATE TABLE
|
||||
--
|
||||
CREATE TABLE "crdt_data_rows" (
|
||||
"id" bigserial PRIMARY KEY,
|
||||
"hlcDatetime" timestamp without time zone NOT NULL,
|
||||
"hlcCounter" bigint NOT NULL,
|
||||
"spaceId" bigint NOT NULL,
|
||||
"tblId" bigint NOT NULL,
|
||||
"uuidRowId" uuid NOT NULL,
|
||||
"nodeId" bigint NOT NULL,
|
||||
"visibility" bigint NOT NULL DEFAULT 0
|
||||
);
|
||||
|
||||
-- Indexes
|
||||
CREATE UNIQUE INDEX "crdt_data_rows_space_tbl_row_idx" ON "crdt_data_rows" USING btree ("spaceId", "tblId", "uuidRowId");
|
||||
|
||||
--
|
||||
-- ACTION CREATE TABLE
|
||||
--
|
||||
CREATE TABLE "crdt_data_tombstone" (
|
||||
"id" bigserial PRIMARY KEY,
|
||||
"hlcDatetime" timestamp without time zone NOT NULL,
|
||||
"hlcCounter" bigint NOT NULL,
|
||||
"rowId" bigint NOT NULL,
|
||||
"nodeId" bigint NOT NULL,
|
||||
"clFlag" bigint NOT NULL,
|
||||
"reason" bigint NOT NULL
|
||||
);
|
||||
|
||||
-- Indexes
|
||||
CREATE UNIQUE INDEX "crdt_data_tombstone_row_idx" ON "crdt_data_tombstone" USING btree ("rowId");
|
||||
|
||||
--
|
||||
-- ACTION CREATE TABLE
|
||||
--
|
||||
CREATE TABLE "crdt_nodes" (
|
||||
"id" bigserial PRIMARY KEY,
|
||||
"uuidNodeId" uuid NOT NULL DEFAULT gen_random_uuid_v7(),
|
||||
"lastHlc" jsonb
|
||||
);
|
||||
|
||||
-- Indexes
|
||||
CREATE UNIQUE INDEX "crdt_nodes__uuidNodeId__unique_idx" ON "crdt_nodes" USING btree ("uuidNodeId");
|
||||
|
||||
--
|
||||
-- ACTION CREATE TABLE
|
||||
--
|
||||
CREATE TABLE "crdt_schema_columns" (
|
||||
"id" bigserial PRIMARY KEY,
|
||||
"tblId" bigint NOT NULL,
|
||||
"name" text NOT NULL,
|
||||
"columnType" text NOT NULL,
|
||||
"dartType" text NOT NULL,
|
||||
"isNullable" boolean NOT NULL
|
||||
);
|
||||
|
||||
-- Indexes
|
||||
CREATE UNIQUE INDEX "crdt_schema_columns_table_column_idx" ON "crdt_schema_columns" USING btree ("tblId", "name");
|
||||
|
||||
--
|
||||
-- ACTION CREATE TABLE
|
||||
--
|
||||
CREATE TABLE "crdt_schema_tables" (
|
||||
"id" bigserial PRIMARY KEY,
|
||||
"name" text NOT NULL
|
||||
);
|
||||
|
||||
-- Indexes
|
||||
CREATE UNIQUE INDEX "crdt_schema_tables__name__unique_idx" ON "crdt_schema_tables" USING btree ("name");
|
||||
|
||||
--
|
||||
-- ACTION CREATE TABLE
|
||||
--
|
||||
CREATE TABLE "offline_sync_integrity_violations" (
|
||||
"id" bigserial PRIMARY KEY,
|
||||
"type" text NOT NULL,
|
||||
"domainTableName" text NOT NULL,
|
||||
"uuidRowId" uuid NOT NULL,
|
||||
"ownerSpaceUuid" uuid,
|
||||
"incomingSpaceUuid" uuid NOT NULL,
|
||||
"operation" text NOT NULL,
|
||||
"uuidNodeId" uuid,
|
||||
"crdtDataRowId" bigint,
|
||||
"hlcDatetime" timestamp without time zone,
|
||||
"hlcCounter" bigint,
|
||||
"firstSeenAt" timestamp without time zone NOT NULL,
|
||||
"lastSeenAt" timestamp without time zone NOT NULL,
|
||||
"occurrences" bigint NOT NULL
|
||||
);
|
||||
|
||||
-- Indexes
|
||||
CREATE UNIQUE INDEX "offline_sync_integrity_violations_key_idx" ON "offline_sync_integrity_violations" USING btree ("type", "operation", "domainTableName", "uuidRowId", "ownerSpaceUuid", "incomingSpaceUuid");
|
||||
|
||||
--
|
||||
-- ACTION CREATE TABLE
|
||||
--
|
||||
CREATE TABLE "offline_sync_space_members" (
|
||||
"id" bigserial PRIMARY KEY,
|
||||
"spaceId" bigint NOT NULL,
|
||||
"userUuid" uuid NOT NULL,
|
||||
"role" text NOT NULL
|
||||
);
|
||||
|
||||
-- Indexes
|
||||
CREATE UNIQUE INDEX "offline_sync_space_member_unique_idx" ON "offline_sync_space_members" USING btree ("userUuid", "spaceId");
|
||||
|
||||
--
|
||||
-- ACTION CREATE TABLE
|
||||
--
|
||||
CREATE TABLE "offline_sync_space_nodes" (
|
||||
"id" bigserial PRIMARY KEY,
|
||||
"spaceId" bigint NOT NULL,
|
||||
"nodeId" bigint NOT NULL,
|
||||
"lastReceivedHlc" jsonb
|
||||
);
|
||||
|
||||
-- Indexes
|
||||
CREATE UNIQUE INDEX "offline_sync_space_node_unique_idx" ON "offline_sync_space_nodes" USING btree ("spaceId", "nodeId");
|
||||
|
||||
--
|
||||
-- ACTION CREATE TABLE
|
||||
--
|
||||
CREATE TABLE "offline_sync_spaces" (
|
||||
"id" bigserial PRIMARY KEY,
|
||||
"uuidSpaceId" uuid NOT NULL DEFAULT gen_random_uuid_v7(),
|
||||
"currentNodeId" bigint
|
||||
);
|
||||
|
||||
-- Indexes
|
||||
CREATE UNIQUE INDEX "offline_sync_spaces__uuidSpaceId__unique_idx" ON "offline_sync_spaces" USING btree ("uuidSpaceId");
|
||||
|
||||
--
|
||||
-- ACTION ALTER TABLE
|
||||
--
|
||||
ALTER TABLE "serverpod_auth_core_profile" DROP CONSTRAINT IF EXISTS "serverpod_auth_core_profile_fk_1";
|
||||
--
|
||||
-- ACTION CREATE FOREIGN KEY
|
||||
--
|
||||
ALTER TABLE ONLY "studyset"
|
||||
ADD CONSTRAINT "studyset_fk_0"
|
||||
FOREIGN KEY("spaceId")
|
||||
REFERENCES "offline_sync_spaces"("id")
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE NO ACTION;
|
||||
|
||||
--
|
||||
-- ACTION CREATE FOREIGN KEY
|
||||
--
|
||||
ALTER TABLE ONLY "crdt_data_attempted_value"
|
||||
ADD CONSTRAINT "crdt_data_attempted_value_fk_0"
|
||||
FOREIGN KEY("fieldId")
|
||||
REFERENCES "crdt_data_fields"("id")
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE NO ACTION;
|
||||
|
||||
--
|
||||
-- ACTION CREATE FOREIGN KEY
|
||||
--
|
||||
ALTER TABLE ONLY "crdt_data_fields"
|
||||
ADD CONSTRAINT "crdt_data_fields_fk_0"
|
||||
FOREIGN KEY("rowId")
|
||||
REFERENCES "crdt_data_rows"("id")
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE NO ACTION;
|
||||
ALTER TABLE ONLY "crdt_data_fields"
|
||||
ADD CONSTRAINT "crdt_data_fields_fk_1"
|
||||
FOREIGN KEY("columnId")
|
||||
REFERENCES "crdt_schema_columns"("id")
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE NO ACTION;
|
||||
ALTER TABLE ONLY "crdt_data_fields"
|
||||
ADD CONSTRAINT "crdt_data_fields_fk_2"
|
||||
FOREIGN KEY("nodeId")
|
||||
REFERENCES "crdt_nodes"("id")
|
||||
ON DELETE NO ACTION
|
||||
ON UPDATE NO ACTION;
|
||||
|
||||
--
|
||||
-- ACTION CREATE FOREIGN KEY
|
||||
--
|
||||
ALTER TABLE ONLY "crdt_data_rows"
|
||||
ADD CONSTRAINT "crdt_data_rows_fk_0"
|
||||
FOREIGN KEY("spaceId")
|
||||
REFERENCES "offline_sync_spaces"("id")
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE NO ACTION;
|
||||
ALTER TABLE ONLY "crdt_data_rows"
|
||||
ADD CONSTRAINT "crdt_data_rows_fk_1"
|
||||
FOREIGN KEY("tblId")
|
||||
REFERENCES "crdt_schema_tables"("id")
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE NO ACTION;
|
||||
ALTER TABLE ONLY "crdt_data_rows"
|
||||
ADD CONSTRAINT "crdt_data_rows_fk_2"
|
||||
FOREIGN KEY("nodeId")
|
||||
REFERENCES "crdt_nodes"("id")
|
||||
ON DELETE NO ACTION
|
||||
ON UPDATE NO ACTION;
|
||||
|
||||
--
|
||||
-- ACTION CREATE FOREIGN KEY
|
||||
--
|
||||
ALTER TABLE ONLY "crdt_data_tombstone"
|
||||
ADD CONSTRAINT "crdt_data_tombstone_fk_0"
|
||||
FOREIGN KEY("rowId")
|
||||
REFERENCES "crdt_data_rows"("id")
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE NO ACTION;
|
||||
ALTER TABLE ONLY "crdt_data_tombstone"
|
||||
ADD CONSTRAINT "crdt_data_tombstone_fk_1"
|
||||
FOREIGN KEY("nodeId")
|
||||
REFERENCES "crdt_nodes"("id")
|
||||
ON DELETE NO ACTION
|
||||
ON UPDATE NO ACTION;
|
||||
|
||||
--
|
||||
-- ACTION CREATE FOREIGN KEY
|
||||
--
|
||||
ALTER TABLE ONLY "crdt_schema_columns"
|
||||
ADD CONSTRAINT "crdt_schema_columns_fk_0"
|
||||
FOREIGN KEY("tblId")
|
||||
REFERENCES "crdt_schema_tables"("id")
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE NO ACTION;
|
||||
|
||||
--
|
||||
-- ACTION CREATE FOREIGN KEY
|
||||
--
|
||||
ALTER TABLE ONLY "offline_sync_space_members"
|
||||
ADD CONSTRAINT "offline_sync_space_members_fk_0"
|
||||
FOREIGN KEY("spaceId")
|
||||
REFERENCES "offline_sync_spaces"("id")
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE NO ACTION;
|
||||
|
||||
--
|
||||
-- ACTION CREATE FOREIGN KEY
|
||||
--
|
||||
ALTER TABLE ONLY "offline_sync_space_nodes"
|
||||
ADD CONSTRAINT "offline_sync_space_nodes_fk_0"
|
||||
FOREIGN KEY("spaceId")
|
||||
REFERENCES "offline_sync_spaces"("id")
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE NO ACTION;
|
||||
ALTER TABLE ONLY "offline_sync_space_nodes"
|
||||
ADD CONSTRAINT "offline_sync_space_nodes_fk_1"
|
||||
FOREIGN KEY("nodeId")
|
||||
REFERENCES "crdt_nodes"("id")
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE NO ACTION;
|
||||
|
||||
--
|
||||
-- ACTION CREATE FOREIGN KEY
|
||||
--
|
||||
ALTER TABLE ONLY "offline_sync_spaces"
|
||||
ADD CONSTRAINT "offline_sync_spaces_fk_0"
|
||||
FOREIGN KEY("currentNodeId")
|
||||
REFERENCES "crdt_nodes"("id")
|
||||
ON DELETE NO ACTION
|
||||
ON UPDATE NO ACTION;
|
||||
|
||||
--
|
||||
-- ACTION CREATE FOREIGN KEY
|
||||
--
|
||||
ALTER TABLE ONLY "serverpod_auth_core_profile"
|
||||
ADD CONSTRAINT "serverpod_auth_core_profile_fk_1"
|
||||
FOREIGN KEY("imageId")
|
||||
REFERENCES "serverpod_auth_core_profile_image"("id")
|
||||
ON DELETE NO ACTION
|
||||
ON UPDATE NO ACTION
|
||||
DEFERRABLE INITIALLY DEFERRED;
|
||||
|
||||
--
|
||||
-- MIGRATION VERSION FOR halkyon_learn
|
||||
--
|
||||
INSERT INTO "serverpod_migrations" ("module", "version", "timestamp")
|
||||
VALUES ('halkyon_learn', '20260930094729362-studysets', now())
|
||||
ON CONFLICT ("module")
|
||||
DO UPDATE SET "version" = '20260930094729362-studysets', "timestamp" = now();
|
||||
|
||||
--
|
||||
-- MIGRATION VERSION FOR serverpod
|
||||
--
|
||||
INSERT INTO "serverpod_migrations" ("module", "version", "timestamp")
|
||||
VALUES ('serverpod', '20260824182259319', now())
|
||||
ON CONFLICT ("module")
|
||||
DO UPDATE SET "version" = '20260824182259319', "timestamp" = now();
|
||||
|
||||
--
|
||||
-- MIGRATION VERSION FOR serverpod_auth_idp
|
||||
--
|
||||
INSERT INTO "serverpod_migrations" ("module", "version", "timestamp")
|
||||
VALUES ('serverpod_auth_idp', '20260924105404509', now())
|
||||
ON CONFLICT ("module")
|
||||
DO UPDATE SET "version" = '20260924105404509', "timestamp" = now();
|
||||
|
||||
--
|
||||
-- MIGRATION VERSION FOR serverpod_offline_sync
|
||||
--
|
||||
INSERT INTO "serverpod_migrations" ("module", "version", "timestamp")
|
||||
VALUES ('serverpod_offline_sync', '20260914143806119', now())
|
||||
ON CONFLICT ("module")
|
||||
DO UPDATE SET "version" = '20260914143806119', "timestamp" = now();
|
||||
|
||||
--
|
||||
-- MIGRATION VERSION FOR serverpod_auth_core
|
||||
--
|
||||
INSERT INTO "serverpod_migrations" ("module", "version", "timestamp")
|
||||
VALUES ('serverpod_auth_core', '20260924105232991', now())
|
||||
ON CONFLICT ("module")
|
||||
DO UPDATE SET "version" = '20260924105232991', "timestamp" = now();
|
||||
|
||||
|
||||
COMMIT;
|
||||
|
|
@ -5,3 +5,4 @@
|
|||
### the conflict by removing and recreating the conflicting migration.
|
||||
|
||||
20260916165410927
|
||||
20260930094729362-studysets
|
||||
|
|
|
|||
Loading…
Reference in a new issue