]> git.mxchange.org Git - friendica.git/commitdiff
Merge remote-tracking branch 'upstream/develop' into 1607-performance
authorMichael <heluecht@pirati.ca>
Wed, 16 Nov 2016 06:27:21 +0000 (06:27 +0000)
committerMichael <heluecht@pirati.ca>
Wed, 16 Nov 2016 06:27:21 +0000 (06:27 +0000)
Conflicts:
include/dbstructure.php
mod/item.php
mod/nodeinfo.php

1  2 
include/Contact.php
include/dba.php
include/dbstructure.php
include/onepoll.php
mod/contacts.php
mod/network.php
mod/nodeinfo.php

diff --combined include/Contact.php
index 0bc7ca0a48185f8dacb49f5150a7f89bd7602b22,23b5bbe5b82be3d8207c9dbf87f70c240736b5f3..05e5dc62fcf84a957f5dde7a571330ae89bad951
@@@ -45,10 -45,10 +45,10 @@@ function user_remove($uid) 
        // don't delete yet, will be done later when contacts have deleted my stuff
        // q("DELETE FROM `user` WHERE `uid` = %d", intval($uid));
        q("UPDATE `user` SET `account_removed` = 1, `account_expires_on` = UTC_TIMESTAMP() WHERE `uid` = %d", intval($uid));
-       proc_run('php', "include/notifier.php", "removeme", $uid);
+       proc_run(PRIORITY_HIGH, "include/notifier.php", "removeme", $uid);
  
        // Send an update to the directory
-       proc_run('php', "include/directory.php", $r[0]['url']);
+       proc_run(PRIORITY_LOW, "include/directory.php", $r[0]['url']);
  
        if($uid == local_user()) {
                unset($_SESSION['authenticated']);
@@@ -159,7 -159,7 +159,7 @@@ function mark_for_death($contact) 
        }
        else {
  
-               /// @todo 
+               /// @todo
                /// We really should send a notification to the owner after 2-3 weeks
                /// so they won't be surprised when the contact vanishes and can take
                /// remedial action if this was a serious mistake or glitch
@@@ -196,6 -196,7 +196,7 @@@ function unmark_for_death($contact) 
   * @brief Get contact data for a given profile link
   *
   * The function looks at several places (contact table and gcontact table) for the contact
+  * It caches its result for the same script execution to prevent duplicate calls
   *
   * @param string $url The profile link
   * @param int $uid User id
   * @return array Contact data
   */
  function get_contact_details_by_url($url, $uid = -1, $default = array()) {
-       if ($uid == -1)
+       static $cache = array();
+       if ($uid == -1) {
                $uid = local_user();
+       }
+       if (isset($cache[$url][$uid])) {
+               return $cache[$url][$uid];
+       }
  
        // Fetch contact data from the contact table for the given user
-       $r = q("SELECT `id`, `id` AS `cid`, 0 AS `gid`, 0 AS `zid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`,
-                       `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `bd` AS `birthday`, `self`
+       $r = q("SELECT `id`, `id` AS `cid`, 0 AS `gid`, 0 AS `zid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
+                       `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, `self`
                FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d",
                        dbesc(normalise_link($url)), intval($uid));
  
        // Fetch the data from the contact table with "uid=0" (which is filled automatically)
        if (!$r)
-               $r = q("SELECT `id`, 0 AS `cid`, `id` AS `zid`, 0 AS `gid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`,
-                               `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `bd` AS `birthday`, 0 AS `self`
+               $r = q("SELECT `id`, 0 AS `cid`, `id` AS `zid`, 0 AS `gid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
+                       `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, 0 AS `self`
                        FROM `contact` WHERE `nurl` = '%s' AND `uid` = 0",
                                dbesc(normalise_link($url)));
  
        // Fetch the data from the gcontact table
        if (!$r)
-               $r = q("SELECT 0 AS `id`, 0 AS `cid`, `id` AS `gid`, 0 AS `zid`, 0 AS `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`,
-                               `keywords`, `gender`, `photo`, `photo` AS `thumb`, `photo` AS `micro`, `community` AS `forum`, 0 AS `prv`, `community`, `birthday`, 0 AS `self`
+               $r = q("SELECT 0 AS `id`, 0 AS `cid`, `id` AS `gid`, 0 AS `zid`, 0 AS `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, '' AS `xmpp`,
+                       `keywords`, `gender`, `photo`, `photo` AS `thumb`, `photo` AS `micro`, `community` AS `forum`, 0 AS `prv`, `community`, `contact-type`, `birthday`, 0 AS `self`
                        FROM `gcontact` WHERE `nurl` = '%s'",
                                dbesc(normalise_link($url)));
  
        if ($r) {
                // If there is more than one entry we filter out the connector networks
-               if (count($r) > 1)
-                       foreach ($r AS $id => $result)
-                               if ($result["network"] == NETWORK_STATUSNET)
+               if (count($r) > 1) {
+                       foreach ($r AS $id => $result) {
+                               if ($result["network"] == NETWORK_STATUSNET) {
                                        unset($r[$id]);
+                               }
+                       }
+               }
  
                $profile = array_shift($r);
  
                        $profile["bd"] = $current_year."-".$month."-".$day;
                        $current = $current_year."-".$current_month."-".$current_day;
  
-                       if ($profile["bd"] < $current)
+                       if ($profile["bd"] < $current) {
                                $profile["bd"] = (++$current_year)."-".$month."-".$day;
-               } else
+                       }
+               } else {
                        $profile["bd"] = "0000-00-00";
-       } else
+               }
+       } else {
                $profile = $default;
+       }
  
-       if (($profile["photo"] == "") AND isset($default["photo"]))
+       if (($profile["photo"] == "") AND isset($default["photo"])) {
                $profile["photo"] = $default["photo"];
+       }
  
-       if (($profile["name"] == "") AND isset($default["name"]))
+       if (($profile["name"] == "") AND isset($default["name"])) {
                $profile["name"] = $default["name"];
+       }
  
-       if (($profile["network"] == "") AND isset($default["network"]))
+       if (($profile["network"] == "") AND isset($default["network"])) {
                $profile["network"] = $default["network"];
+       }
  
-       if (($profile["thumb"] == "") AND isset($profile["photo"]))
+       if (($profile["thumb"] == "") AND isset($profile["photo"])) {
                $profile["thumb"] = $profile["photo"];
+       }
  
