Changeset View
Changeset View
Standalone View
Standalone View
src/infrastructure/storage/lisk/PhabricatorLiskDAO.php
| Show First 20 Lines • Show All 190 Lines • ▼ Show 20 Lines | protected function getDatabaseName() { | ||||
| return self::getStorageNamespace().'_'.$this->getApplicationName(); | return self::getStorageNamespace().'_'.$this->getApplicationName(); | ||||
| } | } | ||||
| /** | /** | ||||
| * Break a list of escaped SQL statement fragments (e.g., VALUES lists for | * Break a list of escaped SQL statement fragments (e.g., VALUES lists for | ||||
| * INSERT, previously built with @{function:qsprintf}) into chunks which will | * INSERT, previously built with @{function:qsprintf}) into chunks which will | ||||
| * fit under the MySQL 'max_allowed_packet' limit. | * fit under the MySQL 'max_allowed_packet' limit. | ||||
| * | * | ||||
| * Chunks are glued together with `$glue`, by default ", ". | |||||
| * | |||||
| * If a statement is too large to fit within the limit, it is broken into | * If a statement is too large to fit within the limit, it is broken into | ||||
| * its own chunk (but might fail when the query executes). | * its own chunk (but might fail when the query executes). | ||||
| */ | */ | ||||
| public static function chunkSQL( | public static function chunkSQL( | ||||
| array $fragments, | array $fragments, | ||||
| $glue = ', ', | |||||
| $limit = null) { | $limit = null) { | ||||
| if ($limit === null) { | if ($limit === null) { | ||||
| // NOTE: Hard-code this at 1MB for now, minus a 10% safety buffer. | // NOTE: Hard-code this at 1MB for now, minus a 10% safety buffer. | ||||
| // Eventually we could query MySQL or let the user configure it. | // Eventually we could query MySQL or let the user configure it. | ||||
| $limit = (int)((1024 * 1024) * 0.90); | $limit = (int)((1024 * 1024) * 0.90); | ||||
| } | } | ||||
| $result = array(); | $result = array(); | ||||
| $chunk = array(); | $chunk = array(); | ||||
| $len = 0; | $len = 0; | ||||
| $glue_len = strlen($glue); | $glue_len = strlen(', '); | ||||
| foreach ($fragments as $fragment) { | foreach ($fragments as $fragment) { | ||||
| if ($fragment instanceof PhutilQueryString) { | |||||
amckinley: Another place where a `TODO` might be appropriate. | |||||
| $this_len = strlen($fragment->getUnmaskedString()); | |||||
| } else { | |||||
| $this_len = strlen($fragment); | $this_len = strlen($fragment); | ||||
| } | |||||
| if ($chunk) { | if ($chunk) { | ||||
| // Chunks after the first also imply glue. | // Chunks after the first also imply glue. | ||||
| $this_len += $glue_len; | $this_len += $glue_len; | ||||
| } | } | ||||
| if ($len + $this_len <= $limit) { | if ($len + $this_len <= $limit) { | ||||
| $len += $this_len; | $len += $this_len; | ||||
| $chunk[] = $fragment; | $chunk[] = $fragment; | ||||
| } else { | } else { | ||||
| if ($chunk) { | if ($chunk) { | ||||
| $result[] = $chunk; | $result[] = $chunk; | ||||
| } | } | ||||
| $len = strlen($fragment); | $len = ($this_len - $glue_len); | ||||
| $chunk = array($fragment); | $chunk = array($fragment); | ||||
| } | } | ||||
| } | } | ||||
| if ($chunk) { | if ($chunk) { | ||||
| $result[] = $chunk; | $result[] = $chunk; | ||||
| } | } | ||||
| foreach ($result as $key => $fragment_list) { | |||||
| $result[$key] = implode($glue, $fragment_list); | |||||
| } | |||||
amckinleyUnsubmitted Not Done Inline ActionsAnd this is dead code because we're now doing this work inside the %LQ conversion, right? amckinley: And this is dead code because we're now doing this work inside the `%LQ` conversion, right? | |||||
epriestleyAuthorUnsubmitted Done Inline ActionsRight -- %LQ (or some other %L*) now do the joins safely, and implode(...) is "unsafe". (We could make this "safe" and keep the semantics, but we'd have to whitelist acceptable glue, and we only ever use , as glue. I'm guessing third-party code has very few chunkSQL() calls since it's mostly an optimization / migration / workaround-for-low-mysql-packet-size thing.) epriestley: Right -- `%LQ` (or some other `%L*`) now do the joins safely, and `implode(...)` is "unsafe". | |||||
| return $result; | return $result; | ||||
| } | } | ||||
| protected function assertAttached($property) { | protected function assertAttached($property) { | ||||
| if ($property === self::ATTACHABLE) { | if ($property === self::ATTACHABLE) { | ||||
| throw new PhabricatorDataNotAttachedException($this); | throw new PhabricatorDataNotAttachedException($this); | ||||
| } | } | ||||
| return $property; | return $property; | ||||
| ▲ Show 20 Lines • Show All 76 Lines • Show Last 20 Lines | |||||
Another place where a TODO might be appropriate.