Commit | Line | Data |
---|---|---|
11ade432 | 1 | <?php |
a9229942 | 2 | |
11ade432 | 3 | namespace wcf\data; |
a9229942 | 4 | |
00c3252a | 5 | use wcf\system\database\exception\DatabaseQueryExecutionException; |
9d3b749f | 6 | use wcf\system\database\util\PreparedStatementConditionBuilder; |
11ade432 AE |
7 | use wcf\system\WCF; |
8 | ||
9 | /** | |
10 | * Basic implementation for object editors following the decorator pattern. | |
a9229942 TD |
11 | * |
12 | * @author Marcel Werk | |
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 | |
11ade432 | 16 | */ |
a9229942 TD |
17 | abstract class DatabaseObjectEditor extends DatabaseObjectDecorator implements IEditableObject |
18 | { | |
306a31b6 TD |
19 | use TFastCreate { |
20 | TFastCreate::fastCreate as private dboEditorCreateBase; | |
21 | } | |
22 | ||
a9229942 TD |
23 | /** |
24 | * @inheritDoc | |
25 | */ | |
26 | public static function create(array $parameters = []) | |
27 | { | |
306a31b6 | 28 | return new static::$baseClass(static::dboEditorCreateBase($parameters)); |
a9229942 TD |
29 | } |
30 | ||
31 | /** | |
32 | * @inheritDoc | |
33 | */ | |
34 | public function update(array $parameters = []) | |
35 | { | |
36 | if (empty($parameters)) { | |
37 | return; | |
38 | } | |
39 | ||
40 | $updateSQL = ''; | |
41 | $statementParameters = []; | |
42 | foreach ($parameters as $key => $value) { | |
43 | if (!empty($updateSQL)) { | |
44 | $updateSQL .= ', '; | |
45 | } | |
46 | $updateSQL .= $key . ' = ?'; | |
47 | $statementParameters[] = $value; | |
48 | } | |
49 | $statementParameters[] = $this->getObjectID(); | |
50 | ||
51 | $sql = "UPDATE " . static::getDatabaseTableName() . " | |
52 | SET " . $updateSQL . " | |
53 | WHERE " . static::getDatabaseTableIndexName() . " = ?"; | |
54 | $statement = WCF::getDB()->prepareStatement($sql); | |
55 | $statement->execute($statementParameters); | |
56 | } | |
57 | ||
58 | /** | |
59 | * @inheritDoc | |
60 | */ | |
61 | public function updateCounters(array $counters = []) | |
62 | { | |
63 | if (empty($counters)) { | |
64 | return; | |
65 | } | |
66 | ||
67 | $updateSQL = ''; | |
68 | $statementParameters = []; | |
69 | foreach ($counters as $key => $value) { | |
70 | if (!empty($updateSQL)) { | |
71 | $updateSQL .= ', '; | |
72 | } | |
73 | $updateSQL .= $key . ' = ' . $key . ' + ?'; | |
74 | $statementParameters[] = $value; | |
75 | } | |
76 | $statementParameters[] = $this->getObjectID(); | |
77 | ||
78 | $sql = "UPDATE " . static::getDatabaseTableName() . " | |
79 | SET " . $updateSQL . " | |
80 | WHERE " . static::getDatabaseTableIndexName() . " = ?"; | |
81 | $statement = WCF::getDB()->prepareStatement($sql); | |
82 | $statement->execute($statementParameters); | |
83 | } | |
84 | ||
85 | /** | |
86 | * @inheritDoc | |
87 | */ | |
88 | public function delete() | |
89 | { | |
90 | static::deleteAll([$this->getObjectID()]); | |
91 | } | |
92 | ||
93 | /** | |
94 | * @inheritDoc | |
95 | */ | |
96 | public static function deleteAll(array $objectIDs = []) | |
97 | { | |
98 | $affectedCount = 0; | |
99 | ||
100 | $itemsPerLoop = 1000; | |
101 | $loopCount = \ceil(\count($objectIDs) / $itemsPerLoop); | |
102 | ||
103 | WCF::getDB()->beginTransaction(); | |
104 | for ($i = 0; $i < $loopCount; $i++) { | |
105 | $batchObjectIDs = \array_slice($objectIDs, $i * $itemsPerLoop, $itemsPerLoop); | |
106 | ||
107 | $conditionBuilder = new PreparedStatementConditionBuilder(); | |
108 | $conditionBuilder->add(static::getDatabaseTableIndexName() . ' IN (?)', [$batchObjectIDs]); | |
109 | ||
110 | $sql = "DELETE FROM " . static::getDatabaseTableName() . " | |
111 | " . $conditionBuilder; | |
112 | $statement = WCF::getDB()->prepareStatement($sql); | |
113 | $statement->execute($conditionBuilder->getParameters()); | |
114 | $affectedCount += $statement->getAffectedRows(); | |
115 | } | |
116 | WCF::getDB()->commitTransaction(); | |
117 | ||
118 | return $affectedCount; | |
119 | } | |
120 | ||
121 | /** | |
122 | * Creates a new object, returns null if the row already exists. | |
123 | * | |
124 | * @param array $parameters | |
125 | * @return IStorableObject|null | |
126 | * @since 5.3 | |
127 | */ | |
128 | public static function createOrIgnore(array $parameters = []) | |
129 | { | |
130 | try { | |
131 | return static::create($parameters); | |
132 | } catch (DatabaseQueryExecutionException $e) { | |
133 | // Error code 23000 = duplicate key | |
134 | if ($e->getCode() == '23000' && $e->getDriverCode() == '1062') { | |
c0b28aa2 | 135 | return null; |
a9229942 TD |
136 | } |
137 | ||
138 | throw $e; | |
139 | } | |
140 | } | |
11ade432 | 141 | } |