Merge pull request #3408 from annando/1704-conversation-2
Conversation data is stored for own posts as well/improved function dba:update
This commit is contained in:
commit
9ff4fed7d2
6 changed files with 163 additions and 48 deletions
|
@ -14,6 +14,7 @@ Database Tables
|
|||
| [config](help/database/db_config) | main configuration storage |
|
||||
| [contact](help/database/db_contact) | contact table |
|
||||
| [conv](help/database/db_conv) | private messages |
|
||||
| [conversation](help/database/db_conversation) | Raw data and structure information for messages |
|
||||
| [event](help/database/db_event) | Events |
|
||||
| [fcontact](help/database/db_fcontact) | friend suggestion stuff |
|
||||
| [ffinder](help/database/db_ffinder) | friend suggestion stuff |
|
||||
|
|
14
doc/database/db_conversation.md
Normal file
14
doc/database/db_conversation.md
Normal file
|
@ -0,0 +1,14 @@
|
|||
Table conversation
|
||||
==================
|
||||
|
||||
| Field | Description | Type | Null | Key | Default | Extra |
|
||||
|-------------------| ---------------------------------- |---------------------|------|-----|---------------------|----------------|
|
||||
| item-uri | URI of the item | varbinary(255) | NO | PRI | NULL | |
|
||||
| reply-to-uri | URI to which this item is a reply | varbinary(255) | NO | | | |
|
||||
| conversation-uri | GNU Social conversation URI | varbinary(255) | NO | | | |
|
||||
| conversation-href | GNU Social conversation link | varbinary(255) | NO | | | |
|
||||
| protocol | The protocol of the item | tinyint(1) unsigned | NO | | 0 | |
|
||||
| source | Original source | mediumtext | NO | | | |
|
||||
| received | Receiving date | datetime | NO | | 0001-01-01 | |
|
||||
|
||||
Return to [database documentation](help/database)
|
|
@ -756,15 +756,77 @@ class dba {
|
|||
/**
|
||||
* @brief Updates rows
|
||||
*
|
||||
* Updates rows in the database. When $old_fields is set to an array,
|
||||
* the system will only do an update if the fields in that array changed.
|
||||
*
|
||||
* Attention:
|
||||
* Only the values in $old_fields are compared.
|
||||
* This is an intentional behaviour.
|
||||
*
|
||||
* Example:
|
||||
* We include the timestamp field in $fields but not in $old_fields.
|
||||
* Then the row will only get the new timestamp when the other fields had changed.
|
||||
*
|
||||
* When $old_fields is set to a boolean value the system will do this compare itself.
|
||||
* When $old_fields is set to "true" the system will do an insert if the row doesn't exists.
|
||||
*
|
||||
* Attention:
|
||||
* Only set $old_fields to a boolean value when you are sure that you will update a single row.
|
||||
* When you set $old_fields to "true" then $fields must contain all relevant fields!
|
||||
*
|
||||
* @param string $table Table name
|
||||
* @param array $fields contains the fields that are updated
|
||||
* @param array $condition condition array with the key values
|
||||
* @param array|boolean $old_fields array with the old field values that are about to be replaced
|
||||
*
|
||||
* @return boolean was the update successfull?
|
||||
*/
|
||||
static public function update($table, $fields, $condition) {
|
||||
static public function update($table, $fields, $condition, $old_fields = array()) {
|
||||
|
||||
$sql = "UPDATE `".self::$dbo->escape($table)."` SET `".
|
||||
/** @todo We may use MySQL specific functions here:
|
||||
* INSERT INTO `config` (`cat`, `k`, `v`) VALUES ('%s', '%s', '%s') ON DUPLICATE KEY UPDATE `v` = '%s'"
|
||||
* But I think that it doesn't make sense here.
|
||||
*/
|
||||
|
||||
$table = self::$dbo->escape($table);
|
||||
|
||||
if (is_bool($old_fields)) {
|
||||
$sql = "SELECT * FROM `".$table."` WHERE `".
|
||||
implode("` = ? AND `", array_keys($condition))."` = ? LIMIT 1";
|
||||
|
||||
$params = array();
|
||||
foreach ($condition AS $value) {
|
||||
$params[] = $value;
|
||||
}
|
||||
|
||||
$do_insert = $old_fields;
|
||||
|
||||
$old_fields = self::fetch_first($sql, $params);
|
||||
if (is_bool($old_fields)) {
|
||||
if ($do_insert) {
|
||||
return self::insert($table, $fields);
|
||||
}
|
||||
$old_fields = array();
|
||||
}
|
||||
}
|
||||
|
||||
$do_update = (count($old_fields) == 0);
|
||||
|
||||
foreach ($old_fields AS $fieldname => $content) {
|
||||
if (isset($fields[$fieldname])) {
|
||||
if ($fields[$fieldname] == $content) {
|
||||
unset($fields[$fieldname]);
|
||||
} else {
|
||||
$do_update = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$do_update OR (count($fields) == 0)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$sql = "UPDATE `".$table."` SET `".
|
||||
implode("` = ?, `", array_keys($fields))."` = ? WHERE `".
|
||||
implode("` = ? AND `", array_keys($condition))."` = ?";
|
||||
|
||||
|
|
|
@ -410,7 +410,70 @@ function uri_to_guid($uri, $host = "") {
|
|||
return $guid_prefix.$host_hash;
|
||||
}
|
||||
|
||||
/// @TODO Maybe $arr must be called-by-reference? This function modifies it
|
||||
/**
|
||||
* @brief Store the conversation data
|
||||
*
|
||||
* @param array $arr Item array with conversation data
|
||||
* @return array Item array with removed conversation data
|
||||
*/
|
||||
function store_conversation($arr) {
|
||||
if (in_array($arr['network'], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS))) {
|
||||
$conversation = array('item-uri' => $arr['uri'], 'received' => dbm::date());
|
||||
|
||||
if (isset($arr['parent-uri']) AND ($arr['parent-uri'] != $arr['uri'])) {
|
||||
$conversation['reply-to-uri'] = $arr['parent-uri'];
|
||||
}
|
||||
if (isset($arr['thr-parent']) AND ($arr['thr-parent'] != $arr['uri'])) {
|
||||
$conversation['reply-to-uri'] = $arr['thr-parent'];
|
||||
}
|
||||
|
||||
if (isset($arr['conversation-uri'])) {
|
||||
$conversation['conversation-uri'] = $arr['conversation-uri'];
|
||||
}
|
||||
|
||||
if (isset($arr['conversation-href'])) {
|
||||
$conversation['conversation-href'] = $arr['conversation-href'];
|
||||
}
|
||||
|
||||
if (isset($arr['protocol'])) {
|
||||
$conversation['protocol'] = $arr['protocol'];
|
||||
}
|
||||
|
||||
if (isset($arr['source'])) {
|
||||
$conversation['source'] = $arr['source'];
|
||||
}
|
||||
|
||||
$old_conv = dba::fetch_first("SELECT `item-uri`, `reply-to-uri`, `conversation-uri`, `conversation-href`, `protocol`, `source`
|
||||
FROM `conversation` WHERE `item-uri` = ?", $conversation['item-uri']);
|
||||
if (dbm::is_result($old_conv)) {
|
||||
// Don't update when only the source has changed.
|
||||
// Only do this when there had been no source before.
|
||||
if ($old_conv['source'] != '') {
|
||||
unset($old_conv['source']);
|
||||
}
|
||||
// Update structure data all the time but the source only when its from a better protocol.
|
||||
if (($old_conv['protocol'] < $conversation['protocol']) AND ($old_conv['protocol'] != 0)) {
|
||||
unset($conversation['protocol']);
|
||||
unset($conversation['source']);
|
||||
}
|
||||
if (!dba::update('conversation', $conversation, array('item-uri' => $conversation['item-uri']), $old_conv)) {
|
||||
logger('Conversation: update for '.$conversation['item-uri'].' from '.$conv['protocol'].' to '.$conversation['protocol'].' failed', LOGGER_DEBUG);
|
||||
}
|
||||
} else {
|
||||
if (!dba::insert('conversation', $conversation)) {
|
||||
logger('Conversation: insert for '.$conversation['item-uri'].' (protocol '.$conversation['protocol'].') failed', LOGGER_DEBUG);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unset($arr['conversation-uri']);
|
||||
unset($arr['conversation-href']);
|
||||
unset($arr['protocol']);
|
||||
unset($arr['source']);
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/// @TODO add type-hint array
|
||||
function item_store($arr, $force_parent = false, $notify = false, $dontcache = false) {
|
||||
|
||||
|
@ -423,6 +486,7 @@ function item_store($arr, $force_parent = false, $notify = false, $dontcache = f
|
|||
$arr['origin'] = 1;
|
||||
$arr['last-child'] = 1;
|
||||
$arr['network'] = NETWORK_DFRN;
|
||||
$arr['protocol'] = PROTOCOL_DFRN;
|
||||
|
||||
// We have to avoid duplicates. So we create the GUID in form of a hash of the plink or uri.
|
||||
// In difference to the call to "uri_to_guid" several lines below we add the hash of our own host.
|
||||
|
@ -436,6 +500,9 @@ function item_store($arr, $force_parent = false, $notify = false, $dontcache = f
|
|||
}
|
||||
}
|
||||
|
||||
// Store conversation data
|
||||
$arr = store_conversation($arr);
|
||||
|
||||
/*
|
||||
* If a Diaspora signature structure was passed in, pull it out of the
|
||||
* item array and set it aside for later storage.
|
||||
|
@ -691,51 +758,6 @@ function item_store($arr, $force_parent = false, $notify = false, $dontcache = f
|
|||
|
||||
$arr['thr-parent'] = $arr['parent-uri'];
|
||||
|
||||
if (in_array($arr['network'], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS))) {
|
||||
$conversation = array('item-uri' => $arr['uri'], 'received' => dbm::date());
|
||||
|
||||
if (isset($arr['thr-parent'])) {
|
||||
if ($arr['thr-parent'] != $arr['uri']) {
|
||||
$conversation['reply-to-uri'] = $arr['thr-parent'];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($arr['conversation-uri'])) {
|
||||
$conversation['conversation-uri'] = $arr['conversation-uri'];
|
||||
}
|
||||
|
||||
if (isset($arr['conversation-href'])) {
|
||||
$conversation['conversation-href'] = $arr['conversation-href'];
|
||||
}
|
||||
|
||||
if (isset($arr['protocol'])) {
|
||||
$conversation['protocol'] = $arr['protocol'];
|
||||
}
|
||||
|
||||
if (isset($arr['source'])) {
|
||||
$conversation['source'] = $arr['source'];
|
||||
}
|
||||
|
||||
$conv = dba::fetch_first("SELECT `protocol` FROM `conversation` WHERE `item-uri` = ?", $conversation['item-uri']);
|
||||
if (dbm::is_result($conv)) {
|
||||
// Replace the conversation entry when the new one is better
|
||||
if ((($conv['protocol'] == 0) OR ($conv['protocol'] > $conversation['protocol'])) AND ($conversation['protocol'] > 0)) {
|
||||
if (!dba::update('conversation', $conversation, array('item-uri' => $conversation['item-uri']))) {
|
||||
logger('Conversation: update for '.$conversation['item-uri'].' from '.$conv['protocol'].' to '.$conversation['protocol'].' failed', LOGGER_DEBUG);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!dba::insert('conversation', $conversation)) {
|
||||
logger('Conversation: insert for '.$conversation['item-uri'].' (protocol '.$conversation['protocol'].') failed', LOGGER_DEBUG);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unset($arr['conversation-uri']);
|
||||
unset($arr['conversation-href']);
|
||||
unset($arr['protocol']);
|
||||
unset($arr['source']);
|
||||
|
||||
if ($arr['parent-uri'] === $arr['uri']) {
|
||||
$parent_id = 0;
|
||||
$parent_deleted = 0;
|
||||
|
|
|
@ -916,6 +916,8 @@ class ostatus {
|
|||
($item["verb"] == ACTIVITY_LIKE) OR ($conversation_url == "")) {
|
||||
$item_stored = item_store($item, $all_threads);
|
||||
return $item_stored;
|
||||
} elseif (count($item) > 0) {
|
||||
$item = store_conversation($item);
|
||||
}
|
||||
|
||||
// Get the parent
|
||||
|
|
14
mod/item.php
14
mod/item.php
|
@ -723,6 +723,18 @@ function item_post(App $a) {
|
|||
$datarray['last-child'] = 1;
|
||||
$datarray['visible'] = 1;
|
||||
|
||||
$datarray['protocol'] = PROTOCOL_DFRN;
|
||||
|
||||
$r = dba::fetch_first("SELECT `conversation-uri`, `conversation-href` FROM `conversation` WHERE `item-uri` = ?", $datarray['parent-uri']);
|
||||
if (dbm::is_result($r)) {
|
||||
if ($r['conversation-uri'] != '') {
|
||||
$datarray['conversation-uri'] = $r['conversation-uri'];
|
||||
}
|
||||
if ($r['conversation-href'] != '') {
|
||||
$datarray['conversation-href'] = $r['conversation-href'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($orig_post) {
|
||||
$datarray['edit'] = true;
|
||||
}
|
||||
|
@ -762,6 +774,8 @@ function item_post(App $a) {
|
|||
// Fill the cache field
|
||||
put_item_in_cache($datarray);
|
||||
|
||||
$datarray = store_conversation($datarray);
|
||||
|
||||
if ($orig_post) {
|
||||
$r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `attach` = '%s', `file` = '%s', `rendered-html` = '%s', `rendered-hash` = '%s', `edited` = '%s', `changed` = '%s' WHERE `id` = %d AND `uid` = %d",
|
||||
dbesc($datarray['title']),
|
||||
|
|
Loading…
Reference in a new issue