5 use wcf\system\database\exception\DatabaseQueryExecutionException
;
6 use wcf\system\database\util\PreparedStatementConditionBuilder
;
10 * Basic implementation for object editors following the decorator pattern.
13 * @copyright 2001-2019 WoltLab GmbH
14 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
15 * @package WoltLabSuite\Core\Data
17 abstract class DatabaseObjectEditor
extends DatabaseObjectDecorator
implements IEditableObject
22 public static function create(array $parameters = [])
25 $statementParameters = [];
26 foreach ($parameters as $key => $value) {
34 $statementParameters[] = $value;
38 $sql = "INSERT INTO " . static::getDatabaseTableName() . "
40 VALUES (" . $values . ")";
41 $statement = WCF
::getDB()->prepareStatement($sql);
42 $statement->execute($statementParameters);
45 if (static::getDatabaseTableIndexIsIdentity()) {
46 $id = WCF
::getDB()->getInsertID(static::getDatabaseTableName(), static::getDatabaseTableIndexName());
48 $id = $parameters[static::getDatabaseTableIndexName()];
51 return new static::$baseClass($id);
57 public function update(array $parameters = [])
59 if (empty($parameters)) {
64 $statementParameters = [];
65 foreach ($parameters as $key => $value) {
66 if (!empty($updateSQL)) {
69 $updateSQL .= $key . ' = ?';
70 $statementParameters[] = $value;
72 $statementParameters[] = $this->getObjectID();
74 $sql = "UPDATE " . static::getDatabaseTableName() . "
75 SET " . $updateSQL . "
76 WHERE " . static::getDatabaseTableIndexName() . " = ?";
77 $statement = WCF
::getDB()->prepareStatement($sql);
78 $statement->execute($statementParameters);
84 public function updateCounters(array $counters = [])
86 if (empty($counters)) {
91 $statementParameters = [];
92 foreach ($counters as $key => $value) {
93 if (!empty($updateSQL)) {
96 $updateSQL .= $key . ' = ' . $key . ' + ?';
97 $statementParameters[] = $value;
99 $statementParameters[] = $this->getObjectID();
101 $sql = "UPDATE " . static::getDatabaseTableName() . "
102 SET " . $updateSQL . "
103 WHERE " . static::getDatabaseTableIndexName() . " = ?";
104 $statement = WCF
::getDB()->prepareStatement($sql);
105 $statement->execute($statementParameters);
111 public function delete()
113 static::deleteAll([$this->getObjectID()]);
119 public static function deleteAll(array $objectIDs = [])
123 $itemsPerLoop = 1000;
124 $loopCount = \
ceil(\
count($objectIDs) / $itemsPerLoop);
126 WCF
::getDB()->beginTransaction();
127 for ($i = 0; $i < $loopCount; $i++
) {
128 $batchObjectIDs = \array_slice
($objectIDs, $i * $itemsPerLoop, $itemsPerLoop);
130 $conditionBuilder = new PreparedStatementConditionBuilder();
131 $conditionBuilder->add(static::getDatabaseTableIndexName() . ' IN (?)', [$batchObjectIDs]);
133 $sql = "DELETE FROM " . static::getDatabaseTableName() . "
134 " . $conditionBuilder;
135 $statement = WCF
::getDB()->prepareStatement($sql);
136 $statement->execute($conditionBuilder->getParameters());
137 $affectedCount +
= $statement->getAffectedRows();
139 WCF
::getDB()->commitTransaction();
141 return $affectedCount;
145 * Creates a new object, returns null if the row already exists.
147 * @param array $parameters
148 * @return IStorableObject|null
151 public static function createOrIgnore(array $parameters = [])
154 return static::create($parameters);
155 } catch (DatabaseQueryExecutionException
$e) {
156 // Error code 23000 = duplicate key
157 if ($e->getCode() == '23000' && $e->getDriverCode() == '1062') {