xtablo-source/sql/12_update_tablos_id_to_random_string.sql

117 lines
4 KiB
MySQL
Raw Normal View History

-- Migration: Update tablos table ID from SERIAL to random 24-character string
-- This migration changes the tablos.id column from SERIAL to TEXT with random 24-character string IDs
-- Step 1: Create function to generate random 24-character strings
CREATE OR REPLACE FUNCTION generate_random_string(length INTEGER DEFAULT 24)
RETURNS TEXT
LANGUAGE plpgsql
AS $$
DECLARE
chars TEXT := 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
result TEXT := '';
i INTEGER := 0;
BEGIN
FOR i IN 1..length LOOP
result := result || substr(chars, floor(random() * length(chars) + 1)::INTEGER, 1);
END LOOP;
RETURN result;
END;
$$;
-- Step 2: Drop existing foreign key constraints
ALTER TABLE tablo_invites DROP CONSTRAINT IF EXISTS fk_tablo_invitations_tablo_id;
ALTER TABLE tablo_access DROP CONSTRAINT IF EXISTS fk_tablo_access_tablo_id;
-- Step 3: Drop the trigger that creates tablo_access records
DROP TRIGGER IF EXISTS trigger_create_tablo_access ON tablos;
-- Step 4: Create temporary columns for the new ID structure
ALTER TABLE tablos ADD COLUMN new_id TEXT;
ALTER TABLE tablo_invites ADD COLUMN new_tablo_id TEXT;
ALTER TABLE tablo_access ADD COLUMN new_tablo_id TEXT;
-- Step 5: Generate new random IDs for existing tablos
UPDATE tablos SET new_id = generate_random_string(24);
-- Step 6: Update foreign key references
UPDATE tablo_invites SET new_tablo_id = (
SELECT new_id FROM tablos WHERE tablos.id = tablo_invites.tablo_id
);
UPDATE tablo_access SET new_tablo_id = (
SELECT new_id FROM tablos WHERE tablos.id = tablo_access.tablo_id
);
-- Step 7: Drop old columns
ALTER TABLE tablo_invites DROP COLUMN tablo_id CASCADE;
ALTER TABLE tablo_access DROP COLUMN tablo_id CASCADE;
ALTER TABLE tablos DROP COLUMN id CASCADE;
-- Step 8: Rename new columns to original names
ALTER TABLE tablos RENAME COLUMN new_id TO id;
ALTER TABLE tablo_invites RENAME COLUMN new_tablo_id TO tablo_id;
ALTER TABLE tablo_access RENAME COLUMN new_tablo_id TO tablo_id;
-- Step 9: Add constraints and indexes
ALTER TABLE tablos ADD PRIMARY KEY (id);
ALTER TABLE tablos ALTER COLUMN id SET NOT NULL;
ALTER TABLE tablos ALTER COLUMN id SET DEFAULT generate_random_string(24);
-- Step 10: Re-add foreign key constraints
ALTER TABLE tablo_invites
ADD CONSTRAINT fk_tablo_invitations_tablo_id
FOREIGN KEY (tablo_id) REFERENCES tablos(id) ON DELETE CASCADE;
ALTER TABLE tablo_access
ADD CONSTRAINT fk_tablo_access_tablo_id
FOREIGN KEY (tablo_id) REFERENCES tablos(id) ON DELETE CASCADE;
-- Step 11: Ensure NOT NULL constraints on foreign keys
ALTER TABLE tablo_invites ALTER COLUMN tablo_id SET NOT NULL;
ALTER TABLE tablo_access ALTER COLUMN tablo_id SET NOT NULL;
-- Step 12: Recreate the trigger function with updated signature
CREATE OR REPLACE FUNCTION create_tablo_access_for_owner()
RETURNS TRIGGER
SECURITY DEFINER
AS $$
BEGIN
-- Insert a tablo_access record for the tablo owner
INSERT INTO tablo_access (
tablo_id,
user_id,
granted_by,
is_active,
is_admin
) VALUES (
NEW.id, -- tablo_id: the newly created tablo's id (now TEXT)
NEW.owner_id, -- user_id: the tablo owner gets access
NEW.owner_id, -- granted_by: self-granted by the owner
TRUE, -- is_active: access is active
TRUE -- is_admin: owner has admin privileges
);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- Step 13: Recreate the trigger
CREATE TRIGGER trigger_create_tablo_access
AFTER INSERT ON tablos
FOR EACH ROW
EXECUTE FUNCTION create_tablo_access_for_owner();
-- Step 14: Add comment to document the changes
COMMENT ON FUNCTION generate_random_string(INTEGER) IS
'Generates a random alphanumeric string of specified length (default 24 characters)';
COMMENT ON COLUMN tablos.id IS
'Primary key: random 24-character alphanumeric string';
COMMENT ON COLUMN tablo_invites.tablo_id IS
'Foreign key reference to tablos.id (24-character string)';
COMMENT ON COLUMN tablo_access.tablo_id IS
'Foreign key reference to tablos.id (24-character string)';