Browse Source

Fix foreign keys in MySQL

microsub
J. King 4 years ago
parent
commit
737dd9f6b8
  1. 6
      CHANGELOG
  2. 10
      UPGRADING
  3. 6
      lib/Database.php
  4. 49
      sql/MySQL/5.sql
  5. 7
      sql/PostgreSQL/5.sql
  6. 7
      sql/SQLite3/5.sql
  7. 4
      tests/lib/DatabaseDrivers/MySQL.php

6
CHANGELOG

@ -1,3 +1,9 @@
Version 0.8.2 (????-??-??)
==========================
Bug fixes:
- Enforce foreign key constraints in MySQL
Version 0.8.1 (2019-10-28)
==========================

10
UPGRADING

@ -10,6 +10,15 @@ usually prudent:
- If installing from source, update dependencies with:
`composer install -o --no-dev`
Upgrading from 0.8.1 to 0.8.2
=============================
- The database schema has changed from rev5 to rev6; if upgrading the database
manually, apply the 5.sql file. MySQL databases may need manual
intervention to ensure foreign key constraints are not violated
Upgrading from 0.7.1 to 0.8.0
=============================
@ -22,6 +31,7 @@ Upgrading from 0.7.1 to 0.8.0
- zendframework/zend-diactoros (version 2.x)
- zendframework/zend-httphandlerrunner
Upgrading from 0.5.1 to 0.6.0
=============================

6
lib/Database.php

