From 9edae1959117fa175d17c3b07303c9f8a37d05e8 Mon Sep 17 00:00:00 2001 From: Stephan Richter Date: Thu, 11 Sep 2025 21:15:01 +0200 Subject: [PATCH] started code to rebuid the wiki tables --- .../de/srsoftware/umbrella/wiki/SqliteDb.java | 92 ++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) diff --git a/wiki/src/main/java/de/srsoftware/umbrella/wiki/SqliteDb.java b/wiki/src/main/java/de/srsoftware/umbrella/wiki/SqliteDb.java index 2427621..4b0a437 100644 --- a/wiki/src/main/java/de/srsoftware/umbrella/wiki/SqliteDb.java +++ b/wiki/src/main/java/de/srsoftware/umbrella/wiki/SqliteDb.java @@ -3,6 +3,7 @@ package de.srsoftware.umbrella.wiki; import de.srsoftware.tools.jdbc.Condition; import de.srsoftware.tools.jdbc.Query; import de.srsoftware.umbrella.core.BaseDb; +import de.srsoftware.umbrella.core.model.Hash; import de.srsoftware.umbrella.core.model.Permission; import de.srsoftware.umbrella.core.model.WikiPage; @@ -19,7 +20,7 @@ import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.notFound; import static de.srsoftware.umbrella.core.model.Permission.EDIT; import static de.srsoftware.umbrella.core.model.Permission.READ_ONLY; import static de.srsoftware.umbrella.wiki.Constants.*; -import static java.lang.System.Logger.Level.ERROR; +import static java.lang.System.Logger.Level.*; import static java.text.MessageFormat.format; public class SqliteDb extends BaseDb implements WikiDb { @@ -37,11 +38,56 @@ public class SqliteDb extends BaseDb implements WikiDb { case 0: createPagesTable(); createPagesUsersTable(); + case 1: + /* + The old structure was: + Pages + | id (String) | version (int) | content (String) | + + Page_Users + | page_id (String) | user_id (long) | permission (long) | + + This poses a problem whenever a page is renamed: + On that occasion, all corresponding entries in the Page_Users table (and tags and notes) need to be updated! + + So the transformation went to the following structure: + Pages + | id (long) | title (String) | version (int) | content (String) | + + Page_Users + | page_id (long) | user_id (long) | permission (long) | + + With this structure we have stable ids even when a page is renamed! + */ + var newPages = TABLE_PAGES+"_new"; + var newUsers = TABLE_PAGES_USERS+"_new"; + createNewTables(newPages, newUsers); + transferValues(newPages, newUsers); + //dropOldTables(); + //moveNewTables(); } return setCurrentVersion(1); } + private void createNewTables(String newPages, String newUsers) { + var pages = "CREATE TABLE IF NOT EXISTS {0} ( {1} INT NOT NULL, {2} INT NOT NULL, {3} VARCHAR(255) NOT NULL, {4} TEXT NOT NULL, PRIMARY KEY({1},{2}))"; + var users = "CREATE TABLE IF NOT EXISTS {0} ( {1} INT NOT NULL, {2} INT NOT NULL, {3} INT NOT NULL, PRIMARY KEY({1}, {2}))"; + + try { + var stmt = db.prepareStatement(format(pages, newPages, ID, VERSION, TITLE, CONTENT)); + stmt.execute(); + stmt.close(); + + stmt = db.prepareStatement(format(users, newUsers, PAGE_ID, USER_ID, PERMISSIONS)); + stmt.execute(); + stmt.close(); + } catch (SQLException e) { + LOG.log(ERROR, ERROR_FAILED_CREATE_TABLE, newPages, e); + throw new RuntimeException(e); + } + } + private void createPagesTable() { var sql = "CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) NOT NULL, {2} INT NOT NULL, {3} TEXT NOT NULL, PRIMARY KEY({1},{2}))"; try { @@ -103,6 +149,50 @@ public class SqliteDb extends BaseDb implements WikiDb { } } + private void transferValues(String newTable, String newUsers) { + var pageMap = new HashMap(); // map from old IDs to new IDs + try { + Long id = 0L; + String lastTitle = null; + var rs = select("MAX(ID)").from(newTable).limit(1).exec(db); + if (rs.next()) id = rs.getLong(1); + rs.close(); + + rs = select(ALL).from(TABLE_PAGES).sort(ID).exec(db); + + while (rs.next()){ + var title = rs.getString(ID); + var version = rs.getInt(VERSION); + var content = rs.getString(CONTENT); + if (!title.equals(lastTitle)) { + pageMap.put(lastTitle = title,++id); + LOG.log(DEBUG,"Transferring \"{0}\" to new table with id = {1}",title,id); + } + insertInto(newTable,ID,VERSION,TITLE,CONTENT).values(id,version,title,content).execute(db).close(); + } + + rs.close(); + + rs = select(ALL).from(TABLE_PAGES_USERS).sort(PAGE_ID).exec(db); + while (rs.next()){ + var userId = rs.getLong(USER_ID); + var title = rs.getString(PAGE_ID); + var perm = rs.getInt(PERMISSIONS); + id = pageMap.get(title); + if (id == null){ + LOG.log(WARNING,"Found reference to non-existing page ({0}) in {1} – skipping transfer of permission",title,TABLE_PAGES_USERS); + continue; + } + insertInto(newUsers,PAGE_ID,USER_ID,PERMISSIONS).values(id,userId,perm).execute(db).close(); + } + rs.close(); + } catch (SQLException e) { + LOG.log(ERROR,"Failed to transfer entries from {0} → {0}_new!",TABLE_PAGES,e); + throw new RuntimeException(e); + + } + } + private int wikiPermissionCode(Permission perm){ return switch (perm){ case READ_ONLY -> 1;