-       if (($profile["micro"] == "") AND isset($profile["thumb"]))
+       if (($profile["micro"] == "") AND isset($profile["thumb"])) {
                $profile["micro"] = $profile["thumb"];
+       }
  
        if ((($profile["addr"] == "") OR ($profile["name"] == "")) AND ($profile["gid"] != 0) AND
-               in_array($profile["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS)))
-               proc_run('php',"include/update_gcontact.php", $profile["gid"]);
+               in_array($profile["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS))) {
+               proc_run(PRIORITY_LOW, "include/update_gcontact.php", $profile["gid"]);
+       }
  
        // Show contact details of Diaspora contacts only if connected
        if (($profile["cid"] == 0) AND ($profile["network"] == NETWORK_DIASPORA)) {
                $profile["birthday"] = "0000-00-00";
        }
  
-       return($profile);
- }
+       $cache[$url][$uid] = $profile;
  
- if(! function_exists('contact_photo_menu')){
- function contact_photo_menu($contact, $uid = 0) {
+       return $profile;
+ }
  
+ if (! function_exists('contact_photo_menu')) {
+ function contact_photo_menu($contact, $uid = 0)
+ {
        $a = get_app();
  
-       $contact_url="";
-       $pm_url="";
-       $status_link="";
-       $photos_link="";
-       $posts_link="";
-       $contact_drop_link = "";
-       $poke_link="";
+       $contact_url = '';
+       $pm_url = '';
+       $status_link = '';
+       $photos_link = '';
+       $posts_link = '';
+       $contact_drop_link = '';
+       $poke_link = '';
  
-       if ($uid == 0)
+       if ($uid == 0) {
                $uid = local_user();
+       }
  
-       if ($contact["uid"] != $uid) {
+       if ($contact['uid'] != $uid) {
                if ($uid == 0) {
                        $profile_link = zrl($contact['url']);
-                       $menu = Array('profile' => array(t("View Profile"), $profile_link, true));
+                       $menu = Array('profile' => array(t('View Profile'), $profile_link, true));
  
                        return $menu;
                }
  
                $r = q("SELECT * FROM `contact` WHERE `nurl` = '%s' AND `network` = '%s' AND `uid` = %d",
-                       dbesc($contact["nurl"]), dbesc($contact["network"]), intval($uid));
-               if ($r)
+                       dbesc($contact['nurl']), dbesc($contact['network']), intval($uid));
+               if ($r) {
                        return contact_photo_menu($r[0], $uid);
-               else {
+               else {
                        $profile_link = zrl($contact['url']);
                        $connlnk = 'follow/?url='.$contact['url'];
-                       $menu = Array(
-                               'profile' => array(t("View Profile"), $profile_link, true),
-                               'follow' => array(t("Connect/Follow"), $connlnk, true)
-                               );
+                       $menu = array(
+                               'profile' => array(t('View Profile'), $profile_link, true),
+                               'follow' => array(t('Connect/Follow'), $connlnk, true)
+                       );
  
                        return $menu;
                }
        }
  
        $sparkle = false;
-       if($contact['network'] === NETWORK_DFRN) {
+       if ($contact['network'] === NETWORK_DFRN) {
                $sparkle = true;
                $profile_link = $a->get_baseurl() . '/redir/' . $contact['id'];
-       }
-       else
+       } else {
                $profile_link = $contact['url'];
+       }
  
-       if($profile_link === 'mailbox')
+       if ($profile_link === 'mailbox') {
                $profile_link = '';
+       }
  
-       if($sparkle) {
-               $status_link = $profile_link . "?url=status";
-               $photos_link = $profile_link . "?url=photos";
-               $profile_link = $profile_link . "?url=profile";
+       if ($sparkle) {
+               $status_link = $profile_link . '?url=status';
+               $photos_link = $profile_link . '?url=photos';
+               $profile_link = $profile_link . '?url=profile';
        }
  
-       if (in_array($contact["network"], array(NETWORK_DFRN, NETWORK_DIASPORA)))
+       if (in_array($contact['network'], array(NETWORK_DFRN, NETWORK_DIASPORA))) {
                $pm_url = $a->get_baseurl() . '/message/new/' . $contact['id'];
+       }
  
-       if ($contact["network"] == NETWORK_DFRN)
+       if ($contact['network'] == NETWORK_DFRN) {
                $poke_link = $a->get_baseurl() . '/poke/?f=&c=' . $contact['id'];
+       }
  
        $contact_url = $a->get_baseurl() . '/contacts/' . $contact['id'];
-       $posts_link = $a->get_baseurl() . "/contacts/" . $contact['id'] . '/posts';
-       $contact_drop_link = $a->get_baseurl() . "/contacts/" . $contact['id'] . '/drop?confirm=1';
  
+       $posts_link = $a->get_baseurl() . '/contacts/' . $contact['id'] . '/posts';
+       $contact_drop_link = $a->get_baseurl() . '/contacts/' . $contact['id'] . '/drop?confirm=1';
  
        /**
         * menu array:
         * "name" => [ "Label", "link", (bool)Should the link opened in a new tab? ]
         */
-       $menu = Array(
+       $menu = array(
                'status' => array(t("View Status"), $status_link, true),
                'profile' => array(t("View Profile"), $profile_link, true),
-               'photos' => array(t("View Photos"), $photos_link,true),
-               'network' => array(t("Network Posts"), $posts_link,false),
-               'edit' => array(t("Edit Contact"), $contact_url, false),
+               'photos' => array(t("View Photos"), $photos_link, true),
+               'network' => array(t("Network Posts"), $posts_link, false),
+               'edit' => array(t("View Contact"), $contact_url, false),
                'drop' => array(t("Drop Contact"), $contact_drop_link, false),
                'pm' => array(t("Send PM"), $pm_url, false),
                'poke' => array(t("Poke"), $poke_link, false),
  
        $menucondensed = array();
  
-       foreach ($menu AS $menuname=>$menuitem)
-               if ($menuitem[1] != "")
+       foreach ($menu AS $menuname => $menuitem) {
+               if ($menuitem[1] != '') {
                        $menucondensed[$menuname] = $menuitem;
+               }
+       }
  
        return $menucondensed;
  }}
@@@ -422,9 -450,20 +450,20 @@@ function contacts_not_grouped($uid,$sta
        return $r;
  }
  
- function get_contact($url, $uid = 0) {
+ /**
+  * @brief Fetch the contact id for a given url and user
+  *
+  * @param string $url Contact URL
+  * @param integer $uid The user id for the contact
+  * @param boolean $no_update Don't update the contact
+  *
+  * @return integer Contact ID
+  */
+ function get_contact($url, $uid = 0, $no_update = false) {
        require_once("include/Scrape.php");
  
+       logger("Get contact data for url ".$url." and user ".$uid." - ".App::callstack(), LOGGER_DEBUG);;
        $data = array();
        $contactid = 0;
  
                $update_photo = ($contact[0]['avatar-date'] < datetime_convert('','','now -7 days'));
                //$update_photo = ($contact[0]['avatar-date'] < datetime_convert('','','now -12 hours'));
  
-               if (!$update_photo)
+               if (!$update_photo OR $no_update) {
                        return($contactid);
+               }
        } elseif ($uid != 0)
                return 0;
  
        if ($contactid == 0) {
                q("INSERT INTO `contact` (`uid`, `created`, `url`, `nurl`, `addr`, `alias`, `notify`, `poll`,
                                        `name`, `nick`, `photo`, `network`, `pubkey`, `rel`, `priority`,
-                                       `batch`, `request`, `confirm`, `poco`,
+                                       `batch`, `request`, `confirm`, `poco`, `name-date`, `uri-date`,
                                        `writable`, `blocked`, `readonly`, `pending`)
-                                       VALUES (%d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', '%s', '%s', 1, 0, 0, 0)",
+                                       VALUES (%d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', 1, 0, 0, 0)",
                        intval($uid),
                        dbesc(datetime_convert()),
                        dbesc($data["url"]),
                        dbesc($data["batch"]),
                        dbesc($data["request"]),
                        dbesc($data["confirm"]),
-                       dbesc($data["poco"])
+                       dbesc($data["poco"]),
+                       dbesc(datetime_convert()),
+                       dbesc(datetime_convert())
                );
  
                $contact = q("SELECT `id` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d ORDER BY `id` LIMIT 2",
  
        update_contact_avatar($data["photo"],$uid,$contactid);
  
-       q("UPDATE `contact` SET `addr` = '%s', `alias` = '%s', `name` = '%s', `nick` = '%s',
-               `name-date` = '%s', `uri-date` = '%s' WHERE `id` = %d",
-               dbesc($data["addr"]),
-               dbesc($data["alias"]),
-               dbesc($data["name"]),
-               dbesc($data["nick"]),
-               dbesc(datetime_convert()),
-               dbesc(datetime_convert()),
-               intval($contactid)
-       );
+       $r = q("SELECT `addr`, `alias`, `name`, `nick` FROM `contact`  WHERE `id` = %d", intval($contactid));
+       // This condition should always be true
+       if (!dbm::is_result($r))
+               return $contactid;
+       // Only update if there had something been changed
+       if (($data["addr"] != $r[0]["addr"]) OR
+               ($data["alias"] != $r[0]["alias"]) OR
+               ($data["name"] != $r[0]["name"]) OR
+               ($data["nick"] != $r[0]["nick"]))
+               q("UPDATE `contact` SET `addr` = '%s', `alias` = '%s', `name` = '%s', `nick` = '%s',
+                       `name-date` = '%s', `uri-date` = '%s' WHERE `id` = %d",
+                       dbesc($data["addr"]),
+                       dbesc($data["alias"]),
+                       dbesc($data["name"]),
+                       dbesc($data["nick"]),
+                       dbesc(datetime_convert()),
+                       dbesc(datetime_convert()),
+                       intval($contactid)
+               );
  
        return $contactid;
  }
@@@ -599,64 -652,57 +652,64 @@@ function posts_from_gcontact($a, $gcont
  
        return $o;
  }
 -
  /**
 - * @brief Returns posts from a given contact
 + * @brief Returns posts from a given contact url
   *
   * @param App $a argv application class
 - * @param int $contact_id contact
 + * @param int $contact_url Contact URL
   *
   * @return string posts in HTML
   */
 -function posts_from_contact($a, $contact_id) {
 +function posts_from_contact_url($a, $contact_url) {
  
        require_once('include/conversation.php');
  
 -      $r = q("SELECT `url` FROM `contact` WHERE `id` = %d", intval($contact_id));
 -      if (!$r)
 -              return false;
 +      // There are no posts with "uid = 0" with connector networks
 +      // This speeds up the query a lot
 +      $r = q("SELECT `network`, `id` AS `author-id` FROM `contact`
 +              WHERE `contact`.`nurl` = '%s' AND `contact`.`uid` = 0",
 +              dbesc(normalise_link($contact_url)));
 +      if (in_array($r[0]["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, "")))
 +              $sql = "(`item`.`uid` = 0 OR  (`item`.`uid` = %d AND `item`.`private`))";
 +      else
 +              $sql = "`item`.`uid` = %d";
  
 -      $contact = $r[0];
 +      $author_id = intval($r[0]["author-id"]);
  
 -      if(get_config('system', 'old_pager')) {
 +      if (get_config('system', 'old_pager')) {
                $r = q("SELECT COUNT(*) AS `total` FROM `item`
 -                      WHERE `item`.`uid` = %d AND `author-link` IN ('%s', '%s')",
 -                      intval(local_user()),
 -                      dbesc(str_replace("https://", "http://", $contact["url"])),
 -                      dbesc(str_replace("http://", "https://", $contact["url"])));
 +                      WHERE `author-id` = %d and $sql",
 +                      intval($author_id),
 +                      intval(local_user()));
  
                $a->set_pager_total($r[0]['total']);
        }
  
 -      $r = q("SELECT `item`.`uri`, `item`.*, `item`.`id` AS `item_id`,
 +/*
 +"SELECT `item`.`uri`, `item`.*, `item`.`id` AS `item_id`,
                        `author-name` AS `name`, `owner-avatar` AS `photo`,
                        `owner-link` AS `url`, `owner-avatar` AS `thumb`
 -              FROM `item` FORCE INDEX (`uid_contactid_id`)
 -              WHERE `item`.`uid` = %d AND `contact-id` = %d
 -                      AND `author-link` IN ('%s', '%s')
 -                      AND NOT `deleted` AND NOT `moderated` AND `visible`
 -              ORDER BY `item`.`id` DESC LIMIT %d, %d",
 +              FROM `item` FORCE INDEX (`authorid_created`)
 +              WHERE `item`.`author-id` = %d AND $sql
 +              AND NOT `deleted` AND NOT `moderated` AND `visible`
 +
 +*/
 +
 +      $r = q(item_query()." AND `item`.`author-id` = %d AND ".$sql.
 +              " ORDER BY `item`.`created` DESC LIMIT %d, %d",
 +              intval($author_id),
                intval(local_user()),
 -              intval($contact_id),
 -              dbesc(str_replace("https://", "http://", $contact["url"])),
 -              dbesc(str_replace("http://", "https://", $contact["url"])),
                intval($a->pager['start']),
                intval($a->pager['itemspage'])
        );
  
 -      $o .= conversation($a,$r,'community',false);
 +      $o = conversation($a,$r,'community',false);
  
 -      if(!get_config('system', 'old_pager'))
 +      if(!get_config('system', 'old_pager')) {
                $o .= alt_pager($a,count($r));
 -      else
 +      } else {
                $o .= paginate($a);
 +      }
  
        return $o;
  }
@@@ -690,4 -736,50 +743,50 @@@ function formatted_location($profile) 
  
        return $location;
  }
+ /**
+  * @brief Returns the account type name
+  *
+  * The function can be called with either the user or the contact array
+  *
+  * @param array $contact contact or user array
+  */
+ function account_type($contact) {
+       // There are several fields that indicate that the contact or user is a forum
+       // "page-flags" is a field in the user table,
+       // "forum" and "prv" are used in the contact table. They stand for PAGE_COMMUNITY and PAGE_PRVGROUP.
+       // "community" is used in the gcontact table and is true if the contact is PAGE_COMMUNITY or PAGE_PRVGROUP.
+       if((isset($contact['page-flags']) && (intval($contact['page-flags']) == PAGE_COMMUNITY))
+               || (isset($contact['page-flags']) && (intval($contact['page-flags']) == PAGE_PRVGROUP))
+               || (isset($contact['forum']) && intval($contact['forum']))
+               || (isset($contact['prv']) && intval($contact['prv']))
+               || (isset($contact['community']) && intval($contact['community'])))
+               $type = ACCOUNT_TYPE_COMMUNITY;
+       else
+               $type = ACCOUNT_TYPE_PERSON;
+       // The "contact-type" (contact table) and "account-type" (user table) are more general then the chaos from above.
+       if (isset($contact["contact-type"]))
+               $type = $contact["contact-type"];
+       if (isset($contact["account-type"]))
+               $type = $contact["account-type"];
+       switch($type) {
+               case ACCOUNT_TYPE_ORGANISATION:
+                       $account_type = t("Organisation");
+                       break;
+               case ACCOUNT_TYPE_NEWS:
+                       $account_type = t('News');
+                       break;
+               case ACCOUNT_TYPE_COMMUNITY:
+                       $account_type = t("Forum");
+                       break;
+               default:
+                       $account_type = "";
+                       break;
+       }
+       return $account_type;
+ }
  ?>
diff --combined include/dba.php
index a9bd571e72ec2d758f5a4edb4a2cee60a0975c3d,082a54bd496694875cb7756974f049c2f065a179..7ca520712a455a31d53d4b92e24800cbcbdac124
@@@ -5,7 -5,7 +5,7 @@@ require_once("dbm.php")
  # TODO: PDO is disabled for release 3.3. We need to investigate why
  # the update from 3.2 fails with pdo
  /*
- if(class_exists('\PDO') && in_array('mysql', PDO::getAvailableDrivers())) {
+ if (class_exists('\PDO') && in_array('mysql', PDO::getAvailableDrivers())) {
    require_once("library/dddbl2/dddbl.php");
    require_once("include/dba_pdo.php");
  }
@@@ -24,7 -24,7 +24,7 @@@ require_once('include/datetime.php')
   *
   */
  
- if(! class_exists('dba')) {
+ if (! class_exists('dba')) {
  class dba {
  
        private $debug = 0;
@@@ -34,7 -34,7 +34,7 @@@
        public  $connected = false;
        public  $error = false;
  
-       function __construct($server,$user,$pass,$db,$install = false) {
+       function __construct($server, $user, $pass, $db, $install = false) {
                global $a;
  
                $stamp1 = microtime(true);
                $pass = trim($pass);
                $db = trim($db);
  
-               if (!(strlen($server) && strlen($user))){
+               if (!(strlen($server) && strlen($user))) {
                        $this->connected = false;
                        $this->db = null;
                        return;
                }
  
-               if($install) {
-                       if(strlen($server) && ($server !== 'localhost') && ($server !== '127.0.0.1')) {
-                               if(! dns_get_record($server, DNS_A + DNS_CNAME + DNS_PTR)) {
+               if ($install) {
+                       if (strlen($server) && ($server !== 'localhost') && ($server !== '127.0.0.1')) {
+                               if (! dns_get_record($server, DNS_A + DNS_CNAME + DNS_PTR)) {
                                        $this->error = sprintf( t('Cannot locate DNS info for database server \'%s\''), $server);
                                        $this->connected = false;
                                        $this->db = null;
                        }
                }
  
-               if(class_exists('mysqli')) {
+               if (class_exists('mysqli')) {
                        $this->db = @new mysqli($server,$user,$pass,$db);
-                       if(! mysqli_connect_errno()) {
+                       if (! mysqli_connect_errno()) {
                                $this->connected = true;
 +                              //mysqli_set_charset($this->db, 'utf8');
                        }
-               }
-               else {
+                       if (isset($a->config["system"]["db_charset"])) {
+                               $this->db->set_charset($a->config["system"]["db_charset"]);
+                       }
+               } else {
                        $this->mysqli = false;
                        $this->db = mysql_connect($server,$user,$pass);
-                       if($this->db && mysql_select_db($db,$this->db)) {
+                       if ($this->db && mysql_select_db($db,$this->db)) {
                                $this->connected = true;
 +                              //mysql_set_charset('utf8', $this->db);
                        }
+                       if (isset($a->config["system"]["db_charset"]))
+                               mysql_set_charset($a->config["system"]["db_charset"], $this->db);
                }
-               if(! $this->connected) {
+               if (!$this->connected) {
                        $this->db = null;
-                       if(! $install)
+                       if (!$install) {
                                system_unavailable();
+                       }
                }
  
                $a->save_timestamp($stamp1, "network");
                return $this->db;
        }
  
+       /**
+        * @brief Returns the MySQL server version string
+        * 
+        * This function discriminate between the deprecated mysql API and the current
+        * object-oriented mysqli API. Example of returned string: 5.5.46-0+deb8u1
+        *
+        * @return string
+        */
+       public function server_info() {
+               if ($this->mysqli) {
+                       $return = $this->db->server_info;
+               } else {
+                       $return = mysql_get_server_info($this->db);
+               }
+               return $return;
+       }
+       /**
+        * @brief Returns the number of rows
+        *
+        * @return integer
+        */
+       public function num_rows() {
+               if (!$this->result) {
+                       return 0;
+               }
+               if ($this->mysqli) {
+                       $return = $this->result->num_rows;
+               } else {
+                       $return = mysql_num_rows($this->result);
+               }
+               return $return;
+       }
        public function q($sql, $onlyquery = false) {
                global $a;
  
-               if((! $this->db) || (! $this->connected))
+               if (!$this->db || !$this->connected) {
                        return false;
+               }
  
                $this->error = '';
  
+               // Check the connection (This can reconnect the connection - if configured)
+               if ($this->mysqli) {
+                       $connected = $this->db->ping();
+               } else {
+                       $connected = mysql_ping($this->db);
+               }
+               $connstr = ($connected ? "Connected" : "Disonnected");
                $stamp1 = microtime(true);
  
-               if($this->mysqli)
+               $orig_sql = $sql;
+               if (x($a->config,'system') && x($a->config['system'], 'db_callstack')) {
+                       $sql = "/*".$a->callstack()." */ ".$sql;
+               }
+               if ($this->mysqli) {
                        $result = @$this->db->query($sql);
-               else
+               } else {
                        $result = @mysql_query($sql,$this->db);
+               }
                $stamp2 = microtime(true);
                $duration = (float)($stamp2-$stamp1);
  
                $a->save_timestamp($stamp1, "database");
  
-               if(x($a->config,'system') && x($a->config['system'],'db_log')) {
+               if (strtolower(substr($orig_sql, 0, 6)) != "select") {
+                       $a->save_timestamp($stamp1, "database_write");
+               }
+               if (x($a->config,'system') && x($a->config['system'],'db_log')) {
                        if (($duration > $a->config["system"]["db_loglimit"])) {
                                $duration = round($duration, 3);
                                $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
                        }
                }
  
-               if($this->mysqli) {
-                       if($this->db->errno)
+               if ($this->mysqli) {
+                       if ($this->db->errno) {
                                $this->error = $this->db->error;
+                               $this->errorno = $this->db->errno;
+                       }
+               } elseif (mysql_errno($this->db)) {
+                       $this->error = mysql_error($this->db);
+                       $this->errorno = mysql_errno($this->db);
                }
-               elseif(mysql_errno($this->db))
-                               $this->error = mysql_error($this->db);
  
-               if(strlen($this->error)) {
-                       logger('dba: ' . $this->error);
+               if (strlen($this->error)) {
+                       logger('DB Error ('.$connstr.') '.$this->errorno.': '.$this->error);
                }
  
-               if($this->debug) {
+               if ($this->debug) {
  
                        $mesg = '';
  
-                       if($result === false)
+                       if ($result === false) {
                                $mesg = 'false';
-                       elseif($result === true)
+                       } elseif ($result === true) {
                                $mesg = 'true';
-                       else {
-                               if($this->mysqli)
+                       else {
+                               if ($this->mysqli) {
                                        $mesg = $result->num_rows . ' results' . EOL;
-                       else
+                               } else {
                                        $mesg = mysql_num_rows($result) . ' results' . EOL;
+                               }
                        }
  
                        $str =  'SQL = ' . printable($sql) . EOL . 'SQL returned ' . $mesg
                 * These usually indicate SQL syntax errors that need to be resolved.
                 */
  
-               if($result === false) {
+               if ($result === false) {
                        logger('dba: ' . printable($sql) . ' returned false.' . "\n" . $this->error);
-                       if(file_exists('dbfail.out'))
+                       if (file_exists('dbfail.out')) {
                                file_put_contents('dbfail.out', datetime_convert() . "\n" . printable($sql) . ' returned false' . "\n" . $this->error . "\n", FILE_APPEND);
+                       }
                }
  
-               if(($result === true) || ($result === false))
+               if (($result === true) || ($result === false)) {
                        return $result;
+               }
                if ($onlyquery) {
                        $this->result = $result;
                        return true;
                }
  
                $r = array();
-               if($this->mysqli) {
-                       if($result->num_rows) {
+               if ($this->mysqli) {
+                       if ($result->num_rows) {
                                while($x = $result->fetch_array(MYSQLI_ASSOC))
                                        $r[] = $x;
                                $result->free_result();
                        }
-               }
-               else {
-                       if(mysql_num_rows($result)) {
+               } else {
+                       if (mysql_num_rows($result)) {
                                while($x = mysql_fetch_array($result, MYSQL_ASSOC))
                                        $r[] = $x;
                                mysql_free_result($result);
  
                //$a->save_timestamp($stamp1, "database");
  
-               if($this->debug)
+               if ($this->debug) {
                        logger('dba: ' . printable(print_r($r, true)));
+               }
                return($r);
        }
  
        public function qfetch() {
                $x = false;
  
-               if ($this->result)
-                       if($this->mysqli) {
-                               if($this->result->num_rows)
+               if ($this->result) {
+                       if ($this->mysqli) {
+                               if ($this->result->num_rows)
                                        $x = $this->result->fetch_array(MYSQLI_ASSOC);
                        } else {
-                               if(mysql_num_rows($this->result))
+                               if (mysql_num_rows($this->result))
                                        $x = mysql_fetch_array($this->result, MYSQL_ASSOC);
                        }
+               }
                return($x);
        }
  
        public function qclose() {
-               if ($this->result)
-                       if($this->mysqli) {
+               if ($this->result) {
+                       if ($this->mysqli) {
                                $this->result->free_result();
                        } else {
                                mysql_free_result($this->result);
                        }
+               }
        }
  
        public function dbg($dbg) {
        }
  
        public function escape($str) {
-               if($this->db && $this->connected) {
-                       if($this->mysqli)
+               if ($this->db && $this->connected) {
+                       if ($this->mysqli) {
                                return @$this->db->real_escape_string($str);
-                       else
+                       } else {
                                return @mysql_real_escape_string($str,$this->db);
+                       }
+               }
+       }
+       function connected() {
+               if ($this->mysqli) {
+                       $connected = $this->db->ping();
+               } else {
+                       $connected = mysql_ping($this->db);
                }
+               return $connected;
        }
  
        function __destruct() {
-               if ($this->db)
-                       if($this->mysqli)
+               if ($this->db) {
+                       if ($this->mysqli) {
                                $this->db->close();
-                       else
+                       } else {
                                mysql_close($this->db);
+                       }
+               }
        }
  }}
  
- if(! function_exists('printable')) {
+ if (! function_exists('printable')) {
  function printable($s) {
        $s = preg_replace("~([\x01-\x08\x0E-\x0F\x10-\x1F\x7F-\xFF])~",".", $s);
        $s = str_replace("\x00",'.',$s);
-       if(x($_SERVER,'SERVER_NAME'))
+       if (x($_SERVER,'SERVER_NAME')) {
                $s = escape_tags($s);
+       }
        return $s;
  }}
  
  // Procedural functions
- if(! function_exists('dbg')) {
+ if (! function_exists('dbg')) {
  function dbg($state) {
        global $db;
-       if($db)
-       $db->dbg($state);
+       if ($db) {
+               $db->dbg($state);
+       }
  }}
  
- if(! function_exists('dbesc')) {
+ if (! function_exists('dbesc')) {
  function dbesc($str) {
        global $db;
-       if($db && $db->connected)
+       if ($db && $db->connected) {
                return($db->escape($str));
-       else
+       } else {
                return(str_replace("'","\\'",$str));
+       }
  }}
  
  
  // Example: $r = q("SELECT * FROM `%s` WHERE `uid` = %d",
  //                   'user', 1);
  
- if(! function_exists('q')) {
+ if (! function_exists('q')) {
  function q($sql) {
  
        global $db;
        $args = func_get_args();
        unset($args[0]);
  
-       if($db && $db->connected) {
+       if ($db && $db->connected) {
                $stmt = @vsprintf($sql,$args); // Disabled warnings
                //logger("dba: q: $stmt", LOGGER_ALL);
-               if($stmt === false)
+               if ($stmt === false)
                        logger('dba: vsprintf error: ' . print_r(debug_backtrace(),true), LOGGER_DEBUG);
                return $db->q($stmt);
        }
  
  }}
  
+ /**
+  * @brief Performs a query with "dirty reads"
+  *
+  * By doing dirty reads (reading uncommitted data) no locks are performed
+  * This function can be used to fetch data that doesn't need to be reliable.
+  *
+  * @param $args Query parameters (1 to N parameters of different types)
+  * @return array Query array
+  */
+ function qu($sql) {
+       global $db;
+       $args = func_get_args();
+       unset($args[0]);
+       if ($db && $db->connected) {
+               $stmt = @vsprintf($sql,$args); // Disabled warnings
+               if ($stmt === false)
+                       logger('dba: vsprintf error: ' . print_r(debug_backtrace(),true), LOGGER_DEBUG);
+               $db->q("SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;");
+               $retval = $db->q($stmt);
+               $db->q("SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;");
+               return $retval;
+       }
+       /**
+        *
+        * This will happen occasionally trying to store the
+        * session data after abnormal program termination
+        *
+        */
+       logger('dba: no database: ' . print_r($args,true));
+       return false;
+ }
  /**
   *
   * Raw db query, no arguments
   *
   */
  
- if(! function_exists('dbq')) {
+ if (! function_exists('dbq')) {
  function dbq($sql) {
  
        global $db;
-       if($db && $db->connected)
+       if ($db && $db->connected) {
                $ret = $db->q($sql);
-       else
+       } else {
                $ret = false;
+       }
        return $ret;
  }}
  
  // cast to int to avoid trouble.
  
  
- if(! function_exists('dbesc_array_cb')) {
+ if (! function_exists('dbesc_array_cb')) {
  function dbesc_array_cb(&$item, $key) {
-       if(is_string($item))
+       if (is_string($item))
                $item = dbesc($item);
  }}
  
  
- if(! function_exists('dbesc_array')) {
+ if (! function_exists('dbesc_array')) {
  function dbesc_array(&$arr) {
-       if(is_array($arr) && count($arr)) {
+       if (is_array($arr) && count($arr)) {
                array_walk($arr,'dbesc_array_cb');
        }
  }}
diff --combined include/dbstructure.php
index 5b1ffc330977dc5165377a345fa520db12955b64,bd4a07eb56e73a9c63bb4cb468409da66d62ebfc..a76e3e2723211d7fa40d8a5d4b0074e37428b727
@@@ -78,8 -78,16 +78,16 @@@ function table_structure($table) 
                        if ($index["Index_type"] == "FULLTEXT")
                                continue;
  
+                       if ($index['Key_name'] != 'PRIMARY' && $index['Non_unique'] == '0' && !isset($indexdata[$index["Key_name"]])) {
+                               $indexdata[$index["Key_name"]] = array('UNIQUE');
+                       }
                        $column = $index["Column_name"];
-                       if ($index["Sub_part"] != "")
+                       // On utf8mb4 a varchar index can only have a length of 191
+                       // To avoid the need to add this to every index definition we just ignore it here.
+                       // Exception are primary indexes
+                       // Since there are some combindex primary indexes we use the limit of 180 here.
+                       if (($index["Sub_part"] != "") AND (($index["Sub_part"] < 180) OR ($index["Key_name"] == "PRIMARY")))
                                $column .= "(".$index["Sub_part"].")";
  
                        $indexdata[$index["Key_name"]][] = $column;
        return(array("fields"=>$fielddata, "indexes"=>$indexdata));
  }
  
- function print_structure($database) {
+ function print_structure($database, $charset) {
        echo "-- ------------------------------------------\n";
        echo "-- ".FRIENDICA_PLATFORM." ".FRIENDICA_VERSION." (".FRIENDICA_CODENAME,")\n";
        echo "-- DB_UPDATE_VERSION ".DB_UPDATE_VERSION."\n";
                echo "--\n";
                echo "-- TABLE $name\n";
                echo "--\n";
-               db_create_table($name, $structure['fields'], true, false, $structure["indexes"]);
+               db_create_table($name, $structure['fields'], $charset, true, false, $structure["indexes"]);
  
                echo "\n";
        }
  function update_structure($verbose, $action, $tables=null, $definition=null) {
        global $a, $db;
  
+       if ($action)
+               set_config('system', 'maintenance', 1);
+       if (isset($a->config["system"]["db_charset"]))
+               $charset = $a->config["system"]["db_charset"];
+       else
+               $charset = "utf8";
        $errors = false;
  
        logger('updating structure', LOGGER_DEBUG);
  
        // Get the definition
        if (is_null($definition))
-               $definition = db_definition();
+               $definition = db_definition($charset);
  
+       // Ensure index conversion to unique removes duplicates
+       $sql_config = "SET session old_alter_table=1;";
+       if ($verbose)
+               echo $sql_config."\n";
+       if ($action)
+               @$db->q($sql_config);
+       // MySQL >= 5.7.4 doesn't support the IGNORE keyword in ALTER TABLE statements
+       if ((version_compare($db->server_info(), '5.7.4') >= 0) AND
+               !(strpos($db->server_info(), 'MariaDB') !== false)) {
+               $ignore = '';
+       }else {
+               $ignore = ' IGNORE';
+       }
  
        // Compare it
        foreach ($definition AS $name => $structure) {
                $is_new_table = False;
                $sql3="";
                if (!isset($database[$name])) {
-                       $r = db_create_table($name, $structure["fields"], $verbose, $action, $structure['indexes']);
+                       $r = db_create_table($name, $structure["fields"], $charset, $verbose, $action, $structure['indexes']);
                        if(false === $r) {
                                $errors .=  t('Errors encountered creating database tables.').$name.EOL;
                        }
                                if ($current_index_definition != $new_index_definition && substr($indexname, 0, 6) != 'local_') {
                                        $sql2=db_drop_index($indexname);
                                        if ($sql3 == "")
-                                               $sql3 = "ALTER TABLE `".$name."` ".$sql2;
+                                               $sql3 = "ALTER".$ignore." TABLE `".$name."` ".$sql2;
                                        else
                                                $sql3 .= ", ".$sql2;
                                }
                                        $sql2=db_create_index($indexname, $fieldnames);
                                        if ($sql2 != "") {
                                                if ($sql3 == "")
-                                                       $sql3 = "ALTER TABLE `".$name."` ".$sql2;
+                                                       $sql3 = "ALTER" . $ignore . " TABLE `".$name."` ".$sql2;
                                                else
                                                        $sql3 .= ", ".$sql2;
                                        }
                }
        }
  
+       if ($action)
+               set_config('system', 'maintenance', 0);
        return $errors;
  }
  
@@@ -257,7 -290,7 +290,7 @@@ function db_field_command($parameters, 
        return($fieldstruct);
  }
  
- function db_create_table($name, $fields, $verbose, $action, $indexes=null) {
+ function db_create_table($name, $fields, $charset, $verbose, $action, $indexes=null) {
        global $a, $db;
  
        $r = true;
  
        $sql = implode(",\n\t", $sql_rows);
  
-       $sql = sprintf("CREATE TABLE IF NOT EXISTS `%s` (\n\t", dbesc($name)).$sql."\n) DEFAULT CHARSET=utf8";
+       $sql = sprintf("CREATE TABLE IF NOT EXISTS `%s` (\n\t", dbesc($name)).$sql."\n) DEFAULT CHARSET=".$charset;
        if ($verbose)
                echo $sql.";\n";
  
@@@ -315,9 -348,9 +348,9 @@@ function db_create_index($indexname, $f
                killme();
        }
  
-       if ($indexname == "PRIMARY") {
-               return sprintf("%s PRIMARY KEY(`%s`)", $method, implode("`,`", $fieldnames));
+       if ($fieldnames[0] == "UNIQUE") {
+               array_shift($fieldnames);
+               $method .= ' UNIQUE';
        }
  
        $names = "";
                        $names .= "`".dbesc($fieldname)."`";
        }
  
+       if ($indexname == "PRIMARY") {
+               return sprintf("%s PRIMARY KEY(%s)", $method, $names);
+       }
  
        $sql = sprintf("%s INDEX `%s` (%s)", $method, dbesc($indexname), $names);
        return($sql);
  }
  
- function db_definition() {
+ function db_index_suffix($charset, $reduce = 0) {
+       if ($charset != "utf8mb4")
+               return "";
+       // On utf8mb4 indexes can only have a length of 191
+       $indexlength = 191 - $reduce;
+       return "(".$indexlength.")";
+ }
+ function db_definition($charset) {
  
        $database = array();
  
                                        "data" => array("type" => "longblob", "not null" => "1"),
                                        "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
                                        "edited" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
-                                       "allow_cid" => array("type" => "mediumtext", "not null" => "1"),
-                                       "allow_gid" => array("type" => "mediumtext", "not null" => "1"),
-                                       "deny_cid" => array("type" => "mediumtext", "not null" => "1"),
-                                       "deny_gid" => array("type" => "mediumtext", "not null" => "1"),
+                                       "allow_cid" => array("type" => "mediumtext"),
+                                       "allow_gid" => array("type" => "mediumtext"),
+                                       "deny_cid" => array("type" => "mediumtext"),
+                                       "deny_gid" => array("type" => "mediumtext"),
                                        ),
                        "indexes" => array(
                                        "PRIMARY" => array("id"),
        $database["cache"] = array(
                        "fields" => array(
                                        "k" => array("type" => "varchar(255)", "not null" => "1", "primary" => "1"),
-                                       "v" => array("type" => "text", "not null" => "1"),
+                                       "v" => array("type" => "text"),
                                        "expire_mode" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
                                        "updated" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
                                        ),
                        "indexes" => array(
-                                       "PRIMARY" => array("k"),
+                                       "PRIMARY" => array("k".db_index_suffix($charset)),
                                        "updated" => array("updated"),
+                                       "expire_mode_updated" => array("expire_mode", "updated"),
                                        )
                        );
        $database["challenge"] = array(
                                        "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
                                        "cat" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "k" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
-                                       "v" => array("type" => "text", "not null" => "1"),
+                                       "v" => array("type" => "text"),
                                        ),
                        "indexes" => array(
                                        "PRIMARY" => array("id"),
-                                       "cat_k" => array("cat(30)","k(30)"),
+                                       "cat_k" => array("UNIQUE", "cat(30)","k(30)"),
                                        )
                        );
        $database["contact"] = array(
                                        "name" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "nick" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "location" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
-                                       "about" => array("type" => "text", "not null" => "1"),
-                                       "keywords" => array("type" => "text", "not null" => "1"),
+                                       "about" => array("type" => "text"),
+                                       "keywords" => array("type" => "text"),
                                        "gender" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
+                                       "xmpp" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "attag" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "avatar" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
-                                       "photo" => array("type" => "text", "not null" => "1"),
-                                       "thumb" => array("type" => "text", "not null" => "1"),
-                                       "micro" => array("type" => "text", "not null" => "1"),
-                                       "site-pubkey" => array("type" => "text", "not null" => "1"),
+                                       "photo" => array("type" => "text"),
+                                       "thumb" => array("type" => "text"),
+                                       "micro" => array("type" => "text"),
+                                       "site-pubkey" => array("type" => "text"),
                                        "issued-id" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "dfrn-id" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "url" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "nurl" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "addr" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "alias" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
-                                       "pubkey" => array("type" => "text", "not null" => "1"),
-                                       "prvkey" => array("type" => "text", "not null" => "1"),
+                                       "pubkey" => array("type" => "text"),
+                                       "prvkey" => array("type" => "text"),
                                        "batch" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
-                                       "request" => array("type" => "text", "not null" => "1"),
-                                       "notify" => array("type" => "text", "not null" => "1"),
-                                       "poll" => array("type" => "text", "not null" => "1"),
-                                       "confirm" => array("type" => "text", "not null" => "1"),
-                                       "poco" => array("type" => "text", "not null" => "1"),
+                                       "request" => array("type" => "text"),
+                                       "notify" => array("type" => "text"),
+                                       "poll" => array("type" => "text"),
+                                       "confirm" => array("type" => "text"),
+                                       "poco" => array("type" => "text"),
                                        "aes_allow" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
                                        "ret-aes" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
                                        "usehub" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
                                        "writable" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
                                        "forum" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
                                        "prv" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "contact-type" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"),
                                        "hidden" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
                                        "archive" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
                                        "pending" => array("type" => "tinyint(1)", "not null" => "1", "default" => "1"),
                                        "rating" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
-                                       "reason" => array("type" => "text", "not null" => "1"),
+                                       "reason" => array("type" => "text"),
                                        "closeness" => array("type" => "tinyint(2)", "not null" => "1", "default" => "99"),
-                                       "info" => array("type" => "mediumtext", "not null" => "1"),
+                                       "info" => array("type" => "mediumtext"),
                                        "profile-id" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
                                        "bdyear" => array("type" => "varchar(4)", "not null" => "1", "default" => ""),
                                        "bd" => array("type" => "date", "not null" => "1", "default" => "0000-00-00"),
                                        "notify_new_posts" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
                                        "fetch_further_information" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
-                                       "ffi_keyword_blacklist" => array("type" => "mediumtext", "not null" => "1"),
+                                       "ffi_keyword_blacklist" => array("type" => "mediumtext"),
                                        ),
                        "indexes" => array(
                                        "PRIMARY" => array("id"),
                                        "uid" => array("uid"),
+                                       "addr_uid" => array("addr", "uid"),
                                        "nurl" => array("nurl"),
                                        )
                        );
                        "fields" => array(
                                        "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" => "mediumtext", "not null" => "1"),
+                                       "recips" => array("type" => "mediumtext"),
                                        "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
                                        "creator" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
                                        "updated" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
-                                       "subject" => array("type" => "mediumtext", "not null" => "1"),
+                                       "subject" => array("type" => "mediumtext"),
                                        ),
                        "indexes" => array(
                                        "PRIMARY" => array("id"),
                                        ),
                        "indexes" => array(
                                        "PRIMARY" => array("id"),
+                                       "cmd_item_contact" => array("UNIQUE", "cmd", "item", "contact"),
                                        )
                        );
        $database["event"] = array(
                                        "edited" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
                                        "start" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
                                        "finish" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
-                                       "summary" => array("type" => "text", "not null" => "1"),
-                                       "desc" => array("type" => "text", "not null" => "1"),
-                                       "location" => array("type" => "text", "not null" => "1"),
+                                       "summary" => array("type" => "text"),
+                                       "desc" => array("type" => "text"),
+                                       "location" => array("type" => "text"),
                                        "type" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "nofinish" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
                                        "adjust" => array("type" => "tinyint(1)", "not null" => "1", "default" => "1"),
                                        "ignore" => array("type" => "tinyint(1) unsigned", "not null" => "1", "default" => "0"),
-                                       "allow_cid" => array("type" => "mediumtext", "not null" => "1"),
-                                       "allow_gid" => array("type" => "mediumtext", "not null" => "1"),
-                                       "deny_cid" => array("type" => "mediumtext", "not null" => "1"),
-                                       "deny_gid" => array("type" => "mediumtext", "not null" => "1"),
+                                       "allow_cid" => array("type" => "mediumtext"),
+                                       "allow_gid" => array("type" => "mediumtext"),
+                                       "deny_cid" => array("type" => "mediumtext"),
+                                       "deny_gid" => array("type" => "mediumtext"),
                                        ),
                        "indexes" => array(
                                        "PRIMARY" => array("id"),
                                        "priority" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
                                        "network" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
                                        "alias" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
-                                       "pubkey" => array("type" => "text", "not null" => "1"),
+                                       "pubkey" => array("type" => "text"),
                                        "updated" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
                                        ),
                        "indexes" => array(
                                        "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
                                        "server" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "posturl" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
-                                       "key" => array("type" => "text", "not null" => "1"),
+                                       "key" => array("type" => "text"),
                                        ),
                        "indexes" => array(
                                        "PRIMARY" => array("id"),
                                        "url" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "request" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "photo" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
-                                       "note" => array("type" => "text", "not null" => "1"),
+                                       "note" => array("type" => "text"),
                                        "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
                                        ),
                        "indexes" => array(
                                        "last_contact" => array("type" => "datetime", "default" => "0000-00-00 00:00:00"),
                                        "last_failure" => array("type" => "datetime", "default" => "0000-00-00 00:00:00"),
                                        "location" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
-                                       "about" => array("type" => "text", "not null" => "1"),
-                                       "keywords" => array("type" => "text", "not null" => "1"),
+                                       "about" => array("type" => "text"),
+                                       "keywords" => array("type" => "text"),
                                        "gender" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
                                        "birthday" => array("type" => "varchar(32)", "not null" => "1", "default" => "0000-00-00"),
                                        "community" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
+                                       "contact-type" => array("type" => "tinyint(1)", "not null" => "1", "default" => "-1"),
                                        "hide" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
                                        "nsfw" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
                                        "network" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "addr" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
-                                       "notify" => array("type" => "text", "not null" => "1"),
+                                       "notify" => array("type" => "text"),
                                        "alias" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "generation" => array("type" => "tinyint(3)", "not null" => "1", "default" => "0"),
                                        "server_url" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "nurl" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "version" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "site_name" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
-                                       "info" => array("type" => "text", "not null" => "1"),
+                                       "info" => array("type" => "text"),
                                        "register_policy" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
                                        "poco" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "noscrape" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "contact-id" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
                                        "knowyou" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
                                        "duplex" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
-                                       "note" => array("type" => "text", "not null" => "1"),
+                                       "note" => array("type" => "text"),
                                        "hash" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "datetime" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
                                        "blocked" => array("type" => "tinyint(1)", "not null" => "1", "default" => "1"),
                                        "author-link" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "author-avatar" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "title" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
-                                       "body" => array("type" => "mediumtext", "not null" => "1"),
+                                       "body" => array("type" => "mediumtext"),
                                        "app" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "verb" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "object-type" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
-                                       "object" => array("type" => "text", "not null" => "1"),
+                                       "object" => array("type" => "text"),
                                        "target-type" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
-                                       "target" => array("type" => "text", "not null" => "1"),
-                                       "postopts" => array("type" => "text", "not null" => "1"),
+                                       "target" => array("type" => "text"),
+                                       "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"),
-                                       "tag" => array("type" => "mediumtext", "not null" => "1"),
-                                       "attach" => array("type" => "mediumtext", "not null" => "1"),
-                                       "inform" => array("type" => "mediumtext", "not null" => "1"),
-                                       "file" => array("type" => "mediumtext", "not null" => "1"),
+                                       "tag" => array("type" => "mediumtext"),
+                                       "attach" => array("type" => "mediumtext"),
+                                       "inform" => array("type" => "mediumtext"),
+                                       "file" => array("type" => "mediumtext"),
                                        "location" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "coord" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
-                                       "allow_cid" => array("type" => "mediumtext", "not null" => "1"),
-                                       "allow_gid" => array("type" => "mediumtext", "not null" => "1"),
-                                       "deny_cid" => array("type" => "mediumtext", "not null" => "1"),
-                                       "deny_gid" => array("type" => "mediumtext", "not null" => "1"),
+                                       "allow_cid" => array("type" => "mediumtext"),
+                                       "allow_gid" => array("type" => "mediumtext"),
+                                       "deny_cid" => array("type" => "mediumtext"),
+                                       "deny_gid" => array("type" => "mediumtext"),
                                        "private" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
                                        "pubmail" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
                                        "moderated" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
                                        "mention" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
                                        "network" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
                                        "rendered-hash" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
-                                       "rendered-html" => array("type" => "mediumtext", "not null" => "1"),
+                                       "rendered-html" => array("type" => "mediumtext"),
                                        "global" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
                                        ),
                        "indexes" => array(
                                        "uid_created" => array("uid","created"),
                                        "uid_unseen_contactid" => array("uid","unseen","contact-id"),
                                        "uid_network_received" => array("uid","network","received"),
 -                                      "uid_received" => array("uid","received"),
 -                                      "uid_network_commented" => array("uid","network","commented"),
 -                                      "uid_commented" => array("uid","commented"),
 +                                      //"uid_received" => array("uid","received"),
 +                                      //"uid_network_commented" => array("uid","network","commented"),
 +                                      //"uid_commented" => array("uid","commented"),
                                        "uid_title" => array("uid","title"),
                                        "uid_thrparent" => array("uid","thr-parent"),
                                        "uid_parenturi" => array("uid","parent-uri"),
                                        "uid_contactid_id" => array("uid","contact-id","id"),
 -                                      "uid_contactid_created" => array("uid","contact-id","created"),
 +                                      //"uid_contactid_created" => array("uid","contact-id","created"),
                                        "gcontactid_uid_created" => array("gcontact-id","uid","created"),
                                        "authorid_created" => array("author-id","created"),
                                        "ownerid_created" => array("owner-id","created"),
 -                                      "wall_body" => array("wall","body(6)"),
 -                                      "uid_visible_moderated_created" => array("uid","visible","moderated","created"),
 -                                      "uid_uri" => array("uid", "uri"),
 +                                      //"wall_body" => array("wall","body(6)"),
 +                                      //"uid_visible_moderated_created" => array("uid","visible","moderated","created"),
 +                                      "uid_uri" => array("uid","uri"),
                                        "uid_wall_created" => array("uid","wall","created"),
                                        "resource-id" => array("resource-id"),
                                        "uid_type" => array("uid","type"),
                                        "contactid_allowcid_allowpid_denycid_denygid" => array("contact-id","allow_cid(10)","allow_gid(10)","deny_cid(10)","deny_gid(10)"),
                                        "uid_wall_parent_created" => array("uid","wall","parent","created"),
                                        "uid_type_changed" => array("uid","type","changed"),
 -                                      "contactid_verb" => array("contact-id","verb"),
 +                                      //"contactid_verb" => array("contact-id","verb"),
 +                                      "contactid" => array("contact-id"),
                                        "deleted_changed" => array("deleted","changed"),
                                        "uid_wall_changed" => array("uid","wall","changed"),
                                        "uid_eventid" => array("uid","event-id"),
                                        "contact-id" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "convid" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"),
                                        "title" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
-                                       "body" => array("type" => "mediumtext", "not null" => "1"),
+                                       "body" => array("type" => "mediumtext"),
                                        "seen" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
                                        "reply" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
                                        "replied" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
                                        "ssltype" => array("type" => "varchar(16)", "not null" => "1", "default" => ""),
                                        "mailbox" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "user" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
-                                       "pass" => array("type" => "text", "not null" => "1"),
+                                       "pass" => array("type" => "text"),
                                        "reply_to" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "action" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
                                        "movetofolder" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "url" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "photo" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "date" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
-                                       "msg" => array("type" => "mediumtext", "not null" => "1"),
+                                       "msg" => array("type" => "mediumtext"),
                                        "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
                                        "link" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "iid" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
                                        "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" => ""),
+                                       "name_cache" => array("type" => "tinytext"),
+                                       "msg_cache" => array("type" => "mediumtext")
                                        ),
                        "indexes" => array(
                                        "PRIMARY" => array("id"),
        $database["oembed"] = array(
                        "fields" => array(
                                        "url" => array("type" => "varchar(255)", "not null" => "1", "primary" => "1"),
-                                       "content" => array("type" => "text", "not null" => "1"),
+                                       "content" => array("type" => "text"),
                                        "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
                                        ),
                        "indexes" => array(
-                                       "PRIMARY" => array("url"),
+                                       "PRIMARY" => array("url".db_index_suffix($charset)),
                                        "created" => array("created"),
                                        )
                        );
                                        "url" => array("type" => "varchar(255)", "not null" => "1", "primary" => "1"),
                                        "guessing" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0", "primary" => "1"),
                                        "oembed" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0", "primary" => "1"),
-                                       "content" => array("type" => "text", "not null" => "1"),
+                                       "content" => array("type" => "text"),
                                        "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
                                        ),
                        "indexes" => array(
-                                       "PRIMARY" => array("url", "guessing", "oembed"),
+                                       "PRIMARY" => array("url".db_index_suffix($charset), "guessing", "oembed"),
                                        "created" => array("created"),
                                        )
                        );
                                        "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
                                        "cat" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "k" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
-                                       "v" => array("type" => "mediumtext", "not null" => "1"),
+                                       "v" => array("type" => "mediumtext"),
                                        ),
                        "indexes" => array(
                                        "PRIMARY" => array("id"),
-                                       "uid_cat_k" => array("uid","cat(30)","k(30)"),
+                                       "uid_cat_k" => array("UNIQUE", "uid","cat(30)","k(30)"),
                                        )
                        );
        $database["photo"] = array(
                                        "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
                                        "edited" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
                                        "title" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
-                                       "desc" => array("type" => "text", "not null" => "1"),
+                                       "desc" => array("type" => "text"),
                                        "album" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "filename" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "type" => array("type" => "varchar(128)", "not null" => "1", "default" => "image/jpeg"),
                                        "data" => array("type" => "mediumblob", "not null" => "1"),
                                        "scale" => array("type" => "tinyint(3)", "not null" => "1", "default" => "0"),
                                        "profile" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
-                                       "allow_cid" => array("type" => "mediumtext", "not null" => "1"),
-                                       "allow_gid" => array("type" => "mediumtext", "not null" => "1"),
-                                       "deny_cid" => array("type" => "mediumtext", "not null" => "1"),
-                                       "deny_gid" => array("type" => "mediumtext", "not null" => "1"),
+                                       "allow_cid" => array("type" => "mediumtext"),
+                                       "allow_gid" => array("type" => "mediumtext"),
+                                       "deny_cid" => array("type" => "mediumtext"),
+                                       "deny_gid" => array("type" => "mediumtext"),
                                        ),
                        "indexes" => array(
                                        "PRIMARY" => array("id"),
-                                       "uid" => array("uid"),
+                                       "uid_contactid" => array("uid", "contact-id"),
+                                       "uid_profile" => array("uid", "profile"),
+                                       "uid_album_created" => array("uid", "album", "created"),
                                        "resource-id" => array("resource-id"),
                                        "guid" => array("guid"),
                                        )
                        "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"),
-                                       "q0" => array("type" => "mediumtext", "not null" => "1"),
-                                       "q1" => array("type" => "mediumtext", "not null" => "1"),
-                                       "q2" => array("type" => "mediumtext", "not null" => "1"),
-                                       "q3" => array("type" => "mediumtext", "not null" => "1"),
-                                       "q4" => array("type" => "mediumtext", "not null" => "1"),
-                                       "q5" => array("type" => "mediumtext", "not null" => "1"),
-                                       "q6" => array("type" => "mediumtext", "not null" => "1"),
-                                       "q7" => array("type" => "mediumtext", "not null" => "1"),
-                                       "q8" => array("type" => "mediumtext", "not null" => "1"),
-                                       "q9" => array("type" => "mediumtext", "not null" => "1"),
+                                       "q0" => array("type" => "mediumtext"),
+                                       "q1" => array("type" => "mediumtext"),
+                                       "q2" => array("type" => "mediumtext"),
+                                       "q3" => array("type" => "mediumtext"),
+                                       "q4" => array("type" => "mediumtext"),
+                                       "q5" => array("type" => "mediumtext"),
+                                       "q6" => array("type" => "mediumtext"),
+                                       "q7" => array("type" => "mediumtext"),
+                                       "q8" => array("type" => "mediumtext"),
+                                       "q9" => array("type" => "mediumtext"),
                                        ),
                        "indexes" => array(
                                        "PRIMARY" => array("id"),
                                        "choice" => array("choice"),
                                        )
                        );
+       $database["process"] = array(
+                       "fields" => array(
+                                       "pid" => array("type" => "int(10) unsigned", "not null" => "1", "primary" => "1"),
+                                       "command" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
+                                       "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
+                                       ),
+                       "indexes" => array(
+                                       "PRIMARY" => array("pid"),
+                                       "command" => array("command"),
+                                       )
+                       );
        $database["profile"] = array(
                        "fields" => array(
                                        "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
                                        "hometown" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "gender" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
                                        "marital" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
-                                       "with" => array("type" => "text", "not null" => "1"),
+                                       "with" => array("type" => "text"),
                                        "howlong" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
                                        "sexual" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "politic" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "religion" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
-                                       "pub_keywords" => array("type" => "text", "not null" => "1"),
-                                       "prv_keywords" => array("type" => "text", "not null" => "1"),
-                                       "likes" => array("type" => "text", "not null" => "1"),
-                                       "dislikes" => array("type" => "text", "not null" => "1"),
-                                       "about" => array("type" => "text", "not null" => "1"),
+                                       "pub_keywords" => array("type" => "text"),
+                                       "prv_keywords" => array("type" => "text"),
+                                       "likes" => array("type" => "text"),
+                                       "dislikes" => array("type" => "text"),
+                                       "about" => array("type" => "text"),
                                        "summary" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
-                                       "music" => array("type" => "text", "not null" => "1"),
-                                       "book" => array("type" => "text", "not null" => "1"),
-                                       "tv" => array("type" => "text", "not null" => "1"),
-                                       "film" => array("type" => "text", "not null" => "1"),
-                                       "interest" => array("type" => "text", "not null" => "1"),
-                                       "romance" => array("type" => "text", "not null" => "1"),
-                                       "work" => array("type" => "text", "not null" => "1"),
-                                       "education" => array("type" => "text", "not null" => "1"),
-                                       "contact" => array("type" => "text", "not null" => "1"),
+                                       "music" => array("type" => "text"),
+                                       "book" => array("type" => "text"),
+                                       "tv" => array("type" => "text"),
+                                       "film" => array("type" => "text"),
+                                       "interest" => array("type" => "text"),
+                                       "romance" => array("type" => "text"),
+                                       "work" => array("type" => "text"),
+                                       "education" => array("type" => "text"),
+                                       "contact" => array("type" => "text"),
                                        "homepage" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
+                                       "xmpp" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "photo" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "thumb" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "publish" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
                                        "network" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
                                        "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
                                        "last" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
-                                       "content" => array("type" => "mediumtext", "not null" => "1"),
+                                       "content" => array("type" => "mediumtext"),
                                        "batch" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
                                        ),
                        "indexes" => array(
                        "fields" => array(
                                        "id" => array("type" => "bigint(20) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
                                        "sid" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
-                                       "data" => array("type" => "text", "not null" => "1"),
+                                       "data" => array("type" => "text"),
                                        "expire" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"),
                                        ),
                        "indexes" => 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"),
-                                       "signed_text" => array("type" => "mediumtext", "not null" => "1"),
-                                       "signature" => array("type" => "text", "not null" => "1"),
+                                       "signed_text" => array("type" => "mediumtext"),
+                                       "signature" => array("type" => "text"),
                                        "signer" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        ),
                        "indexes" => array(
                                        "type_term" => array("type","term"),
                                        "uid_otype_type_term_global_created" => array("uid","otype","type","term","global","created"),
                                        "otype_type_term_tid" => array("otype","type","term","tid"),
+                                       "uid_otype_type_url" => array("uid","otype","type","url"),
                                        "guid" => array("guid"),
                                        )
                        );
        $database["tokens"] = array(
                        "fields" => array(
                                        "id" => array("type" => "varchar(40)", "not null" => "1", "primary" => "1"),
-                                       "secret" => array("type" => "text", "not null" => "1"),
+                                       "secret" => array("type" => "text"),
                                        "client_id" => array("type" => "varchar(20)", "not null" => "1", "default" => ""),
                                        "expires" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
                                        "scope" => array("type" => "varchar(200)", "not null" => "1", "default" => ""),
                                        "default-location" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "allow_location" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
                                        "theme" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
-                                       "pubkey" => array("type" => "text", "not null" => "1"),
-                                       "prvkey" => array("type" => "text", "not null" => "1"),
-                                       "spubkey" => array("type" => "text", "not null" => "1"),
-                                       "sprvkey" => array("type" => "text", "not null" => "1"),
+                                       "pubkey" => array("type" => "text"),
+                                       "prvkey" => array("type" => "text"),
+                                       "spubkey" => array("type" => "text"),
+                                       "sprvkey" => array("type" => "text"),
                                        "verified" => array("type" => "tinyint(1) unsigned", "not null" => "1", "default" => "0"),
                                        "blocked" => array("type" => "tinyint(1) unsigned", "not null" => "1", "default" => "0"),
                                        "blockwall" => array("type" => "tinyint(1) unsigned", "not null" => "1", "default" => "0"),
                                        "cntunkmail" => array("type" => "int(11)", "not null" => "1", "default" => "10"),
                                        "notify-flags" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "65535"),
                                        "page-flags" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"),
+                                       "account-type" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"),
                                        "prvnets" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
                                        "pwdreset" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
                                        "maxreq" => array("type" => "int(11)", "not null" => "1", "default" => "10"),
                                        "expire_notification_sent" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
                                        "service_class" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
                                        "def_gid" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
-                                       "allow_cid" => array("type" => "mediumtext", "not null" => "1"),
-                                       "allow_gid" => array("type" => "mediumtext", "not null" => "1"),
-                                       "deny_cid" => array("type" => "mediumtext", "not null" => "1"),
-                                       "deny_gid" => array("type" => "mediumtext", "not null" => "1"),
-                                       "openidserver" => array("type" => "text", "not null" => "1"),
+                                       "allow_cid" => array("type" => "mediumtext"),
+                                       "allow_gid" => array("type" => "mediumtext"),
+                                       "deny_cid" => array("type" => "mediumtext"),
+                                       "deny_gid" => array("type" => "mediumtext"),
+                                       "openidserver" => array("type" => "text"),
                                        ),
                        "indexes" => array(
                                        "PRIMARY" => array("uid"),
        $database["workerqueue"] = array(
                        "fields" => array(
                                        "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
-                                       "parameter" => array("type" => "text", "not null" => "1"),
+                                       "parameter" => array("type" => "text"),
                                        "priority" => array("type" => "tinyint(3) unsigned", "not null" => "1", "default" => "0"),
                                        "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
                                        "pid" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
@@@ -1452,11 -1522,33 +1523,33 @@@ function dbstructure_run(&$argv, &$argc
  
        if ($argc==2) {
                switch ($argv[1]) {
+                       case "dryrun":
+                               update_structure(true, false);
+                               return;
                        case "update":
                                update_structure(true, true);
+                               $build = get_config('system','build');
+                               if (!x($build)) {
+                                       set_config('system','build',DB_UPDATE_VERSION);
+                                       $build = DB_UPDATE_VERSION;
+                               }
+                               $stored = intval($build);
+                               $current = intval(DB_UPDATE_VERSION);
+                               // run any left update_nnnn functions in update.php
+                               for($x = $stored; $x < $current; $x ++) {
+                                       $r = run_update_function($x);
+                                       if (!$r) break;
+                               }
+                               set_config('system','build',DB_UPDATE_VERSION);
                                return;
                        case "dumpsql":
-                               print_structure(db_definition());
+                               // For the dump that is used to create the database.sql we always assume utfmb4
+                               $charset = "utf8mb4";
+                               print_structure(db_definition($charset), $charset);
                                return;
                }
        }
        // print help
        echo $argv[0]." <command>\n";
        echo "\n";
-       echo "commands:\n";
+       echo "Commands:\n";
+       echo "dryrun            show database update schema queries without running them\n";
        echo "update            update database schema\n";
        echo "dumpsql           dump database schema\n";
        return;
diff --combined include/onepoll.php
index 12bae166dc75f400bb3a95167359557f7b3ee137,951b87043e06d8a014f81ad365eb62d8b5abfdc3..4ac5f38bee43e919a9901104f0ae64b7a2020086
@@@ -24,7 -24,6 +24,6 @@@ function onepoll_run(&$argv, &$argc)
                unset($db_host, $db_user, $db_pass, $db_data);
        };
  
        require_once('include/session.php');
        require_once('include/datetime.php');
        require_once('include/items.php');
                                                                        $refs_arr[$x] = "'" . msgid2iri(str_replace(array('<','>',' '),array('','',''),dbesc($refs_arr[$x]))) . "'";
                                                        }
                                                        $qstr = implode(',',$refs_arr);
-                                                       $r = q("SELECT `uri` , `parent-uri` FROM `item` WHERE `uri` IN ( $qstr ) AND `uid` = %d LIMIT 1",
+                                                       $r = q("SELECT `uri` , `parent-uri` FROM `item` USE INDEX (`uid_uri`) WHERE `uri` IN ($qstr) AND `uid` = %d LIMIT 1",
                                                                intval($importer_uid)
                                                        );
                                                        if(count($r))
  
                                                // If it seems to be a reply but a header couldn't be found take the last message with matching subject
                                                if(!x($datarray,'parent-uri') and $reply) {
 -                                                      $r = q("SELECT `uri` , `parent-uri` FROM `item` WHERE `title` = \"%s\" AND `uid` = %d ORDER BY `created` DESC LIMIT 1",
 +                                                      $r = q("SELECT `uri` , `parent-uri` FROM `item` WHERE `title` = \"%s\" AND `uid` = %d AND `network` = '%s' ORDER BY `created` DESC LIMIT 1",
                                                                dbesc(protect_sprintf($datarray['title'])),
 -                                                              intval($importer_uid));
 +                                                              intval($importer_uid),
 +                                                              dbesc(NETWORK_MAIL));
                                                        if(count($r))
                                                                $datarray['parent-uri'] = $r[0]['parent-uri'];
                                                }
diff --combined mod/contacts.php
index f6551c8a7567a8be450e1db3909af3d1874af9f2,23907669a6a91994f389da881a9afdec73ee7237..1c1c21638d4e2225254debf94d02874ad6845a3f
@@@ -38,7 -38,7 +38,7 @@@ function contacts_init(&$a) 
  
                        if (($a->data['contact']['network'] != "") AND ($a->data['contact']['network'] != NETWORK_DFRN)) {
                                $networkname = format_network_name($a->data['contact']['network'],$a->data['contact']['url']);
-                       } else 
+                       } else
                                $networkname = '';
  
                        $vcard_widget = replace_macros(get_markup_template("vcard-widget.tpl"),array(
@@@ -48,7 -48,7 +48,7 @@@
                                '$addr' => (($a->data['contact']['addr'] != "") ? ($a->data['contact']['addr']) : ""),
                                '$network_name' => $networkname,
                                '$network' => t('Network:'),
-                               'account_type' => (($a->data['contact']['forum'] || $a->data['contact']['prv']) ? t('Forum') : '')
+                               '$account_type' => account_type($a->data['contact'])
                        ));
                        $finpeople_widget = '';
                        $follow_widget = '';
@@@ -237,7 -237,7 +237,7 @@@ function _contact_update($contact_id) 
                                intval($contact_id));
        } else
                // pull feed and consume it, which should subscribe to the hub.
-               proc_run('php',"include/onepoll.php","$contact_id", "force");
+               proc_run(PRIORITY_HIGH, "include/onepoll.php", $contact_id, "force");
  }
  
  function _contact_update_profile($contact_id) {
@@@ -623,9 -623,11 +623,11 @@@ function contacts_content(&$a) 
                        '$url' => $url,
                        '$profileurllabel' => t('Profile URL'),
                        '$profileurl' => $contact['url'],
-                       'account_type' => (($contact['forum'] || $contact['prv']) ? t('Forum') : ''),
+                       '$account_type' => account_type($contact),
                        '$location' => bbcode($contact["location"]),
                        '$location_label' => t("Location:"),
+                       '$xmpp' => bbcode($contact["xmpp"]),
+                       '$xmpp_label' => t("XMPP:"),
                        '$about' => bbcode($contact["about"], false, false),
                        '$about_label' => t("About:"),
                        '$keywords' => $contact["keywords"],
@@@ -892,15 -894,22 +894,13 @@@ function contact_posts($a, $contact_id
  
        $o .= $tab_str;
  
 -      $r = q("SELECT `id` FROM `item` WHERE `contact-id` = %d LIMIT 1", intval($contact_id));
 -      if ($r)
 -              $o .= posts_from_contact($a, $contact_id);
 -      elseif ($contact["url"]) {
 -              $r = q("SELECT `id` FROM `gcontact` WHERE `nurl` = '%s' LIMIT 1",
 -                      dbesc(normalise_link($contact["url"])));
 -
 -              if ($r[0]["id"] <> 0)
 -                      $o .= posts_from_gcontact($a, $r[0]["id"]);
 -      }
 +      $o .= posts_from_contact_url($a, $contact["url"]);
  
        return $o;
  }
  
  function _contact_detail_for_template($rr){
  
-       $community = '';
        switch($rr['rel']) {
                case CONTACT_IS_FRIEND:
                        $dir_icon = 'images/lrarrow.gif';
                $sparkle = '';
        }
  
-       //test if contact is a forum page
-       if (isset($rr['forum']) OR isset($rr['prv']))
-                               $community = ($rr['forum'] OR $rr['prv']);
        return array(
                'img_hover' => sprintf( t('Visit %s\'s profile [%s]'),$rr['name'],$rr['url']),
                'edit_hover' => t('Edit contact'),
                'thumb' => proxy_url($rr['thumb'], false, PROXY_SIZE_THUMB),
                'name' => htmlentities($rr['name']),
                'username' => htmlentities($rr['name']),
-               'account_type' => ($community ? t('Forum') : ''),
+               'account_type' => account_type($rr),
                'sparkle' => $sparkle,
                'itemurl' => (($rr['addr'] != "") ? $rr['addr'] : $rr['url']),
                'url' => $url,
diff --combined mod/network.php
index f62799f768ba883578b37dc53f6004d9b2243d95,559bad0a3e332208c6795898135007f7674ced82..1b7574d1097c99211be99399b14940dc615f2806
@@@ -122,7 -122,7 +122,7 @@@ function network_init(&$a) 
        $search = ((x($_GET,'search')) ? escape_tags($_GET['search']) : '');
  
        if(x($_GET,'save')) {
-               $r = q("SELECT * FROM `search` WHERE `uid` = %d AND `term` = '%s' LIMIT 1",
+               $r = qu("SELECT * FROM `search` WHERE `uid` = %d AND `term` = '%s' LIMIT 1",
                        intval(local_user()),
                        dbesc($search)
                );
@@@ -176,7 -176,7 +176,7 @@@ function saved_searches($search) 
  
        $o = '';
  
-       $r = q("SELECT `id`,`term` FROM `search` WHERE `uid` = %d",
+       $r = qu("SELECT `id`,`term` FROM `search` WHERE `uid` = %d",
                intval(local_user())
        );
  
@@@ -375,7 -375,7 +375,7 @@@ function network_content(&$a, $update 
                $def_acl = array('allow_cid' => '<' . intval($cid) . '>');
  
        if($nets) {
-               $r = q("SELECT `id` FROM `contact` WHERE `uid` = %d AND network = '%s' AND `self` = 0",
+               $r = qu("SELECT `id` FROM `contact` WHERE `uid` = %d AND network = '%s' AND `self` = 0",
                        intval(local_user()),
                        dbesc($nets)
                );
  
                if ($cid) {
                        // If $cid belongs to a communitity forum or a privat goup,.add a mention to the status editor
-                       $contact = q("SELECT `nick` FROM `contact` WHERE `id` = %d AND `uid` = %d AND (`forum` OR `prv`) ",
+                       $contact = qu("SELECT `nick` FROM `contact` WHERE `id` = %d AND `uid` = %d AND (`forum` OR `prv`) ",
                                intval($cid),
                                intval(local_user())
                        );
        $sql_nets = (($nets) ? sprintf(" and $sql_table.`network` = '%s' ", dbesc($nets)) : '');
  
        if($group) {
-               $r = q("SELECT `name`, `id` FROM `group` WHERE `id` = %d AND `uid` = %d LIMIT 1",
+               $r = qu("SELECT `name`, `id` FROM `group` WHERE `id` = %d AND `uid` = %d LIMIT 1",
                        intval($group),
                        intval($_SESSION['uid'])
                );
  
                        $contact_str = implode(',',$contacts);
                        $gcontact_str = implode(',',$gcontacts);
-                       $self = q("SELECT `contact`.`id`, `gcontact`.`id` AS `gid` FROM `contact`
+                       $self = qu("SELECT `contact`.`id`, `gcontact`.`id` AS `gid` FROM `contact`
                                        INNER JOIN `gcontact` ON `gcontact`.`nurl` = `contact`.`nurl`
                                        WHERE `uid` = %d AND `self`", intval($_SESSION['uid']));
                        if (count($self)) {
        }
        elseif($cid) {
  
-               $r = q("SELECT `id`,`name`,`network`,`writable`,`nurl`, `forum`, `prv`, `addr`, `thumb`, `location` FROM `contact` WHERE `id` = %d
+               $r = qu("SELECT `id`,`name`,`network`,`writable`,`nurl`, `forum`, `prv`, `contact-type`, `addr`, `thumb`, `location` FROM `contact` WHERE `id` = %d
                                AND `blocked` = 0 AND `pending` = 0 LIMIT 1",
                        intval($cid)
                );
                                'name' => htmlentities($r[0]['name']),
                                'itemurl' => (($r[0]['addr']) ? ($r[0]['addr']) : ($r[0]['nurl'])),
                                'thumb' => proxy_url($r[0]['thumb'], false, PROXY_SIZE_THUMB),
-                               'account_type' => (($r[0]['forum']) || ($r[0]['prv']) ? t('Forum') : ''),
                                'details' => $r[0]['location'],
                        );
  
+                       $entries[0]["account_type"] = account_type($r[0]);
                        $o = replace_macros(get_markup_template("viewcontact_template.tpl"),array(
                                'contacts' => $entries,
                                'id' => 'network',
                                $sql_extra = sprintf(" AND MATCH (`item`.`body`, `item`.`title`) AGAINST ('%s' in boolean mode) ", dbesc(protect_sprintf($search)));
                        else
                                $sql_extra = sprintf(" AND `item`.`body` REGEXP '%s' ", dbesc(protect_sprintf(preg_quote($search))));
 -                      $sql_order = "`item`.`received`";
 -                      $order_mode = "received";
 +                      $sql_order = "`item`.`id`";
 +                      $order_mode = "id";
                }
        }
        if(strlen($file)) {
                // only setup pagination on initial page view
                $pager_sql = '';
  
 -      }
 -      else {
 +      } else {
                if(get_config('system', 'old_pager')) {
-                       $r = q("SELECT COUNT(*) AS `total`
+                       $r = qu("SELECT COUNT(*) AS `total`
                                FROM $sql_table $sql_post_table INNER JOIN `contact` ON `contact`.`id` = $sql_table.`contact-id`
                                AND NOT `contact`.`blocked` AND NOT `contact`.`pending`
                                WHERE $sql_table.`uid` = %d AND $sql_table.`visible` AND NOT $sql_table.`deleted`
                $simple_update = (($update) ? " AND `item`.`unseen` " : '');
  
                if ($sql_order == "")
 -                      $sql_order = "`item`.`received`";
 +                      $sql_order = "`item`.`id`";
  
                // "New Item View" - show all items unthreaded in reverse created date order
-               $items = q("SELECT %s FROM $sql_table $sql_post_table %s
+               $items = qu("SELECT %s FROM $sql_table $sql_post_table %s
                        WHERE %s AND `item`.`uid` = %d
                        $simple_update
                        $sql_extra $sql_nets
                        else
                                $sql_extra4 = "";
  
-                       $r = q("SELECT `item`.`parent` AS `item_id`, `item`.`network` AS `item_network`, `contact`.`uid` AS `contact_uid`
+                       $r = qu("SELECT `item`.`parent` AS `item_id`, `item`.`network` AS `item_network`, `contact`.`uid` AS `contact_uid`
                                FROM $sql_table $sql_post_table INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
                                AND NOT `contact`.`blocked` AND NOT `contact`.`pending`
                                WHERE `item`.`uid` = %d AND `item`.`visible` AND NOT `item`.`deleted` $sql_extra4
                                intval(local_user())
                        );
                } else {
-                       $r = q("SELECT `thread`.`iid` AS `item_id`, `thread`.`network` AS `item_network`, `contact`.`uid` AS `contact_uid`
+                       $r = qu("SELECT `thread`.`iid` AS `item_id`, `thread`.`network` AS `item_network`, `contact`.`uid` AS `contact_uid`
                                FROM $sql_table $sql_post_table STRAIGHT_JOIN `contact` ON `contact`.`id` = `thread`.`contact-id`
                                AND NOT `contact`.`blocked` AND NOT `contact`.`pending`
                                WHERE `thread`.`uid` = %d AND `thread`.`visible` AND NOT `thread`.`deleted`
                        $items = array();
  
                        foreach ($parents_arr AS $parents) {
-                               $thread_items = q(item_query()." AND `item`.`uid` = %d
+                               $thread_items = qu(item_query()." AND `item`.`uid` = %d
                                        AND `item`.`parent` = %d
                                        ORDER BY `item`.`commented` DESC LIMIT %d",
                                        intval(local_user()),
diff --combined mod/nodeinfo.php
index b90e05174e402a6b1e2ae52a1702d3f8a748333e,40094ee6e3a24047c572d479af1624a97adcd9ac..334dcb055d6c3868c43016e6c864d60ef3ce2222
@@@ -174,7 -174,7 +174,7 @@@ function nodeinfo_cron() 
                return;
  
        $last = get_config('nodeinfo','last_calucation');
 -
 +/*
        if($last) {
                // Calculate every 24 hours
                $next = $last + (24 * 60 * 60);
                        return;
                }
        }
 -        logger("cron_start");
 +*/        logger("cron_start");
  
-       $users = q("SELECT profile.*, `user`.`login_date`, `lastitem`.`lastitem_date`
-                       FROM (SELECT MAX(`item`.`changed`) as `lastitem_date`, `item`.`uid`
-                               FROM `item`
-                                       WHERE `item`.`type` = 'wall'
-                                               GROUP BY `item`.`uid`) AS `lastitem`
-                                               RIGHT OUTER JOIN `user` ON `user`.`uid` = `lastitem`.`uid`, `contact`, `profile`
-                                 WHERE
-                                       `user`.`uid` = `contact`.`uid` AND `profile`.`uid` = `user`.`uid`
-                                       AND `profile`.`is-default` AND (`profile`.`publish` OR `profile`.`net-publish`)
-                                       AND `user`.`verified` AND `contact`.`self`
-                                       AND NOT `user`.`blocked`
-                                       AND NOT `user`.`account_removed`
-                                       AND NOT `user`.`account_expired`");
+       $users = qu("SELECT `user`.`uid`, `user`.`login_date`, `contact`.`last-item`
+                       FROM `user`
+                       INNER JOIN `profile` ON `profile`.`uid` = `user`.`uid` AND `profile`.`is-default`
+                       INNER JOIN `contact` ON `contact`.`uid` = `user`.`uid` AND `contact`.`self`
+                       WHERE (`profile`.`publish` OR `profile`.`net-publish`) AND `user`.`verified`
+                               AND NOT `user`.`blocked` AND NOT `user`.`account_removed`
+                               AND NOT `user`.`account_expired`");
        if (is_array($users)) {
                        $total_users = count($users);
                        $active_users_halfyear = 0;
  
                        foreach ($users AS $user) {
                                if ((strtotime($user['login_date']) > $halfyear) OR
-                                       (strtotime($user['lastitem_date']) > $halfyear))
+                                       (strtotime($user['last-item']) > $halfyear))
                                        ++$active_users_halfyear;
  
                                if ((strtotime($user['login_date']) > $month) OR
-                                       (strtotime($user['lastitem_date']) > $month))
+                                       (strtotime($user['last-item']) > $month))
                                        ++$active_users_monthly;
  
                        }
                        set_config('nodeinfo','active_users_monthly', $active_users_monthly);
        }
  
- //    $posts = q("SELECT COUNT(*) AS `local_posts` FROM `thread`
- //                    INNER JOIN `contact` ON `contact`.`id` = `thread`.`contact-id` AND `contact`.`uid` = `thread`.`uid`
- //                    WHERE `contact`.`self`");
-       $posts = q("SELECT COUNT(*) AS local_posts FROM `thread` WHERE `thread`.`wall`");
- /*
-       $posts = q("SELECT COUNT(*) AS local_posts FROM `thread`
-                       INNER JOIN `item` ON `item`.`id` = `thread`.`iid`
-                       WHERE `thread`.`wall` AND NOT `thread`.`private` AND
-                       `thread`.`uid` != 0 AND LEFT(`item`.`body`, 6) != '[share' AND
-                       `thread`.`network` IN ('%s', '%s', '%s')",
-                       dbesc(NETWORK_OSTATUS), dbesc(NETWORK_DIASPORA), dbesc(NETWORK_DFRN));
- */
++      $posts = qu("SELECT COUNT(*) AS local_posts FROM `thread` WHERE `thread`.`wall`");
 +/*
-       $posts = q("SELECT COUNT(*) AS `local_posts` FROM `item`
+       $posts = qu("SELECT COUNT(*) AS `local_posts` FROM `item`
                        INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
                        WHERE `contact`.`self` and `item`.`id` = `item`.`parent` AND left(body, 6) != '[share' AND `item`.`network` IN ('%s', '%s', '%s')",
                        dbesc(NETWORK_OSTATUS), dbesc(NETWORK_DIASPORA), dbesc(NETWORK_DFRN));
 -
 +*/
        if (!is_array($posts))
                $local_posts = -1;
        else
  
          logger("local_posts: ".$local_posts, LOGGER_DEBUG);
  
-       $posts = q("SELECT COUNT(*) AS `local_comments` FROM `item`
+       $posts = qu("SELECT COUNT(*) AS `local_comments` FROM `item`
                        INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
                        WHERE `contact`.`self` and `item`.`id` != `item`.`parent` AND `item`.`network` IN ('%s', '%s', '%s')",
                        dbesc(NETWORK_OSTATUS), dbesc(NETWORK_DIASPORA), dbesc(NETWORK_DFRN));