Import of language variables is now 5 times faster on MySQL
authorAlexander Ebert <ebert@woltlab.com>
Wed, 15 May 2013 15:37:06 +0000 (17:37 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Wed, 15 May 2013 15:37:06 +0000 (17:37 +0200)
wcfsetup/install/files/lib/data/language/LanguageEditor.class.php

index 204b3d389c7c23dc948bd04d493bf32458b67edb..877ca5cd85e7a9b94d17db2df5792d2d38d0fc88 100644 (file)
@@ -199,7 +199,7 @@ class LanguageEditor extends DatabaseObjectEditor implements IEditableCachedObje
                }
                
                // loop through categories to import items
-               $items = array();
+               $itemData = array();
                foreach ($categories as $category) {
                        $categoryName = $category->getAttribute('name');
                        $categoryID = $usedCategories[$categoryName];
@@ -210,76 +210,30 @@ class LanguageEditor extends DatabaseObjectEditor implements IEditableCachedObje
                                $itemName = $element->getAttribute('name');
                                $itemValue = $element->nodeValue;
                                
-                               $items[$itemName] = array(
-                                       'name' => $itemName,
-                                       'value' => $itemValue,
-                                       'categoryID' => $categoryID
-                               );
+                               $itemData[] = $this->languageID;
+                               $itemData[] = $itemName;
+                               $itemData[] = $itemValue;
+                               $itemData[] = $categoryID;
+                               if ($packageID) $itemData[] = $packageID;
                        }
                }
                
-               if (!empty($items)) {
-                       $existingItems = $statementParameters = array();
-                       
-                       // find existing items
-                       $itemList = new LanguageItemList();
-                       $itemList->getConditionBuilder()->add("language_item.languageItem IN (?)", array(array_keys($items)));
-                       $itemList->getConditionBuilder()->add("language_item.languageID = ?", array($this->languageID));
-                       $itemList->readObjects();
-                       
-                       foreach ($itemList->getObjects() as $languageItem) {
-                               $existingItems[$languageItem->languageItem] = $languageItem;
-                       }
-                       
-                       foreach ($items as $item) {
-                               if (isset($existingItems[$item['name']])) {
-                                       // update existing item
-                                       $itemEditor = new LanguageItemEditor($existingItems[$item['name']]);
-                                       $itemEditor->update(array(
-                                               'languageItemValue' => $item['value'],
-                                               'languageCategoryID' => $item['categoryID'],
-                                               'languageUseCustomValue' => 0,
-                                               'languageItem' => $item['name']
-                                       ));
-                               }
-                               else {
-                                       // store item for later insert
-                                       $statementParameters[] = $item;
-                               }
-                       }
-                       
-                       if (!empty($statementParameters)) {
-                               if ($packageID) {
-                                       $sql = "INSERT INTO     wcf".WCF_N."_language_item
+               if (!empty($itemData)) {
+                       // insert/update a maximum of 50 items per run (prevents issues with max_allowed_packet)
+                       $step = ($packageID) ? 5 : 4;
+                       for ($i = 0, $length = count($itemData); $i < $length; $i += 50 * $step) {
+                               $parameters = array_slice($itemData, $i, 50 * $step);
+                               $repeat = count($parameters) / $step;
+                               
+                               $sql = "INSERT INTO             wcf".WCF_N."_language_item
                                                                (languageID, languageItem, languageItemValue, languageCategoryID, packageID)
-                                               VALUES          (?, ?, ?, ?, ?)";
-                                       $statement = WCF::getDB()->prepareStatement($sql);
-                                       
-                                       foreach ($statementParameters as $item) {
-                                               $statement->execute(array(
-                                                       $this->languageID,
-                                                       $item['name'],
-                                                       $item['value'],
-                                                       $item['categoryID'],
-                                                       $packageID
-                                               ));
-                                       }
-                               }
-                               else {
-                                       $sql = "INSERT INTO     wcf".WCF_N."_language_item
-                                                               (languageID, languageItem, languageItemValue, languageCategoryID)
-                                               VALUES          (?, ?, ?, ?)";
-                                       $statement = WCF::getDB()->prepareStatement($sql);
-                                       
-                                       foreach ($statementParameters as $item) {
-                                               $statement->execute(array(
-                                                       $this->languageID,
-                                                       $item['name'],
-                                                       $item['value'],
-                                                       $item['categoryID']
-                                               ));
-                                       }
-                               }
+                                       VALUES                  ".substr(str_repeat('(?, ?, ?, ?'. ($packageID ? ', ?' : '') .'), ', $repeat), 0, -2)."
+                                       ON DUPLICATE KEY
+                                       UPDATE                  languageItemValue = VALUES(languageItemValue),
+                                                               languageCategoryID = VALUES(languageCategoryID),
+                                                               languageUseCustomValue = 0";
+                               $statement = WCF::getDB()->prepareStatement($sql);
+                               $statement->execute($parameters);
                        }
                }