connection->getQueryBuilder(); $query->update($table) ->set('orphan', $query->createNamedParameter($value, IQueryBuilder::PARAM_BOOL)) ; if ($fileIds) { $query->where($query->expr()->in('fileid', $query->createNamedParameter($fileIds, IQueryBuilder::PARAM_INT_ARRAY))); } return $query->executeStatement(); }; $count = $do('memories'); if ($onlyMain) { return $count; } return $count + $do('memories_livephoto'); } /** * Orphan and run an update on all files. * * @param array $fields list of fields to select * @param int $txnSize number of rows to process in a single transaction * @param \Closure(array): void $callback will be passed each row */ public function orphanAndRun(array $fields, int $txnSize, \Closure $callback): void { // Orphan all files. This means if we are interrupted, // it will lead to a re-index of the whole library! $this->orphanAll(true, null, true); while (\count($orphans = $this->getSomeOrphans($txnSize, $fields))) { $this->connection->beginTransaction(); foreach ($orphans as $row) { $callback($row); } // Mark all files as not orphaned. $fileIds = array_map(static fn ($row): int => (int) $row['fileid'], $orphans); $this->orphanAll(false, $fileIds, true); $this->connection->commit(); } } /** * Get a list of orphaned files. * * @param int $count max number of rows to return * @param string[] $fields list of fields to select */ protected function getSomeOrphans(int $count, array $fields): array { $query = $this->connection->getQueryBuilder(); return $query->select(...$fields) ->from('memories') ->where($query->expr()->eq('orphan', $query->expr()->literal(1))) ->setMaxResults($count) ->executeQuery() ->fetchAll() ; } }