18f259467SAndreas Gohr<?php 2d6d97f60SAnna Dabrowska 37234bfb1Ssplitbrainuse dokuwiki\Extension\ActionPlugin; 47234bfb1Ssplitbrainuse dokuwiki\Extension\EventHandler; 57234bfb1Ssplitbrainuse dokuwiki\Extension\Event; 67234bfb1Ssplitbrainuse dokuwiki\plugin\sqlite\SQLiteDB; 77234bfb1Ssplitbrain 88f259467SAndreas Gohr/** 98f259467SAndreas Gohr * DokuWiki Plugin struct (Action Component) 108f259467SAndreas Gohr * 118f259467SAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 128f259467SAndreas Gohr * @author Andreas Gohr, Michael Große <dokuwiki@cosmocode.de> 138f259467SAndreas Gohr */ 148f259467SAndreas Gohr/** 158f259467SAndreas Gohr * Class action_plugin_struct_migration 168f259467SAndreas Gohr * 178f259467SAndreas Gohr * Handle migrations that need more than just SQL 188f259467SAndreas Gohr */ 197234bfb1Ssplitbrainclass action_plugin_struct_migration extends ActionPlugin 20d6d97f60SAnna Dabrowska{ 218f259467SAndreas Gohr /** 228f259467SAndreas Gohr * @inheritDoc 238f259467SAndreas Gohr */ 247234bfb1Ssplitbrain public function register(EventHandler $controller) 25d6d97f60SAnna Dabrowska { 26748e747fSAnna Dabrowska $controller->register_hook('PLUGIN_SQLITE_DATABASE_UPGRADE', 'BEFORE', $this, 'handleMigrations'); 278f259467SAndreas Gohr } 288f259467SAndreas Gohr 298f259467SAndreas Gohr /** 308f259467SAndreas Gohr * Call our custom migrations when defined 318f259467SAndreas Gohr * 325e29103aSannda * @param Event $event 338f259467SAndreas Gohr * @param $param 348f259467SAndreas Gohr */ 357234bfb1Ssplitbrain public function handleMigrations(Event $event, $param) 36d6d97f60SAnna Dabrowska { 3779b29326SAnna Dabrowska if ($event->data['adapter']->getDbname() !== 'struct') { 383eafcbabSMichael Große return; 393eafcbabSMichael Große } 408f259467SAndreas Gohr $to = $event->data['to']; 418f259467SAndreas Gohr 427234bfb1Ssplitbrain if (is_callable([$this, "migration$to"])) { 438f259467SAndreas Gohr $event->preventDefault(); 447234bfb1Ssplitbrain $event->result = call_user_func([$this, "migration$to"], $event->data['adapter']); 458f259467SAndreas Gohr } 468f259467SAndreas Gohr } 478f259467SAndreas Gohr 488f259467SAndreas Gohr /** 498f259467SAndreas Gohr * Executes Migration 12 508f259467SAndreas Gohr * 518f259467SAndreas Gohr * Add a latest column to all existing multi tables 528f259467SAndreas Gohr * 537234bfb1Ssplitbrain * @param SQLiteDB $sqlite 548f259467SAndreas Gohr * @return bool 558f259467SAndreas Gohr */ 5679b29326SAnna Dabrowska protected function migration12($sqlite) 57d6d97f60SAnna Dabrowska { 588f259467SAndreas Gohr /** @noinspection SqlResolve */ 598f259467SAndreas Gohr $sql = "SELECT name FROM sqlite_master WHERE type = 'table' AND name LIKE 'multi_%'"; 6079b29326SAnna Dabrowska $tables = $sqlite->queryAll($sql); 618f259467SAndreas Gohr 628f259467SAndreas Gohr foreach ($tables as $row) { 6366164365SAndreas Gohr $table = $row['name']; // no escaping needed, it's our own tables 6466164365SAndreas Gohr $sql = "ALTER TABLE $table ADD COLUMN latest INT DEFAULT 1"; 6566164365SAndreas Gohr $sqlite->query($sql); 668f259467SAndreas Gohr } 678f259467SAndreas Gohr 688f259467SAndreas Gohr return true; 698f259467SAndreas Gohr } 7076a74c23SAnna Dabrowska 7176a74c23SAnna Dabrowska /** 7276a74c23SAnna Dabrowska * Executes Migration 16 7376a74c23SAnna Dabrowska * 7476a74c23SAnna Dabrowska * Unifies previous page and lookup schema types 7576a74c23SAnna Dabrowska * 767234bfb1Ssplitbrain * @param SQLiteDB $sqlite 7776a74c23SAnna Dabrowska * @return bool 7876a74c23SAnna Dabrowska */ 7979b29326SAnna Dabrowska protected function migration16($sqlite) 8076a74c23SAnna Dabrowska { 8176a74c23SAnna Dabrowska // get tables and their SQL definitions 8276a74c23SAnna Dabrowska $sql = "SELECT sql, name FROM sqlite_master 8376a74c23SAnna Dabrowska WHERE type = 'table' 8476a74c23SAnna Dabrowska AND (name LIKE 'data_%' OR name LIKE 'multi_%')"; 8579b29326SAnna Dabrowska $tables = $sqlite->queryAll($sql); 8676a74c23SAnna Dabrowska 8776a74c23SAnna Dabrowska // get latest versions of schemas with islookup property 8876a74c23SAnna Dabrowska $sql = "SELECT MAX(id) AS id, tbl, islookup FROM schemas 8976a74c23SAnna Dabrowska GROUP BY tbl 9076a74c23SAnna Dabrowska "; 9179b29326SAnna Dabrowska $schemas = $sqlite->queryAll($sql); 9276a74c23SAnna Dabrowska 9376a74c23SAnna Dabrowska $ok = true; 9476a74c23SAnna Dabrowska 9576a74c23SAnna Dabrowska // Step 1: move original data to temporary tables and create new ones with modified schemas 9676a74c23SAnna Dabrowska foreach ($tables as $table) { 9776a74c23SAnna Dabrowska $name = $table['name']; 9876a74c23SAnna Dabrowska $sql = $table['sql']; 9976a74c23SAnna Dabrowska 10076a74c23SAnna Dabrowska // move original data to temp_* 10176a74c23SAnna Dabrowska $ok = $ok && $sqlite->query("ALTER TABLE $name RENAME TO temp_$name"); 10276a74c23SAnna Dabrowska 10376a74c23SAnna Dabrowska // update pid definitions 10476a74c23SAnna Dabrowska $sql = preg_replace('/pid (\w* ?NOT NULL|\w* ?PRIMARY KEY)/', 'pid TEXT DEFAULT ""', $sql); 10576a74c23SAnna Dabrowska 10676a74c23SAnna Dabrowska // add rid and new primary key to regular tables 10776a74c23SAnna Dabrowska $cnt = 0; 10876a74c23SAnna Dabrowska $sql = preg_replace('/(PRIMARY KEY ?\([^\)]+?)(\))/', ' rid INTEGER, $1, rid $2', $sql, -1, $cnt); 10976a74c23SAnna Dabrowska // add rid and new primary key to lookup tables 11076a74c23SAnna Dabrowska if (!$cnt) { 11176a74c23SAnna Dabrowska $sql = str_replace(')', ', rid INTEGER, PRIMARY KEY(pid,rid) )', $sql); 11276a74c23SAnna Dabrowska } 11376a74c23SAnna Dabrowska 11476a74c23SAnna Dabrowska // create the new table 11576a74c23SAnna Dabrowska $ok = $ok && $sqlite->query($sql); 11676a74c23SAnna Dabrowska if (!$ok) return false; 11776a74c23SAnna Dabrowska } 11876a74c23SAnna Dabrowska 11976a74c23SAnna Dabrowska // Step 2: transfer data back from original tables (temp_*) 12076a74c23SAnna Dabrowska foreach ($schemas as $schema) { 12176a74c23SAnna Dabrowska $name = $schema['tbl']; 12276a74c23SAnna Dabrowska $sid = $schema['id']; 12376a74c23SAnna Dabrowska $isLookup = $schema['islookup']; 12476a74c23SAnna Dabrowska 12576a74c23SAnna Dabrowska if (!$isLookup) { 12676a74c23SAnna Dabrowska $s = sprintf('INSERT INTO data_%s SELECT *, 0 FROM temp_data_%s', $name, $name); 12776a74c23SAnna Dabrowska $ok = $ok && $sqlite->query($s); 12876a74c23SAnna Dabrowska if (!$ok) return false; 12976a74c23SAnna Dabrowska 13076a74c23SAnna Dabrowska $s = sprintf('INSERT INTO multi_%s SELECT *, 0 FROM temp_multi_%s', $name, $name); 13176a74c23SAnna Dabrowska $ok = $ok && $sqlite->query($s); 13276a74c23SAnna Dabrowska if (!$ok) return false; 13376a74c23SAnna Dabrowska } else { 13476a74c23SAnna Dabrowska // transfer pid to rid 13576a74c23SAnna Dabrowska $s = sprintf('INSERT INTO data_%s SELECT *, pid FROM temp_data_%s', $name, $name); 13676a74c23SAnna Dabrowska $ok = $ok && $sqlite->query($s); 13776a74c23SAnna Dabrowska if (!$ok) return false; 13876a74c23SAnna Dabrowska 13976a74c23SAnna Dabrowska $s = sprintf('INSERT INTO multi_%s SELECT *, pid FROM temp_multi_%s', $name, $name); 14076a74c23SAnna Dabrowska $ok = $ok && $sqlite->query($s); 14176a74c23SAnna Dabrowska if (!$ok) return false; 14276a74c23SAnna Dabrowska 14376a74c23SAnna Dabrowska // all lookup data has empty pids at this point 14476a74c23SAnna Dabrowska $s = "UPDATE data_$name SET pid = ''"; 14576a74c23SAnna Dabrowska $ok = $ok && $sqlite->query($s); 14676a74c23SAnna Dabrowska if (!$ok) return false; 14776a74c23SAnna Dabrowska 14876a74c23SAnna Dabrowska $s = "UPDATE multi_$name SET pid = ''"; 14976a74c23SAnna Dabrowska $ok = $ok && $sqlite->query($s); 15076a74c23SAnna Dabrowska if (!$ok) return false; 15176a74c23SAnna Dabrowska } 15276a74c23SAnna Dabrowska 15376a74c23SAnna Dabrowska // introduce composite ids in lookup columns 154544dca1bSAnna Dabrowska $s = $this->getLookupColsSql($sid); 15579b29326SAnna Dabrowska $cols = $sqlite->queryAll($s); 15676a74c23SAnna Dabrowska 15776a74c23SAnna Dabrowska if ($cols) { 15876a74c23SAnna Dabrowska foreach ($cols as $col) { 15976a74c23SAnna Dabrowska $colno = $col['COL']; 160e361da24SAnna Dabrowska $colname = "col$colno"; 161ef747633SAnna Dabrowska // lookup fields pointing to pages have to be migrated first! 162ef747633SAnna Dabrowska // they rely on a simplistic not-a-number check, and already migrated lookups pass the test! 16317a3a578SAndreas Gohr $f = 'UPDATE data_%s 16417a3a578SAndreas Gohr SET %s = \'["\'||%s||\'",0]\' 16517a3a578SAndreas Gohr WHERE %s != \'\' 16617a3a578SAndreas Gohr AND CAST(%s AS DECIMAL) != %s'; 167e361da24SAnna Dabrowska $s = sprintf($f, $name, $colname, $colname, $colname, $colname, $colname); 168e361da24SAnna Dabrowska $ok = $ok && $sqlite->query($s); 169e361da24SAnna Dabrowska if (!$ok) return false; 17076a74c23SAnna Dabrowska // multi_ 17117a3a578SAndreas Gohr $f = 'UPDATE multi_%s 17217a3a578SAndreas Gohr SET value = \'["\'||value||\'",0]\' 17317a3a578SAndreas Gohr WHERE colref = %s 17417a3a578SAndreas Gohr AND CAST(value AS DECIMAL) != value'; 175e361da24SAnna Dabrowska $s = sprintf($f, $name, $colno); 17676a74c23SAnna Dabrowska $ok = $ok && $sqlite->query($s); 17776a74c23SAnna Dabrowska if (!$ok) return false; 178ef747633SAnna Dabrowska 179ef747633SAnna Dabrowska // simple lookup fields 18017a3a578SAndreas Gohr $s = "UPDATE data_$name 18117a3a578SAndreas Gohr SET col$colno = '[" . '""' . ",'||col$colno||']' 18217a3a578SAndreas Gohr WHERE col$colno != '' 18317a3a578SAndreas Gohr AND CAST(col$colno AS DECIMAL) = col$colno"; 184ef747633SAnna Dabrowska $ok = $ok && $sqlite->query($s); 185ef747633SAnna Dabrowska if (!$ok) return false; 186ef747633SAnna Dabrowska // multi_ 18717a3a578SAndreas Gohr $s = "UPDATE multi_$name 18817a3a578SAndreas Gohr SET value = '[" . '""' . ",'||value||']' 18917a3a578SAndreas Gohr WHERE colref=$colno 19017a3a578SAndreas Gohr AND CAST(value AS DECIMAL) = value"; 191ef747633SAnna Dabrowska $ok = $ok && $sqlite->query($s); 192ef747633SAnna Dabrowska if (!$ok) return false; 19376a74c23SAnna Dabrowska } 19476a74c23SAnna Dabrowska } 19576a74c23SAnna Dabrowska } 19676a74c23SAnna Dabrowska 19776a74c23SAnna Dabrowska // Step 3: delete temp_* tables 19876a74c23SAnna Dabrowska foreach ($tables as $table) { 19976a74c23SAnna Dabrowska $name = $table['name']; 20076a74c23SAnna Dabrowska $s = "DROP TABLE temp_$name"; 20176a74c23SAnna Dabrowska $ok = $ok && $sqlite->query($s); 20276a74c23SAnna Dabrowska if (!$ok) return false; 20376a74c23SAnna Dabrowska } 20476a74c23SAnna Dabrowska 20576a74c23SAnna Dabrowska // Step 4: remove islookup in schemas table 20676a74c23SAnna Dabrowska $sql = "SELECT sql FROM sqlite_master 20776a74c23SAnna Dabrowska WHERE type = 'table' 20876a74c23SAnna Dabrowska AND name = 'schemas'"; 20979b29326SAnna Dabrowska $t = $sqlite->queryAll($sql); 21076a74c23SAnna Dabrowska $sql = $t[0]['sql']; 21176a74c23SAnna Dabrowska $sql = str_replace('islookup INTEGER,', '', $sql); 21276a74c23SAnna Dabrowska 21376a74c23SAnna Dabrowska $s = 'ALTER TABLE schemas RENAME TO temp_schemas'; 21476a74c23SAnna Dabrowska $ok = $ok && $sqlite->query($s); 21576a74c23SAnna Dabrowska if (!$ok) return false; 21676a74c23SAnna Dabrowska 21776a74c23SAnna Dabrowska // create a new table without islookup 21876a74c23SAnna Dabrowska $ok = $ok && $sqlite->query($sql); 21976a74c23SAnna Dabrowska if (!$ok) return false; 22076a74c23SAnna Dabrowska 22176a74c23SAnna Dabrowska $s = 'INSERT INTO schemas SELECT id, tbl, ts, user, comment, config FROM temp_schemas'; 22276a74c23SAnna Dabrowska $ok = $ok && $sqlite->query($s); 22376a74c23SAnna Dabrowska 22479b29326SAnna Dabrowska return $ok; 22576a74c23SAnna Dabrowska } 226544dca1bSAnna Dabrowska 227544dca1bSAnna Dabrowska /** 228544dca1bSAnna Dabrowska * Executes Migration 17 229544dca1bSAnna Dabrowska * 230544dca1bSAnna Dabrowska * Fixes lookup data not correctly migrated by #16 231544dca1bSAnna Dabrowska * All lookups were presumed to reference lookup data, not pages, so the migrated value 232544dca1bSAnna Dabrowska * was always ["", <previous-pid-aka-new-rid>]. For page references it is ["<previous-pid>", 0] 233544dca1bSAnna Dabrowska * 2347234bfb1Ssplitbrain * @param SQLiteDB $sqlite 235544dca1bSAnna Dabrowska * @return bool 236544dca1bSAnna Dabrowska */ 23779b29326SAnna Dabrowska protected function migration17($sqlite) 238544dca1bSAnna Dabrowska { 239544dca1bSAnna Dabrowska $sql = "SELECT MAX(id) AS id, tbl FROM schemas 240544dca1bSAnna Dabrowska GROUP BY tbl 241544dca1bSAnna Dabrowska "; 24279b29326SAnna Dabrowska $schemas = $sqlite->queryAll($sql); 243544dca1bSAnna Dabrowska 244544dca1bSAnna Dabrowska $ok = true; 245544dca1bSAnna Dabrowska 246544dca1bSAnna Dabrowska foreach ($schemas as $schema) { 247544dca1bSAnna Dabrowska // find lookup columns 248544dca1bSAnna Dabrowska $name = $schema['tbl']; 249544dca1bSAnna Dabrowska $sid = $schema['id']; 250544dca1bSAnna Dabrowska $s = $this->getLookupColsSql($sid); 25179b29326SAnna Dabrowska $cols = $sqlite->queryAll($s); 252544dca1bSAnna Dabrowska 253544dca1bSAnna Dabrowska if ($cols) { 2545e29103aSannda $colnames = array_map(static fn($c) => 'col' . $c['COL'], $cols); 255544dca1bSAnna Dabrowska 256544dca1bSAnna Dabrowska // data_ tables 257544dca1bSAnna Dabrowska $s = 'SELECT pid, rid, rev, ' . implode(', ', $colnames) . " FROM data_$name"; 25879b29326SAnna Dabrowska $allValues = $sqlite->queryAll($s); 259544dca1bSAnna Dabrowska 260544dca1bSAnna Dabrowska if (!empty($allValues)) { 261544dca1bSAnna Dabrowska foreach ($allValues as $row) { 2627234bfb1Ssplitbrain [$pid, $rid, $rev, $colref, $rowno, $fixes] = $this->getFixedValues($row); 263544dca1bSAnna Dabrowska // now fix the values 264544dca1bSAnna Dabrowska if (!empty($fixes)) { 26517a3a578SAndreas Gohr $sql = "UPDATE data_$name 26617a3a578SAndreas Gohr SET " . implode(', ', $fixes) . " 26717a3a578SAndreas Gohr WHERE pid = ? 26817a3a578SAndreas Gohr AND rid = ? 26917a3a578SAndreas Gohr AND rev = ?"; 270544dca1bSAnna Dabrowska $params = [$pid, $rid, $rev]; 271544dca1bSAnna Dabrowska $ok = $ok && $sqlite->query($sql, $params); 272544dca1bSAnna Dabrowska } 273544dca1bSAnna Dabrowska } 274544dca1bSAnna Dabrowska } 275544dca1bSAnna Dabrowska 276544dca1bSAnna Dabrowska // multi_ tables 277544dca1bSAnna Dabrowska $s = "SELECT colref, pid, rid, rev, row, value FROM multi_$name"; 27879b29326SAnna Dabrowska $allValues = $sqlite->queryAll($s); 279544dca1bSAnna Dabrowska 280544dca1bSAnna Dabrowska if (!empty($allValues)) { 281544dca1bSAnna Dabrowska foreach ($allValues as $row) { 2827234bfb1Ssplitbrain [$pid, $rid, $rev, $colref, $rowno, $fixes] = $this->getFixedValues($row); 283544dca1bSAnna Dabrowska // now fix the values 284544dca1bSAnna Dabrowska if (!empty($fixes)) { 28517a3a578SAndreas Gohr $sql = "UPDATE multi_$name 28617a3a578SAndreas Gohr SET " . implode(', ', $fixes) . " 28717a3a578SAndreas Gohr WHERE pid = ? 28817a3a578SAndreas Gohr AND rid = ? 28917a3a578SAndreas Gohr AND rev = ? 29017a3a578SAndreas Gohr AND colref = ? 29117a3a578SAndreas Gohr AND row = ?"; 292544dca1bSAnna Dabrowska $params = [$pid, $rid, $rev, $colref, $rowno]; 293544dca1bSAnna Dabrowska $ok = $ok && $sqlite->query($sql, $params); 294544dca1bSAnna Dabrowska } 295544dca1bSAnna Dabrowska } 296544dca1bSAnna Dabrowska } 297544dca1bSAnna Dabrowska } 298544dca1bSAnna Dabrowska } 299544dca1bSAnna Dabrowska 30079b29326SAnna Dabrowska return $ok; 301544dca1bSAnna Dabrowska } 302544dca1bSAnna Dabrowska 303544dca1bSAnna Dabrowska /** 304bbd79bccSAnna Dabrowska * Removes a temp table left over by migration 16 305bbd79bccSAnna Dabrowska * 3067234bfb1Ssplitbrain * @param SQLiteDB $sqlite 307bbd79bccSAnna Dabrowska * @return bool 308bbd79bccSAnna Dabrowska */ 30979b29326SAnna Dabrowska protected function migration18($sqlite) 310bbd79bccSAnna Dabrowska { 311bbd79bccSAnna Dabrowska $ok = true; 312bbd79bccSAnna Dabrowska 313bbd79bccSAnna Dabrowska $sql = 'DROP TABLE IF EXISTS temp_schemas'; 314bbd79bccSAnna Dabrowska $ok = $ok && $sqlite->query($sql); 315bbd79bccSAnna Dabrowska 31679b29326SAnna Dabrowska return $ok; 317bbd79bccSAnna Dabrowska } 31866164365SAndreas Gohr 319fc6ac2e5SAnna Dabrowska /** 320fc6ac2e5SAnna Dabrowska * Executes Migration 19 321fc6ac2e5SAnna Dabrowska * 322fc6ac2e5SAnna Dabrowska * Add "published" column to all existing tables 323fc6ac2e5SAnna Dabrowska * 3247234bfb1Ssplitbrain * @param SQLiteDB $sqlite 325fc6ac2e5SAnna Dabrowska * @return bool 326fc6ac2e5SAnna Dabrowska */ 32779b29326SAnna Dabrowska protected function migration19($sqlite) 328fc6ac2e5SAnna Dabrowska { 329fc6ac2e5SAnna Dabrowska $ok = true; 330fc6ac2e5SAnna Dabrowska 331fc6ac2e5SAnna Dabrowska /** @noinspection SqlResolve */ 332fc6ac2e5SAnna Dabrowska $sql = "SELECT name FROM sqlite_master WHERE type = 'table' AND (name LIKE 'data_%' OR name LIKE 'multi_%')"; 33379b29326SAnna Dabrowska $tables = $sqlite->queryAll($sql); 334fc6ac2e5SAnna Dabrowska 335fc6ac2e5SAnna Dabrowska foreach ($tables as $row) { 33666164365SAndreas Gohr $table = $row['name']; // no escaping needed, it's our own tables 33766164365SAndreas Gohr $sql = "ALTER TABLE $table ADD COLUMN published INT DEFAULT NULL"; 33866164365SAndreas Gohr $ok = $ok && $sqlite->query($sql); 339fc6ac2e5SAnna Dabrowska } 34079b29326SAnna Dabrowska return $ok; 341fc6ac2e5SAnna Dabrowska } 342fc6ac2e5SAnna Dabrowska 343*52637a9cSAnna Dabrowska /** 344*52637a9cSAnna Dabrowska * Executes Migration 20 345*52637a9cSAnna Dabrowska * 346*52637a9cSAnna Dabrowska * Adds indexes on "latest" and "published". 347*52637a9cSAnna Dabrowska * Those fields are not part of (autoindexed) primary key, but are used in many queries. 348*52637a9cSAnna Dabrowska * 349*52637a9cSAnna Dabrowska * @param SQLiteDB $sqlite 350*52637a9cSAnna Dabrowska * @return bool 351*52637a9cSAnna Dabrowska */ 352*52637a9cSAnna Dabrowska protected function migration20($sqlite) 353*52637a9cSAnna Dabrowska { 354*52637a9cSAnna Dabrowska $ok = true; 355*52637a9cSAnna Dabrowska 356*52637a9cSAnna Dabrowska /** @noinspection SqlResolve */ 357*52637a9cSAnna Dabrowska $sql = "SELECT name FROM sqlite_master WHERE type = 'table' AND (name LIKE 'data_%' OR name LIKE 'multi_%')"; 358*52637a9cSAnna Dabrowska $tables = $sqlite->queryAll($sql); 359*52637a9cSAnna Dabrowska 360*52637a9cSAnna Dabrowska foreach ($tables as $row) { 361*52637a9cSAnna Dabrowska $table = $row['name']; // no escaping needed, it's our own tables 362*52637a9cSAnna Dabrowska $sql = "CREATE INDEX idx_$table" . "_latest ON $table(latest);"; 363*52637a9cSAnna Dabrowska $ok = $ok && $sqlite->query($sql); 364*52637a9cSAnna Dabrowska $sql = "CREATE INDEX idx_$table" . "_published ON $table(published);"; 365*52637a9cSAnna Dabrowska $ok = $ok && $sqlite->query($sql); 366*52637a9cSAnna Dabrowska } 367*52637a9cSAnna Dabrowska return $ok; 368*52637a9cSAnna Dabrowska } 369*52637a9cSAnna Dabrowska 370bbd79bccSAnna Dabrowska 371bbd79bccSAnna Dabrowska /** 372544dca1bSAnna Dabrowska * Returns a select statement to fetch Lookup columns in the current schema 373544dca1bSAnna Dabrowska * 374544dca1bSAnna Dabrowska * @param int $sid Id of the schema 375544dca1bSAnna Dabrowska * @return string SQL statement 376544dca1bSAnna Dabrowska */ 377544dca1bSAnna Dabrowska protected function getLookupColsSql($sid) 378544dca1bSAnna Dabrowska { 379544dca1bSAnna Dabrowska return "SELECT C.colref AS COL, T.class AS TYPE 380544dca1bSAnna Dabrowska FROM schema_cols AS C 381544dca1bSAnna Dabrowska LEFT OUTER JOIN types AS T 382544dca1bSAnna Dabrowska ON C.tid = T.id 383544dca1bSAnna Dabrowska WHERE C.sid = $sid 384544dca1bSAnna Dabrowska AND TYPE LIKE '%Lookup' 385544dca1bSAnna Dabrowska "; 386544dca1bSAnna Dabrowska } 387544dca1bSAnna Dabrowska 388544dca1bSAnna Dabrowska /** 389544dca1bSAnna Dabrowska * Checks for improperly migrated values and returns an array with 390544dca1bSAnna Dabrowska * "<column> = <fixed-value>" fragments to be used in the UPDATE statement. 391544dca1bSAnna Dabrowska * 392544dca1bSAnna Dabrowska * @param array $row 393544dca1bSAnna Dabrowska * @return array 394544dca1bSAnna Dabrowska */ 395544dca1bSAnna Dabrowska protected function getFixedValues($row) 396544dca1bSAnna Dabrowska { 397544dca1bSAnna Dabrowska $pid = $row['pid']; 398544dca1bSAnna Dabrowska $rid = $row['rid']; 399544dca1bSAnna Dabrowska $rev = $row['rev']; 400544dca1bSAnna Dabrowska $colref = $row['colref']; 401544dca1bSAnna Dabrowska $rowno = $row['row']; 402544dca1bSAnna Dabrowska $fixes = []; 403544dca1bSAnna Dabrowska $matches = []; 404544dca1bSAnna Dabrowska 405544dca1bSAnna Dabrowska // check if anything needs to be fixed in data columns 406544dca1bSAnna Dabrowska foreach ($row as $col => $value) { 407544dca1bSAnna Dabrowska if (in_array($col, ['pid', 'rid', 'rev', 'colref', 'row'])) { 408544dca1bSAnna Dabrowska continue; 409544dca1bSAnna Dabrowska } 410544dca1bSAnna Dabrowska preg_match('/^\["",(?<pid>.*?\D+.*?)\]$/', $value, $matches); 411544dca1bSAnna Dabrowska if (!empty($matches['pid'])) { 412544dca1bSAnna Dabrowska $fixes[$col] = '["' . $matches['pid'] . '",0]'; 413544dca1bSAnna Dabrowska } 414544dca1bSAnna Dabrowska } 415544dca1bSAnna Dabrowska 416544dca1bSAnna Dabrowska if (!empty($fixes)) { 4175e29103aSannda $fixes = array_map(static fn($set, $key) => "$key = '$set'", $fixes, array_keys($fixes)); 418544dca1bSAnna Dabrowska } 419544dca1bSAnna Dabrowska 420544dca1bSAnna Dabrowska return [$pid, $rid, $rev, $colref, $rowno, $fixes]; 421544dca1bSAnna Dabrowska } 4228f259467SAndreas Gohr} 423