diff options
author | Michael Gapczynski <mtgap@owncloud.com> | 2013-05-23 10:25:12 -0400 |
---|---|---|
committer | Michael Gapczynski <mtgap@owncloud.com> | 2013-05-23 10:25:12 -0400 |
commit | 30330b4343b5bca82b95d9df4a13651c8e91063d (patch) | |
tree | 68979fb843a309e43803935f53afe74fab2844e4 /lib | |
parent | 3b6d850e592bbc6db9d67d25ee700c0730c84376 (diff) | |
parent | 698862519de6b364da6c20a97d8c546204e80f3d (diff) | |
download | nextcloud-server-30330b4343b5bca82b95d9df4a13651c8e91063d.tar.gz nextcloud-server-30330b4343b5bca82b95d9df4a13651c8e91063d.zip |
Merge branch 'master' into move-storages
Conflicts:
tests/lib/files/view.php
Diffstat (limited to 'lib')
-rw-r--r-- | lib/app.php | 12 | ||||
-rw-r--r-- | lib/base.php | 1 | ||||
-rw-r--r-- | lib/db.php | 17 | ||||
-rw-r--r-- | lib/files/cache/cache.php | 32 | ||||
-rw-r--r-- | lib/files/cache/scanner.php | 5 | ||||
-rw-r--r-- | lib/files/cache/watcher.php | 2 | ||||
-rw-r--r-- | lib/files/view.php | 7 | ||||
-rw-r--r-- | lib/hooks/basicemitter.php | 89 | ||||
-rw-r--r-- | lib/hooks/emitter.php | 32 | ||||
-rw-r--r-- | lib/hooks/legacyemitter.php | 16 | ||||
-rw-r--r-- | lib/l10n/nb_NO.php | 2 | ||||
-rw-r--r-- | lib/setup.php | 12 | ||||
-rw-r--r-- | lib/user.php | 8 | ||||
-rw-r--r-- | lib/user/database.php | 2 | ||||
-rwxr-xr-x | lib/util.php | 5 | ||||
-rw-r--r-- | lib/vcategories.php | 31 |
16 files changed, 243 insertions, 30 deletions
diff --git a/lib/app.php b/lib/app.php index 55b4543ec9f..c6f6e92e60e 100644 --- a/lib/app.php +++ b/lib/app.php @@ -172,9 +172,17 @@ class OC_App{ return array(); } $apps=array('files'); - $query = OC_DB::prepare( 'SELECT `appid` FROM `*PREFIX*appconfig`' - .' WHERE `configkey` = \'enabled\' AND `configvalue`=\'yes\'' ); + $sql = 'SELECT `appid` FROM `*PREFIX*appconfig`' + .' WHERE `configkey` = \'enabled\' AND `configvalue`=\'yes\''; + if (OC_Config::getValue( 'dbtype', 'sqlite' ) === 'oci') { //FIXME oracle hack + $sql = 'SELECT `appid` FROM `*PREFIX*appconfig`' + .' WHERE `configkey` = \'enabled\' AND to_char(`configvalue`)=\'yes\''; + } + $query = OC_DB::prepare( $sql ); $result=$query->execute(); + if( \OC_DB::isError($result)) { + throw new DatabaseException($result->getMessage(), $query); + } while($row=$result->fetchRow()) { if(array_search($row['appid'], $apps)===false) { $apps[]=$row['appid']; diff --git a/lib/base.php b/lib/base.php index 7d7e690aa6f..724bd250a5c 100644 --- a/lib/base.php +++ b/lib/base.php @@ -260,6 +260,7 @@ class OC { OC_Util::addScript("jquery-tipsy"); OC_Util::addScript("compatibility"); OC_Util::addScript("oc-dialogs"); + OC_Util::addScript("octemplate"); OC_Util::addScript("js"); OC_Util::addScript("eventsource"); OC_Util::addScript("config"); diff --git a/lib/db.php b/lib/db.php index 8f6f50bda6e..61836551833 100644 --- a/lib/db.php +++ b/lib/db.php @@ -273,18 +273,13 @@ class OC_DB { break; case 'oci': $dsn = array( - 'phptype' => 'oci8', - 'username' => $user, - 'password' => $pass, - 'charset' => 'AL32UTF8', + 'phptype' => 'oci8', + 'username' => $user, + 'password' => $pass, + 'service' => $name, + 'hostspec' => $host, + 'charset' => 'AL32UTF8', ); - if ($host != '') { - $dsn['hostspec'] = $host; - $dsn['database'] = $name; - } else { // use dbname for hostspec - $dsn['hostspec'] = $name; - $dsn['database'] = $user; - } break; case 'mssql': $dsn = array( diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 8f5c9643bef..3341fe50525 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -107,7 +107,7 @@ class Cache { $params = array($file); } $query = \OC_DB::prepare( - 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `etag` + 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `storage_mtime`, `encrypted`, `etag` FROM `*PREFIX*filecache` ' . $where); $result = $query->execute($params); $data = $result->fetchRow(); @@ -126,6 +126,9 @@ class Cache { $data['storage'] = $this->storageId; $data['mimetype'] = $this->getMimetype($data['mimetype']); $data['mimepart'] = $this->getMimetype($data['mimepart']); + if ($data['storage_mtime'] == 0) { + $data['storage_mtime'] = $data['mtime']; + } } return $data; @@ -141,13 +144,19 @@ class Cache { $fileId = $this->getId($folder); if ($fileId > -1) { $query = \OC_DB::prepare( - 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `etag` - FROM `*PREFIX*filecache` WHERE parent = ? ORDER BY `name` ASC'); + 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `storage_mtime`, `encrypted`, `etag` + FROM `*PREFIX*filecache` WHERE `parent` = ? ORDER BY `name` ASC'); $result = $query->execute(array($fileId)); + if (\OC_DB::isError($result)) { + \OCP\Util::writeLog('cache', 'getFolderContents failed: ' . $result->getMessage(), \OCP\Util::ERROR); + } $files = $result->fetchAll(); foreach ($files as &$file) { $file['mimetype'] = $this->getMimetype($file['mimetype']); $file['mimepart'] = $this->getMimetype($file['mimepart']); + if ($file['storage_mtime'] == 0) { + $file['storage_mtime'] = $file['mtime']; + } } return $files; } else { @@ -195,7 +204,7 @@ class Cache { . ' VALUES(' . implode(', ', $valuesPlaceholder) . ')'); $result = $query->execute($params); if (\OC_DB::isError($result)) { - \OCP\Util::writeLog('cache', 'Insert to cache failed: ' . $result, \OCP\Util::ERROR); + \OCP\Util::writeLog('cache', 'Insert to cache failed: ' . $result->getMessage(), \OCP\Util::ERROR); } return (int)\OC_DB::insertid('*PREFIX*filecache'); @@ -224,7 +233,7 @@ class Cache { * @return array */ function buildParts(array $data) { - $fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime', 'encrypted', 'etag'); + $fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime', 'storage_mtime', 'encrypted', 'etag'); $params = array(); $queryParts = array(); foreach ($data as $name => $value) { @@ -236,6 +245,11 @@ class Cache { $params[] = $this->getMimetypeId(substr($value, 0, strpos($value, '/'))); $queryParts[] = '`mimepart`'; $value = $this->getMimetypeId($value); + } elseif ($name === 'storage_mtime') { + if (!isset($data['mtime'])) { + $params[] = $value; + $queryParts[] = '`mtime`'; + } } $params[] = $value; $queryParts[] = '`' . $name . '`'; @@ -361,6 +375,9 @@ class Cache { $pathHash = md5($file); $query = \OC_DB::prepare('SELECT `size` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); $result = $query->execute(array($this->getNumericStorageId(), $pathHash)); + if( \OC_DB::isError($result)) { + \OCP\Util::writeLog('cache', 'get status failed: ' . $result->getMessage(), \OCP\Util::ERROR); + } if ($row = $result->fetchRow()) { if ((int)$row['size'] === -1) { return self::SHALLOW; @@ -498,8 +515,11 @@ class Cache { */ public function getIncomplete() { $query = \OC_DB::prepare('SELECT `path` FROM `*PREFIX*filecache`' - . ' WHERE `storage` = ? AND `size` = -1 ORDER BY `fileid` DESC LIMIT 1'); + . ' WHERE `storage` = ? AND `size` = -1 ORDER BY `fileid` DESC',1); $result = $query->execute(array($this->getNumericStorageId())); + if (\OC_DB::isError($result)) { + \OCP\Util::writeLog('cache', 'getIncomplete failed: ' . $result->getMessage(), \OCP\Util::ERROR); + } if ($row = $result->fetchRow()) { return $row['path']; } else { diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 0b1947f17ca..46122221dc2 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -51,6 +51,7 @@ class Scanner { $data['size'] = $this->storage->filesize($path); } $data['etag'] = $this->storage->getETag($path); + $data['storage_mtime'] = $data['mtime']; return $data; } @@ -167,9 +168,11 @@ class Scanner { * walk over any folders that are not fully scanned yet and scan them */ public function backgroundScan() { - while (($path = $this->cache->getIncomplete()) !== false) { + $lastPath = null; + while (($path = $this->cache->getIncomplete()) !== false && $path !== $lastPath) { $this->scan($path); $this->cache->correctFolderSize($path); + $lastPath = $path; } } } diff --git a/lib/files/cache/watcher.php b/lib/files/cache/watcher.php index 31059ec7f56..8bfd4602f3a 100644 --- a/lib/files/cache/watcher.php +++ b/lib/files/cache/watcher.php @@ -43,7 +43,7 @@ class Watcher { */ public function checkUpdate($path) { $cachedEntry = $this->cache->get($path); - if ($this->storage->hasUpdated($path, $cachedEntry['mtime'])) { + if ($this->storage->hasUpdated($path, $cachedEntry['storage_mtime'])) { if ($this->storage->is_dir($path)) { $this->scanner->scan($path, Scanner::SCAN_SHALLOW); } else { diff --git a/lib/files/view.php b/lib/files/view.php index d0d473766cc..168d781d62c 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -251,8 +251,11 @@ class View { if (!$this->file_exists($path)) { $hooks[] = 'write'; } - - return $this->basicOperation('touch', $path, $hooks, $mtime); + $result = $this->basicOperation('touch', $path, $hooks, $mtime); + if (!$result) { //if native touch fails, we emulate it by changing the mtime in the cache + $this->putFileInfo($path, array('mtime' => $mtime)); + } + return true; } public function file_get_contents($path) { diff --git a/lib/hooks/basicemitter.php b/lib/hooks/basicemitter.php new file mode 100644 index 00000000000..e615a58cfe8 --- /dev/null +++ b/lib/hooks/basicemitter.php @@ -0,0 +1,89 @@ +<?php +/** + * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Hooks; + +abstract class BasicEmitter implements Emitter { + + /** + * @var (callable[])[] $listeners + */ + private $listeners = array(); + + /** + * @param string $scope + * @param string $method + * @param callable $callback + */ + public function listen($scope, $method, $callback) { + $eventName = $scope . '::' . $method; + if (!isset($this->listeners[$eventName])) { + $this->listeners[$eventName] = array(); + } + if (array_search($callback, $this->listeners[$eventName]) === false) { + $this->listeners[$eventName][] = $callback; + } + } + + /** + * @param string $scope optional + * @param string $method optional + * @param callable $callback optional + */ + public function removeListener($scope = null, $method = null, $callback = null) { + $names = array(); + $allNames = array_keys($this->listeners); + if ($scope and $method) { + $name = $scope . '::' . $method; + if (isset($this->listeners[$name])) { + $names[] = $name; + } + } elseif ($scope) { + foreach ($allNames as $name) { + $parts = explode('::', $name, 2); + if ($parts[0] == $scope) { + $names[] = $name; + } + } + } elseif ($method) { + foreach ($allNames as $name) { + $parts = explode('::', $name, 2); + if ($parts[1] == $method) { + $names[] = $name; + } + } + } else { + $names = $allNames; + } + + foreach ($names as $name) { + if ($callback) { + $index = array_search($callback, $this->listeners[$name]); + if ($index !== false) { + unset($this->listeners[$name][$index]); + } + } else { + $this->listeners[$name] = array(); + } + } + } + + /** + * @param string $scope + * @param string $method + * @param array $arguments optional + */ + protected function emit($scope, $method, $arguments = array()) { + $eventName = $scope . '::' . $method; + if (isset($this->listeners[$eventName])) { + foreach ($this->listeners[$eventName] as $callback) { + call_user_func_array($callback, $arguments); + } + } + } +} diff --git a/lib/hooks/emitter.php b/lib/hooks/emitter.php new file mode 100644 index 00000000000..8e9074bad67 --- /dev/null +++ b/lib/hooks/emitter.php @@ -0,0 +1,32 @@ +<?php +/** + * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Hooks; + +/** + * Class Emitter + * + * interface for all classes that are able to emit events + * + * @package OC\Hooks + */ +interface Emitter { + /** + * @param string $scope + * @param string $method + * @param callable $callback + */ + public function listen($scope, $method, $callback); + + /** + * @param string $scope optional + * @param string $method optional + * @param callable $callback optional + */ + public function removeListener($scope = null, $method = null, $callback = null); +} diff --git a/lib/hooks/legacyemitter.php b/lib/hooks/legacyemitter.php new file mode 100644 index 00000000000..a2d16ace9a7 --- /dev/null +++ b/lib/hooks/legacyemitter.php @@ -0,0 +1,16 @@ +<?php +/** + * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Hooks; + +abstract class LegacyEmitter extends BasicEmitter { + protected function emit($scope, $method, $arguments = array()) { + \OC_Hook::emit($scope, $method, $arguments); + parent::emit($scope, $method, $arguments); + } +} diff --git a/lib/l10n/nb_NO.php b/lib/l10n/nb_NO.php index fc95561d3b4..23146154c77 100644 --- a/lib/l10n/nb_NO.php +++ b/lib/l10n/nb_NO.php @@ -15,6 +15,8 @@ "Files" => "Filer", "Text" => "Tekst", "Images" => "Bilder", +"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Din nettservev er ikke konfigurert korrekt for filsynkronisering. WebDAV ser ut til å ikke funkere.", +"Please double check the <a href='%s'>installation guides</a>." => "Vennligst dobbelsjekk <a href='%s'>installasjonsguiden</a>.", "seconds ago" => "sekunder siden", "1 minute ago" => "1 minutt siden", "%d minutes ago" => "%d minutter siden", diff --git a/lib/setup.php b/lib/setup.php index f1ac6b8b2b8..a63cc664dbc 100644 --- a/lib/setup.php +++ b/lib/setup.php @@ -152,8 +152,12 @@ class OC_Setup { self::setupOCIDatabase($dbhost, $dbuser, $dbpass, $dbname, $dbtableprefix, $dbtablespace, $username); } catch (Exception $e) { $error[] = array( - 'error' => $l->t('Oracle username and/or password not valid'), - 'hint' => $l->t('You need to enter either an existing account or the administrator.') + 'error' => $l->t('Oracle connection could not be established'), + 'hint' => $e->getMessage().' Check environment: ORACLE_HOME='.getenv('ORACLE_HOME') + .' ORACLE_SID='.getenv('ORACLE_SID') + .' LD_LIBRARY_PATH='.getenv('LD_LIBRARY_PATH') + .' NLS_LANG='.getenv('NLS_LANG') + .' tnsnames.ora is '.(is_readable(getenv('ORACLE_HOME').'/network/admin/tnsnames.ora')?'':'not ').'readable' ); return $error; } @@ -452,9 +456,13 @@ class OC_Setup { } else { $easy_connect_string = '//'.$e_host.'/'.$e_dbname; } + \OC_Log::write('setup oracle', 'connect string: ' . $easy_connect_string, \OC_Log::DEBUG); $connection = @oci_connect($dbuser, $dbpass, $easy_connect_string); if(!$connection) { $e = oci_error(); + if (is_array ($e) && isset ($e['message'])) { + throw new Exception($e['message']); + } throw new Exception($l->t('Oracle username and/or password not valid')); } //check for roles creation rights in oracle diff --git a/lib/user.php b/lib/user.php index 226b716188d..32b91c35efc 100644 --- a/lib/user.php +++ b/lib/user.php @@ -32,7 +32,7 @@ * post_deleteUser(uid) * pre_setPassword(&run, uid, password) * post_setPassword(uid, password) - * pre_login(&run, uid) + * pre_login(&run, uid, password) * post_login(uid) * logout() */ @@ -244,7 +244,7 @@ class OC_User { */ public static function login( $uid, $password ) { $run = true; - OC_Hook::emit( "OC_User", "pre_login", array( "run" => &$run, "uid" => $uid )); + OC_Hook::emit( "OC_User", "pre_login", array( "run" => &$run, "uid" => $uid, "password" => $password)); if( $run ) { $uid = self::checkPassword( $uid, $password ); @@ -610,6 +610,10 @@ class OC_User { public static function isEnabled($userid) { $sql = 'SELECT `userid` FROM `*PREFIX*preferences`' .' WHERE `userid` = ? AND `appid` = ? AND `configkey` = ? AND `configvalue` = ?'; + if (OC_Config::getValue( 'dbtype', 'sqlite' ) === 'oci') { //FIXME oracle hack + $sql = 'SELECT `userid` FROM `*PREFIX*preferences`' + .' WHERE `userid` = ? AND `appid` = ? AND `configkey` = ? AND to_char(`configvalue`) = ?'; + } $stmt = OC_DB::prepare($sql); if ( ! OC_DB::isError($stmt) ) { $result = $stmt->execute(array($userid, 'core', 'enabled', 'false')); diff --git a/lib/user/database.php b/lib/user/database.php index 63c64ed43d3..d70b620f2ab 100644 --- a/lib/user/database.php +++ b/lib/user/database.php @@ -136,7 +136,7 @@ class OC_User_Database extends OC_User_Backend { */ public function getDisplayName($uid) { if( $this->userExists($uid) ) { - $query = OC_DB::prepare( 'SELECT displayname FROM `*PREFIX*users` WHERE `uid` = ?' ); + $query = OC_DB::prepare( 'SELECT `displayname` FROM `*PREFIX*users` WHERE `uid` = ?' ); $result = $query->execute( array( $uid ))->fetchAll(); $displayName = trim($result[0]['displayname'], ' '); if ( !empty($displayName) ) { diff --git a/lib/util.php b/lib/util.php index f30cdf6a534..01e2df7bfc4 100755 --- a/lib/util.php +++ b/lib/util.php @@ -77,7 +77,7 @@ class OC_Util { public static function getVersion() { // hint: We only can count up. Reset minor/patchlevel when // updating major/minor version number. - return array(5, 80, 02); + return array(5, 80, 03); } /** @@ -173,7 +173,8 @@ class OC_Util { //check for database drivers if(!(is_callable('sqlite_open') or class_exists('SQLite3')) and !is_callable('mysql_connect') - and !is_callable('pg_connect')) { + and !is_callable('pg_connect') + and !is_callable('oci_connect')) { $errors[]=array('error'=>'No database drivers (sqlite, mysql, or postgresql) installed.', 'hint'=>'');//TODO: sane hint $web_server_restart= true; diff --git a/lib/vcategories.php b/lib/vcategories.php index 5975e688b75..91c72d5dfae 100644 --- a/lib/vcategories.php +++ b/lib/vcategories.php @@ -325,6 +325,37 @@ class OC_VCategories { } /** + * @brief Rename category. + * @param string $from The name of the existing category + * @param string $to The new name of the category. + * @returns bool + */ + public function rename($from, $to) { + $id = $this->array_searchi($from, $this->categories); + if($id === false) { + OCP\Util::writeLog('core', __METHOD__.', category: ' . $from. ' does not exist', OCP\Util::DEBUG); + return false; + } + + $sql = 'UPDATE `' . self::CATEGORY_TABLE . '` SET `category` = ? ' + . 'WHERE `uid` = ? AND `type` = ? AND `id` = ?'; + try { + $stmt = OCP\DB::prepare($sql); + $result = $stmt->execute(array($to, $this->user, $this->type, $id)); + if (OC_DB::isError($result)) { + OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR); + return false; + } + } catch(Exception $e) { + OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), + OCP\Util::ERROR); + return false; + } + $this->categories[$id] = $to; + return true; + } + + /** * @brief Add a new category. * @param $names A string with a name or an array of strings containing * the name(s) of the categor(y|ies) to add. |