Mode switch for insert

This commit is contained in:
Michael 2020-11-19 19:34:48 +00:00
parent fa5acb3b21
commit 303aaa00ca
15 changed files with 56 additions and 31 deletions

View file

@ -29,6 +29,7 @@ use Exception;
use Friendica\Core\Cache\Duration; use Friendica\Core\Cache\Duration;
use Friendica\Core\Hook; use Friendica\Core\Hook;
use Friendica\Core\Renderer; use Friendica\Core\Renderer;
use Friendica\Database\Database;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\DI; use Friendica\DI;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
@ -131,7 +132,7 @@ class OEmbed
'maxwidth' => $a->videowidth, 'maxwidth' => $a->videowidth,
'content' => $json_string, 'content' => $json_string,
'created' => DateTimeFormat::utcNow() 'created' => DateTimeFormat::utcNow()
], true); ], Database::INSERT_UPDATE);
$cache_ttl = Duration::DAY; $cache_ttl = Duration::DAY;
} else { } else {
$cache_ttl = Duration::FIVE_MINUTES; $cache_ttl = Duration::FIVE_MINUTES;

View file

@ -290,16 +290,16 @@ class DBA
/** /**
* Insert a row into a table * Insert a row into a table
* *
* @param string|array $table Table name or array [schema => table] * @param string|array $table Table name or array [schema => table]
* @param array $param parameter array * @param array $param parameter array
* @param bool $on_duplicate_update Do an update on a duplicate entry * @param int $duplicate_mode What to do on a duplicated entry
* *
* @return boolean was the insert successful? * @return boolean was the insert successful?
* @throws \Exception * @throws \Exception
*/ */
public static function insert($table, $param, $on_duplicate_update = false) public static function insert($table, array $param, int $duplicate_mode = Database::INSERT_DEFAULT)
{ {
return DI::dba()->insert($table, $param, $on_duplicate_update); return DI::dba()->insert($table, $param, $duplicate_mode);
} }
/** /**

View file

@ -1050,7 +1050,7 @@ class DBStructure
{ {
if (self::existsTable('verb') && !DBA::exists('verb', ['id' => 1])) { if (self::existsTable('verb') && !DBA::exists('verb', ['id' => 1])) {
foreach (Item::ACTIVITIES as $index => $activity) { foreach (Item::ACTIVITIES as $index => $activity) {
DBA::insert('verb', ['id' => $index + 1, 'name' => $activity], true); DBA::insert('verb', ['id' => $index + 1, 'name' => $activity], Database::INSERT_IGNORE);
} }
} }

View file

@ -42,6 +42,10 @@ class Database
const PDO = 'pdo'; const PDO = 'pdo';
const MYSQLI = 'mysqli'; const MYSQLI = 'mysqli';
const INSERT_DEFAULT = 0;
const INSERT_UPDATE = 1;
const INSERT_IGNORE = 2;
protected $connected = false; protected $connected = false;
/** /**
@ -966,14 +970,14 @@ class Database
/** /**
* Insert a row into a table * Insert a row into a table
* *
* @param string|array $table Table name or array [schema => table] * @param string|array $table Table name or array [schema => table]
* @param array $param parameter array * @param array $param parameter array
* @param bool $on_duplicate_update Do an update on a duplicate entry * @param int $duplicate_mode What to do on a duplicated entry
* *
* @return boolean was the insert successful? * @return boolean was the insert successful?
* @throws \Exception * @throws \Exception
*/ */
public function insert($table, array $param, bool $on_duplicate_update = false) public function insert($table, array $param, int $duplicate_mode = self::INSERT_DEFAULT)
{ {
if (empty($table) || empty($param)) { if (empty($table) || empty($param)) {
$this->logger->info('Table and fields have to be set'); $this->logger->info('Table and fields have to be set');
@ -986,9 +990,15 @@ class Database
$values_string = substr(str_repeat("?, ", count($param)), 0, -2); $values_string = substr(str_repeat("?, ", count($param)), 0, -2);
$sql = "INSERT INTO " . $table_string . " (" . $fields_string . ") VALUES (" . $values_string . ")"; $sql = "INSERT ";
if ($on_duplicate_update) { if ($duplicate_mode == self::INSERT_IGNORE) {
$sql .= "IGNORE ";
}
$sql .= "INTO " . $table_string . " (" . $fields_string . ") VALUES (" . $values_string . ")";
if ($duplicate_mode == self::INSERT_UPDATE) {
$fields_string = implode(' = ?, ', array_map([DBA::class, 'quoteIdentifier'], array_keys($param))); $fields_string = implode(' = ?, ', array_map([DBA::class, 'quoteIdentifier'], array_keys($param)));
$sql .= " ON DUPLICATE KEY UPDATE " . $fields_string . " = ?"; $sql .= " ON DUPLICATE KEY UPDATE " . $fields_string . " = ?";
@ -997,7 +1007,12 @@ class Database
$param = array_merge_recursive($values, $values); $param = array_merge_recursive($values, $values);
} }
return $this->e($sql, $param); $result = $this->e($sql, $param);
if (!$result || ($duplicate_mode != self::INSERT_IGNORE)) {
return $result;
}
return $this->affectedRows() != 0;
} }
/** /**

View file

@ -736,7 +736,7 @@ class PostUpdate
while ($delivery = DBA::fetch($deliveries)) { while ($delivery = DBA::fetch($deliveries)) {
$id = $delivery['iid']; $id = $delivery['iid'];
unset($delivery['iid']); unset($delivery['iid']);
DBA::insert('post-delivery-data', $delivery, true); DBA::insert('post-delivery-data', $delivery, Database::INSERT_UPDATE);
++$rows; ++$rows;
} }
DBA::close($deliveries); DBA::close($deliveries);

View file

@ -31,6 +31,7 @@ use Friendica\Core\Renderer;
use Friendica\Core\Session; use Friendica\Core\Session;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\Core\Worker; use Friendica\Core\Worker;
use Friendica\Database\Database;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\DI; use Friendica\DI;
use Friendica\Model\Notify\Type; use Friendica\Model\Notify\Type;
@ -168,13 +169,13 @@ class Contact
* Insert a row into the contact table * Insert a row into the contact table
* Important: You can't use DBA::lastInsertId() after this call since it will be set to 0. * Important: You can't use DBA::lastInsertId() after this call since it will be set to 0.
* *
* @param array $fields field array * @param array $fields field array
* @param bool $on_duplicate_update Do an update on a duplicate entry * @param int $duplicate_mode Do an update on a duplicate entry
* *
* @return boolean was the insert successful? * @return boolean was the insert successful?
* @throws \Exception * @throws \Exception
*/ */
public static function insert(array $fields, bool $on_duplicate_update = false) public static function insert(array $fields, int $duplicate_mode = Database::INSERT_DEFAULT)
{ {
if (!empty($fields['baseurl']) && empty($fields['gsid'])) { if (!empty($fields['baseurl']) && empty($fields['gsid'])) {
$fields['gsid'] = GServer::getID($fields['baseurl'], true); $fields['gsid'] = GServer::getID($fields['baseurl'], true);
@ -184,7 +185,7 @@ class Contact
$fields['created'] = DateTimeFormat::utcNow(); $fields['created'] = DateTimeFormat::utcNow();
} }
$ret = DBA::insert('contact', $fields, $on_duplicate_update); $ret = DBA::insert('contact', $fields, $duplicate_mode);
$contact = DBA::selectFirst('contact', ['nurl', 'uid'], ['id' => DBA::lastInsertId()]); $contact = DBA::selectFirst('contact', ['nurl', 'uid'], ['id' => DBA::lastInsertId()]);
if (!DBA::isResult($contact)) { if (!DBA::isResult($contact)) {
// Shouldn't happen // Shouldn't happen

View file

@ -23,6 +23,7 @@ namespace Friendica\Model;
use Friendica\Core\Logger; use Friendica\Core\Logger;
use Friendica\Core\Protocol; use Friendica\Core\Protocol;
use Friendica\Database\Database;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
@ -124,7 +125,7 @@ class Conversation
Logger::DEBUG); Logger::DEBUG);
} }
} else { } else {
if (!DBA::insert('conversation', $conversation, true)) { if (!DBA::insert('conversation', $conversation, Database::INSERT_UPDATE)) {
Logger::log('Conversation: insert for ' . $conversation['item-uri'] . ' (protocol ' . $conversation['protocol'] . ') failed', Logger::log('Conversation: insert for ' . $conversation['item-uri'] . ' (protocol ' . $conversation['protocol'] . ') failed',
Logger::DEBUG); Logger::DEBUG);
} }

View file

@ -27,6 +27,7 @@ use Friendica\Core\Logger;
use Friendica\Core\Protocol; use Friendica\Core\Protocol;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\Core\Worker; use Friendica\Core\Worker;
use Friendica\Database\Database;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\DI; use Friendica\DI;
use Friendica\Module\Register; use Friendica\Module\Register;
@ -541,7 +542,7 @@ class GServer
} }
foreach ($tags as $tag) { foreach ($tags as $tag) {
DBA::insert('gserver-tag', ['gserver-id' => $gserver['id'], 'tag' => $tag], true); DBA::insert('gserver-tag', ['gserver-id' => $gserver['id'], 'tag' => $tag], Database::INSERT_IGNORE);
} }
} }

