From 44beb62e5aa5d7e7b3d7c6c0357554f27850ebcb Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 29 Apr 2017 23:33:02 +0000 Subject: [PATCH 1/9] Added information about table relations --- include/dbstructure.php | 143 ++++++++++++++++++++-------------------- 1 file changed, 73 insertions(+), 70 deletions(-) diff --git a/include/dbstructure.php b/include/dbstructure.php index 98a4a9c307..744dc22dcc 100644 --- a/include/dbstructure.php +++ b/include/dbstructure.php @@ -300,6 +300,9 @@ function update_structure($verbose, $action, $tables=null, $definition=null) { // Compare the field definition $field_definition = $database[$name]["fields"][$fieldname]; + // Remove the relation data that is used for the referential integrity + unset($parameters['relation']); + // We change the collation after the indexes had been changed. // This is done to avoid index length problems. // So here we always ensure that there is no need to change it. @@ -627,7 +630,7 @@ function db_definition() { $database["attach"] = array( "fields" => array( "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), - "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), + "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), "hash" => array("type" => "varchar(64)", "not null" => "1", "default" => ""), "filename" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "filetype" => array("type" => "varchar(64)", "not null" => "1", "default" => ""), @@ -647,7 +650,7 @@ function db_definition() { $database["auth_codes"] = array( "fields" => array( "id" => array("type" => "varchar(40)", "not null" => "1", "primary" => "1"), - "client_id" => array("type" => "varchar(20)", "not null" => "1", "default" => ""), + "client_id" => array("type" => "varchar(20)", "not null" => "1", "default" => "", "relation" => array("clients" => "client_id")), "redirect_uri" => array("type" => "varchar(200)", "not null" => "1", "default" => ""), "expires" => array("type" => "int(11)", "not null" => "1", "default" => "0"), "scope" => array("type" => "varchar(250)", "not null" => "1", "default" => ""), @@ -688,7 +691,7 @@ function db_definition() { "redirect_uri" => array("type" => "varchar(200)", "not null" => "1", "default" => ""), "name" => array("type" => "text"), "icon" => array("type" => "text"), - "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), + "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), ), "indexes" => array( "PRIMARY" => array("client_id"), @@ -709,7 +712,7 @@ function db_definition() { $database["contact"] = array( "fields" => array( "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), - "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), + "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), "self" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), "remote_self" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), @@ -798,7 +801,7 @@ function db_definition() { "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), "guid" => array("type" => "varchar(64)", "not null" => "1", "default" => ""), "recips" => array("type" => "text"), - "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), + "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), "creator" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), "updated" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), @@ -828,8 +831,8 @@ function db_definition() { "fields" => array( "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), "guid" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), - "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), - "cid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), + "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), + "cid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("contact" => "id")), "uri" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), "edited" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), @@ -881,9 +884,9 @@ function db_definition() { $database["ffinder"] = array( "fields" => array( "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), - "uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"), - "cid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"), - "fid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"), + "uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), + "cid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "relation" => array("contact" => "id")), + "fid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "relation" => array("fcontact" => "id")), ), "indexes" => array( "PRIMARY" => array("id"), @@ -904,8 +907,8 @@ function db_definition() { $database["fsuggest"] = array( "fields" => array( "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), - "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), - "cid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), + "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), + "cid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("contact" => "id")), "name" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "url" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "request" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), @@ -920,8 +923,8 @@ function db_definition() { $database["gcign"] = array( "fields" => array( "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), - "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), - "gcid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), + "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), + "gcid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("gcontact" => "id")), ), "indexes" => array( "PRIMARY" => array("id"), @@ -971,10 +974,10 @@ function db_definition() { $database["glink"] = array( "fields" => array( "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), - "cid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), - "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), - "gcid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), - "zcid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), + "cid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("contact" => "id")), + "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), + "gcid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("gcontact" => "id")), + "zcid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("gcontact" => "id")), "updated" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), ), "indexes" => array( @@ -986,7 +989,7 @@ function db_definition() { $database["group"] = array( "fields" => array( "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), - "uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"), + "uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), "visible" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), "deleted" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), "name" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), @@ -999,9 +1002,9 @@ function db_definition() { $database["group_member"] = array( "fields" => array( "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), - "uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"), - "gid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"), - "contact-id" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"), + "uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), + "gid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "relation" => array("group" => "id")), + "contact-id" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "relation" => array("contact" => "id")), ), "indexes" => array( "PRIMARY" => array("id"), @@ -1049,9 +1052,9 @@ function db_definition() { $database["intro"] = array( "fields" => array( "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), - "uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"), - "fid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), - "contact-id" => array("type" => "int(11)", "not null" => "1", "default" => "0"), + "uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), + "fid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("fcontact" => "id")), + "contact-id" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("contact" => "id")), "knowyou" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), "duplex" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), "note" => array("type" => "text"), @@ -1069,9 +1072,9 @@ function db_definition() { "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), "guid" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "uri" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), - "uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"), - "contact-id" => array("type" => "int(11)", "not null" => "1", "default" => "0"), - "gcontact-id" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"), + "uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), + "contact-id" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("contact" => "id")), + "gcontact-id" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0", "relation" => array("gcontact" => "id")), "type" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "wall" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), "gravity" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), @@ -1084,11 +1087,11 @@ function db_definition() { "commented" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), "received" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), "changed" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), - "owner-id" => array("type" => "int(11)", "not null" => "1", "default" => "0"), + "owner-id" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("contact" => "id")), "owner-name" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "owner-link" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "owner-avatar" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), - "author-id" => array("type" => "int(11)", "not null" => "1", "default" => "0"), + "author-id" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("contact" => "id")), "author-name" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "author-link" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "author-avatar" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), @@ -1103,7 +1106,7 @@ function db_definition() { "postopts" => array("type" => "text"), "plink" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "resource-id" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), - "event-id" => array("type" => "int(11)", "not null" => "1", "default" => "0"), + "event-id" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("event" => "id")), "tag" => array("type" => "mediumtext"), "attach" => array("type" => "mediumtext"), "inform" => array("type" => "mediumtext"), @@ -1164,8 +1167,8 @@ function db_definition() { $database["item_id"] = array( "fields" => array( "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), - "iid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), - "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), + "iid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("item" => "id")), + "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), "sid" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "service" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), ), @@ -1191,13 +1194,13 @@ function db_definition() { $database["mail"] = array( "fields" => array( "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), - "uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"), + "uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), "guid" => array("type" => "varchar(64)", "not null" => "1", "default" => ""), "from-name" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "from-photo" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "from-url" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), - "contact-id" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), - "convid" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"), + "contact-id" => array("type" => "varchar(255)", "not null" => "1", "default" => "", "relation" => array("contact" => "id")), + "convid" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0", "relation" => array("conv" => "id")), "title" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "body" => array("type" => "mediumtext"), "seen" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), @@ -1219,7 +1222,7 @@ function db_definition() { $database["mailacct"] = array( "fields" => array( "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), - "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), + "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), "server" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "port" => array("type" => "int(11)", "not null" => "1", "default" => "0"), "ssltype" => array("type" => "varchar(16)", "not null" => "1", "default" => ""), @@ -1239,8 +1242,8 @@ function db_definition() { $database["manage"] = array( "fields" => array( "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), - "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), - "mid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), + "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), + "mid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), ), "indexes" => array( "PRIMARY" => array("id"), @@ -1257,10 +1260,10 @@ function db_definition() { "photo" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "date" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), "msg" => array("type" => "mediumtext"), - "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), + "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), "link" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), - "iid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), - "parent" => array("type" => "int(11)", "not null" => "1", "default" => "0"), + "iid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("item" => "id")), + "parent" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("item" => "id")), "seen" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), "verb" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "otype" => array("type" => "varchar(16)", "not null" => "1", "default" => ""), @@ -1278,10 +1281,10 @@ function db_definition() { $database["notify-threads"] = array( "fields" => array( "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), - "notify-id" => array("type" => "int(11)", "not null" => "1", "default" => "0"), - "master-parent-item" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"), + "notify-id" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("notify" => "id")), + "master-parent-item" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "relation" => array("item" => "id")), "parent-item" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"), - "receiver-uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), + "receiver-uid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("user" => "id")), ), "indexes" => array( "PRIMARY" => array("id"), @@ -1314,7 +1317,7 @@ function db_definition() { $database["pconfig"] = array( "fields" => array( "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), - "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), + "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), "cat" => array("type" => "varbinary(255)", "not null" => "1", "default" => ""), "k" => array("type" => "varbinary(255)", "not null" => "1", "default" => ""), "v" => array("type" => "mediumtext"), @@ -1327,8 +1330,8 @@ function db_definition() { $database["photo"] = array( "fields" => array( "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), - "uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"), - "contact-id" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"), + "uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), + "contact-id" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "relation" => array("contact" => "id")), "guid" => array("type" => "varchar(64)", "not null" => "1", "default" => ""), "resource-id" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), @@ -1361,7 +1364,7 @@ function db_definition() { $database["poll"] = array( "fields" => array( "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), - "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), + "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), "q0" => array("type" => "text"), "q1" => array("type" => "text"), "q2" => array("type" => "text"), @@ -1381,7 +1384,7 @@ function db_definition() { $database["poll_result"] = array( "fields" => array( "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), - "poll_id" => array("type" => "int(11)", "not null" => "1", "default" => "0"), + "poll_id" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("poll" => "id")), "choice" => array("type" => "int(11)", "not null" => "1", "default" => "0"), ), "indexes" => array( @@ -1404,7 +1407,7 @@ function db_definition() { $database["profile"] = array( "fields" => array( "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), - "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), + "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), "profile-name" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "is-default" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), "hide-friends" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), @@ -1454,8 +1457,8 @@ function db_definition() { $database["profile_check"] = array( "fields" => array( "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), - "uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"), - "cid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"), + "uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), + "cid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "relation" => array("contact" => "id")), "dfrn_id" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "sec" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "expire" => array("type" => "int(11)", "not null" => "1", "default" => "0"), @@ -1467,7 +1470,7 @@ function db_definition() { $database["push_subscriber"] = array( "fields" => array( "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), - "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), + "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), "callback_url" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "topic" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "nickname" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), @@ -1482,7 +1485,7 @@ function db_definition() { $database["queue"] = array( "fields" => array( "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), - "cid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), + "cid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("contact" => "id")), "network" => array("type" => "varchar(32)", "not null" => "1", "default" => ""), "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), "last" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), @@ -1503,7 +1506,7 @@ function db_definition() { "id" => array("type" => "int(11) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), "hash" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), - "uid" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"), + "uid" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), "password" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "language" => array("type" => "varchar(16)", "not null" => "1", "default" => ""), "note" => array("type" => "text"), @@ -1515,7 +1518,7 @@ function db_definition() { $database["search"] = array( "fields" => array( "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), - "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), + "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), "term" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), ), "indexes" => array( @@ -1539,7 +1542,7 @@ function db_definition() { $database["sign"] = array( "fields" => array( "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), - "iid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"), + "iid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "relation" => array("item" => "id")), "signed_text" => array("type" => "mediumtext"), "signature" => array("type" => "text"), "signer" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), @@ -1552,7 +1555,7 @@ function db_definition() { $database["spam"] = array( "fields" => array( "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), - "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), + "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), "spam" => array("type" => "int(11)", "not null" => "1", "default" => "0"), "ham" => array("type" => "int(11)", "not null" => "1", "default" => "0"), "term" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), @@ -1569,7 +1572,7 @@ function db_definition() { $database["term"] = array( "fields" => array( "tid" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), - "oid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"), + "oid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "relation" => array("item" => "id")), "otype" => array("type" => "tinyint(3) unsigned", "not null" => "1", "default" => "0"), "type" => array("type" => "tinyint(3) unsigned", "not null" => "1", "default" => "0"), "term" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), @@ -1579,7 +1582,7 @@ function db_definition() { "received" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), "global" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), "aid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"), - "uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"), + "uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), ), "indexes" => array( "PRIMARY" => array("tid"), @@ -1591,12 +1594,12 @@ function db_definition() { ); $database["thread"] = array( "fields" => array( - "iid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "primary" => "1"), - "uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"), - "contact-id" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"), - "gcontact-id" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"), - "owner-id" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"), - "author-id" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"), + "iid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "primary" => "1", "relation" => array("item" => "id")), + "uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), + "contact-id" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0", "relation" => array("contact" => "id")), + "gcontact-id" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0", "relation" => array("gcontact" => "id")), + "owner-id" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0", "relation" => array("contact" => "id")), + "author-id" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0", "relation" => array("contact" => "id")), "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), "edited" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), "commented" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), @@ -1633,10 +1636,10 @@ function db_definition() { "fields" => array( "id" => array("type" => "varchar(40)", "not null" => "1", "primary" => "1"), "secret" => array("type" => "text"), - "client_id" => array("type" => "varchar(20)", "not null" => "1", "default" => ""), + "client_id" => array("type" => "varchar(20)", "not null" => "1", "default" => "", "relation" => array("clients" => "client_id")), "expires" => array("type" => "int(11)", "not null" => "1", "default" => "0"), "scope" => array("type" => "varchar(200)", "not null" => "1", "default" => ""), - "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), + "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), ), "indexes" => array( "PRIMARY" => array("id"), @@ -1780,7 +1783,7 @@ function dbstructure_run(&$argv, &$argc) { echo "dryrun show database update schema queries without running them\n"; echo "update update database schema\n"; echo "dumpsql dump database schema\n"; - echo "toinnodb convert all tables from MyISAM to InnoDB\n"; + echo "toinnodb convert all tables from MyISAM to InnoDB\n"; return; } From c2820c452fbb9b2d26594fb504fe0dfc8206c5a2 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 30 Apr 2017 19:54:41 +0000 Subject: [PATCH 2/9] Delete now works --- include/dba.php | 96 +++++++++++++++++++++++++++++++++++++++++ include/dbstructure.php | 4 +- 2 files changed, 98 insertions(+), 2 deletions(-) diff --git a/include/dba.php b/include/dba.php index f695902afe..b0d05f4458 100644 --- a/include/dba.php +++ b/include/dba.php @@ -23,6 +23,7 @@ class dba { public $error = false; private $_server_info = ''; private static $dbo; + private static $relation = array(); function __construct($server, $user, $pass, $db, $install = false) { $a = get_app(); @@ -753,6 +754,101 @@ class dba { return self::e($sql, $param); } + /** + * @brief Build the array with the table relations + * + * The array is build from the database definitions in dbstructure.php + * + * This process must only be started once, since the value is cached. + */ + static private function build_relation_data() { + $definition = db_definition(); + + foreach ($definition AS $table => $structure) { + foreach ($structure['fields'] AS $field => $field_struct) { + if (isset($field_struct['relation'])) { + foreach ($field_struct['relation'] AS $rel_table => $rel_field) { + self::$relation[$rel_table][$rel_field][$table] = $field; + } + } + } + } + } + + /** + * @brief Insert a row into a table + * + * @param string $table Table name + * @param array $param parameter array + * @param boolean $in_commit Internal use: Only do a commit after the last delete + * @param array $callstack Internal use: prevent endless loops + * + * @return boolean was the delete successfull? + */ + static public function delete($table, $param, $in_commit = false, $callstack = array()) { + + // Create a key for the loop prevention + $key = $table.':'.implode(':', array_keys($param)).':'.implode(':', $param); + + // We quit when this key already exists in the callstack. + if (isset($callstack[$key])) { + return true; + } + + $callstack[$key] = $key; + + $table = self::$dbo->escape($table); + + // To speed up the whole process we cache the table relations + if (count(self::$relation) == 0) { + self::build_relation_data(); + } + + if (!$in_commit) { + self::p("COMMIT"); + self::p("START TRANSACTION"); + } + + // Is there a relation entry for the table? + if (isset(self::$relation[$table])) { + foreach (self::$relation[$table] AS $field => $rel_def) { + // Fetch all rows that are to be deleted + $sql = "SELECT ".self::$dbo->escape($field)." FROM `".$table."` WHERE `". + implode("` = ? AND `", array_keys($param))."` = ?"; + + $retval = false; + $data = self::p($sql, $param); + while ($row = self::fetch($data)) { + foreach ($rel_def AS $rel_table => $rel_field) { + // We do a separate delete process per row + $retval = self::delete($rel_table, array($rel_field => $row[$field]), true, $callstack); + if (!$retval) { + return false; + } + } + } + if (!$retval) { + return true; + } + } + } + + $sql = "DELETE FROM `".$table."` WHERE `". + implode("` = ? AND `", array_keys($param))."` = ?"; + + $retval = self::e($sql, $param); + + if (!$in_commit) { + if ($retval) { + self::p("COMMIT"); + } else { + self::p("ROLLBACK"); + } + } + + return $retval; + } + /** * @brief Updates rows * diff --git a/include/dbstructure.php b/include/dbstructure.php index 744dc22dcc..cedef40d98 100644 --- a/include/dbstructure.php +++ b/include/dbstructure.php @@ -1078,7 +1078,7 @@ function db_definition() { "type" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "wall" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), "gravity" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), - "parent" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"), + "parent" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "relation" => array("item" => "id")), "parent-uri" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "extid" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "thr-parent" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), @@ -1284,7 +1284,7 @@ function db_definition() { "notify-id" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("notify" => "id")), "master-parent-item" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "relation" => array("item" => "id")), "parent-item" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"), - "receiver-uid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("user" => "id")), + "receiver-uid" => array("type" => "int(11)", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), ), "indexes" => array( "PRIMARY" => array("id"), From f1c53530a13ca73281f5dc1dd51ac1319f138e81 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 30 Apr 2017 20:19:47 +0000 Subject: [PATCH 3/9] Add a missing relation --- include/dbstructure.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/dbstructure.php b/include/dbstructure.php index cedef40d98..25109b5f40 100644 --- a/include/dbstructure.php +++ b/include/dbstructure.php @@ -1069,7 +1069,7 @@ function db_definition() { ); $database["item"] = array( "fields" => array( - "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), + "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1", "relation" => array("thread" => "iid")), "guid" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "uri" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0", "relation" => array("user" => "uid")), From 0d7996d8520a215189ed7a37ff180f6eb7e67d01 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 1 May 2017 05:45:36 +0000 Subject: [PATCH 4/9] Only fetch the rows when needed --- include/dba.php | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/include/dba.php b/include/dba.php index b0d05f4458..b2ed96eeb9 100644 --- a/include/dba.php +++ b/include/dba.php @@ -812,23 +812,37 @@ class dba { // Is there a relation entry for the table? if (isset(self::$relation[$table])) { foreach (self::$relation[$table] AS $field => $rel_def) { - // Fetch all rows that are to be deleted - $sql = "SELECT ".self::$dbo->escape($field)." FROM `".$table."` WHERE `". - implode("` = ? AND `", array_keys($param))."` = ?"; + // Currently we only support relations with a single variable + if (count($rel_def) > 1) { + return false; + } - $retval = false; - $data = self::p($sql, $param); - while ($row = self::fetch($data)) { - foreach ($rel_def AS $rel_table => $rel_field) { - // We do a separate delete process per row + $rel_field = array_values($rel_def)[0]; + $rel_table = array_keys($rel_def)[0]; + + // When the search field is the relation field, we don't need to fetch the rows + // This is useful when the leading record is already deleted in the frontend but the rest is done in the backend + if ((count($param) == 1) AND ($field == array_keys($param)[0])) { + $retval = self::delete($rel_table, array($rel_field => array_values($param)[0]), true, $callstack); + if (!$retval) { + return false; + } + } else { + // Fetch all rows that are to be deleted + $sql = "SELECT ".self::$dbo->escape($field)." FROM `".$table."` WHERE `". + implode("` = ? AND `", array_keys($param))."` = ?"; + $retval = false; + $data = self::p($sql, $param); + while ($row = self::fetch($data)) { + // We have to do a separate delete process per row $retval = self::delete($rel_table, array($rel_field => $row[$field]), true, $callstack); if (!$retval) { return false; } } - } - if (!$retval) { - return true; + if (!$retval) { + return true; + } } } } From e6cbe3be11ea348ef041258473c101523a004d94 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 1 May 2017 06:35:41 +0000 Subject: [PATCH 5/9] This is better --- include/dba.php | 26 +++++++++++--------------- include/remove_contact.php | 11 ++--------- 2 files changed, 13 insertions(+), 24 deletions(-) diff --git a/include/dba.php b/include/dba.php index b2ed96eeb9..6fc51dfbe7 100644 --- a/include/dba.php +++ b/include/dba.php @@ -812,20 +812,14 @@ class dba { // Is there a relation entry for the table? if (isset(self::$relation[$table])) { foreach (self::$relation[$table] AS $field => $rel_def) { - // Currently we only support relations with a single variable - if (count($rel_def) > 1) { - return false; - } - - $rel_field = array_values($rel_def)[0]; - $rel_table = array_keys($rel_def)[0]; - // When the search field is the relation field, we don't need to fetch the rows // This is useful when the leading record is already deleted in the frontend but the rest is done in the backend if ((count($param) == 1) AND ($field == array_keys($param)[0])) { - $retval = self::delete($rel_table, array($rel_field => array_values($param)[0]), true, $callstack); - if (!$retval) { - return false; + foreach ($rel_def AS $rel_table => $rel_field) { + $retval = self::delete($rel_table, array($rel_field => array_values($param)[0]), true, $callstack); + if (!$retval) { + return false; + } } } else { // Fetch all rows that are to be deleted @@ -834,10 +828,12 @@ class dba { $retval = false; $data = self::p($sql, $param); while ($row = self::fetch($data)) { - // We have to do a separate delete process per row - $retval = self::delete($rel_table, array($rel_field => $row[$field]), true, $callstack); - if (!$retval) { - return false; + foreach ($rel_def AS $rel_table => $rel_field) { + // We have to do a separate delete process per row + $retval = self::delete($rel_table, array($rel_field => $row[$field]), true, $callstack); + if (!$retval) { + return false; + } } } if (!$retval) { diff --git a/include/remove_contact.php b/include/remove_contact.php index 68bf2adfea..bb110a284b 100644 --- a/include/remove_contact.php +++ b/include/remove_contact.php @@ -19,14 +19,7 @@ function remove_contact_run($argv, $argc) { return; } - q("DELETE FROM `item` WHERE `contact-id` = %d", intval($id)); - - q("DELETE FROM `photo` WHERE `contact-id` = %d", intval($id)); - - q("DELETE FROM `mail` WHERE `contact-id` = %d", intval($id)); - - q("DELETE FROM `event` WHERE `cid` = %d", intval($id)); - - q("DELETE FROM `queue` WHERE `cid` = %d", intval($id)); + // Now we delete all the depending table entries + dba::delete('contact', array('id' => $id)); } ?> From e90ae79d35eecf6e107c26a989df2dafe5bb895a Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 1 May 2017 09:34:15 +0000 Subject: [PATCH 6/9] The number of queries is reduced dramatically --- include/dba.php | 117 +++++++++++++++++++++++++++++------------------- 1 file changed, 71 insertions(+), 46 deletions(-) diff --git a/include/dba.php b/include/dba.php index 6fc51dfbe7..dfba269bf4 100644 --- a/include/dba.php +++ b/include/dba.php @@ -783,80 +783,105 @@ class dba { * @param boolean $in_commit Internal use: Only do a commit after the last delete * @param array $callstack Internal use: prevent endless loops * - * @return boolean was the delete successfull? + * @return boolean|array was the delete successfull? When $in_commit is set: deletion data */ static public function delete($table, $param, $in_commit = false, $callstack = array()) { + $commands = array(); + // Create a key for the loop prevention $key = $table.':'.implode(':', array_keys($param)).':'.implode(':', $param); // We quit when this key already exists in the callstack. if (isset($callstack[$key])) { - return true; + return $commands; } $callstack[$key] = $key; $table = self::$dbo->escape($table); + $commands[$key] = array('table' => $table, 'param' => $param); + // To speed up the whole process we cache the table relations if (count(self::$relation) == 0) { self::build_relation_data(); } - if (!$in_commit) { - self::p("COMMIT"); - self::p("START TRANSACTION"); - } - // Is there a relation entry for the table? if (isset(self::$relation[$table])) { - foreach (self::$relation[$table] AS $field => $rel_def) { - // When the search field is the relation field, we don't need to fetch the rows - // This is useful when the leading record is already deleted in the frontend but the rest is done in the backend - if ((count($param) == 1) AND ($field == array_keys($param)[0])) { - foreach ($rel_def AS $rel_table => $rel_field) { - $retval = self::delete($rel_table, array($rel_field => array_values($param)[0]), true, $callstack); - if (!$retval) { - return false; - } + // We only allow a simple "one field" relation. + $field = array_keys(self::$relation[$table])[0]; + $rel_def = array_values(self::$relation[$table])[0]; + + // When the search field is the relation field, we don't need to fetch the rows + // This is useful when the leading record is already deleted in the frontend but the rest is done in the backend + if ((count($param) == 1) AND ($field == array_keys($param)[0])) { + foreach ($rel_def AS $rel_table => $rel_field) { + $retval = self::delete($rel_table, array($rel_field => array_values($param)[0]), true, $callstack); + $commands = array_merge($commands, $retval); + } + } else { + // Fetch all rows that are to be deleted + $sql = "SELECT ".self::$dbo->escape($field)." FROM `".$table."` WHERE `". + implode("` = ? AND `", array_keys($param))."` = ?"; + $retval = false; + $data = self::p($sql, $param); + while ($row = self::fetch($data)) { + // Now we accumulate the delete commands + $retval = self::delete($table, array($field => $row[$field]), true, $callstack); + $commands = array_merge($commands, $retval); + } + + // When we don't find data then we don't need to delete it + if (is_bool($retval)) { + return $in_commit ? $commands : true; + } + // Since we had split the delete command we don't need the original command anymore + unset($commands[$key]); + } + } + + if (!$in_commit) { + // Now we finalize the process + self::p("COMMIT"); + self::p("START TRANSACTION"); + + $compacted = array(); + foreach ($commands AS $command) { + if (count($command['param']) > 1) { + $sql = "DELETE FROM `".$command['table']."` WHERE `". + implode("` = ? AND `", array_keys($command['param']))."` = ?"; + + logger(dba::replace_parameters($sql, $command['param']), LOGGER_DATA); + + if (!self::e($sql, $param)) { + self::p("ROLLBACK"); + return false; } } else { - // Fetch all rows that are to be deleted - $sql = "SELECT ".self::$dbo->escape($field)." FROM `".$table."` WHERE `". - implode("` = ? AND `", array_keys($param))."` = ?"; - $retval = false; - $data = self::p($sql, $param); - while ($row = self::fetch($data)) { - foreach ($rel_def AS $rel_table => $rel_field) { - // We have to do a separate delete process per row - $retval = self::delete($rel_table, array($rel_field => $row[$field]), true, $callstack); - if (!$retval) { - return false; - } - } - } - if (!$retval) { - return true; + $value = array_values($command['param'])[0]; + $compacted[$command['table']][array_keys($command['param'])[0]][$value] = $value; + } + } + foreach ($compacted AS $table => $values) { + foreach ($values AS $field => $field_values) { + $sql = "DELETE FROM `".$table."` WHERE `".$field."` IN (". + substr(str_repeat("?, ", count($field_values)), 0, -2).");"; + + logger(dba::replace_parameters($sql, $field_values), LOGGER_DATA); + + if (!self::e($sql, $param)) { + self::p("ROLLBACK"); + return false; } } } + self::p("COMMIT"); + return true; } - $sql = "DELETE FROM `".$table."` WHERE `". - implode("` = ? AND `", array_keys($param))."` = ?"; - - $retval = self::e($sql, $param); - - if (!$in_commit) { - if ($retval) { - self::p("COMMIT"); - } else { - self::p("ROLLBACK"); - } - } - - return $retval; + return $commands; } /** From b9b43e30e6a7222cdf29880a4600cb56be38250f Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 1 May 2017 17:42:37 +0000 Subject: [PATCH 7/9] Delete queries are now split into chunks. --- boot.php | 2 +- include/dba.php | 46 ++++++++++++++++++++++++++--------------- include/dbstructure.php | 4 ++++ update.php | 2 +- 4 files changed, 35 insertions(+), 19 deletions(-) diff --git a/boot.php b/boot.php index 99af7d3778..b689b73eec 100644 --- a/boot.php +++ b/boot.php @@ -38,7 +38,7 @@ define ( 'FRIENDICA_PLATFORM', 'Friendica'); define ( 'FRIENDICA_CODENAME', 'Asparagus'); define ( 'FRIENDICA_VERSION', '3.5.2-dev' ); define ( 'DFRN_PROTOCOL_VERSION', '2.23' ); -define ( 'DB_UPDATE_VERSION', 1221 ); +define ( 'DB_UPDATE_VERSION', 1222 ); /** * @brief Constant with a HTML line break. diff --git a/include/dba.php b/include/dba.php index dfba269bf4..11e1d2131d 100644 --- a/include/dba.php +++ b/include/dba.php @@ -768,7 +768,7 @@ class dba { foreach ($structure['fields'] AS $field => $field_struct) { if (isset($field_struct['relation'])) { foreach ($field_struct['relation'] AS $rel_table => $rel_field) { - self::$relation[$rel_table][$rel_field][$table] = $field; + self::$relation[$rel_table][$rel_field][$table][] = $field; } } } @@ -817,15 +817,17 @@ class dba { // When the search field is the relation field, we don't need to fetch the rows // This is useful when the leading record is already deleted in the frontend but the rest is done in the backend if ((count($param) == 1) AND ($field == array_keys($param)[0])) { - foreach ($rel_def AS $rel_table => $rel_field) { - $retval = self::delete($rel_table, array($rel_field => array_values($param)[0]), true, $callstack); - $commands = array_merge($commands, $retval); + foreach ($rel_def AS $rel_table => $rel_fields) { + foreach ($rel_fields AS $rel_field) { + $retval = self::delete($rel_table, array($rel_field => array_values($param)[0]), true, $callstack); + $commands = array_merge($commands, $retval); + } } } else { // Fetch all rows that are to be deleted $sql = "SELECT ".self::$dbo->escape($field)." FROM `".$table."` WHERE `". implode("` = ? AND `", array_keys($param))."` = ?"; - $retval = false; + $data = self::p($sql, $param); while ($row = self::fetch($data)) { // Now we accumulate the delete commands @@ -833,10 +835,6 @@ class dba { $commands = array_merge($commands, $retval); } - // When we don't find data then we don't need to delete it - if (is_bool($retval)) { - return $in_commit ? $commands : true; - } // Since we had split the delete command we don't need the original command anymore unset($commands[$key]); } @@ -848,6 +846,7 @@ class dba { self::p("START TRANSACTION"); $compacted = array(); + $counter = array(); foreach ($commands AS $command) { if (count($command['param']) > 1) { $sql = "DELETE FROM `".$command['table']."` WHERE `". @@ -860,20 +859,33 @@ class dba { return false; } } else { + $key_table = $command['table']; + $key_param = array_keys($command['param'])[0]; $value = array_values($command['param'])[0]; - $compacted[$command['table']][array_keys($command['param'])[0]][$value] = $value; + + // Split the SQL queries in chunks of 100 values + // We do the $i stuff here to make the code better readable + $i = $counter[$key_table][$key_param]; + if (count($compacted[$key_table][$key_param][$i]) > 100) { + ++$i; + } + + $compacted[$key_table][$key_param][$i][$value] = $value; + $counter[$key_table][$key_param] = $i; } } foreach ($compacted AS $table => $values) { - foreach ($values AS $field => $field_values) { - $sql = "DELETE FROM `".$table."` WHERE `".$field."` IN (". - substr(str_repeat("?, ", count($field_values)), 0, -2).");"; + foreach ($values AS $field => $field_value_list) { + foreach ($field_value_list AS $field_values) { + $sql = "DELETE FROM `".$table."` WHERE `".$field."` IN (". + substr(str_repeat("?, ", count($field_values)), 0, -2).");"; - logger(dba::replace_parameters($sql, $field_values), LOGGER_DATA); + logger(dba::replace_parameters($sql, $field_values), LOGGER_DATA); - if (!self::e($sql, $param)) { - self::p("ROLLBACK"); - return false; + if (!self::e($sql, $param)) { + self::p("ROLLBACK"); + return false; + } } } } diff --git a/include/dbstructure.php b/include/dbstructure.php index 25109b5f40..06e81e4958 100644 --- a/include/dbstructure.php +++ b/include/dbstructure.php @@ -1152,6 +1152,7 @@ function db_definition() { "uid_parenturi" => array("uid","parent-uri(190)"), "uid_contactid_created" => array("uid","contact-id","created"), "authorid_created" => array("author-id","created"), + "ownerid" => array("owner-id"), "uid_uri" => array("uid", "uri(190)"), "resource-id" => array("resource-id"), "contactid_allowcid_allowpid_denycid_denygid" => array("contact-id","allow_cid(10)","allow_gid(10)","deny_cid(10)","deny_gid(10)"), // @@ -1627,6 +1628,9 @@ function db_definition() { "uid_network_created" => array("uid","network","created"), "uid_contactid_commented" => array("uid","contact-id","commented"), "uid_contactid_created" => array("uid","contact-id","created"), + "contactid" => array("contact-id"), + "ownerid" => array("owner-id"), + "authorid" => array("author-id"), "uid_created" => array("uid","created"), "uid_commented" => array("uid","commented"), "uid_wall_created" => array("uid","wall","created"), diff --git a/update.php b/update.php index 704f2ac061..bdb3d68839 100644 --- a/update.php +++ b/update.php @@ -1,6 +1,6 @@ Date: Mon, 1 May 2017 19:54:08 +0000 Subject: [PATCH 8/9] Avoid duplicated queries --- include/dba.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/include/dba.php b/include/dba.php index 11e1d2131d..924c31e05f 100644 --- a/include/dba.php +++ b/include/dba.php @@ -785,7 +785,7 @@ class dba { * * @return boolean|array was the delete successfull? When $in_commit is set: deletion data */ - static public function delete($table, $param, $in_commit = false, $callstack = array()) { + static public function delete($table, $param, $in_commit = false, &$callstack = array()) { $commands = array(); @@ -797,7 +797,7 @@ class dba { return $commands; } - $callstack[$key] = $key; + $callstack[$key] = true; $table = self::$dbo->escape($table); @@ -824,6 +824,16 @@ class dba { } } } else { + // Create a key for preventing double queries + $qkey = $field.'-'.$table.':'.implode(':', array_keys($param)).':'.implode(':', $param); + + // We quit when this key already exists in the callstack. + if (isset($callstack[$qkey])) { + continue; + } + + $callstack[$qkey] = true; + // Fetch all rows that are to be deleted $sql = "SELECT ".self::$dbo->escape($field)." FROM `".$table."` WHERE `". implode("` = ? AND `", array_keys($param))."` = ?"; From d106ff5086229714a42c811b4b1f75d75dffcaad Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 1 May 2017 21:38:37 +0000 Subject: [PATCH 9/9] Error reporting hadn't worked for the new functions --- include/dba.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/dba.php b/include/dba.php index 924c31e05f..1ee2662150 100644 --- a/include/dba.php +++ b/include/dba.php @@ -520,7 +520,7 @@ class dba { } if (!$stmt->execute()) { - $errorInfo = self::$dbo->db->errorInfo(); + $errorInfo = $stmt->errorInfo(); self::$dbo->error = $errorInfo[2]; self::$dbo->errorno = $errorInfo[1]; $retval = false; @@ -532,8 +532,8 @@ class dba { $stmt = self::$dbo->db->stmt_init(); if (!$stmt->prepare($sql)) { - self::$dbo->error = self::$dbo->db->error; - self::$dbo->errorno = self::$dbo->db->errno; + self::$dbo->error = $stmt->error; + self::$dbo->errorno = $stmt->errno; $retval = false; break; }