@ -39,7 +39,7 @@ use JKingWeb\Arsse\Misc\URL;
*/
class Database {
/** The version number of the latest schema the interface is aware of */
const SCHEMA_VERSION = 5;
const SCHEMA_VERSION = 6;
/** The size of a set of values beyond which the set will be embedded into the query text */
const LIMIT_SET_SIZE = 25;
/** The length of a string in an embedded set beyond which a parameter placeholder will be used for the string */
@ -50,7 +50,7 @@ class Database {
const ASSOC_ADD = 1;
/** Makes tag/label association change operations replace members */
const ASSOC_REPLACE = 2;
/** A map database driver short-names and their associated class names */
/** A map of database driver short-names and their associated class names */
const DRIVER_NAMES = [
'sqlite3' => \JKingWeb\Arsse\Db\SQLite3\Driver::class,
'postgresql' => \JKingWeb\Arsse\Db\PostgreSQL\Driver::class,
@ -520,7 +520,7 @@ class Database {
if (!ValueInfo::id($id)) {
throw new Db\ExceptionInput("typeViolation", ["action" => __FUNCTION__, "field" => "folder", 'type' => "int > 0"]);
}
$changes = $this->db->prepare("WITH RECURSIVE folders(folder) as (SELECT ? union select id from arsse_folders join folders on parent = folder) DELETE FROM arsse_folders where owner = ? and id in (select folder from folders)", "int", "str")->run($id, $user)->changes();
$changes = $this->db->prepare("DELETE FROM arsse_folders where owner = ? and id = ?", "str", "int")->run($user, $id)->changes();
if (!$changes) {
throw new Db\ExceptionInput("subjectMissing", ["action" => __FUNCTION__, "field" => "folder", 'id' => $id]);
}

49
sql/MySQL/5.sql

@ -0,0 +1,49 @@
-- SPDX-License-Identifier: MIT
-- Copyright 2017 J. King, Dustin Wilson et al.
-- See LICENSE and AUTHORS files for details
-- Please consult the SQLite 3 schemata for commented version
-- Correct character set and collation of sessions table
alter table arsse_sessions default character set utf8mb4 collate utf8mb4_unicode_ci;
alter table arsse_sessions convert to character set utf8mb4 collate utf8mb4_unicode_ci;
-- Make integer foreign key referrers unsigned to match serial-type keys
alter table arsse_folders modify parent bigint unsigned;
alter table arsse_subscriptions modify feed bigint unsigned not null;
alter table arsse_subscriptions modify folder bigint unsigned;
alter table arsse_articles modify feed bigint unsigned not null;
alter table arsse_enclosures modify article bigint unsigned not null;
alter table arsse_marks modify article bigint unsigned not null;
alter table arsse_marks modify subscription bigint unsigned not null;
alter table arsse_editions modify article bigint unsigned not null;
alter table arsse_categories modify article bigint unsigned not null;
alter table arsse_label_members modify label bigint unsigned not null;
alter table arsse_label_members modify article bigint unsigned not null;
alter table arsse_label_members modify subscription bigint unsigned not null;
alter table arsse_tag_members modify tag bigint unsigned not null;
alter table arsse_tag_members modify subscription bigint unsigned not null;
-- Fix foreign key constraints
alter table arsse_folders add foreign key(owner) references arsse_users(id) on delete cascade on update cascade;
alter table arsse_folders add foreign key(parent) references arsse_folders(id) on delete cascade;
alter table arsse_subscriptions add foreign key(owner) references arsse_users(id) on delete cascade on update cascade;
alter table arsse_subscriptions add foreign key(feed) references arsse_feeds(id) on delete cascade;
alter table arsse_subscriptions add foreign key(folder) references arsse_folders(id) on delete cascade;
alter table arsse_articles add foreign key(feed) references arsse_feeds(id) on delete cascade;
alter table arsse_enclosures add foreign key(article) references arsse_articles(id) on delete cascade;
alter table arsse_marks add foreign key(article) references arsse_articles(id) on delete cascade;
alter table arsse_marks add foreign key(subscription) references arsse_subscriptions(id) on delete cascade;
alter table arsse_editions add foreign key(article) references arsse_articles(id) on delete cascade;
alter table arsse_categories add foreign key(article) references arsse_articles(id) on delete cascade;
alter table arsse_sessions add foreign key("user") references arsse_users(id) on delete cascade on update cascade;
alter table arsse_labels add foreign key(owner) references arsse_users(id) on delete cascade on update cascade;
alter table arsse_label_members add foreign key(label) references arsse_labels(id) on delete cascade;
alter table arsse_label_members add foreign key(article) references arsse_articles(id) on delete cascade;
alter table arsse_label_members add foreign key(subscription) references arsse_subscriptions(id) on delete cascade;
alter table arsse_tags add foreign key(owner) references arsse_users(id) on delete cascade on update cascade;
alter table arsse_tag_members add foreign key(tag) references arsse_tags(id) on delete cascade;
alter table arsse_tag_members add foreign key(subscription) references arsse_subscriptions(id) on delete cascade;
alter table arsse_tokens add foreign key("user") references arsse_users(id) on delete cascade on update cascade;
update arsse_meta set value = '6' where "key" = 'schema_version';

7
sql/PostgreSQL/5.sql

@ -0,0 +1,7 @@
-- SPDX-License-Identifier: MIT
-- Copyright 2017 J. King, Dustin Wilson et al.
-- See LICENSE and AUTHORS files for details
-- Please consult the SQLite 3 schemata for commented version
update arsse_meta set value = '6' where "key" = 'schema_version';

7
sql/SQLite3/5.sql

@ -0,0 +1,7 @@
-- SPDX-License-Identifier: MIT
-- Copyright 2017 J. King, Dustin Wilson et al.
-- See LICENSE and AUTHORS files for details
-- set version marker
pragma user_version = 6;
update arsse_meta set value = '6' where "key" = 'schema_version';

4
tests/lib/DatabaseDrivers/MySQL.php

@ -48,6 +48,7 @@ trait MySQL {
$db->query("UNLOCK TABLES; ROLLBACK");
} catch (\Throwable $e) {
}
$db->query("SET FOREIGN_KEY_CHECKS=0");
foreach (self::dbTableList($db) as $table) {
if ($table === "arsse_meta") {
$db->query("DELETE FROM $table where `key` <> 'schema_version'");
@ -56,6 +57,7 @@ trait MySQL {
}
$db->query("ALTER TABLE $table auto_increment = 1");
}
$db->query("SET FOREIGN_KEY_CHECKS=1");
foreach ($afterStatements as $st) {
$db->query($st);
}
@ -67,9 +69,11 @@ trait MySQL {
$db->query("UNLOCK TABLES; ROLLBACK");
} catch (\Throwable $e) {
}
$db->query("SET FOREIGN_KEY_CHECKS=0");
foreach (self::dbTableList($db) as $table) {
$db->query("DROP TABLE IF EXISTS $table");
}
$db->query("SET FOREIGN_KEY_CHECKS=1");
foreach ($afterStatements as $st) {
$db->query($st);
}

Loading…
Cancel
Save