refactor database schema upgrade to support skipping versions

This commit is contained in:
El RIDO 2024-05-25 09:40:41 +02:00
parent b96c8ae531
commit 99a3e087ed

View file

@ -853,90 +853,87 @@ class Database extends AbstractData
{ {
$dataType = $this->_getDataType(); $dataType = $this->_getDataType();
$attachmentType = $this->_getAttachmentType(); $attachmentType = $this->_getAttachmentType();
switch ($oldversion) { if (version_compare($oldversion, '0.21', '<=')) {
case '0.21': // create the meta column if necessary (pre 0.21 change)
// create the meta column if necessary (pre 0.21 change) try {
try { $this->_db->exec(
$this->_db->exec( 'SELECT "meta" FROM "' . $this->_sanitizeIdentifier('paste') . '" ' .
'SELECT "meta" FROM "' . $this->_sanitizeIdentifier('paste') . '" ' . ($this->_type === 'oci' ? 'FETCH NEXT 1 ROWS ONLY' : 'LIMIT 1')
($this->_type === 'oci' ? 'FETCH NEXT 1 ROWS ONLY' : 'LIMIT 1') );
); } catch (PDOException $e) {
} catch (PDOException $e) { $this->_db->exec('ALTER TABLE "' . $this->_sanitizeIdentifier('paste') . '" ADD COLUMN "meta" TEXT');
$this->_db->exec('ALTER TABLE "' . $this->_sanitizeIdentifier('paste') . '" ADD COLUMN "meta" TEXT'); }
} // SQLite only allows one ALTER statement at a time...
// SQLite only allows one ALTER statement at a time... $this->_db->exec(
'ALTER TABLE "' . $this->_sanitizeIdentifier('paste') .
"\" ADD COLUMN \"attachment\" $attachmentType"
);
$this->_db->exec(
'ALTER TABLE "' . $this->_sanitizeIdentifier('paste') . "\" ADD COLUMN \"attachmentname\" $dataType"
);
// SQLite doesn't support MODIFY, but it allows TEXT of similar
// size as BLOB, so there is no need to change it there
if ($this->_type !== 'sqlite') {
$this->_db->exec( $this->_db->exec(
'ALTER TABLE "' . $this->_sanitizeIdentifier('paste') . 'ALTER TABLE "' . $this->_sanitizeIdentifier('paste') .
"\" ADD COLUMN \"attachment\" $attachmentType" "\" ADD PRIMARY KEY (\"dataid\"), MODIFY COLUMN \"data\" $dataType"
); );
$this->_db->exec( $this->_db->exec(
'ALTER TABLE "' . $this->_sanitizeIdentifier('paste') . "\" ADD COLUMN \"attachmentname\" $dataType" 'ALTER TABLE "' . $this->_sanitizeIdentifier('comment') .
"\" ADD PRIMARY KEY (\"dataid\"), MODIFY COLUMN \"data\" $dataType, " .
"MODIFY COLUMN \"nickname\" $dataType, MODIFY COLUMN \"vizhash\" $dataType"
); );
// SQLite doesn't support MODIFY, but it allows TEXT of similar } else {
// size as BLOB, so there is no need to change it there
if ($this->_type !== 'sqlite') {
$this->_db->exec(
'ALTER TABLE "' . $this->_sanitizeIdentifier('paste') .
"\" ADD PRIMARY KEY (\"dataid\"), MODIFY COLUMN \"data\" $dataType"
);
$this->_db->exec(
'ALTER TABLE "' . $this->_sanitizeIdentifier('comment') .
"\" ADD PRIMARY KEY (\"dataid\"), MODIFY COLUMN \"data\" $dataType, " .
"MODIFY COLUMN \"nickname\" $dataType, MODIFY COLUMN \"vizhash\" $dataType"
);
} else {
$this->_db->exec(
'CREATE UNIQUE INDEX IF NOT EXISTS "' .
$this->_sanitizeIdentifier('paste_dataid') . '" ON "' .
$this->_sanitizeIdentifier('paste') . '" ("dataid")'
);
$this->_db->exec(
'CREATE UNIQUE INDEX IF NOT EXISTS "' .
$this->_sanitizeIdentifier('comment_dataid') . '" ON "' .
$this->_sanitizeIdentifier('comment') . '" ("dataid")'
);
}
// CREATE INDEX IF NOT EXISTS not supported as of Oracle MySQL <= 8.0
$this->_db->exec( $this->_db->exec(
'CREATE INDEX "' . 'CREATE UNIQUE INDEX IF NOT EXISTS "' .
$this->_sanitizeIdentifier('comment_parent') . '" ON "' . $this->_sanitizeIdentifier('paste_dataid') . '" ON "' .
$this->_sanitizeIdentifier('comment') . '" ("pasteid")' $this->_sanitizeIdentifier('paste') . '" ("dataid")'
); );
// no break, continue with updates for 0.22 and later $this->_db->exec(
case '1.3': 'CREATE UNIQUE INDEX IF NOT EXISTS "' .
// SQLite doesn't support MODIFY, but it allows TEXT of similar $this->_sanitizeIdentifier('comment_dataid') . '" ON "' .
// size as BLOB and PostgreSQL uses TEXT, so there is no need $this->_sanitizeIdentifier('comment') . '" ("dataid")'
// to change it there
if ($this->_type !== 'sqlite' && $this->_type !== 'pgsql') {
$this->_db->exec(
'ALTER TABLE "' . $this->_sanitizeIdentifier('paste') .
"\" MODIFY COLUMN \"data\" $attachmentType"
);
}
// no break, continue with updates for all newer versions
case '1.7.2':
$supportsDropColumn = true;
if ($this->_type === 'sqlite') {
try {
$row = $this->_select('SELECT sqlite_version() AS "v"', array(), true);
$supportsDropColumn = version_compare($row['v'], '3.35.0', '>=');
} catch (PDOException $e) {
$supportsDropColumn = false;
}
}
if ($supportsDropColumn) {
$this->_db->exec(
'ALTER TABLE "' . $this->_sanitizeIdentifier('paste') .
'" DROP COLUMN "postdate"'
);
}
// no break, continue with updates for all newer versions
default:
$this->_exec(
'UPDATE "' . $this->_sanitizeIdentifier('config') .
'" SET "value" = ? WHERE "id" = ?',
array(Controller::VERSION, 'VERSION')
); );
}
// CREATE INDEX IF NOT EXISTS not supported as of Oracle MySQL <= 8.0
$this->_db->exec(
'CREATE INDEX "' .
$this->_sanitizeIdentifier('comment_parent') . '" ON "' .
$this->_sanitizeIdentifier('comment') . '" ("pasteid")'
);
} }
if (version_compare($oldversion, '1.3', '<=')) {
// SQLite doesn't support MODIFY, but it allows TEXT of similar
// size as BLOB and PostgreSQL uses TEXT, so there is no need
// to change it there
if ($this->_type !== 'sqlite' && $this->_type !== 'pgsql') {
$this->_db->exec(
'ALTER TABLE "' . $this->_sanitizeIdentifier('paste') .
"\" MODIFY COLUMN \"data\" $attachmentType"
);
}
}
if (version_compare($oldversion, '1.7.1', '<=')) {
$supportsDropColumn = true;
if ($this->_type === 'sqlite') {
try {
$row = $this->_select('SELECT sqlite_version() AS "v"', array(), true);
$supportsDropColumn = version_compare($row['v'], '3.35.0', '>=');
} catch (PDOException $e) {
$supportsDropColumn = false;
}
}
if ($supportsDropColumn) {
$this->_db->exec(
'ALTER TABLE "' . $this->_sanitizeIdentifier('paste') .
'" DROP COLUMN "postdate"'
);
}
}
$this->_exec(
'UPDATE "' . $this->_sanitizeIdentifier('config') .
'" SET "value" = ? WHERE "id" = ?',
array(Controller::VERSION, 'VERSION')
);
} }
} }