View file

@ -21,6 +21,7 @@
namespace Friendica\Model; namespace Friendica\Model;
use Friendica\Database\Database;
use Friendica\Database\DBA; use Friendica\Database\DBA;
class ItemURI class ItemURI
@ -39,7 +40,7 @@ class ItemURI
$uri = substr($fields['uri'], 0, 255); $uri = substr($fields['uri'], 0, 255);
if (!DBA::exists('item-uri', ['uri' => $uri])) { if (!DBA::exists('item-uri', ['uri' => $uri])) {
DBA::insert('item-uri', $fields, true); DBA::insert('item-uri', $fields, Database::INSERT_UPDATE);
} }
$itemuri = DBA::selectFirst('item-uri', ['id', 'guid'], ['uri' => $uri]); $itemuri = DBA::selectFirst('item-uri', ['id', 'guid'], ['uri' => $uri]);

View file

@ -23,6 +23,7 @@ namespace Friendica\Model\Post;
use Friendica\Core\Logger; use Friendica\Core\Logger;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\Database\Database;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\DI; use Friendica\DI;
use Friendica\Util\Images; use Friendica\Util\Images;
@ -72,14 +73,14 @@ class Media
// We are storing as fast as possible to avoid duplicated network requests // We are storing as fast as possible to avoid duplicated network requests
// when fetching additional information for pictures and other content. // when fetching additional information for pictures and other content.
$result = DBA::insert('post-media', $media, true); $result = DBA::insert('post-media', $media, Database::INSERT_UPDATE);
Logger::info('Stored media', ['result' => $result, 'media' => $media, 'callstack' => System::callstack()]); Logger::info('Stored media', ['result' => $result, 'media' => $media, 'callstack' => System::callstack()]);
$stored = $media; $stored = $media;
$media = self::fetchAdditionalData($media); $media = self::fetchAdditionalData($media);
if (array_diff_assoc($media, $stored)) { if (array_diff_assoc($media, $stored)) {
$result = DBA::insert('post-media', $media, true); $result = DBA::insert('post-media', $media, Database::INSERT_UPDATE);
Logger::info('Updated media', ['result' => $result, 'media' => $media]); Logger::info('Updated media', ['result' => $result, 'media' => $media]);
} else { } else {
Logger::info('Nothing to update', ['media' => $media]); Logger::info('Nothing to update', ['media' => $media]);

View file

@ -23,7 +23,7 @@ namespace Friendica\Model\Post;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use \BadMethodCallException; use \BadMethodCallException;
use Friendica\Core\Logger; use Friendica\Database\Database;
use Friendica\Database\DBStructure; use Friendica\Database\DBStructure;
class User class User
@ -58,7 +58,7 @@ class User
$fields['unseen'] = false; $fields['unseen'] = false;
} }
return DBA::insert('post-user', $fields); return DBA::insert('post-user', $fields, Database::INSERT_IGNORE);
} }
/** /**

View file

@ -25,6 +25,7 @@ use Friendica\Content\Text\BBCode;
use Friendica\Core\Cache\Duration; use Friendica\Core\Cache\Duration;
use Friendica\Core\Logger; use Friendica\Core\Logger;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\Database\Database;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\DI; use Friendica\DI;
use Friendica\Util\Strings; use Friendica\Util\Strings;
@ -151,7 +152,7 @@ class Tag
} }
} }
DBA::insert('post-tag', $fields, true); DBA::insert('post-tag', $fields, Database::INSERT_IGNORE);
Logger::info('Stored tag/mention', ['uri-id' => $uriid, 'tag-id' => $tagid, 'contact-id' => $cid, 'name' => $name, 'type' => $type, 'callstack' => System::callstack(8)]); Logger::info('Stored tag/mention', ['uri-id' => $uriid, 'tag-id' => $tagid, 'contact-id' => $cid, 'name' => $name, 'type' => $type, 'callstack' => System::callstack(8)]);
} }
@ -172,7 +173,7 @@ class Tag
return $tag['id']; return $tag['id'];
} }
DBA::insert('tag', $fields, true); DBA::insert('tag', $fields, Database::INSERT_IGNORE);
$tid = DBA::lastInsertId(); $tid = DBA::lastInsertId();
if (!empty($tid)) { if (!empty($tid)) {
return $tid; return $tid;

View file

@ -21,6 +21,7 @@
namespace Friendica\Model; namespace Friendica\Model;
use Friendica\Database\Database;
use Friendica\Database\DBA; use Friendica\Database\DBA;
class Verb class Verb
@ -44,7 +45,7 @@ class Verb
return $verb_record['id']; return $verb_record['id'];
} }
DBA::insert('verb', ['name' => $verb], true); DBA::insert('verb', ['name' => $verb], Database::INSERT_IGNORE);
return DBA::lastInsertId(); return DBA::lastInsertId();
} }

View file

@ -26,6 +26,7 @@ use DOMXPath;
use Friendica\Content\OEmbed; use Friendica\Content\OEmbed;
use Friendica\Core\Hook; use Friendica\Core\Hook;
use Friendica\Core\Logger; use Friendica\Core\Logger;
use Friendica\Database\Database;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\DI; use Friendica\DI;
@ -91,7 +92,7 @@ class ParseUrl
'oembed' => $do_oembed, 'content' => serialize($data), 'oembed' => $do_oembed, 'content' => serialize($data),
'created' => DateTimeFormat::utcNow() 'created' => DateTimeFormat::utcNow()
], ],
true Database::INSERT_UPDATE
); );
return $data; return $data;

View file

@ -44,6 +44,7 @@ use Friendica\Core\Addon;
use Friendica\Core\Logger; use Friendica\Core\Logger;
use Friendica\Core\Update; use Friendica\Core\Update;
use Friendica\Core\Worker; use Friendica\Core\Worker;
use Friendica\Database\Database;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\Database\DBStructure; use Friendica\Database\DBStructure;
use Friendica\DI; use Friendica\DI;
@ -429,7 +430,7 @@ function update_1332()
function update_1347() function update_1347()
{ {
foreach (Item::ACTIVITIES as $index => $activity) { foreach (Item::ACTIVITIES as $index => $activity) {
DBA::insert('verb', ['id' => $index + 1, 'name' => $activity], true); DBA::insert('verb', ['id' => $index + 1, 'name' => $activity], Database::INSERT_IGNORE);
} }
return Update::SUCCESS; return Update::SUCCESS;