/**
  * Bulk load properties for directory children
  *
  * @param Directory $node
  * @param array $requestedProperties requested properties
  *
  * @return void
  */
 private function loadChildrenProperties(Directory $node, $requestedProperties)
 {
     $path = $node->getPath();
     if (isset($this->cache[$path])) {
         // we already loaded them at some point
         return;
     }
     $childNodes = $node->getChildren();
     // pre-fill cache
     foreach ($childNodes as $childNode) {
         $this->cache[$childNode->getPath()] = [];
     }
     $sql = 'SELECT * FROM `*PREFIX*properties` WHERE `userid` = ? AND `propertypath` LIKE ?';
     $sql .= ' AND `propertyname` in (?) ORDER BY `propertypath`, `propertyname`';
     $result = $this->connection->executeQuery($sql, array($this->user, $this->connection->escapeLikeParameter(rtrim($path, '/')) . '/%', $requestedProperties), array(null, null, \Doctrine\DBAL\Connection::PARAM_STR_ARRAY));
     $oldPath = null;
     $props = [];
     while ($row = $result->fetch()) {
         $path = $row['propertypath'];
         if ($oldPath !== $path) {
             // save previously gathered props
             $this->cache[$oldPath] = $props;
             $oldPath = $path;
             // prepare props for next path
             $props = [];
         }
         $props[$row['propertyname']] = $row['propertyvalue'];
     }
     if (!is_null($oldPath)) {
         // save props from last run
         $this->cache[$oldPath] = $props;
     }
     $result->closeCursor();
 }
Beispiel #2
0
 /**
  * Move a file or folder in the cache
  *
  * @param \OC\Files\Cache\Cache $sourceCache
  * @param string $sourcePath
  * @param string $targetPath
  * @throws \OC\DatabaseException
  */
 public function moveFromCache(Cache $sourceCache, $sourcePath, $targetPath)
 {
     // normalize source and target
     $sourcePath = $this->normalize($sourcePath);
     $targetPath = $this->normalize($targetPath);
     $sourceData = $sourceCache->get($sourcePath);
     $sourceId = $sourceData['fileid'];
     $newParentId = $this->getParentId($targetPath);
     list($sourceStorageId, $sourcePath) = $sourceCache->getMoveInfo($sourcePath);
     list($targetStorageId, $targetPath) = $this->getMoveInfo($targetPath);
     // sql for final update
     $moveSql = 'UPDATE `*PREFIX*filecache` SET `storage` =  ?, `path` = ?, `path_hash` = ?, `name` = ?, `parent` =? WHERE `fileid` = ?';
     if ($sourceData['mimetype'] === 'httpd/unix-directory') {
         //find all child entries
         $sql = 'SELECT `path`, `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path` LIKE ?';
         $result = $this->connection->executeQuery($sql, [$sourceStorageId, $this->connection->escapeLikeParameter($sourcePath) . '/%']);
         $childEntries = $result->fetchAll();
         $sourceLength = strlen($sourcePath);
         $this->connection->beginTransaction();
         $query = $this->connection->prepare('UPDATE `*PREFIX*filecache` SET `storage` = ?, `path` = ?, `path_hash` = ? WHERE `fileid` = ?');
         foreach ($childEntries as $child) {
             $newTargetPath = $targetPath . substr($child['path'], $sourceLength);
             $query->execute([$targetStorageId, $newTargetPath, md5($newTargetPath), $child['fileid']]);
         }
         $this->connection->executeQuery($moveSql, [$targetStorageId, $targetPath, md5($targetPath), basename($targetPath), $newParentId, $sourceId]);
         $this->connection->commit();
     } else {
         $this->connection->executeQuery($moveSql, [$targetStorageId, $targetPath, md5($targetPath), basename($targetPath), $newParentId, $sourceId]);
     }
 }
Beispiel #3
0
 /**
  * get the number of all users matching the search string in a group
  * @param string $gid
  * @param string $search
  * @return int|false
  * @throws \OC\DatabaseException
  */
 public function countUsersInGroup($gid, $search = '')
 {
     $parameters = [$gid];
     $searchLike = '';
     if ($search !== '') {
         $parameters[] = '%' . $this->dbConn->escapeLikeParameter($search) . '%';
         $searchLike = ' AND `uid` LIKE ?';
     }
     $stmt = \OC_DB::prepare('SELECT COUNT(`uid`) AS `count` FROM `*PREFIX*group_user` WHERE `gid` = ?' . $searchLike);
     $result = $stmt->execute($parameters);
     $count = $result->fetchOne();
     if ($count !== false) {
         $count = intval($count);
     }
     return $count;
 }
    /**
     * Searches mapped names by the giving string in the name column
     * @param string $search
     * @param string $prefixMatch
     * @param string $postfixMatch
     * @return string[]
     */
    public function getNamesBySearch($search, $prefixMatch = "", $postfixMatch = "")
    {
        $query = $this->dbc->prepare('
			SELECT `owncloud_name`
			FROM `' . $this->getTableName() . '`
			WHERE `owncloud_name` LIKE ?
		');
        $res = $query->execute(array($prefixMatch . $this->dbc->escapeLikeParameter($search) . $postfixMatch));
        $names = array();
        if ($res !== false) {
            while ($row = $query->fetch()) {
                $names[] = $row['owncloud_name'];
            }
        }
        return $names;
    }
Beispiel #5
0
 /**
  * search contact
  *
  * @param int $addressBookId
  * @param string $pattern which should match within the $searchProperties
  * @param array $searchProperties defines the properties within the query pattern should match
  * @return array an array of contacts which are arrays of key-value-pairs
  */
 public function search($addressBookId, $pattern, $searchProperties)
 {
     $query = $this->db->getQueryBuilder();
     $query2 = $this->db->getQueryBuilder();
     $query2->selectDistinct('cp.cardid')->from($this->dbCardsPropertiesTable, 'cp');
     foreach ($searchProperties as $property) {
         $query2->orWhere($query2->expr()->andX($query2->expr()->eq('cp.name', $query->createNamedParameter($property)), $query2->expr()->like('cp.value', $query->createNamedParameter('%' . $this->db->escapeLikeParameter($pattern) . '%'))));
     }
     $query2->andWhere($query2->expr()->eq('cp.addressbookid', $query->createNamedParameter($addressBookId)));
     $query->select('c.carddata')->from($this->dbCardsTable, 'c')->where($query->expr()->in('c.id', $query->createFunction($query2->getSQL())));
     $result = $query->execute();
     $cards = $result->fetchAll();
     $result->closeCursor();
     return array_map(function ($array) {
         return $this->readBlob($array['carddata']);
     }, $cards);
 }
Beispiel #6
0
 /**
  * {@inheritdoc}
  */
 public function getAllTags($visibilityFilter = null, $nameSearchPattern = null)
 {
     $tags = [];
     $query = $this->connection->getQueryBuilder();
     $query->select('*')->from(self::TAG_TABLE);
     if (!is_null($visibilityFilter)) {
         $query->andWhere($query->expr()->eq('visibility', $query->createNamedParameter((int) $visibilityFilter)));
     }
     if (!empty($nameSearchPattern)) {
         $query->andWhere($query->expr()->like('name', $query->expr()->literal('%' . $this->connection->escapeLikeParameter($nameSearchPattern) . '%')));
     }
     $query->addOrderBy('name', 'ASC')->addOrderBy('visibility', 'ASC')->addOrderBy('editable', 'ASC');
     $result = $query->execute();
     while ($row = $result->fetch()) {
         $tags[$row['id']] = $this->createSystemTagFromRow($row);
     }
     $result->closeCursor();
     return $tags;
 }
Beispiel #7
0
 /**
  * For a given filter the extension can specify the sql query conditions including parameters for that query.
  * In case the extension does not know the filter false is to be returned.
  * The query condition and the parameters are to be returned as array with two elements.
  * E.g. return array('`app` = ? and `message` like ?', array('mail', 'ownCloud%'));
  *
  * @param string $filter
  * @return array|false
  */
 public function getQueryForFilter($filter)
 {
     $user = $this->activityManager->getCurrentUserId();
     // Display actions from all files
     if ($filter === self::FILTER_FILES) {
         return ['`app` = ?', [self::APP_FILES]];
     }
     if (!$user) {
         // Remaining filters only work with a user/token
         return false;
     }
     // Display actions from favorites only
     if ($filter === self::FILTER_FAVORITES || in_array($filter, ['all', 'by', 'self']) && $this->userSettingFavoritesOnly($user)) {
         try {
             $favorites = $this->helper->getFavoriteFilePaths($user);
         } catch (\RuntimeException $e) {
             // Too many favorites, can not put them into one query anymore...
             return ['`app` = ?', [self::APP_FILES]];
         }
         /*
          * Display activities only, when they are not `type` create/change
          * or `file` is a favorite or in a favorite folder
          */
         $parameters = $fileQueryList = [];
         $parameters[] = self::APP_FILES;
         $parameters[] = self::APP_FILES;
         $fileQueryList[] = '(`type` <> ? AND `type` <> ?)';
         $parameters[] = self::TYPE_SHARE_CREATED;
         $parameters[] = self::TYPE_SHARE_CHANGED;
         foreach ($favorites['items'] as $favorite) {
             $fileQueryList[] = '`file` = ?';
             $parameters[] = $favorite;
         }
         foreach ($favorites['folders'] as $favorite) {
             $fileQueryList[] = '`file` LIKE ?';
             $parameters[] = $this->connection->escapeLikeParameter($favorite) . '/%';
         }
         return [' CASE ' . 'WHEN `app` <> ? THEN 1 ' . 'WHEN `app` = ? AND (' . implode(' OR ', $fileQueryList) . ') THEN 1 ' . 'ELSE 0 ' . 'END = 1 ', $parameters];
     }
     return false;
 }
Beispiel #8
0
 /**
  * Espace a parameter to be used in a LIKE query
  *
  * @param string $param
  * @return string
  */
 public function escapeLikeParameter($param)
 {
     return $this->connection->escapeLikeParameter($param);
 }
 /**
  * Converts legacy home storage ids in the format
  * "local::/data/dir/path/userid/" to the new format "home::userid"
  */
 public function run(IOutput $out)
 {
     // only run once
     if ($this->config->getAppValue('core', 'repairlegacystoragesdone') === 'yes') {
         return;
     }
     $dataDir = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data/');
     $dataDir = rtrim($dataDir, '/') . '/';
     $dataDirId = 'local::' . $dataDir;
     $count = 0;
     $hasWarnings = false;
     $this->connection->beginTransaction();
     // note: not doing a direct UPDATE with the REPLACE function
     // because regexp search/extract is needed and it is not guaranteed
     // to work on all database types
     $sql = 'SELECT `id`, `numeric_id` FROM `*PREFIX*storages`' . ' WHERE `id` LIKE ?' . ' ORDER BY `id`';
     $result = $this->connection->executeQuery($sql, array($this->connection->escapeLikeParameter($dataDirId) . '%'));
     while ($row = $result->fetch()) {
         $currentId = $row['id'];
         // one entry is the datadir itself
         if ($currentId === $dataDirId) {
             continue;
         }
         try {
             if ($this->fixLegacyStorage($currentId, (int) $row['numeric_id'])) {
                 $count++;
             }
         } catch (RepairException $e) {
             $hasWarnings = true;
             $out->warning('Could not repair legacy storage ' . $currentId . ' automatically.');
         }
     }
     // check for md5 ids, not in the format "prefix::"
     $sql = 'SELECT COUNT(*) AS "c" FROM `*PREFIX*storages`' . ' WHERE `id` NOT LIKE \'%::%\'';
     $result = $this->connection->executeQuery($sql);
     $row = $result->fetch();
     // find at least one to make sure it's worth
     // querying the user list
     if ((int) $row['c'] > 0) {
         $userManager = \OC::$server->getUserManager();
         // use chunks to avoid caching too many users in memory
         $limit = 30;
         $offset = 0;
         do {
             // query the next page of users
             $results = $userManager->search('', $limit, $offset);
             $storageIds = array();
             foreach ($results as $uid => $userObject) {
                 $storageId = $dataDirId . $uid . '/';
                 if (strlen($storageId) <= 64) {
                     // skip short storage ids as they were handled in the previous section
                     continue;
                 }
                 $storageIds[$uid] = $storageId;
             }
             if (count($storageIds) > 0) {
                 // update the storages of these users
                 foreach ($storageIds as $uid => $storageId) {
                     $numericId = Storage::getNumericStorageId($storageId);
                     try {
                         if (!is_null($numericId) && $this->fixLegacyStorage($storageId, (int) $numericId)) {
                             $count++;
                         }
                     } catch (RepairException $e) {
                         $hasWarnings = true;
                         $out->warning('Could not repair legacy storage ' . $storageId . ' automatically.');
                     }
                 }
             }
             $offset += $limit;
         } while (count($results) >= $limit);
     }
     $out->info('Updated ' . $count . ' legacy home storage ids');
     $this->connection->commit();
     if ($hasWarnings) {
         $out->warning('Some legacy storages could not be repaired. Please manually fix them then re-run ./occ maintenance:repair');
     } else {
         // if all were done, no need to redo the repair during next upgrade
         $this->config->setAppValue('core', 'repairlegacystoragesdone', 'yes');
     }
 }