Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| df380d0291 | |||
| d12c339549 | |||
| 19beae15f3 | |||
| 41642aae45 | |||
| 5642b6b336 |
+1
-1
Submodule 3rdparty updated: 34fdf0b083...8f97d8cef3
@@ -191,7 +191,6 @@ OC.L10N.register(
|
||||
"{actor} updated contact {card} in address book {addressbook}" : "{actor} оновив(-ла) контакт {card} в адресній книзі {addressbook}",
|
||||
"You updated contact {card} in address book {addressbook}" : "Ви оновили контакт {card} в адресній книзі {addressbook}",
|
||||
"A <strong>contact</strong> or <strong>address book</strong> was modified" : "<strong>Контактну</strong> або <strong>адресну книгу</strong> було змінено",
|
||||
"System address book disabled" : "Системну адресну книгу вимкнено",
|
||||
"Accounts" : "Облікові записи",
|
||||
"System address book which holds all accounts" : "Системна адресна книга, в якій містяться всі облікові записи",
|
||||
"File is not updatable: %1$s" : "Файл не оновлюється: %1$s",
|
||||
@@ -204,8 +203,6 @@ OC.L10N.register(
|
||||
"Could not rename part file to final file, canceled by hook" : "Не вдалося перейменувати файл частини на остаточний файл, скасовано підхопленням",
|
||||
"Could not rename part file to final file" : "Не вдалося перейменувати файл частини на остаточний файл",
|
||||
"Failed to check file size: %1$s" : "Не вдалося перевірити розмір файлу: %1$s",
|
||||
"Could not open file: %1$s (%2$d), file does seem to exist" : "Не вдалося відкрити файл: %1$s (%2$d), хоча схоже, що файл наявний",
|
||||
"Could not open file: %1$s (%2$d), file doesn't seem to exist" : "Не вдалося відкрити файл: %1$s (%2$d), схоже, що файл відсутній",
|
||||
"Encryption not ready: %1$s" : "Шифрування не готове: %1$s",
|
||||
"Failed to open file: %1$s" : "Не вдалося відкрити файл: %1$s",
|
||||
"Failed to unlink: %1$s" : "Не вдалося від’єднати: %1$s",
|
||||
@@ -230,10 +227,6 @@ OC.L10N.register(
|
||||
"DAV system address book" : "Системна адресна книга DAV",
|
||||
"No outstanding DAV system address book sync." : "Немає незавершеної синхронізації системної адресної книги DAV.",
|
||||
"The DAV system address book sync has not run yet as your instance has more than 1000 users or because an error occurred. Please run it manually by calling \"occ dav:sync-system-addressbook\"." : "Синхронізація системної адресної книги DAV ще не запускалася, оскільки, або ваша система вже має понад 1000 користувачів, або сталася помилка. Будь ласка, запустіть синхронізацію вручну за допомогою команди \"occ dav:sync-system-addressbook\".",
|
||||
"DAV system address book size" : "Розмір системної адресної книги DAV ",
|
||||
"The system address book is disabled" : "Системну адресну книгу вимкнено",
|
||||
"The system address book is enabled, but contains more than the configured limit of %d contacts" : "Системну адресну книгу увімкнено, проте вона містить більше, ніж визначено максимальну кількість у %d контактів.",
|
||||
"The system address book is enabled and contains less than the configured limit of %d contacts" : "Системну адресну книгу увімкнено, проте вона містить менше, ніж визначено максимальну кількість у %d контактів.",
|
||||
"WebDAV endpoint" : "Точка доступу WebDAV",
|
||||
"Could not check that your web server is properly set up to allow file synchronization over WebDAV. Please check manually." : "Неможливо перевірити, чи на вашому вебсервері правильно налаштовано доступ для синхронізації файлів через протокол WebDAV. Перевірте це вручну.",
|
||||
"Your web server is not yet properly set up to allow file synchronization, because the WebDAV interface seems to be broken." : "Ваш вебсервер не налаштований як треба для синхронізації файлів, схоже інтерфейс WebDAV поламаний.",
|
||||
|
||||
@@ -189,7 +189,6 @@
|
||||
"{actor} updated contact {card} in address book {addressbook}" : "{actor} оновив(-ла) контакт {card} в адресній книзі {addressbook}",
|
||||
"You updated contact {card} in address book {addressbook}" : "Ви оновили контакт {card} в адресній книзі {addressbook}",
|
||||
"A <strong>contact</strong> or <strong>address book</strong> was modified" : "<strong>Контактну</strong> або <strong>адресну книгу</strong> було змінено",
|
||||
"System address book disabled" : "Системну адресну книгу вимкнено",
|
||||
"Accounts" : "Облікові записи",
|
||||
"System address book which holds all accounts" : "Системна адресна книга, в якій містяться всі облікові записи",
|
||||
"File is not updatable: %1$s" : "Файл не оновлюється: %1$s",
|
||||
@@ -202,8 +201,6 @@
|
||||
"Could not rename part file to final file, canceled by hook" : "Не вдалося перейменувати файл частини на остаточний файл, скасовано підхопленням",
|
||||
"Could not rename part file to final file" : "Не вдалося перейменувати файл частини на остаточний файл",
|
||||
"Failed to check file size: %1$s" : "Не вдалося перевірити розмір файлу: %1$s",
|
||||
"Could not open file: %1$s (%2$d), file does seem to exist" : "Не вдалося відкрити файл: %1$s (%2$d), хоча схоже, що файл наявний",
|
||||
"Could not open file: %1$s (%2$d), file doesn't seem to exist" : "Не вдалося відкрити файл: %1$s (%2$d), схоже, що файл відсутній",
|
||||
"Encryption not ready: %1$s" : "Шифрування не готове: %1$s",
|
||||
"Failed to open file: %1$s" : "Не вдалося відкрити файл: %1$s",
|
||||
"Failed to unlink: %1$s" : "Не вдалося від’єднати: %1$s",
|
||||
@@ -228,10 +225,6 @@
|
||||
"DAV system address book" : "Системна адресна книга DAV",
|
||||
"No outstanding DAV system address book sync." : "Немає незавершеної синхронізації системної адресної книги DAV.",
|
||||
"The DAV system address book sync has not run yet as your instance has more than 1000 users or because an error occurred. Please run it manually by calling \"occ dav:sync-system-addressbook\"." : "Синхронізація системної адресної книги DAV ще не запускалася, оскільки, або ваша система вже має понад 1000 користувачів, або сталася помилка. Будь ласка, запустіть синхронізацію вручну за допомогою команди \"occ dav:sync-system-addressbook\".",
|
||||
"DAV system address book size" : "Розмір системної адресної книги DAV ",
|
||||
"The system address book is disabled" : "Системну адресну книгу вимкнено",
|
||||
"The system address book is enabled, but contains more than the configured limit of %d contacts" : "Системну адресну книгу увімкнено, проте вона містить більше, ніж визначено максимальну кількість у %d контактів.",
|
||||
"The system address book is enabled and contains less than the configured limit of %d contacts" : "Системну адресну книгу увімкнено, проте вона містить менше, ніж визначено максимальну кількість у %d контактів.",
|
||||
"WebDAV endpoint" : "Точка доступу WebDAV",
|
||||
"Could not check that your web server is properly set up to allow file synchronization over WebDAV. Please check manually." : "Неможливо перевірити, чи на вашому вебсервері правильно налаштовано доступ для синхронізації файлів через протокол WebDAV. Перевірте це вручну.",
|
||||
"Your web server is not yet properly set up to allow file synchronization, because the WebDAV interface seems to be broken." : "Ваш вебсервер не налаштований як треба для синхронізації файлів, схоже інтерфейс WebDAV поламаний.",
|
||||
|
||||
@@ -1020,7 +1020,7 @@ class CardDavBackend implements BackendInterface, SyncSupport {
|
||||
'synctoken' => $query->createNamedParameter($syncToken),
|
||||
'addressbookid' => $query->createNamedParameter($addressBookId),
|
||||
'operation' => $query->createNamedParameter($operation),
|
||||
'created_at' => $query->createNamedParameter(time()),
|
||||
'created_at' => time(),
|
||||
])
|
||||
->executeStatement();
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ declare(strict_types=1);
|
||||
*/
|
||||
namespace OCA\DAV\CardDAV\Notification;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use OCA\DAV\AppInfo\Application;
|
||||
use OCP\IL10N;
|
||||
use OCP\L10N\IFactory;
|
||||
@@ -41,7 +42,7 @@ class Notifier implements INotifier {
|
||||
*/
|
||||
public function prepare(INotification $notification, string $languageCode): INotification {
|
||||
if ($notification->getApp() !== Application::APP_ID) {
|
||||
throw new UnknownNotificationException();
|
||||
throw new InvalidArgumentException();
|
||||
}
|
||||
|
||||
$l = $this->l10nFactory->get(Application::APP_ID, $languageCode);
|
||||
|
||||
@@ -482,10 +482,9 @@ class File extends Node implements IFile {
|
||||
|
||||
// comparing current file size with the one in DB
|
||||
// if different, fix DB and refresh cache.
|
||||
$fsSize = $this->fileView->filesize($this->getPath());
|
||||
if ($this->getSize() !== $fsSize) {
|
||||
if ($this->getSize() !== $this->fileView->filesize($this->getPath())) {
|
||||
$logger = Server::get(LoggerInterface::class);
|
||||
$logger->warning('fixing cached size of file id=' . $this->getId() . ', cached size was ' . $this->getSize() . ', but the filesystem reported a size of ' . $fsSize);
|
||||
$logger->warning('fixing cached size of file id=' . $this->getId());
|
||||
|
||||
$this->getFileInfo()->getStorage()->getUpdater()->update($this->getFileInfo()->getInternalPath());
|
||||
$this->refreshInfo();
|
||||
|
||||
@@ -164,6 +164,7 @@ class SharingMapper {
|
||||
->andWhere($query->expr()->eq(
|
||||
'type',
|
||||
$query->createNamedParameter($resourceType, IQueryBuilder::PARAM_STR)),
|
||||
IQueryBuilder::PARAM_STR,
|
||||
)
|
||||
->executeQuery();
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ namespace OCA\DAV\Tests\unit\BackgroundJob;
|
||||
use OCA\DAV\BackgroundJob\CleanupInvitationTokenJob;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\DB\QueryBuilder\IExpressionBuilder;
|
||||
use OCP\DB\QueryBuilder\IParameter;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\IDBConnection;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
@@ -47,12 +46,9 @@ class CleanupInvitationTokenJobTest extends TestCase {
|
||||
->willReturn($queryBuilder);
|
||||
$queryBuilder->method('expr')
|
||||
->willReturn($expr);
|
||||
$parameter = $this->createMock(IParameter::class);
|
||||
$parameter->method('__toString')
|
||||
->willReturn('namedParameter1337');
|
||||
$queryBuilder->method('createNamedParameter')
|
||||
->willReturnMap([
|
||||
[1337, \PDO::PARAM_STR, null, $parameter],
|
||||
[1337, \PDO::PARAM_STR, null, 'namedParameter1337']
|
||||
]);
|
||||
|
||||
$function = 'function1337';
|
||||
|
||||
@@ -15,7 +15,6 @@ use OCP\AppFramework\Http\TemplateResponse;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\DB\IResult;
|
||||
use OCP\DB\QueryBuilder\IExpressionBuilder;
|
||||
use OCP\DB\QueryBuilder\IParameter;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\IRequest;
|
||||
@@ -416,12 +415,9 @@ EOF;
|
||||
->willReturn($queryBuilder);
|
||||
$queryBuilder->method('expr')
|
||||
->willReturn($expr);
|
||||
$parameter = $this->createMock(IParameter::class);
|
||||
$parameter->method('__toString')
|
||||
->willReturn('namedParameterToken');
|
||||
$queryBuilder->method('createNamedParameter')
|
||||
->willReturnMap([
|
||||
[$token, \PDO::PARAM_STR, null, $parameter]
|
||||
[$token, \PDO::PARAM_STR, null, 'namedParameterToken']
|
||||
]);
|
||||
|
||||
$stmt->expects($this->once())
|
||||
|
||||
@@ -42,8 +42,8 @@ OC.L10N.register(
|
||||
"The lookup server is only available for global scale." : "Сервер пошуку доступний тільки для глобального масштабу.",
|
||||
"Search global and public address book for people" : "Шукати користувачів у глобальній та публічній адресних книгах",
|
||||
"Allow people to publish their data to a global and public address book" : "Дозволити користувачам розміщувати власні дані у глобальній публічній адресній книзі",
|
||||
"Trusted federation" : "Довірені об'єднані хмари",
|
||||
"Automatically accept shares from trusted federated accounts and groups by default" : "Стандартно автоматично приймати пропозиції спільного доступу від надійних облікових записів та груп об'єднаних хмар",
|
||||
"Trusted federation" : "Довірена федерація",
|
||||
"Automatically accept shares from trusted federated accounts and groups by default" : "Типово автоматично приймати пропозиції спільного доступу від надійних облікових записів та груп об'єднаних хмар",
|
||||
"Share with me through my #Nextcloud Federated Cloud ID, see {url}" : "Поділітися зі мною через мій #Nextcloud Federated Cloud ID, див. {url}",
|
||||
"Share with me through my #Nextcloud Federated Cloud ID" : "Поділітися зі мною через мій #Nextcloud Federated Cloud ID",
|
||||
"Share with me via Nextcloud" : "Поділіться зі мною у Nextcloud",
|
||||
|
||||
@@ -40,8 +40,8 @@
|
||||
"The lookup server is only available for global scale." : "Сервер пошуку доступний тільки для глобального масштабу.",
|
||||
"Search global and public address book for people" : "Шукати користувачів у глобальній та публічній адресних книгах",
|
||||
"Allow people to publish their data to a global and public address book" : "Дозволити користувачам розміщувати власні дані у глобальній публічній адресній книзі",
|
||||
"Trusted federation" : "Довірені об'єднані хмари",
|
||||
"Automatically accept shares from trusted federated accounts and groups by default" : "Стандартно автоматично приймати пропозиції спільного доступу від надійних облікових записів та груп об'єднаних хмар",
|
||||
"Trusted federation" : "Довірена федерація",
|
||||
"Automatically accept shares from trusted federated accounts and groups by default" : "Типово автоматично приймати пропозиції спільного доступу від надійних облікових записів та груп об'єднаних хмар",
|
||||
"Share with me through my #Nextcloud Federated Cloud ID, see {url}" : "Поділітися зі мною через мій #Nextcloud Federated Cloud ID, див. {url}",
|
||||
"Share with me through my #Nextcloud Federated Cloud ID" : "Поділітися зі мною через мій #Nextcloud Federated Cloud ID",
|
||||
"Share with me via Nextcloud" : "Поділіться зі мною у Nextcloud",
|
||||
|
||||
@@ -11,18 +11,7 @@ OC.L10N.register(
|
||||
"Federation" : "Об'єднання",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory." : "Об'єднання хмар дозволяє з'єднуватися з іншими довіреними серверами й обмінюватися обліковими даними користувачів.",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing." : "Об'єднання хмар дозволяє з'єднуватися з іншими довіреними серверами й обмінюватися обліковими даними користувачів. Так, це може бути корисно для автоматичної підстановки зовнішніх користувачів під час надання у спільний доступ ресурсів об'єднаних хмар.",
|
||||
"Could not add trusted server. Please try again later." : "Не вдалося додати довірений сервер. Спробуйте ще раз пізніше.",
|
||||
"Add trusted server" : "Додати довірений сервер",
|
||||
"Server url" : " Посилання на сервер",
|
||||
"Add" : "Додати",
|
||||
"Server ok" : "Сервер ОК",
|
||||
"User list was exchanged at least once successfully with the remote server." : "Принаймні один раз відбувся обмін списком користувачів з віддаленим сервером.",
|
||||
"Server pending" : "Очікування сервера",
|
||||
"Waiting for shared secret or initial user list exchange." : "Очікування парольної фрази спільного доступу або початкового обміну списком користувачів",
|
||||
"Server access revoked" : "Відкликано доступ для сервера",
|
||||
"Server failure" : "Помилка на стороні сервера",
|
||||
"Connection to the remote server failed or the remote server is misconfigured." : "Не вдалося встановити з'єднання з віддаленим сервером, або віддалений сервер має помилки з налаштуванням",
|
||||
"Failed to delete trusted server. Please try again later." : "Не вдалося вилучити довірений сервер. Спробуйте ще раз пізніше.",
|
||||
"Delete" : "Видалити",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing. It is not necessary to add a server as trusted server in order to create a federated share." : "Об'єднання хмар дозволяє з'єднуватися з іншими довіреними серверами й обмінюватися обліковими даними користувачів. Так, це може бути корисно для автоматичної підстановки зовнішніх користувачів під час надання у спільний доступ ресурсів об'єднаних хмар. Необов'язково додавати сервер яко довірений для створення спільного ресурсу між об'єднаними хмарами.",
|
||||
"Each server must validate the other. This process may require a few cron cycles." : "Кожен сервер має підтвердити один одного. Цей процес може вимагати кількох циклів виконання cron.",
|
||||
|
||||
@@ -9,18 +9,7 @@
|
||||
"Federation" : "Об'єднання",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory." : "Об'єднання хмар дозволяє з'єднуватися з іншими довіреними серверами й обмінюватися обліковими даними користувачів.",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing." : "Об'єднання хмар дозволяє з'єднуватися з іншими довіреними серверами й обмінюватися обліковими даними користувачів. Так, це може бути корисно для автоматичної підстановки зовнішніх користувачів під час надання у спільний доступ ресурсів об'єднаних хмар.",
|
||||
"Could not add trusted server. Please try again later." : "Не вдалося додати довірений сервер. Спробуйте ще раз пізніше.",
|
||||
"Add trusted server" : "Додати довірений сервер",
|
||||
"Server url" : " Посилання на сервер",
|
||||
"Add" : "Додати",
|
||||
"Server ok" : "Сервер ОК",
|
||||
"User list was exchanged at least once successfully with the remote server." : "Принаймні один раз відбувся обмін списком користувачів з віддаленим сервером.",
|
||||
"Server pending" : "Очікування сервера",
|
||||
"Waiting for shared secret or initial user list exchange." : "Очікування парольної фрази спільного доступу або початкового обміну списком користувачів",
|
||||
"Server access revoked" : "Відкликано доступ для сервера",
|
||||
"Server failure" : "Помилка на стороні сервера",
|
||||
"Connection to the remote server failed or the remote server is misconfigured." : "Не вдалося встановити з'єднання з віддаленим сервером, або віддалений сервер має помилки з налаштуванням",
|
||||
"Failed to delete trusted server. Please try again later." : "Не вдалося вилучити довірений сервер. Спробуйте ще раз пізніше.",
|
||||
"Delete" : "Видалити",
|
||||
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing. It is not necessary to add a server as trusted server in order to create a federated share." : "Об'єднання хмар дозволяє з'єднуватися з іншими довіреними серверами й обмінюватися обліковими даними користувачів. Так, це може бути корисно для автоматичної підстановки зовнішніх користувачів під час надання у спільний доступ ресурсів об'єднаних хмар. Необов'язково додавати сервер яко довірений для створення спільного ресурсу між об'єднаними хмарами.",
|
||||
"Each server must validate the other. This process may require a few cron cycles." : "Кожен сервер має підтвердити один одного. Цей процес може вимагати кількох циклів виконання cron.",
|
||||
|
||||
@@ -79,7 +79,6 @@ OC.L10N.register(
|
||||
"Go to the \"{dir}\" directory" : "\"{dir}\" klasörüne git",
|
||||
"Current directory path" : "Geçerli klasör yolu",
|
||||
"Share" : "Paylaş",
|
||||
"Reload content" : "İçeriği yeniden yükle",
|
||||
"Your have used your space quota and cannot upload files anymore" : "Depolama alanınızın tümünü kullandığınız için başka dosya yüklemezsiniz",
|
||||
"You do not have permission to upload or create files here." : "Buraya dosya yükleme ya da ekleme izniniz yok.",
|
||||
"Drag and drop files here to upload" : "Yüklemek istediğiniz dosyaları sürükleyip buraya bırakın",
|
||||
@@ -110,7 +109,6 @@ OC.L10N.register(
|
||||
"Last 30 days" : "Önceki 30 gün",
|
||||
"This year ({year})" : "Bu yıl ({year})",
|
||||
"Last year ({year})" : "Önceki yıl ({year})",
|
||||
"Custom range" : "Özel aralık",
|
||||
"Custom date range" : "Özel tarih aralığı",
|
||||
"Search everywhere" : "Her yerde ara",
|
||||
"Documents" : "Belgeler",
|
||||
@@ -122,7 +120,6 @@ OC.L10N.register(
|
||||
"Images" : "Görseller",
|
||||
"Videos" : "Görüntüler",
|
||||
"Filters" : "Süzgeçler",
|
||||
"Back to filters" : "Süzgeçlere dön",
|
||||
"Appearance" : "Görünüm",
|
||||
"Show hidden files" : "Gizli dosyaları görüntüle",
|
||||
"Show file type column" : "Dosya türü sütunu görüntülensin",
|
||||
@@ -234,9 +231,6 @@ OC.L10N.register(
|
||||
"Removing the file extension \"{old}\" may render the file unreadable." : "\"{old}\" dosya uzantısının kaldırılması dosyayı okunamaz yapabilir.",
|
||||
"Adding the file extension \"{new}\" may render the file unreadable." : "\"{new}\" dosya uzantısının eklenmesi dosyayı okunamaz yapabilir.",
|
||||
"Do not show this dialog again." : "Bu ileti bir daha görüntülenmesin.",
|
||||
"Rename file to hidden" : "Gizlemek için dosyayı yeniden adlandırın",
|
||||
"Prefixing a filename with a dot may render the file hidden." : "Dosya adının başına nokta koymak onu görünümlerde gizler.",
|
||||
"Are you sure you want to rename the file to \"{filename}\"?" : "Dosyanın adını \"{filename}\" olarak değiştirmek istediğinize emin misiniz?",
|
||||
"Cancel" : "İptal",
|
||||
"Rename" : "Yeniden adlandır",
|
||||
"Select file or folder to link to" : "Bağlantı verilecek dosya ya da klasörü seçin",
|
||||
@@ -251,7 +245,6 @@ OC.L10N.register(
|
||||
"Error during upload: {message}" : "Yükleme sırasında sorun çıktı: {message}",
|
||||
"Error during upload, status code {status}" : "Yüklenirken sorun çıktı, durum kodu {status}",
|
||||
"Unknown error during upload" : "Yükleme sırasında bilinmeyen bir sorun çıktı",
|
||||
"File list is reloading" : "Dosya listesi yeniden yükleniyor",
|
||||
"Loading current folder" : "Geçerli klasör yükleniyor",
|
||||
"Retry" : "Yeniden dene",
|
||||
"No files in here" : "Burada herhangi bir dosya yok",
|
||||
@@ -319,9 +312,7 @@ OC.L10N.register(
|
||||
"The files are locked" : "Dosyalar kilitli",
|
||||
"The file does not exist anymore" : "Dosya artık yok",
|
||||
"Moving \"{source}\" to \"{destination}\" …" : "\"{source}\", \"{destination}\" üzerine taşınıyor…",
|
||||
"Moving {count} files to \"{destination}\" …" : "{count} dosya \"{destination}\" konumuna taşınıyor…",
|
||||
"Copying \"{source}\" to \"{destination}\" …" : "\"{source}\", \"{destination}\" üzerine kopyalanıyor…",
|
||||
"Copying {count} files to \"{destination}\" …" : "{count} dosya \"{destination}\" konumuna kopyalanıyor…",
|
||||
"Choose destination" : "Hedefi seçin",
|
||||
"Copy to {target}" : "{target} içine kopyala",
|
||||
"Move to {target}" : "{target} içine taşı",
|
||||
@@ -346,7 +337,6 @@ OC.L10N.register(
|
||||
"Templates" : "Kalıplar",
|
||||
"New template folder" : "Yeni kalıp klasörü",
|
||||
"In folder" : "Klasörde",
|
||||
"Pick folder to search in" : "Aranacak klasörü seçin",
|
||||
"Search in all files" : "Tüm dosyalarda ara",
|
||||
"Search in folder: {folder}" : "Şu klasörde ara: {folder}",
|
||||
"One of the dropped files could not be processed" : "Bırakılan dosyalardan biri işlenemedi",
|
||||
|
||||
@@ -77,7 +77,6 @@
|
||||
"Go to the \"{dir}\" directory" : "\"{dir}\" klasörüne git",
|
||||
"Current directory path" : "Geçerli klasör yolu",
|
||||
"Share" : "Paylaş",
|
||||
"Reload content" : "İçeriği yeniden yükle",
|
||||
"Your have used your space quota and cannot upload files anymore" : "Depolama alanınızın tümünü kullandığınız için başka dosya yüklemezsiniz",
|
||||
"You do not have permission to upload or create files here." : "Buraya dosya yükleme ya da ekleme izniniz yok.",
|
||||
"Drag and drop files here to upload" : "Yüklemek istediğiniz dosyaları sürükleyip buraya bırakın",
|
||||
@@ -108,7 +107,6 @@
|
||||
"Last 30 days" : "Önceki 30 gün",
|
||||
"This year ({year})" : "Bu yıl ({year})",
|
||||
"Last year ({year})" : "Önceki yıl ({year})",
|
||||
"Custom range" : "Özel aralık",
|
||||
"Custom date range" : "Özel tarih aralığı",
|
||||
"Search everywhere" : "Her yerde ara",
|
||||
"Documents" : "Belgeler",
|
||||
@@ -120,7 +118,6 @@
|
||||
"Images" : "Görseller",
|
||||
"Videos" : "Görüntüler",
|
||||
"Filters" : "Süzgeçler",
|
||||
"Back to filters" : "Süzgeçlere dön",
|
||||
"Appearance" : "Görünüm",
|
||||
"Show hidden files" : "Gizli dosyaları görüntüle",
|
||||
"Show file type column" : "Dosya türü sütunu görüntülensin",
|
||||
@@ -232,9 +229,6 @@
|
||||
"Removing the file extension \"{old}\" may render the file unreadable." : "\"{old}\" dosya uzantısının kaldırılması dosyayı okunamaz yapabilir.",
|
||||
"Adding the file extension \"{new}\" may render the file unreadable." : "\"{new}\" dosya uzantısının eklenmesi dosyayı okunamaz yapabilir.",
|
||||
"Do not show this dialog again." : "Bu ileti bir daha görüntülenmesin.",
|
||||
"Rename file to hidden" : "Gizlemek için dosyayı yeniden adlandırın",
|
||||
"Prefixing a filename with a dot may render the file hidden." : "Dosya adının başına nokta koymak onu görünümlerde gizler.",
|
||||
"Are you sure you want to rename the file to \"{filename}\"?" : "Dosyanın adını \"{filename}\" olarak değiştirmek istediğinize emin misiniz?",
|
||||
"Cancel" : "İptal",
|
||||
"Rename" : "Yeniden adlandır",
|
||||
"Select file or folder to link to" : "Bağlantı verilecek dosya ya da klasörü seçin",
|
||||
@@ -249,7 +243,6 @@
|
||||
"Error during upload: {message}" : "Yükleme sırasında sorun çıktı: {message}",
|
||||
"Error during upload, status code {status}" : "Yüklenirken sorun çıktı, durum kodu {status}",
|
||||
"Unknown error during upload" : "Yükleme sırasında bilinmeyen bir sorun çıktı",
|
||||
"File list is reloading" : "Dosya listesi yeniden yükleniyor",
|
||||
"Loading current folder" : "Geçerli klasör yükleniyor",
|
||||
"Retry" : "Yeniden dene",
|
||||
"No files in here" : "Burada herhangi bir dosya yok",
|
||||
@@ -317,9 +310,7 @@
|
||||
"The files are locked" : "Dosyalar kilitli",
|
||||
"The file does not exist anymore" : "Dosya artık yok",
|
||||
"Moving \"{source}\" to \"{destination}\" …" : "\"{source}\", \"{destination}\" üzerine taşınıyor…",
|
||||
"Moving {count} files to \"{destination}\" …" : "{count} dosya \"{destination}\" konumuna taşınıyor…",
|
||||
"Copying \"{source}\" to \"{destination}\" …" : "\"{source}\", \"{destination}\" üzerine kopyalanıyor…",
|
||||
"Copying {count} files to \"{destination}\" …" : "{count} dosya \"{destination}\" konumuna kopyalanıyor…",
|
||||
"Choose destination" : "Hedefi seçin",
|
||||
"Copy to {target}" : "{target} içine kopyala",
|
||||
"Move to {target}" : "{target} içine taşı",
|
||||
@@ -344,7 +335,6 @@
|
||||
"Templates" : "Kalıplar",
|
||||
"New template folder" : "Yeni kalıp klasörü",
|
||||
"In folder" : "Klasörde",
|
||||
"Pick folder to search in" : "Aranacak klasörü seçin",
|
||||
"Search in all files" : "Tüm dosyalarda ara",
|
||||
"Search in folder: {folder}" : "Şu klasörde ara: {folder}",
|
||||
"One of the dropped files could not be processed" : "Bırakılan dosyalardan biri işlenemedi",
|
||||
|
||||
@@ -387,7 +387,7 @@ OC.L10N.register(
|
||||
"Files that are not shared will show up here." : "Тут показуватимуться файли, які не є у спільному доступі.",
|
||||
"Recent" : "Останні",
|
||||
"List of recently modified files and folders." : "Список нещодавно змінених файлів та каталогів.",
|
||||
"No recently modified files" : "Відсутні файли, які було нещодавно змінено",
|
||||
"No recently modified files" : "Відсутні файли із нещодавними змінами",
|
||||
"Files and folders you recently modified will show up here." : "Тут показуватимуться файли та каталоги, які було нещодавно змінено.",
|
||||
"Search" : "Пошук",
|
||||
"Search results within your files." : "Шукати результати серед ваших файлів.",
|
||||
|
||||
@@ -385,7 +385,7 @@
|
||||
"Files that are not shared will show up here." : "Тут показуватимуться файли, які не є у спільному доступі.",
|
||||
"Recent" : "Останні",
|
||||
"List of recently modified files and folders." : "Список нещодавно змінених файлів та каталогів.",
|
||||
"No recently modified files" : "Відсутні файли, які було нещодавно змінено",
|
||||
"No recently modified files" : "Відсутні файли із нещодавними змінами",
|
||||
"Files and folders you recently modified will show up here." : "Тут показуватимуться файли та каталоги, які було нещодавно змінено.",
|
||||
"Search" : "Пошук",
|
||||
"Search results within your files." : "Шукати результати серед ваших файлів.",
|
||||
|
||||
@@ -35,7 +35,7 @@ describe('View in folder action conditions tests', () => {
|
||||
contents: [],
|
||||
})).toMatch(/<svg.+<\/svg>/)
|
||||
expect(action.default).toBeUndefined()
|
||||
expect(action.order).toBe(10)
|
||||
expect(action.order).toBe(80)
|
||||
expect(action.enabled).toBeDefined()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import type { IFileAction } from '@nextcloud/files'
|
||||
|
||||
import FolderEyeSvg from '@mdi/svg/svg/folder-eye-outline.svg?raw'
|
||||
import FolderMoveSvg from '@mdi/svg/svg/folder-move-outline.svg?raw'
|
||||
import { FileType, Permission } from '@nextcloud/files'
|
||||
import { t } from '@nextcloud/l10n'
|
||||
import { isPublicShare } from '@nextcloud/sharing/public'
|
||||
@@ -15,7 +15,7 @@ export const action: IFileAction = {
|
||||
displayName() {
|
||||
return t('files', 'View in folder')
|
||||
},
|
||||
iconSvgInline: () => FolderEyeSvg,
|
||||
iconSvgInline: () => FolderMoveSvg,
|
||||
|
||||
enabled({ nodes, view }) {
|
||||
// Not enabled for public shares
|
||||
@@ -63,5 +63,5 @@ export const action: IFileAction = {
|
||||
return null
|
||||
},
|
||||
|
||||
order: 10,
|
||||
order: 80,
|
||||
}
|
||||
|
||||
@@ -282,7 +282,7 @@ OC.L10N.register(
|
||||
"Advanced settings" : "Розширені",
|
||||
"Share label" : "Мітка спільного ресурсу",
|
||||
"Share link token" : "Токен спільного ресурсу",
|
||||
"Set the public share link token to something easy to remember or generate a new token. It is not recommended to use a guessable token for shares which contain sensitive information." : "Встановіть токен для публічного посилання на спільний ресурс з простою для запам'ятовування назвою або створіть новий токен. Не рекомендується використовувати токени, які можна легко вгадати, для спільних ресурсів, що містять чутливі дані.",
|
||||
"Set the public share link token to something easy to remember or generate a new token. It is not recommended to use a guessable token for shares which contain sensitive information." : "Встановити публічне посилання на спільний ресурс у просту для запам'ятовування назву або створити новий токен. Не рекомендується використовувати токени, які можна легко вгадати для спільних ресурсів, які містять чутливі дані.",
|
||||
"Generating…" : "Створення...",
|
||||
"Generate new token" : "Створити новий токен",
|
||||
"Set password" : "Встановити пароль",
|
||||
|
||||
@@ -280,7 +280,7 @@
|
||||
"Advanced settings" : "Розширені",
|
||||
"Share label" : "Мітка спільного ресурсу",
|
||||
"Share link token" : "Токен спільного ресурсу",
|
||||
"Set the public share link token to something easy to remember or generate a new token. It is not recommended to use a guessable token for shares which contain sensitive information." : "Встановіть токен для публічного посилання на спільний ресурс з простою для запам'ятовування назвою або створіть новий токен. Не рекомендується використовувати токени, які можна легко вгадати, для спільних ресурсів, що містять чутливі дані.",
|
||||
"Set the public share link token to something easy to remember or generate a new token. It is not recommended to use a guessable token for shares which contain sensitive information." : "Встановити публічне посилання на спільний ресурс у просту для запам'ятовування назву або створити новий токен. Не рекомендується використовувати токени, які можна легко вгадати для спільних ресурсів, які містять чутливі дані.",
|
||||
"Generating…" : "Створення...",
|
||||
"Generate new token" : "Створити новий токен",
|
||||
"Set password" : "Встановити пароль",
|
||||
|
||||
@@ -236,7 +236,7 @@ class ShareAPIController extends OCSController {
|
||||
$expiration = $share->getExpirationDate();
|
||||
if ($expiration !== null) {
|
||||
$expiration->setTimezone($this->dateTimeZone->getTimeZone());
|
||||
$result['expiration'] = $expiration->format('Y-m-d H:i:s');
|
||||
$result['expiration'] = $expiration->format('Y-m-d 00:00:00');
|
||||
}
|
||||
|
||||
if ($share->getShareType() === IShare::TYPE_USER) {
|
||||
|
||||
@@ -1052,7 +1052,7 @@ class ApiTest extends TestCase {
|
||||
$share1 = $this->shareManager->getShareById($share1->getFullId());
|
||||
|
||||
// date should be changed
|
||||
$dateWithinRange->setTime(23, 59, 59);
|
||||
$dateWithinRange->setTime(0, 0, 0);
|
||||
$dateWithinRange->setTimezone(new \DateTimeZone(date_default_timezone_get()));
|
||||
$this->assertEquals($dateWithinRange, $share1->getExpirationDate());
|
||||
|
||||
@@ -1263,7 +1263,7 @@ class ApiTest extends TestCase {
|
||||
|
||||
public static function datesProvider() {
|
||||
$date = new \DateTime();
|
||||
$date->setTime(23, 59, 59);
|
||||
$date->setTime(0, 0);
|
||||
$date->add(new \DateInterval('P5D'));
|
||||
$date->setTimezone(new \DateTimeZone(date_default_timezone_get()));
|
||||
|
||||
@@ -1325,14 +1325,14 @@ class ApiTest extends TestCase {
|
||||
|
||||
$data = $result->getData();
|
||||
$this->assertTrue(is_string($data['token']));
|
||||
$this->assertEquals($date->format('Y-m-d 23:59:59'), $data['expiration']);
|
||||
$this->assertEquals($date->format('Y-m-d 00:00:00'), $data['expiration']);
|
||||
|
||||
// check for correct link
|
||||
$url = Server::get(IURLGenerator::class)->getAbsoluteURL('/index.php/s/' . $data['token']);
|
||||
$this->assertEquals($url, $data['url']);
|
||||
|
||||
$share = $this->shareManager->getShareById('ocinternal:' . $data['id']);
|
||||
$date->setTime(23, 59, 59);
|
||||
$date->setTime(0, 0, 0);
|
||||
$this->assertEquals($date, $share->getExpirationDate());
|
||||
|
||||
$this->shareManager->deleteShare($share);
|
||||
|
||||
@@ -773,7 +773,7 @@ class ShareAPIControllerTest extends TestCase {
|
||||
$data['Folder shared with group'] = [$share, $expected, true];
|
||||
|
||||
// File shared by link with Expire
|
||||
$expire = \DateTime::createFromFormat('Y-m-d H:i:s', '2000-01-02 23:59:59');
|
||||
$expire = \DateTime::createFromFormat('Y-m-d h:i:s', '2000-01-02 01:02:03');
|
||||
$share = [
|
||||
'101',
|
||||
IShare::TYPE_LINK,
|
||||
@@ -807,7 +807,7 @@ class ShareAPIControllerTest extends TestCase {
|
||||
'file_target' => 'target',
|
||||
'file_parent' => 3,
|
||||
'token' => 'token',
|
||||
'expiration' => '2000-01-02 23:59:59',
|
||||
'expiration' => '2000-01-02 00:00:00',
|
||||
'permissions' => 4,
|
||||
'attributes' => null,
|
||||
'stime' => 5,
|
||||
@@ -4504,7 +4504,7 @@ class ShareAPIControllerTest extends TestCase {
|
||||
'permissions' => 1,
|
||||
'stime' => 946684862,
|
||||
'parent' => null,
|
||||
'expiration' => '2001-02-03 04:05:06',
|
||||
'expiration' => '2001-02-03 00:00:00',
|
||||
'token' => null,
|
||||
'uid_file_owner' => 'owner',
|
||||
'displayname_file_owner' => 'owner',
|
||||
@@ -4554,7 +4554,7 @@ class ShareAPIControllerTest extends TestCase {
|
||||
'permissions' => 1,
|
||||
'stime' => 946684862,
|
||||
'parent' => null,
|
||||
'expiration' => '2001-02-03 04:05:06',
|
||||
'expiration' => '2001-02-03 00:00:00',
|
||||
'token' => null,
|
||||
'uid_file_owner' => 'owner',
|
||||
'displayname_file_owner' => 'owner',
|
||||
|
||||
@@ -99,11 +99,12 @@ class SharesReminderJobTest extends \Test\TestCase {
|
||||
$someMail = 'test@test.com';
|
||||
$noExpirationDate = null;
|
||||
$today = new \DateTime();
|
||||
// Expiration dates are set to end of day (23:59:59) by the Share Manager
|
||||
$today->setTime(23, 59, 59);
|
||||
$nearFuture = clone $today;
|
||||
// For expiration dates, the time is always automatically set to zero by ShareAPIController
|
||||
$today->setTime(0, 0);
|
||||
$nearFuture = new \DateTime();
|
||||
$nearFuture->setTimestamp($today->getTimestamp() + 86400 * 1);
|
||||
$farFuture = new \DateTime();
|
||||
$farFuture->setTimestamp($today->getTimestamp() + 86400 * 1);
|
||||
$farFuture->setTimestamp($today->getTimestamp() + 86400 * 2);
|
||||
$permissionRead = Constants::PERMISSION_READ;
|
||||
$permissionCreate = $permissionRead | Constants::PERMISSION_CREATE;
|
||||
$permissionUpdate = $permissionRead | Constants::PERMISSION_UPDATE;
|
||||
|
||||
@@ -193,6 +193,7 @@ abstract class TestCase extends \Test\TestCase {
|
||||
Server::get(IUserSession::class)->setUser(null);
|
||||
Filesystem::tearDown();
|
||||
Server::get(IUserSession::class)->login($user, $password);
|
||||
Filesystem::initMountPoints($user);
|
||||
\OC::$server->getUserFolder($user);
|
||||
|
||||
\OC_Util::setupFS($user);
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
OC.L10N.register(
|
||||
"profile",
|
||||
{
|
||||
"Profile" : "Профіль",
|
||||
"Searching …" : "Пошук …",
|
||||
"Not found" : "Не знойдзена",
|
||||
"Insert" : "Уставіць",
|
||||
"You have not added any info yet" : "Вы пакуль не дадалі ніякай інфармацыі",
|
||||
"{user} has not added any info yet" : "{user} пакуль не дадаў(-ла) ніякай інфармацыі",
|
||||
"Error opening the user status modal, try hard refreshing the page" : "Памылка пры адкрыцці статусу карыстальніка, паспрабуйце абнавіць старонку",
|
||||
"Edit Profile" : "Рэдагаваць профіль",
|
||||
"Profile not found" : "Профіль не знойдзены",
|
||||
"The profile does not exist." : "Профіль не існуе.",
|
||||
"Back to %s" : "Назад да %s"
|
||||
},
|
||||
"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);");
|
||||
@@ -1,14 +0,0 @@
|
||||
{ "translations": {
|
||||
"Profile" : "Профіль",
|
||||
"Searching …" : "Пошук …",
|
||||
"Not found" : "Не знойдзена",
|
||||
"Insert" : "Уставіць",
|
||||
"You have not added any info yet" : "Вы пакуль не дадалі ніякай інфармацыі",
|
||||
"{user} has not added any info yet" : "{user} пакуль не дадаў(-ла) ніякай інфармацыі",
|
||||
"Error opening the user status modal, try hard refreshing the page" : "Памылка пры адкрыцці статусу карыстальніка, паспрабуйце абнавіць старонку",
|
||||
"Edit Profile" : "Рэдагаваць профіль",
|
||||
"Profile not found" : "Профіль не знойдзены",
|
||||
"The profile does not exist." : "Профіль не існуе.",
|
||||
"Back to %s" : "Назад да %s"
|
||||
},"pluralForm" :"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);"
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
OC.L10N.register(
|
||||
"profile",
|
||||
{
|
||||
"Searching …" : "Cercant …",
|
||||
"Not found" : "No s'ha trobat",
|
||||
"Insert" : "Insereix",
|
||||
"You have not added any info yet" : "Encara no heu afegit cap informació",
|
||||
"{user} has not added any info yet" : "{user} encara no ha afegit cap informació",
|
||||
"Error opening the user status modal, try hard refreshing the page" : "S'ha produït un error en obrir el quadre de diàleg modal d'estat de l'usuari, proveu d'actualitzar la pàgina",
|
||||
"Edit Profile" : "Edita el perfil",
|
||||
"The headline and about sections will show up here" : "La capçalera i les seccions d'informació es mostraran aquí",
|
||||
"Profile not found" : "No s'ha trobat el perfil",
|
||||
"The profile does not exist." : "El perfil no existeix.",
|
||||
"Back to %s" : "Torna a %s"
|
||||
},
|
||||
"nplurals=2; plural=(n != 1);");
|
||||
@@ -1,14 +0,0 @@
|
||||
{ "translations": {
|
||||
"Searching …" : "Cercant …",
|
||||
"Not found" : "No s'ha trobat",
|
||||
"Insert" : "Insereix",
|
||||
"You have not added any info yet" : "Encara no heu afegit cap informació",
|
||||
"{user} has not added any info yet" : "{user} encara no ha afegit cap informació",
|
||||
"Error opening the user status modal, try hard refreshing the page" : "S'ha produït un error en obrir el quadre de diàleg modal d'estat de l'usuari, proveu d'actualitzar la pàgina",
|
||||
"Edit Profile" : "Edita el perfil",
|
||||
"The headline and about sections will show up here" : "La capçalera i les seccions d'informació es mostraran aquí",
|
||||
"Profile not found" : "No s'ha trobat el perfil",
|
||||
"The profile does not exist." : "El perfil no existeix.",
|
||||
"Back to %s" : "Torna a %s"
|
||||
},"pluralForm" :"nplurals=2; plural=(n != 1);"
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
OC.L10N.register(
|
||||
"profile",
|
||||
{
|
||||
"Searching …" : "Leita …",
|
||||
"Not found" : "Fannst ekki",
|
||||
"Insert" : "Setja inn",
|
||||
"You have not added any info yet" : "Þú hefur ekki bætt við neinum upplýsingum ennþá",
|
||||
"{user} has not added any info yet" : "{user} hefur ekki bætt við neinum upplýsingum ennþá",
|
||||
"Error opening the user status modal, try hard refreshing the page" : "Villa við að opna stöðuglugga notandans, prófaðu að þvinga endurlestur síðunnar",
|
||||
"Edit Profile" : "Breyta sniði",
|
||||
"The headline and about sections will show up here" : "Fyrirsögnin og hlutar um hugbúnaðinn munu birtast hér",
|
||||
"Profile not found" : "Sniðið finnst ekki",
|
||||
"The profile does not exist." : "Sniðið er ekki til.",
|
||||
"Back to %s" : "Til baka í %s"
|
||||
},
|
||||
"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);");
|
||||
@@ -1,14 +0,0 @@
|
||||
{ "translations": {
|
||||
"Searching …" : "Leita …",
|
||||
"Not found" : "Fannst ekki",
|
||||
"Insert" : "Setja inn",
|
||||
"You have not added any info yet" : "Þú hefur ekki bætt við neinum upplýsingum ennþá",
|
||||
"{user} has not added any info yet" : "{user} hefur ekki bætt við neinum upplýsingum ennþá",
|
||||
"Error opening the user status modal, try hard refreshing the page" : "Villa við að opna stöðuglugga notandans, prófaðu að þvinga endurlestur síðunnar",
|
||||
"Edit Profile" : "Breyta sniði",
|
||||
"The headline and about sections will show up here" : "Fyrirsögnin og hlutar um hugbúnaðinn munu birtast hér",
|
||||
"Profile not found" : "Sniðið finnst ekki",
|
||||
"The profile does not exist." : "Sniðið er ekki til.",
|
||||
"Back to %s" : "Til baka í %s"
|
||||
},"pluralForm" :"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);"
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
OC.L10N.register(
|
||||
"profile",
|
||||
{
|
||||
"Profile" : "Профил",
|
||||
"Searching …" : "Пребарување …",
|
||||
"Not found" : "Не е пронајдено",
|
||||
"You have not added any info yet" : "Сè уште немате додадено никакви информации",
|
||||
"{user} has not added any info yet" : "{user} нема додадено никакви информации",
|
||||
"Edit Profile" : "Уреди профил",
|
||||
"The headline and about sections will show up here" : "Насловот и за секциите ќе се појават овде",
|
||||
"Profile not found" : "Профилот не е пронајден",
|
||||
"The profile does not exist." : "Профилот на постои",
|
||||
"Back to %s" : "Врати се на %s"
|
||||
},
|
||||
"nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;");
|
||||
@@ -1,13 +0,0 @@
|
||||
{ "translations": {
|
||||
"Profile" : "Профил",
|
||||
"Searching …" : "Пребарување …",
|
||||
"Not found" : "Не е пронајдено",
|
||||
"You have not added any info yet" : "Сè уште немате додадено никакви информации",
|
||||
"{user} has not added any info yet" : "{user} нема додадено никакви информации",
|
||||
"Edit Profile" : "Уреди профил",
|
||||
"The headline and about sections will show up here" : "Насловот и за секциите ќе се појават овде",
|
||||
"Profile not found" : "Профилот не е пронајден",
|
||||
"The profile does not exist." : "Профилот на постои",
|
||||
"Back to %s" : "Врати се на %s"
|
||||
},"pluralForm" :"nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;"
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
OC.L10N.register(
|
||||
"profile",
|
||||
{
|
||||
"Profile picker" : "Selector de perfil",
|
||||
"Profile" : "Perfil",
|
||||
"Searching …" : "Recèrca…",
|
||||
"Not found" : "Non trobat",
|
||||
"Search for a user profile" : "Cercar un perfil utilizaire",
|
||||
"Search for a user profile. Start typing" : "Cercar un perfil utilizaire. Començatz de picar",
|
||||
"Insert selected user profile link" : "Inserir lo ligam del perfil utilizaire seleccionat",
|
||||
"Insert" : "Inserir",
|
||||
"Edit Profile" : "Modificar perfil",
|
||||
"Profile not found" : "Perfil pas trobat",
|
||||
"The profile does not exist." : "Lo perfil existís pas.",
|
||||
"Back to %s" : "Tornar a %s"
|
||||
},
|
||||
"nplurals=2; plural=(n > 1);");
|
||||
@@ -1,15 +0,0 @@
|
||||
{ "translations": {
|
||||
"Profile picker" : "Selector de perfil",
|
||||
"Profile" : "Perfil",
|
||||
"Searching …" : "Recèrca…",
|
||||
"Not found" : "Non trobat",
|
||||
"Search for a user profile" : "Cercar un perfil utilizaire",
|
||||
"Search for a user profile. Start typing" : "Cercar un perfil utilizaire. Començatz de picar",
|
||||
"Insert selected user profile link" : "Inserir lo ligam del perfil utilizaire seleccionat",
|
||||
"Insert" : "Inserir",
|
||||
"Edit Profile" : "Modificar perfil",
|
||||
"Profile not found" : "Perfil pas trobat",
|
||||
"The profile does not exist." : "Lo perfil existís pas.",
|
||||
"Back to %s" : "Tornar a %s"
|
||||
},"pluralForm" :"nplurals=2; plural=(n > 1);"
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
OC.L10N.register(
|
||||
"profile",
|
||||
{
|
||||
"Not found" : "Nu a fost găsit",
|
||||
"You have not added any info yet" : "Nu ați adăugat nicio informație",
|
||||
"{user} has not added any info yet" : "{user} nu a adăugat nicio informație",
|
||||
"Error opening the user status modal, try hard refreshing the page" : "Eroare la deschiderea status utilizator, încercați refresh",
|
||||
"Edit Profile" : "Editare profil",
|
||||
"The headline and about sections will show up here" : "Secțiunile titlu și despre vor fi afișate aici",
|
||||
"Profile not found" : "Profil inexistent",
|
||||
"The profile does not exist." : "Profilul nu există",
|
||||
"Back to %s" : "Înapoi la %s"
|
||||
},
|
||||
"nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));");
|
||||
@@ -1,12 +0,0 @@
|
||||
{ "translations": {
|
||||
"Not found" : "Nu a fost găsit",
|
||||
"You have not added any info yet" : "Nu ați adăugat nicio informație",
|
||||
"{user} has not added any info yet" : "{user} nu a adăugat nicio informație",
|
||||
"Error opening the user status modal, try hard refreshing the page" : "Eroare la deschiderea status utilizator, încercați refresh",
|
||||
"Edit Profile" : "Editare profil",
|
||||
"The headline and about sections will show up here" : "Secțiunile titlu și despre vor fi afișate aici",
|
||||
"Profile not found" : "Profil inexistent",
|
||||
"The profile does not exist." : "Profilul nu există",
|
||||
"Back to %s" : "Înapoi la %s"
|
||||
},"pluralForm" :"nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
OC.L10N.register(
|
||||
"profile",
|
||||
{
|
||||
"Not found" : "ไม่พบ",
|
||||
"You have not added any info yet" : "คุณยังไม่ได้เพิ่มข้อมูลใด ๆ",
|
||||
"{user} has not added any info yet" : "{user} ยังไม่ได้เพิ่มข้อมูลใด ๆ",
|
||||
"Edit Profile" : "แก้ไขโปรไฟล์",
|
||||
"Profile not found" : "ไม่พบโปรไฟล์",
|
||||
"The profile does not exist." : "โปรไฟล์นี้ไม่มีอยู่",
|
||||
"Back to %s" : "กลับสู่ %s"
|
||||
},
|
||||
"nplurals=1; plural=0;");
|
||||
@@ -0,0 +1,10 @@
|
||||
{ "translations": {
|
||||
"Not found" : "ไม่พบ",
|
||||
"You have not added any info yet" : "คุณยังไม่ได้เพิ่มข้อมูลใด ๆ",
|
||||
"{user} has not added any info yet" : "{user} ยังไม่ได้เพิ่มข้อมูลใด ๆ",
|
||||
"Edit Profile" : "แก้ไขโปรไฟล์",
|
||||
"Profile not found" : "ไม่พบโปรไฟล์",
|
||||
"The profile does not exist." : "โปรไฟล์นี้ไม่มีอยู่",
|
||||
"Back to %s" : "กลับสู่ %s"
|
||||
},"pluralForm" :"nplurals=1; plural=0;"
|
||||
}
|
||||
@@ -1,15 +1,11 @@
|
||||
OC.L10N.register(
|
||||
"profile",
|
||||
{
|
||||
"Profile picker" : "Profil seçici",
|
||||
"Profile" : "Profil",
|
||||
"This application provides the profile" : "Bu uygulama profili sağlar",
|
||||
"Provides a customisable user profile interface." : "Özelleştirilebilir bir kullanıcı profili arayüzü sağlar.",
|
||||
"Searching …" : "Aranıyor…",
|
||||
"Not found" : "Bulunamadı",
|
||||
"Search for a user profile" : "Kullanıcı profili ara",
|
||||
"Search for a user profile. Start typing" : "Aranacak kullanıcı profilini yazmaya başlayın",
|
||||
"Insert selected user profile link" : "Seçilmiş kullanıcı profili bağlantısını ekle",
|
||||
"Insert" : "Ekle",
|
||||
"You have not added any info yet" : "Henüz herhangi bir bilgi eklememişsiniz",
|
||||
"{user} has not added any info yet" : "{user} henüz herhangi bir bilgi eklememiş",
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
{ "translations": {
|
||||
"Profile picker" : "Profil seçici",
|
||||
"Profile" : "Profil",
|
||||
"This application provides the profile" : "Bu uygulama profili sağlar",
|
||||
"Provides a customisable user profile interface." : "Özelleştirilebilir bir kullanıcı profili arayüzü sağlar.",
|
||||
"Searching …" : "Aranıyor…",
|
||||
"Not found" : "Bulunamadı",
|
||||
"Search for a user profile" : "Kullanıcı profili ara",
|
||||
"Search for a user profile. Start typing" : "Aranacak kullanıcı profilini yazmaya başlayın",
|
||||
"Insert selected user profile link" : "Seçilmiş kullanıcı profili bağlantısını ekle",
|
||||
"Insert" : "Ekle",
|
||||
"You have not added any info yet" : "Henüz herhangi bir bilgi eklememişsiniz",
|
||||
"{user} has not added any info yet" : "{user} henüz herhangi bir bilgi eklememiş",
|
||||
|
||||
@@ -593,11 +593,8 @@ OC.L10N.register(
|
||||
"cron.php is registered at a webcron service to call cron.php every 5 minutes over HTTP. Use case: Very small instance (1–5 accounts depending on the usage)." : "cron.php ist bei einem Webcron-Dienst registriert, um cron.php alle 5 Minuten über HTTP aufzurufen. Anwendungsfall: Sehr kleine Instanz (1–5 Konten, je nach Nutzung).",
|
||||
"Cron (Recommended)" : "Cron (Empfohlen)",
|
||||
"Unable to update profile default setting" : "Standardeinstellung des Profils kann nicht aktualisiert werden",
|
||||
"Unable to update profile picker setting" : "Einstellungen der Profilauswahl konnten nicht aktualisiert werden",
|
||||
"Profile" : "Profil",
|
||||
"Enable or disable profile by default for new accounts." : "Profil für neue Konten standardmäßig aktivieren oder deaktivieren.",
|
||||
"Enable the profile picker" : "Profilauswahl aktivieren",
|
||||
"Enable or disable the profile picker in the Smart Picker and the profile link previews." : "Aktivieren oder deaktivieren der Profilauswahl im Smart Picker und die Vorschau der Profilverknüpfungen.",
|
||||
"Password confirmation is required" : "Passwortbestätigung erforderlich",
|
||||
"Failed to save setting" : "Einstellung konnte nicht gespeichert werden",
|
||||
"{app}'s declarative setting field: {name}" : "Deklaratives Einstellungsfeld von {app}: {name}",
|
||||
|
||||
@@ -591,11 +591,8 @@
|
||||
"cron.php is registered at a webcron service to call cron.php every 5 minutes over HTTP. Use case: Very small instance (1–5 accounts depending on the usage)." : "cron.php ist bei einem Webcron-Dienst registriert, um cron.php alle 5 Minuten über HTTP aufzurufen. Anwendungsfall: Sehr kleine Instanz (1–5 Konten, je nach Nutzung).",
|
||||
"Cron (Recommended)" : "Cron (Empfohlen)",
|
||||
"Unable to update profile default setting" : "Standardeinstellung des Profils kann nicht aktualisiert werden",
|
||||
"Unable to update profile picker setting" : "Einstellungen der Profilauswahl konnten nicht aktualisiert werden",
|
||||
"Profile" : "Profil",
|
||||
"Enable or disable profile by default for new accounts." : "Profil für neue Konten standardmäßig aktivieren oder deaktivieren.",
|
||||
"Enable the profile picker" : "Profilauswahl aktivieren",
|
||||
"Enable or disable the profile picker in the Smart Picker and the profile link previews." : "Aktivieren oder deaktivieren der Profilauswahl im Smart Picker und die Vorschau der Profilverknüpfungen.",
|
||||
"Password confirmation is required" : "Passwortbestätigung erforderlich",
|
||||
"Failed to save setting" : "Einstellung konnte nicht gespeichert werden",
|
||||
"{app}'s declarative setting field: {name}" : "Deklaratives Einstellungsfeld von {app}: {name}",
|
||||
|
||||
@@ -593,11 +593,8 @@ OC.L10N.register(
|
||||
"cron.php is registered at a webcron service to call cron.php every 5 minutes over HTTP. Use case: Very small instance (1–5 accounts depending on the usage)." : "cron.php ist bei einem Webcron-Dienst registriert, um cron.php alle 5 Minuten über HTTP aufzurufen. Anwendungsfall: Sehr kleine Instanz (1–5 Konten, je nach Nutzung).",
|
||||
"Cron (Recommended)" : "Cron (Empfohlen)",
|
||||
"Unable to update profile default setting" : "Standardeinstellung des Profils kann nicht aktualisiert werden",
|
||||
"Unable to update profile picker setting" : "Einstellungen der Profilauswahl konnten nicht aktualisiert werden",
|
||||
"Profile" : "Profil",
|
||||
"Enable or disable profile by default for new accounts." : "Profil für neue Konten standardmäßig aktivieren oder deaktivieren.",
|
||||
"Enable the profile picker" : "Profilauswahl aktivieren",
|
||||
"Enable or disable the profile picker in the Smart Picker and the profile link previews." : "Aktivieren oder deaktivieren der Profilauswahl im Smart Picker und die Vorschau der Profilverknüpfungen.",
|
||||
"Password confirmation is required" : "Passwortbestätigung erforderlich",
|
||||
"Failed to save setting" : "Einstellung konnte nicht gespeichert werden",
|
||||
"{app}'s declarative setting field: {name}" : "Deklaratives Einstellungsfeld von {app}: {name}",
|
||||
|
||||
@@ -591,11 +591,8 @@
|
||||
"cron.php is registered at a webcron service to call cron.php every 5 minutes over HTTP. Use case: Very small instance (1–5 accounts depending on the usage)." : "cron.php ist bei einem Webcron-Dienst registriert, um cron.php alle 5 Minuten über HTTP aufzurufen. Anwendungsfall: Sehr kleine Instanz (1–5 Konten, je nach Nutzung).",
|
||||
"Cron (Recommended)" : "Cron (Empfohlen)",
|
||||
"Unable to update profile default setting" : "Standardeinstellung des Profils kann nicht aktualisiert werden",
|
||||
"Unable to update profile picker setting" : "Einstellungen der Profilauswahl konnten nicht aktualisiert werden",
|
||||
"Profile" : "Profil",
|
||||
"Enable or disable profile by default for new accounts." : "Profil für neue Konten standardmäßig aktivieren oder deaktivieren.",
|
||||
"Enable the profile picker" : "Profilauswahl aktivieren",
|
||||
"Enable or disable the profile picker in the Smart Picker and the profile link previews." : "Aktivieren oder deaktivieren der Profilauswahl im Smart Picker und die Vorschau der Profilverknüpfungen.",
|
||||
"Password confirmation is required" : "Passwortbestätigung erforderlich",
|
||||
"Failed to save setting" : "Einstellung konnte nicht gespeichert werden",
|
||||
"{app}'s declarative setting field: {name}" : "Deklaratives Einstellungsfeld von {app}: {name}",
|
||||
|
||||
@@ -593,11 +593,8 @@ OC.L10N.register(
|
||||
"cron.php is registered at a webcron service to call cron.php every 5 minutes over HTTP. Use case: Very small instance (1–5 accounts depending on the usage)." : "cron.php está rexistrado nun servizo webcron para chamar a cron.php cada 5 minutos a través de HTTP. Caso de uso: instancia moi pequena (de 1 a 5 contas segundo o uso).",
|
||||
"Cron (Recommended)" : "Cron (Recomendado)",
|
||||
"Unable to update profile default setting" : "Non é posíbel actualizar a configuración predeterminada do perfil",
|
||||
"Unable to update profile picker setting" : "Non é posíbel actualizar a configuración do selector de perfil",
|
||||
"Profile" : "Perfil",
|
||||
"Enable or disable profile by default for new accounts." : "Activar ou desactivar o perfil predeterminado para as novas contas.",
|
||||
"Enable the profile picker" : "Activar o selector de perfil",
|
||||
"Enable or disable the profile picker in the Smart Picker and the profile link previews." : "Activar ou desactivar o selector de perfís no Selector intelixente e nas vistas previas da ligazón ao perfil.",
|
||||
"Password confirmation is required" : "Requírese a confirmación do contrasinal",
|
||||
"Failed to save setting" : "Produciuse un fallo ao gardar o axuste",
|
||||
"{app}'s declarative setting field: {name}" : "Campo de axuste declarativo de {app}: {name}",
|
||||
|
||||
@@ -591,11 +591,8 @@
|
||||
"cron.php is registered at a webcron service to call cron.php every 5 minutes over HTTP. Use case: Very small instance (1–5 accounts depending on the usage)." : "cron.php está rexistrado nun servizo webcron para chamar a cron.php cada 5 minutos a través de HTTP. Caso de uso: instancia moi pequena (de 1 a 5 contas segundo o uso).",
|
||||
"Cron (Recommended)" : "Cron (Recomendado)",
|
||||
"Unable to update profile default setting" : "Non é posíbel actualizar a configuración predeterminada do perfil",
|
||||
"Unable to update profile picker setting" : "Non é posíbel actualizar a configuración do selector de perfil",
|
||||
"Profile" : "Perfil",
|
||||
"Enable or disable profile by default for new accounts." : "Activar ou desactivar o perfil predeterminado para as novas contas.",
|
||||
"Enable the profile picker" : "Activar o selector de perfil",
|
||||
"Enable or disable the profile picker in the Smart Picker and the profile link previews." : "Activar ou desactivar o selector de perfís no Selector intelixente e nas vistas previas da ligazón ao perfil.",
|
||||
"Password confirmation is required" : "Requírese a confirmación do contrasinal",
|
||||
"Failed to save setting" : "Produciuse un fallo ao gardar o axuste",
|
||||
"{app}'s declarative setting field: {name}" : "Campo de axuste declarativo de {app}: {name}",
|
||||
|
||||
@@ -593,11 +593,8 @@ OC.L10N.register(
|
||||
"cron.php is registered at a webcron service to call cron.php every 5 minutes over HTTP. Use case: Very small instance (1–5 accounts depending on the usage)." : "cron.php é registrado em um serviço webcron para chamar cron.php a cada 5 minutos por HTTP. Caso de uso: Instância muito pequena (1–5 contas dependendo do uso).",
|
||||
"Cron (Recommended)" : "Cron (Recomendado)",
|
||||
"Unable to update profile default setting" : "Não foi possível atualizar a configuração padrão do perfil",
|
||||
"Unable to update profile picker setting" : "Não é possível atualizar a configuração do seletor de perfis",
|
||||
"Profile" : "Perfil",
|
||||
"Enable or disable profile by default for new accounts." : "Ativar ou desativar o perfil por padrão para novas contas.",
|
||||
"Enable the profile picker" : "Ativar o seletor de perfis",
|
||||
"Enable or disable the profile picker in the Smart Picker and the profile link previews." : "Ative ou desative o seletor de perfis no seletor inteligente e as pré-visualizações dos links dos perfis.",
|
||||
"Password confirmation is required" : "A confirmação da senha é necessária",
|
||||
"Failed to save setting" : "Falha ao salvar a configuração",
|
||||
"{app}'s declarative setting field: {name}" : "Campo de configuração declarativa de {app}: {name}",
|
||||
|
||||
@@ -591,11 +591,8 @@
|
||||
"cron.php is registered at a webcron service to call cron.php every 5 minutes over HTTP. Use case: Very small instance (1–5 accounts depending on the usage)." : "cron.php é registrado em um serviço webcron para chamar cron.php a cada 5 minutos por HTTP. Caso de uso: Instância muito pequena (1–5 contas dependendo do uso).",
|
||||
"Cron (Recommended)" : "Cron (Recomendado)",
|
||||
"Unable to update profile default setting" : "Não foi possível atualizar a configuração padrão do perfil",
|
||||
"Unable to update profile picker setting" : "Não é possível atualizar a configuração do seletor de perfis",
|
||||
"Profile" : "Perfil",
|
||||
"Enable or disable profile by default for new accounts." : "Ativar ou desativar o perfil por padrão para novas contas.",
|
||||
"Enable the profile picker" : "Ativar o seletor de perfis",
|
||||
"Enable or disable the profile picker in the Smart Picker and the profile link previews." : "Ative ou desative o seletor de perfis no seletor inteligente e as pré-visualizações dos links dos perfis.",
|
||||
"Password confirmation is required" : "A confirmação da senha é necessária",
|
||||
"Failed to save setting" : "Falha ao salvar a configuração",
|
||||
"{app}'s declarative setting field: {name}" : "Campo de configuração declarativa de {app}: {name}",
|
||||
|
||||
@@ -330,10 +330,6 @@ OC.L10N.register(
|
||||
"Database transaction isolation level" : "Veri tabanı işlemsel yalıtım düzeyi",
|
||||
"Your database does not run with \"READ COMMITTED\" transaction isolation level. This can cause problems when multiple actions are executed in parallel." : "Veri tabanınız \"READ COMMITTED\" işlem yalıtma düzeyinde çalışmıyor. Bu durum aynı anda birden çok işlem yapıldığında sorun çıkmasına yol açabilir.",
|
||||
"Was not able to get transaction isolation level: %s" : "İşlemsel yalıtım düzeyi alınamadı: %s",
|
||||
"Second factor configuration" : "İkinci adım yapılandırması",
|
||||
"This instance has no second factor provider available." : "Bu kopyada kullanılabilecek bir ikinci adım hizmeti sağlayıcısı yok.",
|
||||
"Second factor providers are available but two-factor authentication is not enforced." : "Kullanılabilecek ikinci adım hizmeti sağlayıcıları var, ancak iki adımlı doğrulama zorunlu değil.",
|
||||
"Second factor providers are available and enforced: %s." : "Kullanılabilecek ikinci adım hizmeti sağlayıcıları var ve kullanılması zorunlu: %s.",
|
||||
".well-known URLs" : ".well-known adresler",
|
||||
"`check_for_working_wellknown_setup` is set to false in your configuration, so this check was skipped." : "Yapılandırmanızda `check_for_working_wellknown_setup` değerinin false olarak ayarlandığından emin olun. Böylece bu denetim atlanır.",
|
||||
"Could not check that your web server serves `.well-known` correctly. Please check manually." : "Site sunucunuzun `.well.known` bilgisini doğru şekilde sunup sunmadığı denetlenemedi. Lütfen el ile denetleyin.",
|
||||
@@ -386,8 +382,6 @@ OC.L10N.register(
|
||||
"Shares with guessable tokens may be accessed easily" : "Öngörülebilir kodları olan paylaşımlara kolayca erişilebilir",
|
||||
"Limit sharing based on groups" : "Paylaşımlar gruplara göre sınırlansın",
|
||||
"Allow sharing for everyone (default)" : "Herkes ile paylaşım yapılabilsin (varsayılan)",
|
||||
"Exclude some groups" : "Bazı gruplar katılmasın",
|
||||
"Allow some groups" : "Bazı gruplar katılsın",
|
||||
"Groups allowed to share" : "Paylaşım yapılabilecek gruplar",
|
||||
"Groups excluded from sharing" : "Paylaşıma katılmayacak gruplar",
|
||||
"Not allowed groups will still be able to receive shares, but not to initiate them." : "İzin verilmeyen gruplar paylaşımları almayı sürdürebilir ancak paylaşım yapamaz.",
|
||||
@@ -442,16 +436,9 @@ OC.L10N.register(
|
||||
"This app is supported via your current Nextcloud subscription." : "Bu uygulamanın desteği geçerli Nextcloud aboneliğiniz ile sağlanır.",
|
||||
"Featured apps are developed by and within the community. They offer central functionality and are ready for production use." : "Öne çıkarılmış uygulamalar topluluk tarafından geliştirilmiştir. Temel işlevleri yerine getirirler ve üretim ortamında kullanılabilirler.",
|
||||
"Community rating: {score}/5" : "Topluluk değerlendirmesi: {score}/5",
|
||||
"Office suite switching is managed through the Nextcloud All-in-One interface." : "Ofis paketi değişikliği Nextcloud tümü bir arada arayüzünden yapılır.",
|
||||
"Please use the AIO interface to switch between office suites." : "Ofis paketi değişikliği yapmak için tümü bir arada arayüzünü kullanın.",
|
||||
"Select your preferred office suite. Please note that installing requires manual server setup." : "Kullanmak istediğiniz ofis paketini seçin. Kurulum için sunucuda el ile işlem yapılması gerektirdiğini unutmayın.",
|
||||
"installed" : "kurulmuş",
|
||||
"Learn more" : "Ayrıntılı bilgi alın",
|
||||
"Disable office suites" : "Ofis paketlerini kullanımdan kaldır",
|
||||
"Disable all" : "Tümünü kullanımdan kaldır",
|
||||
"Download and enable all" : "İndir ve tümünü kullanıma al",
|
||||
"All office suites disabled" : "Tüm ofis paketleri kullanımdan kaldırıldı",
|
||||
"{name} enabled" : "{name} kullanıma alındı",
|
||||
"All apps are up-to-date." : "Tüm uygulamalar güncel",
|
||||
"Icon" : "Simge",
|
||||
"Name" : "Ad",
|
||||
@@ -593,11 +580,8 @@ OC.L10N.register(
|
||||
"cron.php is registered at a webcron service to call cron.php every 5 minutes over HTTP. Use case: Very small instance (1–5 accounts depending on the usage)." : "cron.php, HTTP üzerinden her 5 dakikada bir cron.php sayfasını çağıran bir internet zamanlanmış görevi hizmetinde kayıtlıdır. Kullanım şekli: Çok küçük kopya (kullanıma bağlı olarak 1–5 hesap).",
|
||||
"Cron (Recommended)" : "Cron (önerilen)",
|
||||
"Unable to update profile default setting" : "Profil varsayılan ayarı güncellenemedi",
|
||||
"Unable to update profile picker setting" : "Profil seçici ayarı güncellenemedi",
|
||||
"Profile" : "Profil",
|
||||
"Enable or disable profile by default for new accounts." : "Yeni hesaplar için profilleri varsayılan olarak kullanıma al ya da kaldır.",
|
||||
"Enable the profile picker" : "Profil seçiciyi aç",
|
||||
"Enable or disable the profile picker in the Smart Picker and the profile link previews." : "Akıllı seçicide profil seçiciyi ve profil bağlantısı ön izlemelerini açar ya da kapatır.",
|
||||
"Password confirmation is required" : "Parola onayının yazılması zorunludur",
|
||||
"Failed to save setting" : "Ayar kaydedilemedi",
|
||||
"{app}'s declarative setting field: {name}" : "{app} uygulamasının bildirdiği ayar alanı: {name}",
|
||||
@@ -914,17 +898,6 @@ OC.L10N.register(
|
||||
"App bundles" : "Uygulama Paketleri",
|
||||
"Featured apps" : "Öne çıkarılmış uygulamalar",
|
||||
"Supported apps" : "Desteklenen uygulamalar",
|
||||
"Best Nextcloud integration" : "En iyi Nextcloud bütünleştirmesi",
|
||||
"Open source" : "Açık kaynaklı",
|
||||
"Good performance" : "İyi başarım",
|
||||
"Best security: documents never leave your server" : "En iyi güvenlik: Belgeler asla sunucunuzdan ayrılmaz",
|
||||
"Best ODF compatibility" : "En iyi ODF uyumluluğu",
|
||||
"Best support for legacy files" : "Eski dosyalar için en iyi destek",
|
||||
"Good Nextcloud integration" : "İyi Nextcloud bütünleştirmesi",
|
||||
"Open core" : "Açık çekirdekli",
|
||||
"Best performance" : "En iyi başarım",
|
||||
"Limited ODF compatibility" : "Sınırlı ODF uyumluluğu",
|
||||
"Best Microsoft compatibility" : "En iyi Microsoft uyumluluğu",
|
||||
"Show to everyone" : "Herkese görüntülensin",
|
||||
"Show to logged in accounts only" : "Yalnızca oturum açmış hesaplara görüntülensin",
|
||||
"Hide" : "Gizlensin",
|
||||
|
||||
@@ -328,10 +328,6 @@
|
||||
"Database transaction isolation level" : "Veri tabanı işlemsel yalıtım düzeyi",
|
||||
"Your database does not run with \"READ COMMITTED\" transaction isolation level. This can cause problems when multiple actions are executed in parallel." : "Veri tabanınız \"READ COMMITTED\" işlem yalıtma düzeyinde çalışmıyor. Bu durum aynı anda birden çok işlem yapıldığında sorun çıkmasına yol açabilir.",
|
||||
"Was not able to get transaction isolation level: %s" : "İşlemsel yalıtım düzeyi alınamadı: %s",
|
||||
"Second factor configuration" : "İkinci adım yapılandırması",
|
||||
"This instance has no second factor provider available." : "Bu kopyada kullanılabilecek bir ikinci adım hizmeti sağlayıcısı yok.",
|
||||
"Second factor providers are available but two-factor authentication is not enforced." : "Kullanılabilecek ikinci adım hizmeti sağlayıcıları var, ancak iki adımlı doğrulama zorunlu değil.",
|
||||
"Second factor providers are available and enforced: %s." : "Kullanılabilecek ikinci adım hizmeti sağlayıcıları var ve kullanılması zorunlu: %s.",
|
||||
".well-known URLs" : ".well-known adresler",
|
||||
"`check_for_working_wellknown_setup` is set to false in your configuration, so this check was skipped." : "Yapılandırmanızda `check_for_working_wellknown_setup` değerinin false olarak ayarlandığından emin olun. Böylece bu denetim atlanır.",
|
||||
"Could not check that your web server serves `.well-known` correctly. Please check manually." : "Site sunucunuzun `.well.known` bilgisini doğru şekilde sunup sunmadığı denetlenemedi. Lütfen el ile denetleyin.",
|
||||
@@ -384,8 +380,6 @@
|
||||
"Shares with guessable tokens may be accessed easily" : "Öngörülebilir kodları olan paylaşımlara kolayca erişilebilir",
|
||||
"Limit sharing based on groups" : "Paylaşımlar gruplara göre sınırlansın",
|
||||
"Allow sharing for everyone (default)" : "Herkes ile paylaşım yapılabilsin (varsayılan)",
|
||||
"Exclude some groups" : "Bazı gruplar katılmasın",
|
||||
"Allow some groups" : "Bazı gruplar katılsın",
|
||||
"Groups allowed to share" : "Paylaşım yapılabilecek gruplar",
|
||||
"Groups excluded from sharing" : "Paylaşıma katılmayacak gruplar",
|
||||
"Not allowed groups will still be able to receive shares, but not to initiate them." : "İzin verilmeyen gruplar paylaşımları almayı sürdürebilir ancak paylaşım yapamaz.",
|
||||
@@ -440,16 +434,9 @@
|
||||
"This app is supported via your current Nextcloud subscription." : "Bu uygulamanın desteği geçerli Nextcloud aboneliğiniz ile sağlanır.",
|
||||
"Featured apps are developed by and within the community. They offer central functionality and are ready for production use." : "Öne çıkarılmış uygulamalar topluluk tarafından geliştirilmiştir. Temel işlevleri yerine getirirler ve üretim ortamında kullanılabilirler.",
|
||||
"Community rating: {score}/5" : "Topluluk değerlendirmesi: {score}/5",
|
||||
"Office suite switching is managed through the Nextcloud All-in-One interface." : "Ofis paketi değişikliği Nextcloud tümü bir arada arayüzünden yapılır.",
|
||||
"Please use the AIO interface to switch between office suites." : "Ofis paketi değişikliği yapmak için tümü bir arada arayüzünü kullanın.",
|
||||
"Select your preferred office suite. Please note that installing requires manual server setup." : "Kullanmak istediğiniz ofis paketini seçin. Kurulum için sunucuda el ile işlem yapılması gerektirdiğini unutmayın.",
|
||||
"installed" : "kurulmuş",
|
||||
"Learn more" : "Ayrıntılı bilgi alın",
|
||||
"Disable office suites" : "Ofis paketlerini kullanımdan kaldır",
|
||||
"Disable all" : "Tümünü kullanımdan kaldır",
|
||||
"Download and enable all" : "İndir ve tümünü kullanıma al",
|
||||
"All office suites disabled" : "Tüm ofis paketleri kullanımdan kaldırıldı",
|
||||
"{name} enabled" : "{name} kullanıma alındı",
|
||||
"All apps are up-to-date." : "Tüm uygulamalar güncel",
|
||||
"Icon" : "Simge",
|
||||
"Name" : "Ad",
|
||||
@@ -591,11 +578,8 @@
|
||||
"cron.php is registered at a webcron service to call cron.php every 5 minutes over HTTP. Use case: Very small instance (1–5 accounts depending on the usage)." : "cron.php, HTTP üzerinden her 5 dakikada bir cron.php sayfasını çağıran bir internet zamanlanmış görevi hizmetinde kayıtlıdır. Kullanım şekli: Çok küçük kopya (kullanıma bağlı olarak 1–5 hesap).",
|
||||
"Cron (Recommended)" : "Cron (önerilen)",
|
||||
"Unable to update profile default setting" : "Profil varsayılan ayarı güncellenemedi",
|
||||
"Unable to update profile picker setting" : "Profil seçici ayarı güncellenemedi",
|
||||
"Profile" : "Profil",
|
||||
"Enable or disable profile by default for new accounts." : "Yeni hesaplar için profilleri varsayılan olarak kullanıma al ya da kaldır.",
|
||||
"Enable the profile picker" : "Profil seçiciyi aç",
|
||||
"Enable or disable the profile picker in the Smart Picker and the profile link previews." : "Akıllı seçicide profil seçiciyi ve profil bağlantısı ön izlemelerini açar ya da kapatır.",
|
||||
"Password confirmation is required" : "Parola onayının yazılması zorunludur",
|
||||
"Failed to save setting" : "Ayar kaydedilemedi",
|
||||
"{app}'s declarative setting field: {name}" : "{app} uygulamasının bildirdiği ayar alanı: {name}",
|
||||
@@ -912,17 +896,6 @@
|
||||
"App bundles" : "Uygulama Paketleri",
|
||||
"Featured apps" : "Öne çıkarılmış uygulamalar",
|
||||
"Supported apps" : "Desteklenen uygulamalar",
|
||||
"Best Nextcloud integration" : "En iyi Nextcloud bütünleştirmesi",
|
||||
"Open source" : "Açık kaynaklı",
|
||||
"Good performance" : "İyi başarım",
|
||||
"Best security: documents never leave your server" : "En iyi güvenlik: Belgeler asla sunucunuzdan ayrılmaz",
|
||||
"Best ODF compatibility" : "En iyi ODF uyumluluğu",
|
||||
"Best support for legacy files" : "Eski dosyalar için en iyi destek",
|
||||
"Good Nextcloud integration" : "İyi Nextcloud bütünleştirmesi",
|
||||
"Open core" : "Açık çekirdekli",
|
||||
"Best performance" : "En iyi başarım",
|
||||
"Limited ODF compatibility" : "Sınırlı ODF uyumluluğu",
|
||||
"Best Microsoft compatibility" : "En iyi Microsoft uyumluluğu",
|
||||
"Show to everyone" : "Herkese görüntülensin",
|
||||
"Show to logged in accounts only" : "Yalnızca oturum açmış hesaplara görüntülensin",
|
||||
"Hide" : "Gizlensin",
|
||||
|
||||
+16
-19
@@ -369,18 +369,18 @@ OC.L10N.register(
|
||||
"Restrict users to only share with users in their groups" : "Дозволити надання у спільний доступ тільки в межах власних груп",
|
||||
"Ignore the following groups when checking group membership" : "Ігнорувати такі групи під час перевірки участи в групі",
|
||||
"Allow users to preview files even if download is disabled" : "Дозволити користувачам переглядати файли, навіть якщо завантаження вимкнено",
|
||||
"Users will still be able to screenshot or record the screen. This does not provide any definitive protection." : "Користувачі все одно можуть робити скріншоти або записувати екран. Це не забезпечить надійним захистом.",
|
||||
"Users will still be able to screenshot or record the screen. This does not provide any definitive protection." : "Користувачі все одно зможуть робити скріншоти або записувати екран. Це не забезпечує жодного остаточного захисту.",
|
||||
"Allow users to share via link and emails" : "Дозволити користувачам надання у спільний доступ за допомогою посилань та ел. листів",
|
||||
"Allow public uploads" : "Дозволити публічне завантаження",
|
||||
"Allow public shares to be added to other clouds by federation." : "Дозволити додавати публічні ресурси до інших хмар за допомогою функціоналу об'єднаних хмар.",
|
||||
"Allow public shares to be added to other clouds by federation." : "Дозволити додавати публічні ресурси до інших хмар за допомогою федерації.",
|
||||
"This will add share permissions to all newly created link shares." : "Це додасть дозволи на спільний доступ до всіх новостворених спільних ресурсів посилань.",
|
||||
"Always ask for a password" : "Завжди запитувати пароль",
|
||||
"Enforce password protection" : "Захист паролем обов'язковий",
|
||||
"Exclude groups from password requirements" : "Виключення щодо вимог пароля для груп",
|
||||
"Exclude groups from creating link shares" : "Не дозволяти користувачам таких груп створювати посилання спільного доступу",
|
||||
"Allow users to set custom share link tokens" : "Дозволити користувачам встановлювати власні токени для спільного доступу",
|
||||
"Shares with custom tokens will continue to be accessible after this setting has been disabled" : "Спільний доступ з токенами користувачів залишатиметься активним після вимкнення цього параметра",
|
||||
"Shares with guessable tokens may be accessed easily" : "До спільних ресурсів з токенами, які можна спробувати вгадати, інші можуть легко отримати доступ.",
|
||||
"Allow users to set custom share link tokens" : "Дозволити користвучам встановити власні токени спільних посилань",
|
||||
"Shares with custom tokens will continue to be accessible after this setting has been disabled" : "Частки з власними токенами залишатимуться доступними після вимкнення цього параметра",
|
||||
"Shares with guessable tokens may be accessed easily" : "До спільних ресурсів з токенами, які можна вгадати, можна легко отримати доступ.",
|
||||
"Limit sharing based on groups" : "Обмежити надання у спільний доступ на основі груп",
|
||||
"Allow sharing for everyone (default)" : "Дозволити надання у спільний доступ для всіх (типово)",
|
||||
"Exclude some groups" : "Вилучити окремі групи",
|
||||
@@ -400,16 +400,16 @@ OC.L10N.register(
|
||||
"Enforce expiration date for link or mail shares" : "Застосовувати термін дії для посилань або спільного доступу до пошти",
|
||||
"Default expiration time of shares in days" : "Типовий термін дії спільних ресурсів у днях",
|
||||
"Privacy settings for sharing" : "Налаштування конфіденційності для спільного доступу",
|
||||
"Allow account name autocompletion in share dialog and allow access to the system address book" : "Дозволити автоматичне заповнення імени користувача та доступ до системної адресної книги",
|
||||
"Sharing autocompletion restrictions" : "Дозволи автоматичного заповнення для спільного доступу",
|
||||
"If autocompletion restrictions for both \"same group\" and \"phonebook integration\" are enabled, a match in either is enough to show the user." : "Якщо уімкнено автоматичне заповнення \"в межах власної групи\" та \"доступ за адресною книгою\", достатньо, щоби хоч раз було виконано умови, щоб показати ім'я користувача.",
|
||||
"Restrict account name autocompletion and system address book access to users within the same groups" : "Дозволити автоматичне заповнення імени користувача, доступ до системної адресної книги користувачам тільки в межах власних груп",
|
||||
"Restrict account name autocompletion to users based on their phonebook" : "Дозволити автоматичне заповнення імени користувача тільки з власних адресних книг користувачів",
|
||||
"Allow autocompletion to full match when entering the full name (ignoring restrictions like group membership or missing phonebook match)" : "Дозволити автоматичне заповнення, якщо введено ім'я користувача повністю (при цьому не враховуватимуться такі дозволи, як участь в групах або відсутність у адресній книзі)",
|
||||
"Full match autocompletion restrictions" : "Дозволи для автоматичного заповнення, якщо дані введено повністю",
|
||||
"Also allow autocompletion on full match of the user ID" : "Дозволити автоматичне заповнення, якщо введено повний ідентифікатор користувача",
|
||||
"Also allow autocompletion on full match of the display name" : "Дзволити автоматичне заповнення, якщо введено ім'я користувача",
|
||||
"Also allow autocompletion on full match of the user email" : "Дозволити автоматичне заповнення, якщо введено ел. адресу користувача",
|
||||
"Allow account name autocompletion in share dialog and allow access to the system address book" : "Дозволити автозаповнення імени користувача та доступ до системної адресної книги",
|
||||
"Sharing autocompletion restrictions" : "Обмеження автозавершення для спільного доступу",
|
||||
"If autocompletion restrictions for both \"same group\" and \"phonebook integration\" are enabled, a match in either is enough to show the user." : "Якщо задіяно автозавершення як для \"тієї саме групи\" та \"інтеграції з адресною книгою\", достатньо одного збігу, щоби показати ім'я користувача.",
|
||||
"Restrict account name autocompletion and system address book access to users within the same groups" : "Обмежити автозаповнення імени користувача та доступу до системної адресної книги тільки користувачам однієї й тої саме групи",
|
||||
"Restrict account name autocompletion to users based on their phonebook" : "Обмежити автозавершення імени користувача на основі адресних книг користувачів",
|
||||
"Allow autocompletion to full match when entering the full name (ignoring restrictions like group membership or missing phonebook match)" : "Дозволити автозавершення для повного збігу при введенні повного імени (не враховуватимуться такі обмеження, як участь в групах або незбіг з адресною книгою)",
|
||||
"Full match autocompletion restrictions" : "Обмеження повного збігу для автозавершення",
|
||||
"Also allow autocompletion on full match of the user ID" : "Також дозволити автозавершення при повному збігу ідентифікатора користувача",
|
||||
"Also allow autocompletion on full match of the display name" : "Також дозволити автозаповнення при повному збігу імени для показу",
|
||||
"Also allow autocompletion on full match of the user email" : "Також дозволити автозавершення при повному збігу ел. адреси користувача",
|
||||
"Do not use second user displayname for full match" : "Не використовувати друге ім'я для показу для повного збігу",
|
||||
"Show disclaimer text on the public link upload page (only shown when the file list is hidden)" : "Показувати текст застереження на сторінці завантаження публічного посилання (відображається, лише якщо список файлів приховано)",
|
||||
"Disclaimer text" : "Текст відмови від відповідальності",
|
||||
@@ -590,11 +590,8 @@ OC.L10N.register(
|
||||
"cron.php is registered at a webcron service to call cron.php every 5 minutes over HTTP. Use case: Very small instance (1–5 accounts depending on the usage)." : "cron.php зареєстровано на сервісі webcron, щоб викликати cron.php кожні 5 хвилин по HTTP. Варіант використання: Дуже маленький екземпляр (1-5 акаунтів залежно від використання).",
|
||||
"Cron (Recommended)" : "Cron (рекомендовано)",
|
||||
"Unable to update profile default setting" : "Не вдалося оновити стандартні налаштування профілю",
|
||||
"Unable to update profile picker setting" : "Не вдалося оновити налаштування вибору профілю",
|
||||
"Profile" : "Профіль",
|
||||
"Enable or disable profile by default for new accounts." : "Увімкнути або вимкнути стандартний профіль для нових акаунтів.",
|
||||
"Enable the profile picker" : "Увімкнути вибір профілю",
|
||||
"Enable or disable the profile picker in the Smart Picker and the profile link previews." : "Увімкнути або вимкнути вибір профілю для Асистента з вибору та попереднього перегляду посилання на профіль.",
|
||||
"Password confirmation is required" : "Необхідне підтвердження паролем",
|
||||
"Failed to save setting" : "Не вдалося зберегти налаштування",
|
||||
"{app}'s declarative setting field: {name}" : "Декларативне поле налаштувань {app}: {name}",
|
||||
@@ -981,7 +978,7 @@ OC.L10N.register(
|
||||
"Unable to retrieve the group list" : "Неможливо отримати список груп",
|
||||
"Exclude some groups from sharing" : "Не дозволяти таким групам надавати у спільний доступ",
|
||||
"Limit sharing to some groups" : "Дозволити надання у спільний доступ тільки для таких груп",
|
||||
"Also allow autocompletion on full match of the user id" : "Дозволити автоматичне заповнення, якщо введено повністю ідентифікатор користувача",
|
||||
"Also allow autocompletion on full match of the user id" : "Також дозволити автозавершення при повному збігу ідентифікатора користувача",
|
||||
"Loading accounts …" : "Завантаження облікових записів ...",
|
||||
"Set account as admin for …" : "Встановити адміністратором для ...",
|
||||
"_{userCount} account …_::_{userCount} accounts …_" : ["{userCount} обліковий запис …","{userCount} облікові записи …","{userCount} облікових записів …","{userCount} облікових записів …"],
|
||||
|
||||
+16
-19
@@ -367,18 +367,18 @@
|
||||
"Restrict users to only share with users in their groups" : "Дозволити надання у спільний доступ тільки в межах власних груп",
|
||||
"Ignore the following groups when checking group membership" : "Ігнорувати такі групи під час перевірки участи в групі",
|
||||
"Allow users to preview files even if download is disabled" : "Дозволити користувачам переглядати файли, навіть якщо завантаження вимкнено",
|
||||
"Users will still be able to screenshot or record the screen. This does not provide any definitive protection." : "Користувачі все одно можуть робити скріншоти або записувати екран. Це не забезпечить надійним захистом.",
|
||||
"Users will still be able to screenshot or record the screen. This does not provide any definitive protection." : "Користувачі все одно зможуть робити скріншоти або записувати екран. Це не забезпечує жодного остаточного захисту.",
|
||||
"Allow users to share via link and emails" : "Дозволити користувачам надання у спільний доступ за допомогою посилань та ел. листів",
|
||||
"Allow public uploads" : "Дозволити публічне завантаження",
|
||||
"Allow public shares to be added to other clouds by federation." : "Дозволити додавати публічні ресурси до інших хмар за допомогою функціоналу об'єднаних хмар.",
|
||||
"Allow public shares to be added to other clouds by federation." : "Дозволити додавати публічні ресурси до інших хмар за допомогою федерації.",
|
||||
"This will add share permissions to all newly created link shares." : "Це додасть дозволи на спільний доступ до всіх новостворених спільних ресурсів посилань.",
|
||||
"Always ask for a password" : "Завжди запитувати пароль",
|
||||
"Enforce password protection" : "Захист паролем обов'язковий",
|
||||
"Exclude groups from password requirements" : "Виключення щодо вимог пароля для груп",
|
||||
"Exclude groups from creating link shares" : "Не дозволяти користувачам таких груп створювати посилання спільного доступу",
|
||||
"Allow users to set custom share link tokens" : "Дозволити користувачам встановлювати власні токени для спільного доступу",
|
||||
"Shares with custom tokens will continue to be accessible after this setting has been disabled" : "Спільний доступ з токенами користувачів залишатиметься активним після вимкнення цього параметра",
|
||||
"Shares with guessable tokens may be accessed easily" : "До спільних ресурсів з токенами, які можна спробувати вгадати, інші можуть легко отримати доступ.",
|
||||
"Allow users to set custom share link tokens" : "Дозволити користвучам встановити власні токени спільних посилань",
|
||||
"Shares with custom tokens will continue to be accessible after this setting has been disabled" : "Частки з власними токенами залишатимуться доступними після вимкнення цього параметра",
|
||||
"Shares with guessable tokens may be accessed easily" : "До спільних ресурсів з токенами, які можна вгадати, можна легко отримати доступ.",
|
||||
"Limit sharing based on groups" : "Обмежити надання у спільний доступ на основі груп",
|
||||
"Allow sharing for everyone (default)" : "Дозволити надання у спільний доступ для всіх (типово)",
|
||||
"Exclude some groups" : "Вилучити окремі групи",
|
||||
@@ -398,16 +398,16 @@
|
||||
"Enforce expiration date for link or mail shares" : "Застосовувати термін дії для посилань або спільного доступу до пошти",
|
||||
"Default expiration time of shares in days" : "Типовий термін дії спільних ресурсів у днях",
|
||||
"Privacy settings for sharing" : "Налаштування конфіденційності для спільного доступу",
|
||||
"Allow account name autocompletion in share dialog and allow access to the system address book" : "Дозволити автоматичне заповнення імени користувача та доступ до системної адресної книги",
|
||||
"Sharing autocompletion restrictions" : "Дозволи автоматичного заповнення для спільного доступу",
|
||||
"If autocompletion restrictions for both \"same group\" and \"phonebook integration\" are enabled, a match in either is enough to show the user." : "Якщо уімкнено автоматичне заповнення \"в межах власної групи\" та \"доступ за адресною книгою\", достатньо, щоби хоч раз було виконано умови, щоб показати ім'я користувача.",
|
||||
"Restrict account name autocompletion and system address book access to users within the same groups" : "Дозволити автоматичне заповнення імени користувача, доступ до системної адресної книги користувачам тільки в межах власних груп",
|
||||
"Restrict account name autocompletion to users based on their phonebook" : "Дозволити автоматичне заповнення імени користувача тільки з власних адресних книг користувачів",
|
||||
"Allow autocompletion to full match when entering the full name (ignoring restrictions like group membership or missing phonebook match)" : "Дозволити автоматичне заповнення, якщо введено ім'я користувача повністю (при цьому не враховуватимуться такі дозволи, як участь в групах або відсутність у адресній книзі)",
|
||||
"Full match autocompletion restrictions" : "Дозволи для автоматичного заповнення, якщо дані введено повністю",
|
||||
"Also allow autocompletion on full match of the user ID" : "Дозволити автоматичне заповнення, якщо введено повний ідентифікатор користувача",
|
||||
"Also allow autocompletion on full match of the display name" : "Дзволити автоматичне заповнення, якщо введено ім'я користувача",
|
||||
"Also allow autocompletion on full match of the user email" : "Дозволити автоматичне заповнення, якщо введено ел. адресу користувача",
|
||||
"Allow account name autocompletion in share dialog and allow access to the system address book" : "Дозволити автозаповнення імени користувача та доступ до системної адресної книги",
|
||||
"Sharing autocompletion restrictions" : "Обмеження автозавершення для спільного доступу",
|
||||
"If autocompletion restrictions for both \"same group\" and \"phonebook integration\" are enabled, a match in either is enough to show the user." : "Якщо задіяно автозавершення як для \"тієї саме групи\" та \"інтеграції з адресною книгою\", достатньо одного збігу, щоби показати ім'я користувача.",
|
||||
"Restrict account name autocompletion and system address book access to users within the same groups" : "Обмежити автозаповнення імени користувача та доступу до системної адресної книги тільки користувачам однієї й тої саме групи",
|
||||
"Restrict account name autocompletion to users based on their phonebook" : "Обмежити автозавершення імени користувача на основі адресних книг користувачів",
|
||||
"Allow autocompletion to full match when entering the full name (ignoring restrictions like group membership or missing phonebook match)" : "Дозволити автозавершення для повного збігу при введенні повного імени (не враховуватимуться такі обмеження, як участь в групах або незбіг з адресною книгою)",
|
||||
"Full match autocompletion restrictions" : "Обмеження повного збігу для автозавершення",
|
||||
"Also allow autocompletion on full match of the user ID" : "Також дозволити автозавершення при повному збігу ідентифікатора користувача",
|
||||
"Also allow autocompletion on full match of the display name" : "Також дозволити автозаповнення при повному збігу імени для показу",
|
||||
"Also allow autocompletion on full match of the user email" : "Також дозволити автозавершення при повному збігу ел. адреси користувача",
|
||||
"Do not use second user displayname for full match" : "Не використовувати друге ім'я для показу для повного збігу",
|
||||
"Show disclaimer text on the public link upload page (only shown when the file list is hidden)" : "Показувати текст застереження на сторінці завантаження публічного посилання (відображається, лише якщо список файлів приховано)",
|
||||
"Disclaimer text" : "Текст відмови від відповідальності",
|
||||
@@ -588,11 +588,8 @@
|
||||
"cron.php is registered at a webcron service to call cron.php every 5 minutes over HTTP. Use case: Very small instance (1–5 accounts depending on the usage)." : "cron.php зареєстровано на сервісі webcron, щоб викликати cron.php кожні 5 хвилин по HTTP. Варіант використання: Дуже маленький екземпляр (1-5 акаунтів залежно від використання).",
|
||||
"Cron (Recommended)" : "Cron (рекомендовано)",
|
||||
"Unable to update profile default setting" : "Не вдалося оновити стандартні налаштування профілю",
|
||||
"Unable to update profile picker setting" : "Не вдалося оновити налаштування вибору профілю",
|
||||
"Profile" : "Профіль",
|
||||
"Enable or disable profile by default for new accounts." : "Увімкнути або вимкнути стандартний профіль для нових акаунтів.",
|
||||
"Enable the profile picker" : "Увімкнути вибір профілю",
|
||||
"Enable or disable the profile picker in the Smart Picker and the profile link previews." : "Увімкнути або вимкнути вибір профілю для Асистента з вибору та попереднього перегляду посилання на профіль.",
|
||||
"Password confirmation is required" : "Необхідне підтвердження паролем",
|
||||
"Failed to save setting" : "Не вдалося зберегти налаштування",
|
||||
"{app}'s declarative setting field: {name}" : "Декларативне поле налаштувань {app}: {name}",
|
||||
@@ -979,7 +976,7 @@
|
||||
"Unable to retrieve the group list" : "Неможливо отримати список груп",
|
||||
"Exclude some groups from sharing" : "Не дозволяти таким групам надавати у спільний доступ",
|
||||
"Limit sharing to some groups" : "Дозволити надання у спільний доступ тільки для таких груп",
|
||||
"Also allow autocompletion on full match of the user id" : "Дозволити автоматичне заповнення, якщо введено повністю ідентифікатор користувача",
|
||||
"Also allow autocompletion on full match of the user id" : "Також дозволити автозавершення при повному збігу ідентифікатора користувача",
|
||||
"Loading accounts …" : "Завантаження облікових записів ...",
|
||||
"Set account as admin for …" : "Встановити адміністратором для ...",
|
||||
"_{userCount} account …_::_{userCount} accounts …_" : ["{userCount} обліковий запис …","{userCount} облікові записи …","{userCount} облікових записів …","{userCount} облікових записів …"],
|
||||
|
||||
@@ -593,11 +593,8 @@ OC.L10N.register(
|
||||
"cron.php is registered at a webcron service to call cron.php every 5 minutes over HTTP. Use case: Very small instance (1–5 accounts depending on the usage)." : "cron.php 在 webcron 服務中註冊,每五分鐘透過 HTTP 呼叫一次 cron.php。使用情境:非常小的站台(一到五個帳號,取決於使用量)。",
|
||||
"Cron (Recommended)" : "Cron(建議)",
|
||||
"Unable to update profile default setting" : "無法更新個人檔案預設設定",
|
||||
"Unable to update profile picker setting" : "無法更新個人檔案挑選程式設定",
|
||||
"Profile" : "個人檔案",
|
||||
"Enable or disable profile by default for new accounts." : "預設情況下為新帳號啟用或停用個人檔案",
|
||||
"Enable the profile picker" : "啟用個人檔案挑選程式",
|
||||
"Enable or disable the profile picker in the Smart Picker and the profile link previews." : "在智慧型挑選程式與個人檔案連結預覽中啟用或停用個人檔案挑選程式。",
|
||||
"Password confirmation is required" : "需要密碼確認",
|
||||
"Failed to save setting" : "儲存設定失敗",
|
||||
"{app}'s declarative setting field: {name}" : "{app} 的聲明性設定欄位:{name}",
|
||||
|
||||
@@ -591,11 +591,8 @@
|
||||
"cron.php is registered at a webcron service to call cron.php every 5 minutes over HTTP. Use case: Very small instance (1–5 accounts depending on the usage)." : "cron.php 在 webcron 服務中註冊,每五分鐘透過 HTTP 呼叫一次 cron.php。使用情境:非常小的站台(一到五個帳號,取決於使用量)。",
|
||||
"Cron (Recommended)" : "Cron(建議)",
|
||||
"Unable to update profile default setting" : "無法更新個人檔案預設設定",
|
||||
"Unable to update profile picker setting" : "無法更新個人檔案挑選程式設定",
|
||||
"Profile" : "個人檔案",
|
||||
"Enable or disable profile by default for new accounts." : "預設情況下為新帳號啟用或停用個人檔案",
|
||||
"Enable the profile picker" : "啟用個人檔案挑選程式",
|
||||
"Enable or disable the profile picker in the Smart Picker and the profile link previews." : "在智慧型挑選程式與個人檔案連結預覽中啟用或停用個人檔案挑選程式。",
|
||||
"Password confirmation is required" : "需要密碼確認",
|
||||
"Failed to save setting" : "儲存設定失敗",
|
||||
"{app}'s declarative setting field: {name}" : "{app} 的聲明性設定欄位:{name}",
|
||||
|
||||
@@ -41,6 +41,6 @@ OC.L10N.register(
|
||||
"Unable to update share by mail config" : "Не вдається оновити конфігурацію спільного доступу за допомогою пошти",
|
||||
"Allows people to share a personalized link to a file or folder by putting in an email address." : "Дозволяє користувачам надавати персоналізоване посилання на файл або каталог шляхом додавання адреси ел. пошти.",
|
||||
"Send password by mail" : "Надіслати пароль поштою",
|
||||
"Reply to initiator" : "Відповісти ініціатору"
|
||||
"Reply to initiator" : "Відповідь ініціатору"
|
||||
},
|
||||
"nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != 11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || (n % 100 >=11 && n % 100 <=14 )) ? 2: 3);");
|
||||
|
||||
@@ -39,6 +39,6 @@
|
||||
"Unable to update share by mail config" : "Не вдається оновити конфігурацію спільного доступу за допомогою пошти",
|
||||
"Allows people to share a personalized link to a file or folder by putting in an email address." : "Дозволяє користувачам надавати персоналізоване посилання на файл або каталог шляхом додавання адреси ел. пошти.",
|
||||
"Send password by mail" : "Надіслати пароль поштою",
|
||||
"Reply to initiator" : "Відповісти ініціатору"
|
||||
"Reply to initiator" : "Відповідь ініціатору"
|
||||
},"pluralForm" :"nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != 11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || (n % 100 >=11 && n % 100 <=14 )) ? 2: 3);"
|
||||
}
|
||||
@@ -109,7 +109,6 @@ OC.L10N.register(
|
||||
"Reset primary color" : "Birincil rengi sıfırla",
|
||||
"Reset to default" : "Varsayılanlara dön",
|
||||
"Non image file selected" : "Seçilen dosya bir görsel değil",
|
||||
"Failed to upload image" : "Görsel yüklenemedi",
|
||||
"Preview of the selected image" : "Seçilmiş görselin ön izlemesi",
|
||||
"Universal access is very important to us. We follow web standards and check to make everything usable also without mouse, and assistive software such as screenreaders. We aim to be compliant with the {linkstart}Web Content Accessibility Guidelines{linkend} 2.1 on AA level, with the high contrast theme even on AAA level." : "Uygulamalarımızı herkesin kullanabilmesini çok önemsiyoruz. internet sitesi standartlarını izleyerek, işlemlerin fare olmadan da yapılabilmesini ve ekran okuyucular gibi yardımcı yazılımların kullanılabilmesini sağlıyoruz. AAA düzeyinde yüksek renk karşıtlığı teması ile AA düzeyinde {linkstart}İnternet Sitesi İçeriği Erişilebilirlik Kuralları{linkend} 2.1 ile uyumlu olmayı amaçladık.",
|
||||
"If you find any issues, do not hesitate to report them on {issuetracker}our issue tracker{linkend}. And if you want to get involved, come join {designteam}our design team{linkend}!" : "Bir sorunla karşılaşırsanız, bunları {issuetracker}sorun izleyicimiz{linkend} üzerinden bildirmekten çekinmeyin. Katkıda bulunmak istiyorsanız {designteam}tasarım ekibimize{linkend} katılın!",
|
||||
|
||||
@@ -107,7 +107,6 @@
|
||||
"Reset primary color" : "Birincil rengi sıfırla",
|
||||
"Reset to default" : "Varsayılanlara dön",
|
||||
"Non image file selected" : "Seçilen dosya bir görsel değil",
|
||||
"Failed to upload image" : "Görsel yüklenemedi",
|
||||
"Preview of the selected image" : "Seçilmiş görselin ön izlemesi",
|
||||
"Universal access is very important to us. We follow web standards and check to make everything usable also without mouse, and assistive software such as screenreaders. We aim to be compliant with the {linkstart}Web Content Accessibility Guidelines{linkend} 2.1 on AA level, with the high contrast theme even on AAA level." : "Uygulamalarımızı herkesin kullanabilmesini çok önemsiyoruz. internet sitesi standartlarını izleyerek, işlemlerin fare olmadan da yapılabilmesini ve ekran okuyucular gibi yardımcı yazılımların kullanılabilmesini sağlıyoruz. AAA düzeyinde yüksek renk karşıtlığı teması ile AA düzeyinde {linkstart}İnternet Sitesi İçeriği Erişilebilirlik Kuralları{linkend} 2.1 ile uyumlu olmayı amaçladık.",
|
||||
"If you find any issues, do not hesitate to report them on {issuetracker}our issue tracker{linkend}. And if you want to get involved, come join {designteam}our design team{linkend}!" : "Bir sorunla karşılaşırsanız, bunları {issuetracker}sorun izleyicimiz{linkend} üzerinden bildirmekten çekinmeyin. Katkıda bulunmak istiyorsanız {designteam}tasarım ekibimize{linkend} katılın!",
|
||||
|
||||
@@ -310,7 +310,7 @@ trait Sharing {
|
||||
$data = simplexml_load_string($this->response->getBody())->data[0];
|
||||
if ((string)$field == 'expiration') {
|
||||
if (!empty($contentExpected)) {
|
||||
$contentExpected = date('Y-m-d', strtotime($contentExpected)) . ' 23:59:59';
|
||||
$contentExpected = date('Y-m-d', strtotime($contentExpected)) . ' 00:00:00';
|
||||
}
|
||||
}
|
||||
if (count($data->element) > 0) {
|
||||
@@ -611,7 +611,7 @@ trait Sharing {
|
||||
}
|
||||
|
||||
if ($field === 'expiration' && !empty($contentExpected)) {
|
||||
$contentExpected = date('Y-m-d', strtotime($contentExpected)) . ' 23:59:59';
|
||||
$contentExpected = date('Y-m-d', strtotime($contentExpected)) . ' 00:00:00';
|
||||
}
|
||||
|
||||
if ($contentExpected === 'A_NUMBER') {
|
||||
|
||||
@@ -3265,12 +3265,6 @@
|
||||
<code><![CDATA[$this->providers]]></code>
|
||||
</UndefinedInterfaceMethod>
|
||||
</file>
|
||||
<file src="lib/private/Cache/File.php">
|
||||
<LessSpecificImplementedReturnType>
|
||||
<code><![CDATA[bool|mixed]]></code>
|
||||
<code><![CDATA[bool|mixed]]></code>
|
||||
</LessSpecificImplementedReturnType>
|
||||
</file>
|
||||
<file src="lib/private/Calendar/Manager.php">
|
||||
<LessSpecificReturnStatement>
|
||||
<code><![CDATA[array_merge(
|
||||
@@ -3371,6 +3365,42 @@
|
||||
<code><![CDATA[0]]></code>
|
||||
</TypeDoesNotContainType>
|
||||
</file>
|
||||
<file src="lib/private/DB/QueryBuilder/ExpressionBuilder/ExpressionBuilder.php">
|
||||
<ImplicitToStringCast>
|
||||
<code><![CDATA[$this->functionBuilder->lower($x)]]></code>
|
||||
</ImplicitToStringCast>
|
||||
<InvalidArgument>
|
||||
<code><![CDATA[$y]]></code>
|
||||
<code><![CDATA[$y]]></code>
|
||||
</InvalidArgument>
|
||||
</file>
|
||||
<file src="lib/private/DB/QueryBuilder/ExpressionBuilder/MySqlExpressionBuilder.php">
|
||||
<InternalMethod>
|
||||
<code><![CDATA[getParams]]></code>
|
||||
</InternalMethod>
|
||||
<InvalidArrayOffset>
|
||||
<code><![CDATA[$params['collation']]]></code>
|
||||
</InvalidArrayOffset>
|
||||
</file>
|
||||
<file src="lib/private/DB/QueryBuilder/QueryBuilder.php">
|
||||
<InvalidNullableReturnType>
|
||||
<code><![CDATA[string]]></code>
|
||||
</InvalidNullableReturnType>
|
||||
<NullableReturnStatement>
|
||||
<code><![CDATA[$alias]]></code>
|
||||
</NullableReturnStatement>
|
||||
<ParamNameMismatch>
|
||||
<code><![CDATA[$selects]]></code>
|
||||
</ParamNameMismatch>
|
||||
</file>
|
||||
<file src="lib/private/DB/QueryBuilder/QuoteHelper.php">
|
||||
<InvalidNullableReturnType>
|
||||
<code><![CDATA[string]]></code>
|
||||
</InvalidNullableReturnType>
|
||||
<NullableReturnStatement>
|
||||
<code><![CDATA[$string]]></code>
|
||||
</NullableReturnStatement>
|
||||
</file>
|
||||
<file src="lib/private/DateTimeFormatter.php">
|
||||
<FalsableReturnStatement>
|
||||
<code><![CDATA[$l->l($type, $timestamp, [
|
||||
@@ -3970,4 +4000,13 @@
|
||||
<code><![CDATA[getAppValue]]></code>
|
||||
</DeprecatedMethod>
|
||||
</file>
|
||||
<file src="tests/lib/TestCase.php">
|
||||
<DeprecatedMethod>
|
||||
<code><![CDATA[$container]]></code>
|
||||
</DeprecatedMethod>
|
||||
<InternalMethod>
|
||||
<code><![CDATA[lockFile]]></code>
|
||||
<code><![CDATA[unlockFile]]></code>
|
||||
</InternalMethod>
|
||||
</file>
|
||||
</files>
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use OCP\IDBConnection;
|
||||
use OCP\Server;
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
$qb = Server::get(IDBConnection::class)->getTypedQueryBuilder();
|
||||
|
||||
$qb->selectColumns('a', 'b');
|
||||
$qb->selectColumns('c');
|
||||
|
||||
$qb->selectColumnsDistinct('d', 'e');
|
||||
$qb->selectColumnsDistinct('f');
|
||||
|
||||
$qb->selectAlias('g', 'h');
|
||||
$qb->selectAlias($qb->func()->lower('i'), 'j');
|
||||
|
||||
/** @psalm-check-type-exact $result = \OCP\DB\IResult<'a'|'b'|'c'|'d'|'e'|'f'|'h'|'j'> */
|
||||
$result = $qb->executeQuery();
|
||||
|
||||
/** @psalm-check-type-exact $rows = array<'a'|'b'|'c'|'d'|'e'|'f'|'h'|'j', mixed>|false */
|
||||
$rows = $result->fetch(\PDO::FETCH_ASSOC);
|
||||
|
||||
/** @psalm-check-type-exact $rows = array<'a'|'b'|'c'|'d'|'e'|'f'|'h'|'j', mixed>|false */
|
||||
$rows = $result->fetchAssociative();
|
||||
|
||||
/** @psalm-check-type-exact $rows = list<array<'a'|'b'|'c'|'d'|'e'|'f'|'h'|'j', mixed>> */
|
||||
$rows = $result->fetchAll(\PDO::FETCH_ASSOC);
|
||||
|
||||
/** @psalm-check-type-exact $rows = list<array<'a'|'b'|'c'|'d'|'e'|'f'|'h'|'j', mixed>> */
|
||||
$rows = $result->fetchAllAssociative();
|
||||
@@ -19,9 +19,6 @@ return (require __DIR__ . '/rector-shared.php')
|
||||
$nextcloudDir . '/apps/settings/lib/Service/AuthorizedGroupService.php',
|
||||
$nextcloudDir . '/lib/private/Files/Storage/Storage.php',
|
||||
$nextcloudDir . '/lib/private/Files/Storage/Wrapper/Wrapper.php',
|
||||
$nextcloudDir . '/build/psalm/ITypedQueryBuilderTest.php',
|
||||
$nextcloudDir . '/lib/private/DB/QueryBuilder/TypedQueryBuilder.php',
|
||||
$nextcloudDir . '/lib/public/DB/QueryBuilder/ITypedQueryBuilder.php',
|
||||
])
|
||||
->withPreparedSets(
|
||||
deadCode: true,
|
||||
|
||||
Vendored
+2
-2
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -977,23 +977,6 @@ class OC {
|
||||
$throttler = Server::get(IThrottler::class);
|
||||
$throttler->resetDelay($request->getRemoteAddress(), 'login', ['user' => $uid]);
|
||||
}
|
||||
|
||||
try {
|
||||
$cache = new \OC\Cache\File();
|
||||
$cache->gc();
|
||||
} catch (\OC\ServerNotAvailableException $e) {
|
||||
// not a GC exception, pass it on
|
||||
throw $e;
|
||||
} catch (\OC\ForbiddenException $e) {
|
||||
// filesystem blocked for this request, ignore
|
||||
} catch (\Exception $e) {
|
||||
// a GC exception should not prevent users from using OC,
|
||||
// so log the exception
|
||||
Server::get(LoggerInterface::class)->warning('Exception when running cache gc.', [
|
||||
'app' => 'core',
|
||||
'exception' => $e,
|
||||
]);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,7 +327,6 @@ return array(
|
||||
'OCP\\DB\\QueryBuilder\\IParameter' => $baseDir . '/lib/public/DB/QueryBuilder/IParameter.php',
|
||||
'OCP\\DB\\QueryBuilder\\IQueryBuilder' => $baseDir . '/lib/public/DB/QueryBuilder/IQueryBuilder.php',
|
||||
'OCP\\DB\\QueryBuilder\\IQueryFunction' => $baseDir . '/lib/public/DB/QueryBuilder/IQueryFunction.php',
|
||||
'OCP\\DB\\QueryBuilder\\ITypedQueryBuilder' => $baseDir . '/lib/public/DB/QueryBuilder/ITypedQueryBuilder.php',
|
||||
'OCP\\DB\\QueryBuilder\\Sharded\\IShardMapper' => $baseDir . '/lib/public/DB/QueryBuilder/Sharded/IShardMapper.php',
|
||||
'OCP\\DB\\Types' => $baseDir . '/lib/public/DB/Types.php',
|
||||
'OCP\\Dashboard\\IAPIWidget' => $baseDir . '/lib/public/Dashboard/IAPIWidget.php',
|
||||
@@ -1248,7 +1247,6 @@ return array(
|
||||
'OC\\BinaryFinder' => $baseDir . '/lib/private/BinaryFinder.php',
|
||||
'OC\\Blurhash\\Listener\\GenerateBlurhashMetadata' => $baseDir . '/lib/private/Blurhash/Listener/GenerateBlurhashMetadata.php',
|
||||
'OC\\Broadcast\\Events\\BroadcastEvent' => $baseDir . '/lib/private/Broadcast/Events/BroadcastEvent.php',
|
||||
'OC\\Cache\\File' => $baseDir . '/lib/private/Cache/File.php',
|
||||
'OC\\Calendar\\AvailabilityResult' => $baseDir . '/lib/private/Calendar/AvailabilityResult.php',
|
||||
'OC\\Calendar\\CalendarEventBuilder' => $baseDir . '/lib/private/Calendar/CalendarEventBuilder.php',
|
||||
'OC\\Calendar\\CalendarQuery' => $baseDir . '/lib/private/Calendar/CalendarQuery.php',
|
||||
@@ -1658,7 +1656,6 @@ return array(
|
||||
'OC\\DB\\QueryBuilder\\Sharded\\ShardDefinition' => $baseDir . '/lib/private/DB/QueryBuilder/Sharded/ShardDefinition.php',
|
||||
'OC\\DB\\QueryBuilder\\Sharded\\ShardQueryRunner' => $baseDir . '/lib/private/DB/QueryBuilder/Sharded/ShardQueryRunner.php',
|
||||
'OC\\DB\\QueryBuilder\\Sharded\\ShardedQueryBuilder' => $baseDir . '/lib/private/DB/QueryBuilder/Sharded/ShardedQueryBuilder.php',
|
||||
'OC\\DB\\QueryBuilder\\TypedQueryBuilder' => $baseDir . '/lib/private/DB/QueryBuilder/TypedQueryBuilder.php',
|
||||
'OC\\DB\\ResultAdapter' => $baseDir . '/lib/private/DB/ResultAdapter.php',
|
||||
'OC\\DB\\SQLiteMigrator' => $baseDir . '/lib/private/DB/SQLiteMigrator.php',
|
||||
'OC\\DB\\SQLiteSessionInit' => $baseDir . '/lib/private/DB/SQLiteSessionInit.php',
|
||||
|
||||
@@ -368,7 +368,6 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
|
||||
'OCP\\DB\\QueryBuilder\\IParameter' => __DIR__ . '/../../..' . '/lib/public/DB/QueryBuilder/IParameter.php',
|
||||
'OCP\\DB\\QueryBuilder\\IQueryBuilder' => __DIR__ . '/../../..' . '/lib/public/DB/QueryBuilder/IQueryBuilder.php',
|
||||
'OCP\\DB\\QueryBuilder\\IQueryFunction' => __DIR__ . '/../../..' . '/lib/public/DB/QueryBuilder/IQueryFunction.php',
|
||||
'OCP\\DB\\QueryBuilder\\ITypedQueryBuilder' => __DIR__ . '/../../..' . '/lib/public/DB/QueryBuilder/ITypedQueryBuilder.php',
|
||||
'OCP\\DB\\QueryBuilder\\Sharded\\IShardMapper' => __DIR__ . '/../../..' . '/lib/public/DB/QueryBuilder/Sharded/IShardMapper.php',
|
||||
'OCP\\DB\\Types' => __DIR__ . '/../../..' . '/lib/public/DB/Types.php',
|
||||
'OCP\\Dashboard\\IAPIWidget' => __DIR__ . '/../../..' . '/lib/public/Dashboard/IAPIWidget.php',
|
||||
@@ -1289,7 +1288,6 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
|
||||
'OC\\BinaryFinder' => __DIR__ . '/../../..' . '/lib/private/BinaryFinder.php',
|
||||
'OC\\Blurhash\\Listener\\GenerateBlurhashMetadata' => __DIR__ . '/../../..' . '/lib/private/Blurhash/Listener/GenerateBlurhashMetadata.php',
|
||||
'OC\\Broadcast\\Events\\BroadcastEvent' => __DIR__ . '/../../..' . '/lib/private/Broadcast/Events/BroadcastEvent.php',
|
||||
'OC\\Cache\\File' => __DIR__ . '/../../..' . '/lib/private/Cache/File.php',
|
||||
'OC\\Calendar\\AvailabilityResult' => __DIR__ . '/../../..' . '/lib/private/Calendar/AvailabilityResult.php',
|
||||
'OC\\Calendar\\CalendarEventBuilder' => __DIR__ . '/../../..' . '/lib/private/Calendar/CalendarEventBuilder.php',
|
||||
'OC\\Calendar\\CalendarQuery' => __DIR__ . '/../../..' . '/lib/private/Calendar/CalendarQuery.php',
|
||||
@@ -1699,7 +1697,6 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
|
||||
'OC\\DB\\QueryBuilder\\Sharded\\ShardDefinition' => __DIR__ . '/../../..' . '/lib/private/DB/QueryBuilder/Sharded/ShardDefinition.php',
|
||||
'OC\\DB\\QueryBuilder\\Sharded\\ShardQueryRunner' => __DIR__ . '/../../..' . '/lib/private/DB/QueryBuilder/Sharded/ShardQueryRunner.php',
|
||||
'OC\\DB\\QueryBuilder\\Sharded\\ShardedQueryBuilder' => __DIR__ . '/../../..' . '/lib/private/DB/QueryBuilder/Sharded/ShardedQueryBuilder.php',
|
||||
'OC\\DB\\QueryBuilder\\TypedQueryBuilder' => __DIR__ . '/../../..' . '/lib/private/DB/QueryBuilder/TypedQueryBuilder.php',
|
||||
'OC\\DB\\ResultAdapter' => __DIR__ . '/../../..' . '/lib/private/DB/ResultAdapter.php',
|
||||
'OC\\DB\\SQLiteMigrator' => __DIR__ . '/../../..' . '/lib/private/DB/SQLiteMigrator.php',
|
||||
'OC\\DB\\SQLiteSessionInit' => __DIR__ . '/../../..' . '/lib/private/DB/SQLiteSessionInit.php',
|
||||
|
||||
@@ -1,194 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
namespace OC\Cache;
|
||||
|
||||
use OC\Files\Filesystem;
|
||||
use OC\Files\View;
|
||||
use OC\ForbiddenException;
|
||||
use OC\User\NoUserException;
|
||||
use OCP\Files\LockNotAcquiredException;
|
||||
use OCP\ICache;
|
||||
use OCP\IUserSession;
|
||||
use OCP\Lock\LockedException;
|
||||
use OCP\Security\ISecureRandom;
|
||||
use OCP\Server;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class File implements ICache {
|
||||
/** @var View */
|
||||
protected $storage;
|
||||
|
||||
/**
|
||||
* Returns the cache storage for the logged in user
|
||||
*
|
||||
* @return View cache storage
|
||||
* @throws ForbiddenException
|
||||
* @throws NoUserException
|
||||
*/
|
||||
protected function getStorage() {
|
||||
if ($this->storage !== null) {
|
||||
return $this->storage;
|
||||
}
|
||||
$session = Server::get(IUserSession::class);
|
||||
if ($session->isLoggedIn()) {
|
||||
$rootView = new View();
|
||||
$userId = $session->getUser()->getUID();
|
||||
Filesystem::initMountPoints($userId);
|
||||
if (!$rootView->file_exists('/' . $userId . '/cache')) {
|
||||
$rootView->mkdir('/' . $userId . '/cache');
|
||||
}
|
||||
$this->storage = new View('/' . $userId . '/cache');
|
||||
return $this->storage;
|
||||
} else {
|
||||
Server::get(LoggerInterface::class)->error('Can\'t get cache storage, user not logged in', ['app' => 'core']);
|
||||
throw new ForbiddenException('Can\t get cache storage, user not logged in');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @return mixed|null
|
||||
* @throws ForbiddenException
|
||||
*/
|
||||
public function get($key) {
|
||||
$result = null;
|
||||
if ($this->hasKey($key)) {
|
||||
$storage = $this->getStorage();
|
||||
$result = $storage->file_get_contents($key);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of the stored/cached data
|
||||
*
|
||||
* @param string $key
|
||||
* @return int
|
||||
*/
|
||||
public function size($key) {
|
||||
$result = 0;
|
||||
if ($this->hasKey($key)) {
|
||||
$storage = $this->getStorage();
|
||||
$result = $storage->filesize($key);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param int $ttl
|
||||
* @return bool|mixed
|
||||
* @throws ForbiddenException
|
||||
*/
|
||||
public function set($key, $value, $ttl = 0) {
|
||||
$storage = $this->getStorage();
|
||||
$result = false;
|
||||
// unique id to avoid chunk collision, just in case
|
||||
$uniqueId = Server::get(ISecureRandom::class)->generate(
|
||||
16,
|
||||
ISecureRandom::CHAR_ALPHANUMERIC
|
||||
);
|
||||
|
||||
// use part file to prevent hasKey() to find the key
|
||||
// while it is being written
|
||||
$keyPart = $key . '.' . $uniqueId . '.part';
|
||||
if ($storage && $storage->file_put_contents($keyPart, $value)) {
|
||||
if ($ttl === 0) {
|
||||
$ttl = 86400; // 60*60*24
|
||||
}
|
||||
$result = $storage->touch($keyPart, time() + $ttl);
|
||||
$result &= $storage->rename($keyPart, $key);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @return bool
|
||||
* @throws ForbiddenException
|
||||
*/
|
||||
public function hasKey($key) {
|
||||
$storage = $this->getStorage();
|
||||
if ($storage && $storage->is_file($key) && $storage->isReadable($key)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @return bool|mixed
|
||||
* @throws ForbiddenException
|
||||
*/
|
||||
public function remove($key) {
|
||||
$storage = $this->getStorage();
|
||||
if (!$storage) {
|
||||
return false;
|
||||
}
|
||||
return $storage->unlink($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $prefix
|
||||
* @return bool
|
||||
* @throws ForbiddenException
|
||||
*/
|
||||
public function clear($prefix = '') {
|
||||
$storage = $this->getStorage();
|
||||
if ($storage && $storage->is_dir('/')) {
|
||||
$dh = $storage->opendir('/');
|
||||
if (is_resource($dh)) {
|
||||
while (($file = readdir($dh)) !== false) {
|
||||
if ($file !== '.' && $file !== '..' && ($prefix === '' || str_starts_with($file, $prefix))) {
|
||||
$storage->unlink('/' . $file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs GC
|
||||
* @throws ForbiddenException
|
||||
*/
|
||||
public function gc() {
|
||||
$storage = $this->getStorage();
|
||||
if ($storage) {
|
||||
$ttl = \OC::$server->getConfig()->getSystemValueInt('cache_chunk_gc_ttl', 60 * 60 * 24);
|
||||
$now = time() - $ttl;
|
||||
|
||||
$dh = $storage->opendir('/');
|
||||
if (!is_resource($dh)) {
|
||||
return null;
|
||||
}
|
||||
while (($file = readdir($dh)) !== false) {
|
||||
if ($file !== '.' && $file !== '..') {
|
||||
try {
|
||||
$mtime = $storage->filemtime('/' . $file);
|
||||
if ($mtime < $now) {
|
||||
$storage->unlink('/' . $file);
|
||||
}
|
||||
} catch (LockedException $e) {
|
||||
// ignore locked chunks
|
||||
Server::get(LoggerInterface::class)->debug('Could not cleanup locked chunk "' . $file . '"', ['app' => 'core']);
|
||||
} catch (\OCP\Files\ForbiddenException $e) {
|
||||
Server::get(LoggerInterface::class)->debug('Could not cleanup forbidden chunk "' . $file . '"', ['app' => 'core']);
|
||||
} catch (LockNotAcquiredException $e) {
|
||||
Server::get(LoggerInterface::class)->debug('Could not cleanup locked chunk "' . $file . '"', ['app' => 'core']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function isAvailable(): bool {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -14,8 +14,6 @@ use PDO;
|
||||
|
||||
/**
|
||||
* Wrap an array or rows into a result interface
|
||||
*
|
||||
* @template-implements IResult<string>
|
||||
*/
|
||||
class ArrayResult implements IResult {
|
||||
protected int $count;
|
||||
|
||||
@@ -34,7 +34,6 @@ use OC\DB\QueryBuilder\Sharded\ShardConnectionManager;
|
||||
use OC\DB\QueryBuilder\Sharded\ShardDefinition;
|
||||
use OC\SystemConfig;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\DB\QueryBuilder\ITypedQueryBuilder;
|
||||
use OCP\DB\QueryBuilder\Sharded\IShardMapper;
|
||||
use OCP\Diagnostics\IEventLogger;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
@@ -248,14 +247,6 @@ class Connection extends PrimaryReadReplicaConnection {
|
||||
* Returns a QueryBuilder for the connection.
|
||||
*/
|
||||
public function getQueryBuilder(): IQueryBuilder {
|
||||
return $this->getInnerQueryBuilder();
|
||||
}
|
||||
|
||||
public function getTypedQueryBuilder(): ITypedQueryBuilder {
|
||||
return $this->getInnerQueryBuilder();
|
||||
}
|
||||
|
||||
private function getInnerQueryBuilder(): IQueryBuilder&ITypedQueryBuilder {
|
||||
$this->queriesBuilt++;
|
||||
|
||||
$builder = new QueryBuilder(
|
||||
|
||||
@@ -17,7 +17,6 @@ use OC\DB\QueryBuilder\Sharded\ShardDefinition;
|
||||
use OCP\DB\IPreparedStatement;
|
||||
use OCP\DB\IResult;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\DB\QueryBuilder\ITypedQueryBuilder;
|
||||
use OCP\IDBConnection;
|
||||
|
||||
/**
|
||||
@@ -33,10 +32,6 @@ class ConnectionAdapter implements IDBConnection {
|
||||
return $this->inner->getQueryBuilder();
|
||||
}
|
||||
|
||||
public function getTypedQueryBuilder(): ITypedQueryBuilder {
|
||||
return $this->inner->getTypedQueryBuilder();
|
||||
}
|
||||
|
||||
public function prepare($sql, $limit = null, $offset = null): IPreparedStatement {
|
||||
try {
|
||||
return new PreparedStatement(
|
||||
|
||||
@@ -16,10 +16,6 @@ class CompositeExpression implements ICompositeExpression, \Countable {
|
||||
public const TYPE_AND = 'AND';
|
||||
public const TYPE_OR = 'OR';
|
||||
|
||||
/**
|
||||
* @param self::TYPE_* $type
|
||||
* @param array<ICompositeExpression|string> $parts
|
||||
*/
|
||||
public function __construct(
|
||||
private string $type,
|
||||
private array $parts = [],
|
||||
|
||||
@@ -5,9 +5,6 @@
|
||||
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OC\DB\QueryBuilder\ExpressionBuilder;
|
||||
|
||||
use Doctrine\DBAL\Query\Expression\ExpressionBuilder as DoctrineExpressionBuilder;
|
||||
@@ -23,7 +20,6 @@ use OCP\DB\QueryBuilder\ILiteral;
|
||||
use OCP\DB\QueryBuilder\IParameter;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\DB\QueryBuilder\IQueryFunction;
|
||||
use Override;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class ExpressionBuilder implements IExpressionBuilder {
|
||||
@@ -41,178 +37,385 @@ class ExpressionBuilder implements IExpressionBuilder {
|
||||
$this->functionBuilder = $queryBuilder->func();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function andX(ICompositeExpression|string ...$x): ICompositeExpression {
|
||||
/**
|
||||
* Creates a conjunction of the given boolean expressions.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* [php]
|
||||
* // (u.type = ?) AND (u.role = ?)
|
||||
* $expr->andX('u.type = ?', 'u.role = ?'));
|
||||
*
|
||||
* @param mixed ...$x Optional clause. Defaults = null, but requires
|
||||
* at least one defined when converting to string.
|
||||
*
|
||||
* @return ICompositeExpression
|
||||
*/
|
||||
public function andX(...$x): ICompositeExpression {
|
||||
if (empty($x)) {
|
||||
$this->logger->debug('Calling ' . IQueryBuilder::class . '::' . __FUNCTION__ . ' without parameters is deprecated and will throw soon.', ['exception' => new \Exception('No parameters in call to ' . __METHOD__)]);
|
||||
}
|
||||
return new CompositeExpression(CompositeExpression::TYPE_AND, $x);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function orX(ICompositeExpression|string ...$x): ICompositeExpression {
|
||||
/**
|
||||
* Creates a disjunction of the given boolean expressions.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* [php]
|
||||
* // (u.type = ?) OR (u.role = ?)
|
||||
* $qb->where($qb->expr()->orX('u.type = ?', 'u.role = ?'));
|
||||
*
|
||||
* @param mixed ...$x Optional clause. Defaults = null, but requires
|
||||
* at least one defined when converting to string.
|
||||
*
|
||||
* @return ICompositeExpression
|
||||
*/
|
||||
public function orX(...$x): ICompositeExpression {
|
||||
if (empty($x)) {
|
||||
$this->logger->debug('Calling ' . IQueryBuilder::class . '::' . __FUNCTION__ . ' without parameters is deprecated and will throw soon.', ['exception' => new \Exception('No parameters in call to ' . __METHOD__)]);
|
||||
}
|
||||
return new CompositeExpression(CompositeExpression::TYPE_OR, $x);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function comparison(string|ILiteral|IQueryFunction|IParameter $x, string $operator, $y, int|string|null $type = null): string {
|
||||
/**
|
||||
* Creates a comparison expression.
|
||||
*
|
||||
* @param mixed $x The left expression.
|
||||
* @param string $operator One of the IExpressionBuilder::* constants.
|
||||
* @param mixed $y The right expression.
|
||||
* @param mixed|null $type one of the IQueryBuilder::PARAM_* constants
|
||||
* required when comparing text fields for oci compatibility
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function comparison($x, string $operator, $y, $type = null): string {
|
||||
$x = $this->prepareColumn($x, $type);
|
||||
$y = $this->prepareColumn($y, $type);
|
||||
return $this->expressionBuilder->comparison($x, $operator, $y);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function eq(string|ILiteral|IQueryFunction|IParameter $x, IQueryFunction|ILiteral|IParameter|string $y, int|string|null $type = null): string {
|
||||
/**
|
||||
* Creates an equality comparison expression with the given arguments.
|
||||
*
|
||||
* First argument is considered the left expression and the second is the right expression.
|
||||
* When converted to string, it will generated a <left expr> = <right expr>. Example:
|
||||
*
|
||||
* [php]
|
||||
* // u.id = ?
|
||||
* $expr->eq('u.id', '?');
|
||||
*
|
||||
* @param mixed $x The left expression.
|
||||
* @param mixed $y The right expression.
|
||||
* @param mixed|null $type one of the IQueryBuilder::PARAM_* constants
|
||||
* required when comparing text fields for oci compatibility
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function eq($x, $y, $type = null): string {
|
||||
$x = $this->prepareColumn($x, $type);
|
||||
$y = $this->prepareColumn($y, $type);
|
||||
return $this->expressionBuilder->eq($x, $y);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function neq(string|ILiteral|IQueryFunction|IParameter $x, string|ILiteral|IQueryFunction|IParameter $y, int|string|null $type = null): string {
|
||||
/**
|
||||
* Creates a non equality comparison expression with the given arguments.
|
||||
* First argument is considered the left expression and the second is the right expression.
|
||||
* When converted to string, it will generated a <left expr> <> <right expr>. Example:
|
||||
*
|
||||
* [php]
|
||||
* // u.id <> 1
|
||||
* $q->where($q->expr()->neq('u.id', '1'));
|
||||
*
|
||||
* @param mixed $x The left expression.
|
||||
* @param mixed $y The right expression.
|
||||
* @param mixed|null $type one of the IQueryBuilder::PARAM_* constants
|
||||
* required when comparing text fields for oci compatibility
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function neq($x, $y, $type = null): string {
|
||||
$x = $this->prepareColumn($x, $type);
|
||||
$y = $this->prepareColumn($y, $type);
|
||||
return $this->expressionBuilder->neq($x, $y);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function lt(string|ILiteral|IQueryFunction|IParameter $x, string|ILiteral|IQueryFunction|IParameter $y, int|string|null $type = null): string {
|
||||
/**
|
||||
* Creates a lower-than comparison expression with the given arguments.
|
||||
* First argument is considered the left expression and the second is the right expression.
|
||||
* When converted to string, it will generated a <left expr> < <right expr>. Example:
|
||||
*
|
||||
* [php]
|
||||
* // u.id < ?
|
||||
* $q->where($q->expr()->lt('u.id', '?'));
|
||||
*
|
||||
* @param mixed $x The left expression.
|
||||
* @param mixed $y The right expression.
|
||||
* @param mixed|null $type one of the IQueryBuilder::PARAM_* constants
|
||||
* required when comparing text fields for oci compatibility
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function lt($x, $y, $type = null): string {
|
||||
$x = $this->prepareColumn($x, $type);
|
||||
$y = $this->prepareColumn($y, $type);
|
||||
return $this->expressionBuilder->lt($x, $y);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function lte(string|ILiteral|IQueryFunction|IParameter $x, string|ILiteral|IQueryFunction|IParameter $y, int|string|null $type = null): string {
|
||||
/**
|
||||
* Creates a lower-than-equal comparison expression with the given arguments.
|
||||
* First argument is considered the left expression and the second is the right expression.
|
||||
* When converted to string, it will generated a <left expr> <= <right expr>. Example:
|
||||
*
|
||||
* [php]
|
||||
* // u.id <= ?
|
||||
* $q->where($q->expr()->lte('u.id', '?'));
|
||||
*
|
||||
* @param mixed $x The left expression.
|
||||
* @param mixed $y The right expression.
|
||||
* @param mixed|null $type one of the IQueryBuilder::PARAM_* constants
|
||||
* required when comparing text fields for oci compatibility
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function lte($x, $y, $type = null): string {
|
||||
$x = $this->prepareColumn($x, $type);
|
||||
$y = $this->prepareColumn($y, $type);
|
||||
return $this->expressionBuilder->lte($x, $y);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function gt(string|ILiteral|IQueryFunction|IParameter $x, string|ILiteral|IQueryFunction|IParameter $y, int|string|null $type = null): string {
|
||||
/**
|
||||
* Creates a greater-than comparison expression with the given arguments.
|
||||
* First argument is considered the left expression and the second is the right expression.
|
||||
* When converted to string, it will generated a <left expr> > <right expr>. Example:
|
||||
*
|
||||
* [php]
|
||||
* // u.id > ?
|
||||
* $q->where($q->expr()->gt('u.id', '?'));
|
||||
*
|
||||
* @param mixed $x The left expression.
|
||||
* @param mixed $y The right expression.
|
||||
* @param mixed|null $type one of the IQueryBuilder::PARAM_* constants
|
||||
* required when comparing text fields for oci compatibility
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function gt($x, $y, $type = null): string {
|
||||
$x = $this->prepareColumn($x, $type);
|
||||
$y = $this->prepareColumn($y, $type);
|
||||
return $this->expressionBuilder->gt($x, $y);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function gte(string|ILiteral|IQueryFunction|IParameter $x, string|ILiteral|IQueryFunction|IParameter $y, int|string|null $type = null): string {
|
||||
/**
|
||||
* Creates a greater-than-equal comparison expression with the given arguments.
|
||||
* First argument is considered the left expression and the second is the right expression.
|
||||
* When converted to string, it will generated a <left expr> >= <right expr>. Example:
|
||||
*
|
||||
* [php]
|
||||
* // u.id >= ?
|
||||
* $q->where($q->expr()->gte('u.id', '?'));
|
||||
*
|
||||
* @param mixed $x The left expression.
|
||||
* @param mixed $y The right expression.
|
||||
* @param mixed|null $type one of the IQueryBuilder::PARAM_* constants
|
||||
* required when comparing text fields for oci compatibility
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function gte($x, $y, $type = null): string {
|
||||
$x = $this->prepareColumn($x, $type);
|
||||
$y = $this->prepareColumn($y, $type);
|
||||
return $this->expressionBuilder->gte($x, $y);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function isNull(string|ILiteral|IParameter|IQueryFunction $x): string {
|
||||
/**
|
||||
* Creates an IS NULL expression with the given arguments.
|
||||
*
|
||||
* @param string|ILiteral|IParameter|IQueryFunction $x The field in string format to be restricted by IS NULL.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function isNull($x): string {
|
||||
$x = $this->helper->quoteColumnName($x);
|
||||
return $this->expressionBuilder->isNull($x);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function isNotNull(string|ILiteral|IParameter|IQueryFunction $x): string {
|
||||
/**
|
||||
* Creates an IS NOT NULL expression with the given arguments.
|
||||
*
|
||||
* @param string|ILiteral|IParameter|IQueryFunction $x The field in string format to be restricted by IS NOT NULL.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function isNotNull($x): string {
|
||||
$x = $this->helper->quoteColumnName($x);
|
||||
return $this->expressionBuilder->isNotNull($x);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function like(
|
||||
string|IParameter|ILiteral|IQueryFunction $x,
|
||||
string|IParameter|ILiteral|IQueryFunction $y,
|
||||
int|string|null $type = null,
|
||||
): string {
|
||||
/**
|
||||
* Creates a LIKE() comparison expression with the given arguments.
|
||||
*
|
||||
* @param ILiteral|IParameter|IQueryFunction|string $x Field in string format to be inspected by LIKE() comparison.
|
||||
* @param mixed $y Argument to be used in LIKE() comparison.
|
||||
* @param mixed|null $type one of the IQueryBuilder::PARAM_* constants
|
||||
* required when comparing text fields for oci compatibility
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function like($x, $y, $type = null): string {
|
||||
$x = $this->helper->quoteColumnName($x);
|
||||
$y = $this->helper->quoteColumnName($y);
|
||||
return $this->expressionBuilder->like($x, $y);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function iLike(
|
||||
string|IParameter|ILiteral|IQueryFunction $x,
|
||||
string|IParameter|ILiteral|IQueryFunction $y,
|
||||
int|string|null $type = null,
|
||||
): string {
|
||||
return $this->expressionBuilder->like((string)$this->functionBuilder->lower($x), (string)$this->functionBuilder->lower($y));
|
||||
/**
|
||||
* Creates a ILIKE() comparison expression with the given arguments.
|
||||
*
|
||||
* @param string $x Field in string format to be inspected by ILIKE() comparison.
|
||||
* @param mixed $y Argument to be used in ILIKE() comparison.
|
||||
* @param mixed|null $type one of the IQueryBuilder::PARAM_* constants
|
||||
* required when comparing text fields for oci compatibility
|
||||
*
|
||||
* @return string
|
||||
* @since 9.0.0
|
||||
*/
|
||||
public function iLike($x, $y, $type = null): string {
|
||||
return $this->expressionBuilder->like($this->functionBuilder->lower($x), $this->functionBuilder->lower($y));
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function notLike(
|
||||
string|IParameter|ILiteral|IQueryFunction $x,
|
||||
string|IParameter|ILiteral|IQueryFunction $y,
|
||||
int|string|null $type = null,
|
||||
): string {
|
||||
/**
|
||||
* Creates a NOT LIKE() comparison expression with the given arguments.
|
||||
*
|
||||
* @param ILiteral|IParameter|IQueryFunction|string $x Field in string format to be inspected by NOT LIKE() comparison.
|
||||
* @param mixed $y Argument to be used in NOT LIKE() comparison.
|
||||
* @param mixed|null $type one of the IQueryBuilder::PARAM_* constants
|
||||
* required when comparing text fields for oci compatibility
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function notLike($x, $y, $type = null): string {
|
||||
$x = $this->helper->quoteColumnName($x);
|
||||
$y = $this->helper->quoteColumnName($y);
|
||||
return $this->expressionBuilder->notLike($x, $y);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function in(
|
||||
ILiteral|IParameter|IQueryFunction|string $x,
|
||||
ILiteral|IParameter|IQueryFunction|string|array $y,
|
||||
int|string|null $type = null,
|
||||
): string {
|
||||
/**
|
||||
* Creates a IN () comparison expression with the given arguments.
|
||||
*
|
||||
* @param ILiteral|IParameter|IQueryFunction|string $x The field in string format to be inspected by IN() comparison.
|
||||
* @param ILiteral|IParameter|IQueryFunction|string|array $y The placeholder or the array of values to be used by IN() comparison.
|
||||
* @param mixed|null $type one of the IQueryBuilder::PARAM_* constants
|
||||
* required when comparing text fields for oci compatibility
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function in($x, $y, $type = null): string {
|
||||
$x = $this->helper->quoteColumnName($x);
|
||||
$y = $this->helper->quoteColumnNames($y);
|
||||
return $this->expressionBuilder->in($x, $y);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function notIn(
|
||||
ILiteral|IParameter|IQueryFunction|string $x,
|
||||
ILiteral|IParameter|IQueryFunction|string|array $y,
|
||||
int|string|null $type = null,
|
||||
): string {
|
||||
/**
|
||||
* Creates a NOT IN () comparison expression with the given arguments.
|
||||
*
|
||||
* @param ILiteral|IParameter|IQueryFunction|string $x The field in string format to be inspected by NOT IN() comparison.
|
||||
* @param ILiteral|IParameter|IQueryFunction|string|array $y The placeholder or the array of values to be used by NOT IN() comparison.
|
||||
* @param mixed|null $type one of the IQueryBuilder::PARAM_* constants
|
||||
* required when comparing text fields for oci compatibility
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function notIn($x, $y, $type = null): string {
|
||||
$x = $this->helper->quoteColumnName($x);
|
||||
$y = $this->helper->quoteColumnNames($y);
|
||||
return $this->expressionBuilder->notIn($x, $y);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function emptyString(string|ILiteral|IParameter|IQueryFunction $x): string {
|
||||
/**
|
||||
* Creates a $x = '' statement, because Oracle needs a different check
|
||||
*
|
||||
* @param string|ILiteral|IParameter|IQueryFunction $x The field in string format to be inspected by the comparison.
|
||||
* @return string
|
||||
* @since 13.0.0
|
||||
*/
|
||||
public function emptyString($x): string {
|
||||
return $this->eq($x, $this->literal('', IQueryBuilder::PARAM_STR));
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function nonEmptyString(string|ILiteral|IParameter|IQueryFunction $x): string {
|
||||
/**
|
||||
* Creates a `$x <> ''` statement, because Oracle needs a different check
|
||||
*
|
||||
* @param string|ILiteral|IParameter|IQueryFunction $x The field in string format to be inspected by the comparison.
|
||||
* @return string
|
||||
* @since 13.0.0
|
||||
*/
|
||||
public function nonEmptyString($x): string {
|
||||
return $this->neq($x, $this->literal('', IQueryBuilder::PARAM_STR));
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function bitwiseAnd(string|ILiteral $x, int $y): IQueryFunction {
|
||||
/**
|
||||
* Binary AND Operator copies a bit to the result if it exists in both operands.
|
||||
*
|
||||
* @param string|ILiteral $x The field or value to check
|
||||
* @param int $y Bitmap that must be set
|
||||
* @return IQueryFunction
|
||||
* @since 12.0.0
|
||||
*/
|
||||
public function bitwiseAnd($x, int $y): IQueryFunction {
|
||||
return new QueryFunction($this->connection->getDatabasePlatform()->getBitAndComparisonExpression(
|
||||
$this->helper->quoteColumnName($x),
|
||||
(string)$y
|
||||
$y
|
||||
));
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function bitwiseOr(string|ILiteral $x, int $y): IQueryFunction {
|
||||
/**
|
||||
* Binary OR Operator copies a bit if it exists in either operand.
|
||||
*
|
||||
* @param string|ILiteral $x The field or value to check
|
||||
* @param int $y Bitmap that must be set
|
||||
* @return IQueryFunction
|
||||
* @since 12.0.0
|
||||
*/
|
||||
public function bitwiseOr($x, int $y): IQueryFunction {
|
||||
return new QueryFunction($this->connection->getDatabasePlatform()->getBitOrComparisonExpression(
|
||||
$this->helper->quoteColumnName($x),
|
||||
(string)$y
|
||||
$y
|
||||
));
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function literal($input, int|string $type = IQueryBuilder::PARAM_STR): ILiteral {
|
||||
/**
|
||||
* Quotes a given input parameter.
|
||||
*
|
||||
* @param mixed $input The parameter to be quoted.
|
||||
* @param int $type One of the IQueryBuilder::PARAM_* constants
|
||||
*
|
||||
* @return ILiteral
|
||||
*/
|
||||
public function literal($input, $type = IQueryBuilder::PARAM_STR): ILiteral {
|
||||
return new Literal($this->expressionBuilder->literal($input, $type));
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function castColumn(string|IQueryFunction|ILiteral|IParameter $column, int|string $type): IQueryFunction {
|
||||
/**
|
||||
* Returns a IQueryFunction that casts the column to the given type
|
||||
*
|
||||
* @param string|IQueryFunction $column
|
||||
* @param mixed $type One of IQueryBuilder::PARAM_*
|
||||
* @psalm-param IQueryBuilder::PARAM_* $type
|
||||
* @return IQueryFunction
|
||||
*/
|
||||
public function castColumn($column, $type): IQueryFunction {
|
||||
return new QueryFunction(
|
||||
$this->helper->quoteColumnName($column)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IQueryBuilder::PARAM_* $type
|
||||
* @param mixed $column
|
||||
* @param mixed|null $type
|
||||
* @return array|IQueryFunction|string
|
||||
*/
|
||||
protected function prepareColumn(IQueryFunction|ILiteral|IParameter|string|array $column, int|string|null $type): array|string {
|
||||
protected function prepareColumn($column, $type) {
|
||||
return $this->helper->quoteColumnNames($column);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,18 +5,12 @@
|
||||
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OC\DB\QueryBuilder\ExpressionBuilder;
|
||||
|
||||
use OC\DB\ConnectionAdapter;
|
||||
use OC\DB\QueryBuilder\QueryFunction;
|
||||
use OCP\DB\QueryBuilder\ILiteral;
|
||||
use OCP\DB\QueryBuilder\IParameter;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\DB\QueryBuilder\IQueryFunction;
|
||||
use Override;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class MySqlExpressionBuilder extends ExpressionBuilder {
|
||||
@@ -25,25 +19,35 @@ class MySqlExpressionBuilder extends ExpressionBuilder {
|
||||
public function __construct(ConnectionAdapter $connection, IQueryBuilder $queryBuilder, LoggerInterface $logger) {
|
||||
parent::__construct($connection, $queryBuilder, $logger);
|
||||
|
||||
/** @psalm-suppress InternalMethod */
|
||||
$params = $connection->getInner()->getParams();
|
||||
/** @psalm-suppress InvalidArrayOffset collation is sometime defined */
|
||||
$this->collation = $params['collation'] ?? (($params['charset'] ?? 'utf8') . '_general_ci');
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function iLike(string|IParameter|ILiteral|IQueryFunction $x, string|IParameter|ILiteral|IQueryFunction $y, int|string|null $type = null): string {
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function iLike($x, $y, $type = null): string {
|
||||
$x = $this->helper->quoteColumnName($x);
|
||||
$y = $this->helper->quoteColumnName($y);
|
||||
return $this->expressionBuilder->comparison($x, ' COLLATE ' . $this->collation . ' LIKE', $y);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function castColumn(string|IParameter|ILiteral|IQueryFunction $column, int|string $type): IQueryFunction {
|
||||
return match ($type) {
|
||||
IQueryBuilder::PARAM_STR => new QueryFunction('CAST(' . $this->helper->quoteColumnName($column) . ' AS CHAR)'),
|
||||
IQueryBuilder::PARAM_JSON => new QueryFunction('CAST(' . $this->helper->quoteColumnName($column) . ' AS JSON)'),
|
||||
default => parent::castColumn($column, $type),
|
||||
};
|
||||
/**
|
||||
* Returns a IQueryFunction that casts the column to the given type
|
||||
*
|
||||
* @param string|IQueryFunction $column
|
||||
* @param mixed $type One of IQueryBuilder::PARAM_*
|
||||
* @psalm-param IQueryBuilder::PARAM_* $type
|
||||
* @return IQueryFunction
|
||||
*/
|
||||
public function castColumn($column, $type): IQueryFunction {
|
||||
switch ($type) {
|
||||
case IQueryBuilder::PARAM_STR:
|
||||
return new QueryFunction('CAST(' . $this->helper->quoteColumnName($column) . ' AS CHAR)');
|
||||
case IQueryBuilder::PARAM_JSON:
|
||||
return new QueryFunction('CAST(' . $this->helper->quoteColumnName($column) . ' AS JSON)');
|
||||
default:
|
||||
return parent::castColumn($column, $type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,11 +12,14 @@ use OCP\DB\QueryBuilder\ILiteral;
|
||||
use OCP\DB\QueryBuilder\IParameter;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\DB\QueryBuilder\IQueryFunction;
|
||||
use Override;
|
||||
|
||||
class OCIExpressionBuilder extends ExpressionBuilder {
|
||||
#[Override]
|
||||
protected function prepareColumn(IQueryFunction|ILiteral|IParameter|string|array $column, int|string|null $type): array|string {
|
||||
/**
|
||||
* @param mixed $column
|
||||
* @param mixed|null $type
|
||||
* @return array|IQueryFunction|string
|
||||
*/
|
||||
protected function prepareColumn($column, $type) {
|
||||
if ($type === IQueryBuilder::PARAM_STR && !is_array($column) && !($column instanceof IParameter) && !($column instanceof ILiteral)) {
|
||||
$column = $this->castColumn($column, $type);
|
||||
}
|
||||
@@ -24,8 +27,10 @@ class OCIExpressionBuilder extends ExpressionBuilder {
|
||||
return parent::prepareColumn($column, $type);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function eq(IQueryFunction|ILiteral|IParameter|string $x, IQueryFunction|ILiteral|IParameter|string $y, int|string|null $type = null): string {
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function eq($x, $y, $type = null): string {
|
||||
if ($type === IQueryBuilder::PARAM_JSON) {
|
||||
$x = $this->prepareColumn($x, $type);
|
||||
$y = $this->prepareColumn($y, $type);
|
||||
@@ -35,8 +40,10 @@ class OCIExpressionBuilder extends ExpressionBuilder {
|
||||
return parent::eq($x, $y, $type);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function neq(string|ILiteral|IQueryFunction|IParameter $x, string|ILiteral|IQueryFunction|IParameter $y, int|string|null $type = null): string {
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function neq($x, $y, $type = null): string {
|
||||
if ($type === IQueryBuilder::PARAM_JSON) {
|
||||
$x = $this->prepareColumn($x, $type);
|
||||
$y = $this->prepareColumn($y, $type);
|
||||
@@ -46,34 +53,57 @@ class OCIExpressionBuilder extends ExpressionBuilder {
|
||||
return parent::neq($x, $y, $type);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function in(ILiteral|IParameter|IQueryFunction|string $x, ILiteral|IParameter|IQueryFunction|string|array $y, int|string|null $type = null): string {
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function in($x, $y, $type = null): string {
|
||||
$x = $this->prepareColumn($x, $type);
|
||||
$y = $this->prepareColumn($y, $type);
|
||||
|
||||
return $this->expressionBuilder->in($x, $y);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function notIn(ILiteral|IParameter|IQueryFunction|string $x, ILiteral|IParameter|IQueryFunction|string|array $y, int|string|null $type = null): string {
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function notIn($x, $y, $type = null): string {
|
||||
$x = $this->prepareColumn($x, $type);
|
||||
$y = $this->prepareColumn($y, $type);
|
||||
|
||||
return $this->expressionBuilder->notIn($x, $y);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function emptyString(string|ILiteral|IParameter|IQueryFunction $x): string {
|
||||
/**
|
||||
* Creates a $x = '' statement, because Oracle needs a different check
|
||||
*
|
||||
* @param string|ILiteral|IParameter|IQueryFunction $x The field in string format to be inspected by the comparison.
|
||||
* @return string
|
||||
* @since 13.0.0
|
||||
*/
|
||||
public function emptyString($x): string {
|
||||
return $this->isNull($x);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function nonEmptyString(string|ILiteral|IParameter|IQueryFunction $x): string {
|
||||
/**
|
||||
* Creates a `$x <> ''` statement, because Oracle needs a different check
|
||||
*
|
||||
* @param string|ILiteral|IParameter|IQueryFunction $x The field in string format to be inspected by the comparison.
|
||||
* @return string
|
||||
* @since 13.0.0
|
||||
*/
|
||||
public function nonEmptyString($x): string {
|
||||
return $this->isNotNull($x);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function castColumn(string|IQueryFunction|ILiteral|IParameter $column, int|string|null $type): IQueryFunction {
|
||||
/**
|
||||
* Returns a IQueryFunction that casts the column to the given type
|
||||
*
|
||||
* @param string|IQueryFunction $column
|
||||
* @param mixed $type One of IQueryBuilder::PARAM_*
|
||||
* @psalm-param IQueryBuilder::PARAM_* $type
|
||||
* @return IQueryFunction
|
||||
*/
|
||||
public function castColumn($column, $type): IQueryFunction {
|
||||
if ($type === IQueryBuilder::PARAM_STR) {
|
||||
$column = $this->helper->quoteColumnName($column);
|
||||
return new QueryFunction('to_char(' . $column . ')');
|
||||
@@ -86,21 +116,17 @@ class OCIExpressionBuilder extends ExpressionBuilder {
|
||||
return parent::castColumn($column, $type);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function like(
|
||||
ILiteral|IParameter|IQueryFunction|string $x,
|
||||
ILiteral|IParameter|IQueryFunction|string $y,
|
||||
int|string|null $type = null,
|
||||
): string {
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function like($x, $y, $type = null): string {
|
||||
return parent::like($x, $y, $type) . " ESCAPE '\\'";
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function iLike(
|
||||
ILiteral|IParameter|IQueryFunction|string $x,
|
||||
ILiteral|IParameter|IQueryFunction|string $y,
|
||||
int|string|null $type = null,
|
||||
): string {
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function iLike($x, $y, $type = null): string {
|
||||
return $this->like($this->functionBuilder->lower($x), $this->functionBuilder->lower($y));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,20 +12,32 @@ use OCP\DB\QueryBuilder\ILiteral;
|
||||
use OCP\DB\QueryBuilder\IParameter;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\DB\QueryBuilder\IQueryFunction;
|
||||
use Override;
|
||||
|
||||
class PgSqlExpressionBuilder extends ExpressionBuilder {
|
||||
#[Override]
|
||||
public function castColumn(string|IQueryFunction|ILiteral|IParameter $column, string|int $type): IQueryFunction {
|
||||
return match ($type) {
|
||||
IQueryBuilder::PARAM_INT => new QueryFunction('CAST(' . $this->helper->quoteColumnName($column) . ' AS BIGINT)'),
|
||||
IQueryBuilder::PARAM_STR, IQueryBuilder::PARAM_JSON => new QueryFunction('CAST(' . $this->helper->quoteColumnName($column) . ' AS TEXT)'),
|
||||
default => parent::castColumn($column, $type),
|
||||
};
|
||||
/**
|
||||
* Returns a IQueryFunction that casts the column to the given type
|
||||
*
|
||||
* @param string|IQueryFunction $column
|
||||
* @param mixed $type One of IQueryBuilder::PARAM_*
|
||||
* @psalm-param IQueryBuilder::PARAM_* $type
|
||||
* @return IQueryFunction
|
||||
*/
|
||||
public function castColumn($column, $type): IQueryFunction {
|
||||
switch ($type) {
|
||||
case IQueryBuilder::PARAM_INT:
|
||||
return new QueryFunction('CAST(' . $this->helper->quoteColumnName($column) . ' AS BIGINT)');
|
||||
case IQueryBuilder::PARAM_STR:
|
||||
case IQueryBuilder::PARAM_JSON:
|
||||
return new QueryFunction('CAST(' . $this->helper->quoteColumnName($column) . ' AS TEXT)');
|
||||
default:
|
||||
return parent::castColumn($column, $type);
|
||||
}
|
||||
}
|
||||
|
||||
#[Override]
|
||||
protected function prepareColumn(IQueryFunction|ILiteral|IParameter|string|array $column, int|string|null $type): string|array {
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected function prepareColumn($column, $type) {
|
||||
if ($type === IQueryBuilder::PARAM_JSON && !is_array($column) && !($column instanceof IParameter) && !($column instanceof ILiteral)) {
|
||||
$column = $this->castColumn($column, $type);
|
||||
}
|
||||
@@ -33,8 +45,10 @@ class PgSqlExpressionBuilder extends ExpressionBuilder {
|
||||
return parent::prepareColumn($column, $type);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function iLike(string|IParameter|ILiteral|IQueryFunction $x, mixed $y, mixed $type = null): string {
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function iLike($x, $y, $type = null): string {
|
||||
$x = $this->helper->quoteColumnName($x);
|
||||
$y = $this->helper->quoteColumnName($y);
|
||||
return $this->expressionBuilder->comparison($x, 'ILIKE', $y);
|
||||
|
||||
@@ -11,35 +11,44 @@ use OCP\DB\QueryBuilder\ILiteral;
|
||||
use OCP\DB\QueryBuilder\IParameter;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\DB\QueryBuilder\IQueryFunction;
|
||||
use Override;
|
||||
|
||||
class SqliteExpressionBuilder extends ExpressionBuilder {
|
||||
#[Override]
|
||||
public function like(ILiteral|IParameter|IQueryFunction|string $x, mixed $y, int|string|null $type = null): string {
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function like($x, $y, $type = null): string {
|
||||
return parent::like($x, $y, $type) . " ESCAPE '\\'";
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function iLike(string|IParameter|ILiteral|IQueryFunction $x, mixed $y, int|string|null $type = null): string {
|
||||
public function iLike($x, $y, $type = null): string {
|
||||
return $this->like($this->functionBuilder->lower($x), $this->functionBuilder->lower($y), $type);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
protected function prepareColumn(IQueryFunction|ILiteral|IParameter|string|array $column, int|string|null $type): string|array {
|
||||
if (!($column instanceof IParameter)
|
||||
&& !($column instanceof IQueryFunction)
|
||||
&& !($column instanceof ILiteral)
|
||||
/**
|
||||
* @param mixed $column
|
||||
* @param mixed|null $type
|
||||
* @return array|IQueryFunction|string
|
||||
*/
|
||||
protected function prepareColumn($column, $type) {
|
||||
if ($type !== null
|
||||
&& !is_array($column)
|
||||
&& is_string($type)
|
||||
&& !($column instanceof IParameter)
|
||||
&& !($column instanceof ILiteral)
|
||||
&& (str_starts_with($type, 'date') || str_starts_with($type, 'time'))) {
|
||||
return (string)$this->castColumn($column, $type);
|
||||
return $this->castColumn($column, $type);
|
||||
}
|
||||
|
||||
return parent::prepareColumn($column, $type);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function castColumn(string|IQueryFunction|ILiteral|IParameter $column, string|int $type): IQueryFunction {
|
||||
/**
|
||||
* Returns a IQueryFunction that casts the column to the given type
|
||||
*
|
||||
* @param string $column
|
||||
* @param mixed $type One of IQueryBuilder::PARAM_*
|
||||
* @return IQueryFunction
|
||||
*/
|
||||
public function castColumn($column, $type): IQueryFunction {
|
||||
switch ($type) {
|
||||
case IQueryBuilder::PARAM_DATE_MUTABLE:
|
||||
case IQueryBuilder::PARAM_DATE_IMMUTABLE:
|
||||
|
||||
@@ -10,349 +10,284 @@ namespace OC\DB\QueryBuilder;
|
||||
|
||||
use OCP\DB\IResult;
|
||||
use OCP\DB\QueryBuilder\ConflictResolutionMode;
|
||||
use OCP\DB\QueryBuilder\ICompositeExpression;
|
||||
use OCP\DB\QueryBuilder\IExpressionBuilder;
|
||||
use OCP\DB\QueryBuilder\IFunctionBuilder;
|
||||
use OCP\DB\QueryBuilder\ILiteral;
|
||||
use OCP\DB\QueryBuilder\IParameter;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\DB\QueryBuilder\IQueryFunction;
|
||||
use OCP\IDBConnection;
|
||||
use Override;
|
||||
|
||||
/**
|
||||
* Base class for creating classes that extend the builtin query builder
|
||||
*/
|
||||
abstract class ExtendedQueryBuilder extends TypedQueryBuilder {
|
||||
abstract class ExtendedQueryBuilder implements IQueryBuilder {
|
||||
public function __construct(
|
||||
protected readonly IQueryBuilder $builder,
|
||||
protected IQueryBuilder $builder,
|
||||
) {
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function automaticTablePrefix(bool $enabled): void {
|
||||
public function automaticTablePrefix($enabled) {
|
||||
$this->builder->automaticTablePrefix($enabled);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function expr(): IExpressionBuilder {
|
||||
public function expr() {
|
||||
return $this->builder->expr();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function func(): IFunctionBuilder {
|
||||
public function func() {
|
||||
return $this->builder->func();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getType(): int {
|
||||
public function getType() {
|
||||
return $this->builder->getType();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getConnection(): IDBConnection {
|
||||
public function getConnection() {
|
||||
return $this->builder->getConnection();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getState(): int {
|
||||
public function getState() {
|
||||
return $this->builder->getState();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getSQL(): string {
|
||||
public function getSQL() {
|
||||
return $this->builder->getSQL();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function setParameter(string|int $key, mixed $value, string|null|int $type = null): self {
|
||||
public function setParameter($key, $value, $type = null) {
|
||||
$this->builder->setParameter($key, $value, $type);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function setParameters(array $params, array $types = []): self {
|
||||
public function setParameters(array $params, array $types = []) {
|
||||
$this->builder->setParameters($params, $types);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getParameters(): array {
|
||||
public function getParameters() {
|
||||
return $this->builder->getParameters();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getParameter(int|string $key): mixed {
|
||||
public function getParameter($key) {
|
||||
return $this->builder->getParameter($key);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getParameterTypes(): array {
|
||||
public function getParameterTypes() {
|
||||
return $this->builder->getParameterTypes();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getParameterType(int|string $key): int|string {
|
||||
public function getParameterType($key) {
|
||||
return $this->builder->getParameterType($key);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function setFirstResult(int $firstResult): self {
|
||||
public function setFirstResult($firstResult) {
|
||||
$this->builder->setFirstResult($firstResult);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getFirstResult(): int {
|
||||
public function getFirstResult() {
|
||||
return $this->builder->getFirstResult();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function setMaxResults(?int $maxResults): self {
|
||||
public function setMaxResults($maxResults) {
|
||||
$this->builder->setMaxResults($maxResults);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getMaxResults(): ?int {
|
||||
public function getMaxResults() {
|
||||
return $this->builder->getMaxResults();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function select(...$selects): self {
|
||||
public function select(...$selects) {
|
||||
$this->builder->select(...$selects);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function selectAlias(string|IQueryFunction|IParameter|ILiteral $select, string $alias): self {
|
||||
public function selectAlias($select, $alias) {
|
||||
$this->builder->selectAlias($select, $alias);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function selectDistinct(string|array $select): self {
|
||||
public function selectDistinct($select) {
|
||||
$this->builder->selectDistinct($select);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function addSelect(...$select): self {
|
||||
public function addSelect(...$select) {
|
||||
$this->builder->addSelect(...$select);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function delete(string $delete, ?string $alias = null): self {
|
||||
public function delete($delete = null, $alias = null) {
|
||||
$this->builder->delete($delete, $alias);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function update(string $update, ?string $alias = null): self {
|
||||
public function update($update = null, $alias = null) {
|
||||
$this->builder->update($update, $alias);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function insert(string $insert): self {
|
||||
public function insert($insert = null) {
|
||||
$this->builder->insert($insert);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function from(string|IQueryFunction $from, ?string $alias = null): self {
|
||||
public function from($from, $alias = null) {
|
||||
$this->builder->from($from, $alias);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function join(string $fromAlias, string|IQueryFunction $join, ?string $alias, string|ICompositeExpression|null $condition = null): self {
|
||||
public function join($fromAlias, $join, $alias, $condition = null) {
|
||||
$this->builder->join($fromAlias, $join, $alias, $condition);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function innerJoin(string $fromAlias, string|IQueryFunction $join, ?string $alias, string|ICompositeExpression|null $condition = null): self {
|
||||
public function innerJoin($fromAlias, $join, $alias, $condition = null) {
|
||||
$this->builder->innerJoin($fromAlias, $join, $alias, $condition);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function leftJoin(string $fromAlias, string|IQueryFunction $join, ?string $alias, string|ICompositeExpression|null $condition = null): self {
|
||||
public function leftJoin($fromAlias, $join, $alias, $condition = null) {
|
||||
$this->builder->leftJoin($fromAlias, $join, $alias, $condition);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function rightJoin(string $fromAlias, string|IQueryFunction $join, ?string $alias, string|ICompositeExpression|null $condition = null): self {
|
||||
public function rightJoin($fromAlias, $join, $alias, $condition = null) {
|
||||
$this->builder->rightJoin($fromAlias, $join, $alias, $condition);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function set(string $key, ILiteral|IParameter|IQueryFunction|string $value): self {
|
||||
public function set($key, $value) {
|
||||
$this->builder->set($key, $value);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function where(...$predicates): self {
|
||||
public function where(...$predicates) {
|
||||
$this->builder->where(...$predicates);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function andWhere(...$where): self {
|
||||
public function andWhere(...$where) {
|
||||
$this->builder->andWhere(...$where);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function orWhere(...$where): self {
|
||||
public function orWhere(...$where) {
|
||||
$this->builder->orWhere(...$where);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function groupBy(...$groupBys): self {
|
||||
public function groupBy(...$groupBys) {
|
||||
$this->builder->groupBy(...$groupBys);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function addGroupBy(...$groupBy): self {
|
||||
public function addGroupBy(...$groupBy) {
|
||||
$this->builder->addGroupBy(...$groupBy);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function setValue(string $column, ILiteral|IParameter|IQueryFunction|string $value): self {
|
||||
public function setValue($column, $value) {
|
||||
$this->builder->setValue($column, $value);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function values(array $values): self {
|
||||
public function values(array $values) {
|
||||
$this->builder->values($values);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function having(...$having): self {
|
||||
public function having(...$having) {
|
||||
$this->builder->having(...$having);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function andHaving(...$having): self {
|
||||
public function andHaving(...$having) {
|
||||
$this->builder->andHaving(...$having);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function orHaving(...$having): self {
|
||||
public function orHaving(...$having) {
|
||||
$this->builder->orHaving(...$having);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function orderBy(string|ILiteral|IParameter|IQueryFunction $sort, ?string $order = null): self {
|
||||
public function orderBy($sort, $order = null) {
|
||||
$this->builder->orderBy($sort, $order);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function addOrderBy(string|ILiteral|IParameter|IQueryFunction $sort, ?string $order = null): self {
|
||||
public function addOrderBy($sort, $order = null) {
|
||||
$this->builder->addOrderBy($sort, $order);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getQueryPart(string $queryPartName): mixed {
|
||||
public function getQueryPart($queryPartName) {
|
||||
return $this->builder->getQueryPart($queryPartName);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getQueryParts(): array {
|
||||
public function getQueryParts() {
|
||||
return $this->builder->getQueryParts();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function resetQueryParts(?array $queryPartNames = null): self {
|
||||
public function resetQueryParts($queryPartNames = null) {
|
||||
$this->builder->resetQueryParts($queryPartNames);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function resetQueryPart(string $queryPartName): self {
|
||||
public function resetQueryPart($queryPartName) {
|
||||
$this->builder->resetQueryPart($queryPartName);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function createNamedParameter(mixed $value, mixed $type = self::PARAM_STR, $placeHolder = null): IParameter {
|
||||
public function createNamedParameter($value, $type = self::PARAM_STR, $placeHolder = null) {
|
||||
return $this->builder->createNamedParameter($value, $type, $placeHolder);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function createPositionalParameter(mixed $value, mixed $type = self::PARAM_STR): IParameter {
|
||||
public function createPositionalParameter($value, $type = self::PARAM_STR) {
|
||||
return $this->builder->createPositionalParameter($value, $type);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function createParameter(string $name): IParameter {
|
||||
public function createParameter($name) {
|
||||
return $this->builder->createParameter($name);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function createFunction(string $call): IQueryFunction {
|
||||
public function createFunction($call) {
|
||||
return $this->builder->createFunction($call);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getLastInsertId(): int {
|
||||
return $this->builder->getLastInsertId();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getTableName(string|IQueryFunction $table): string {
|
||||
public function getTableName($table) {
|
||||
return $this->builder->getTableName($table);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getColumnName(string $column, string $tableAlias = ''): string {
|
||||
public function getColumnName($column, $tableAlias = '') {
|
||||
return $this->builder->getColumnName($column, $tableAlias);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function executeQuery(?IDBConnection $connection = null): IResult {
|
||||
return $this->builder->executeQuery($connection);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function executeStatement(?IDBConnection $connection = null): int {
|
||||
return $this->builder->executeStatement($connection);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function hintShardKey(string $column, mixed $value, bool $overwrite = false): self {
|
||||
$this->builder->hintShardKey($column, $value, $overwrite);
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function runAcrossAllShards(): self {
|
||||
$this->builder->runAcrossAllShards();
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getOutputColumns(): array {
|
||||
return $this->builder->getOutputColumns();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function prefixTableName(string $table): string {
|
||||
return $this->builder->prefixTableName($table);
|
||||
}
|
||||
|
||||
@@ -6,31 +6,27 @@
|
||||
*/
|
||||
namespace OC\DB\QueryBuilder\FunctionBuilder;
|
||||
|
||||
use OC\DB\ConnectionAdapter;
|
||||
use OC\DB\QueryBuilder\QueryFunction;
|
||||
use OC\DB\QueryBuilder\QuoteHelper;
|
||||
use OCP\DB\QueryBuilder\IFunctionBuilder;
|
||||
use OCP\DB\QueryBuilder\ILiteral;
|
||||
use OCP\DB\QueryBuilder\IParameter;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\DB\QueryBuilder\IQueryFunction;
|
||||
use OCP\IDBConnection;
|
||||
use Override;
|
||||
|
||||
class FunctionBuilder implements IFunctionBuilder {
|
||||
public function __construct(
|
||||
protected readonly ConnectionAdapter $connection,
|
||||
protected readonly IQueryBuilder $queryBuilder,
|
||||
protected readonly QuoteHelper $helper,
|
||||
protected IDBConnection $connection,
|
||||
protected IQueryBuilder $queryBuilder,
|
||||
protected QuoteHelper $helper,
|
||||
) {
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function md5(string|ILiteral|IParameter|IQueryFunction $input): IQueryFunction {
|
||||
public function md5($input): IQueryFunction {
|
||||
return new QueryFunction('MD5(' . $this->helper->quoteColumnName($input) . ')');
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function concat(string|ILiteral|IParameter|IQueryFunction $x, string|ILiteral|IParameter|IQueryFunction ...$expr): IQueryFunction {
|
||||
public function concat($x, ...$expr): IQueryFunction {
|
||||
$args = func_get_args();
|
||||
$list = [];
|
||||
foreach ($args as $item) {
|
||||
@@ -39,18 +35,12 @@ class FunctionBuilder implements IFunctionBuilder {
|
||||
return new QueryFunction(sprintf('CONCAT(%s)', implode(', ', $list)));
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function groupConcat(string|ILiteral|IParameter|IQueryFunction $expr, ?string $separator = ','): IQueryFunction {
|
||||
public function groupConcat($expr, ?string $separator = ','): IQueryFunction {
|
||||
$separator = $this->connection->quote($separator);
|
||||
return new QueryFunction('GROUP_CONCAT(' . $this->helper->quoteColumnName($expr) . ' SEPARATOR ' . $separator . ')');
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function substring(
|
||||
string|ILiteral|IParameter|IQueryFunction $input,
|
||||
string|ILiteral|IParameter|IQueryFunction $start,
|
||||
null|ILiteral|IParameter|IQueryFunction $length = null,
|
||||
): IQueryFunction {
|
||||
public function substring($input, $start, $length = null): IQueryFunction {
|
||||
if ($length) {
|
||||
return new QueryFunction('SUBSTR(' . $this->helper->quoteColumnName($input) . ', ' . $this->helper->quoteColumnName($start) . ', ' . $this->helper->quoteColumnName($length) . ')');
|
||||
} else {
|
||||
@@ -58,76 +48,53 @@ class FunctionBuilder implements IFunctionBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function sum(string|ILiteral|IParameter|IQueryFunction $field): IQueryFunction {
|
||||
public function sum($field): IQueryFunction {
|
||||
return new QueryFunction('SUM(' . $this->helper->quoteColumnName($field) . ')');
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function lower(string|ILiteral|IParameter|IQueryFunction $field): IQueryFunction {
|
||||
public function lower($field): IQueryFunction {
|
||||
return new QueryFunction('LOWER(' . $this->helper->quoteColumnName($field) . ')');
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function add(
|
||||
string|ILiteral|IParameter|IQueryFunction $x,
|
||||
string|ILiteral|IParameter|IQueryFunction $y,
|
||||
): IQueryFunction {
|
||||
public function add($x, $y): IQueryFunction {
|
||||
return new QueryFunction($this->helper->quoteColumnName($x) . ' + ' . $this->helper->quoteColumnName($y));
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function subtract(
|
||||
string|ILiteral|IParameter|IQueryFunction $x,
|
||||
string|ILiteral|IParameter|IQueryFunction $y,
|
||||
): IQueryFunction {
|
||||
public function subtract($x, $y): IQueryFunction {
|
||||
return new QueryFunction($this->helper->quoteColumnName($x) . ' - ' . $this->helper->quoteColumnName($y));
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function count(string|ILiteral|IParameter|IQueryFunction $count = '', string $alias = ''): IQueryFunction {
|
||||
public function count($count = '', $alias = ''): IQueryFunction {
|
||||
$alias = $alias ? (' AS ' . $this->helper->quoteColumnName($alias)) : '';
|
||||
$quotedName = $count === '' ? '*' : $this->helper->quoteColumnName($count);
|
||||
return new QueryFunction('COUNT(' . $quotedName . ')' . $alias);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function octetLength(string|ILiteral|IParameter|IQueryFunction $field, string $alias = ''): IQueryFunction {
|
||||
public function octetLength($field, $alias = ''): IQueryFunction {
|
||||
$alias = $alias ? (' AS ' . $this->helper->quoteColumnName($alias)) : '';
|
||||
$quotedName = $this->helper->quoteColumnName($field);
|
||||
return new QueryFunction('OCTET_LENGTH(' . $quotedName . ')' . $alias);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function charLength(string|ILiteral|IParameter|IQueryFunction $field, string $alias = ''): IQueryFunction {
|
||||
public function charLength($field, $alias = ''): IQueryFunction {
|
||||
$alias = $alias ? (' AS ' . $this->helper->quoteColumnName($alias)) : '';
|
||||
$quotedName = $this->helper->quoteColumnName($field);
|
||||
return new QueryFunction('CHAR_LENGTH(' . $quotedName . ')' . $alias);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function max(string|ILiteral|IParameter|IQueryFunction $field): IQueryFunction {
|
||||
public function max($field): IQueryFunction {
|
||||
return new QueryFunction('MAX(' . $this->helper->quoteColumnName($field) . ')');
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function min(string|ILiteral|IParameter|IQueryFunction $field): IQueryFunction {
|
||||
public function min($field): IQueryFunction {
|
||||
return new QueryFunction('MIN(' . $this->helper->quoteColumnName($field) . ')');
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function greatest(
|
||||
string|ILiteral|IParameter|IQueryFunction $x,
|
||||
string|ILiteral|IParameter|IQueryFunction $y,
|
||||
): IQueryFunction {
|
||||
public function greatest($x, $y): IQueryFunction {
|
||||
return new QueryFunction('GREATEST(' . $this->helper->quoteColumnName($x) . ', ' . $this->helper->quoteColumnName($y) . ')');
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function least(
|
||||
string|ILiteral|IParameter|IQueryFunction $x,
|
||||
string|ILiteral|IParameter|IQueryFunction $y,
|
||||
): IQueryFunction {
|
||||
public function least($x, $y): IQueryFunction {
|
||||
return new QueryFunction('LEAST(' . $this->helper->quoteColumnName($x) . ', ' . $this->helper->quoteColumnName($y) . ')');
|
||||
}
|
||||
|
||||
|
||||
@@ -6,15 +6,17 @@
|
||||
*/
|
||||
namespace OC\DB\QueryBuilder\FunctionBuilder;
|
||||
|
||||
use OC\DB\ConnectionAdapter;
|
||||
use OC\DB\QueryBuilder\QueryFunction;
|
||||
use OCP\DB\QueryBuilder\ILiteral;
|
||||
use OCP\DB\QueryBuilder\IParameter;
|
||||
use OCP\DB\QueryBuilder\IQueryFunction;
|
||||
use Override;
|
||||
|
||||
class OCIFunctionBuilder extends FunctionBuilder {
|
||||
public function md5(string|ILiteral|IParameter|IQueryFunction $input): IQueryFunction {
|
||||
if (version_compare($this->connection->getServerVersion(), '20', '>=')) {
|
||||
public function md5($input): IQueryFunction {
|
||||
/** @var ConnectionAdapter $co */
|
||||
$co = $this->connection;
|
||||
if (version_compare($co->getServerVersion(), '20', '>=')) {
|
||||
return new QueryFunction('LOWER(STANDARD_HASH(' . $this->helper->quoteColumnName($input) . ", 'MD5'))");
|
||||
}
|
||||
return new QueryFunction('LOWER(DBMS_OBFUSCATION_TOOLKIT.md5 (input => UTL_RAW.cast_to_raw(' . $this->helper->quoteColumnName($input) . ')))');
|
||||
@@ -28,12 +30,11 @@ class OCIFunctionBuilder extends FunctionBuilder {
|
||||
* the second parameter is a function or column, we have to put that as
|
||||
* first parameter.
|
||||
*
|
||||
* @param string|ILiteral|IParameter|IQueryFunction $x
|
||||
* @param string|ILiteral|IParameter|IQueryFunction $y
|
||||
* @return IQueryFunction
|
||||
*/
|
||||
#[Override]
|
||||
public function greatest(
|
||||
string|ILiteral|IParameter|IQueryFunction $x,
|
||||
string|ILiteral|IParameter|IQueryFunction $y,
|
||||
): IQueryFunction {
|
||||
public function greatest($x, $y): IQueryFunction {
|
||||
if (is_string($y) || $y instanceof IQueryFunction) {
|
||||
return parent::greatest($y, $x);
|
||||
}
|
||||
@@ -48,12 +49,12 @@ class OCIFunctionBuilder extends FunctionBuilder {
|
||||
* math, it will cast the expression to int and continue with a "0". So when
|
||||
* the second parameter is a function or column, we have to put that as
|
||||
* first parameter.
|
||||
*
|
||||
* @param string|ILiteral|IParameter|IQueryFunction $x
|
||||
* @param string|ILiteral|IParameter|IQueryFunction $y
|
||||
* @return IQueryFunction
|
||||
*/
|
||||
#[Override]
|
||||
public function least(
|
||||
string|ILiteral|IParameter|IQueryFunction $x,
|
||||
string|ILiteral|IParameter|IQueryFunction $y,
|
||||
): IQueryFunction {
|
||||
public function least($x, $y): IQueryFunction {
|
||||
if (is_string($y) || $y instanceof IQueryFunction) {
|
||||
return parent::least($y, $x);
|
||||
}
|
||||
@@ -61,8 +62,7 @@ class OCIFunctionBuilder extends FunctionBuilder {
|
||||
return parent::least($x, $y);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function concat(string|ILiteral|IParameter|IQueryFunction $x, string|ILiteral|IParameter|IQueryFunction ...$expr): IQueryFunction {
|
||||
public function concat($x, ...$expr): IQueryFunction {
|
||||
$args = func_get_args();
|
||||
$list = [];
|
||||
foreach ($args as $item) {
|
||||
@@ -71,8 +71,7 @@ class OCIFunctionBuilder extends FunctionBuilder {
|
||||
return new QueryFunction(sprintf('(%s)', implode(' || ', $list)));
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function groupConcat(string|ILiteral|IParameter|IQueryFunction $expr, ?string $separator = ','): IQueryFunction {
|
||||
public function groupConcat($expr, ?string $separator = ','): IQueryFunction {
|
||||
$orderByClause = ' WITHIN GROUP(ORDER BY NULL)';
|
||||
if (is_null($separator)) {
|
||||
return new QueryFunction('LISTAGG(' . $this->helper->quoteColumnName($expr) . ')' . $orderByClause);
|
||||
@@ -82,15 +81,13 @@ class OCIFunctionBuilder extends FunctionBuilder {
|
||||
return new QueryFunction('LISTAGG(' . $this->helper->quoteColumnName($expr) . ', ' . $separator . ')' . $orderByClause);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function octetLength(string|ILiteral|IParameter|IQueryFunction $field, string $alias = ''): IQueryFunction {
|
||||
public function octetLength($field, $alias = ''): IQueryFunction {
|
||||
$alias = $alias ? (' AS ' . $this->helper->quoteColumnName($alias)) : '';
|
||||
$quotedName = $this->helper->quoteColumnName($field);
|
||||
return new QueryFunction('COALESCE(LENGTHB(' . $quotedName . '), 0)' . $alias);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function charLength(string|ILiteral|IParameter|IQueryFunction $field, string $alias = ''): IQueryFunction {
|
||||
public function charLength($field, $alias = ''): IQueryFunction {
|
||||
$alias = $alias ? (' AS ' . $this->helper->quoteColumnName($alias)) : '';
|
||||
$quotedName = $this->helper->quoteColumnName($field);
|
||||
return new QueryFunction('COALESCE(LENGTH(' . $quotedName . '), 0)' . $alias);
|
||||
|
||||
@@ -9,10 +9,8 @@ namespace OC\DB\QueryBuilder\FunctionBuilder;
|
||||
use OC\DB\QueryBuilder\QueryFunction;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\DB\QueryBuilder\IQueryFunction;
|
||||
use Override;
|
||||
|
||||
class PgSqlFunctionBuilder extends FunctionBuilder {
|
||||
#[Override]
|
||||
public function concat($x, ...$expr): IQueryFunction {
|
||||
$args = func_get_args();
|
||||
$list = [];
|
||||
@@ -22,7 +20,6 @@ class PgSqlFunctionBuilder extends FunctionBuilder {
|
||||
return new QueryFunction(sprintf('(%s)', implode(' || ', $list)));
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function groupConcat($expr, ?string $separator = ','): IQueryFunction {
|
||||
$castedExpression = $this->queryBuilder->expr()->castColumn($expr, IQueryBuilder::PARAM_STR);
|
||||
|
||||
|
||||
@@ -7,10 +7,7 @@
|
||||
namespace OC\DB\QueryBuilder\FunctionBuilder;
|
||||
|
||||
use OC\DB\QueryBuilder\QueryFunction;
|
||||
use OCP\DB\QueryBuilder\ILiteral;
|
||||
use OCP\DB\QueryBuilder\IParameter;
|
||||
use OCP\DB\QueryBuilder\IQueryFunction;
|
||||
use Override;
|
||||
|
||||
class SqliteFunctionBuilder extends FunctionBuilder {
|
||||
public function concat($x, ...$expr): IQueryFunction {
|
||||
@@ -27,19 +24,11 @@ class SqliteFunctionBuilder extends FunctionBuilder {
|
||||
return new QueryFunction('GROUP_CONCAT(' . $this->helper->quoteColumnName($expr) . ', ' . $separator . ')');
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function greatest(
|
||||
string|ILiteral|IParameter|IQueryFunction $x,
|
||||
string|ILiteral|IParameter|IQueryFunction $y,
|
||||
): IQueryFunction {
|
||||
public function greatest($x, $y): IQueryFunction {
|
||||
return new QueryFunction('MAX(' . $this->helper->quoteColumnName($x) . ', ' . $this->helper->quoteColumnName($y) . ')');
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function least(
|
||||
string|ILiteral|IParameter|IQueryFunction $x,
|
||||
string|ILiteral|IParameter|IQueryFunction $y,
|
||||
): IQueryFunction {
|
||||
public function least($x, $y): IQueryFunction {
|
||||
return new QueryFunction('MIN(' . $this->helper->quoteColumnName($x) . ', ' . $this->helper->quoteColumnName($y) . ')');
|
||||
}
|
||||
|
||||
|
||||
@@ -12,8 +12,11 @@ namespace OC\DB\QueryBuilder;
|
||||
use OCP\DB\QueryBuilder\ILiteral;
|
||||
|
||||
class Literal implements ILiteral {
|
||||
/**
|
||||
* @param mixed $literal
|
||||
*/
|
||||
public function __construct(
|
||||
protected readonly mixed $literal,
|
||||
protected $literal,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ namespace OC\DB\QueryBuilder\Partitioned;
|
||||
|
||||
use OC\DB\QueryBuilder\CompositeExpression;
|
||||
use OC\DB\QueryBuilder\QueryFunction;
|
||||
use OCP\DB\QueryBuilder\ICompositeExpression;
|
||||
use OCP\DB\QueryBuilder\IQueryFunction;
|
||||
|
||||
/**
|
||||
@@ -67,9 +66,14 @@ class JoinCondition {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|string|CompositeExpression $condition
|
||||
* @param string $join
|
||||
* @param string $alias
|
||||
* @param string $fromAlias
|
||||
* @return JoinCondition
|
||||
* @throws InvalidPartitionedQueryException
|
||||
*/
|
||||
public static function parse(null|string|ICompositeExpression $condition, string $join, string $alias, string $fromAlias): JoinCondition {
|
||||
public static function parse($condition, string $join, string $alias, string $fromAlias): JoinCondition {
|
||||
if ($condition === null) {
|
||||
throw new InvalidPartitionedQueryException("Can't join on $join without a condition");
|
||||
}
|
||||
@@ -81,7 +85,7 @@ class JoinCondition {
|
||||
return $result;
|
||||
}
|
||||
|
||||
private static function parseSubCondition(string|ICompositeExpression $condition, string $join, string $alias, string $fromAlias): JoinCondition {
|
||||
private static function parseSubCondition($condition, string $join, string $alias, string $fromAlias): JoinCondition {
|
||||
if ($condition instanceof CompositeExpression) {
|
||||
if ($condition->getType() === CompositeExpression::TYPE_OR) {
|
||||
throw new InvalidPartitionedQueryException("Cannot join on $join with an OR expression");
|
||||
|
||||
@@ -14,13 +14,9 @@ use OC\DB\QueryBuilder\Sharded\AutoIncrementHandler;
|
||||
use OC\DB\QueryBuilder\Sharded\ShardConnectionManager;
|
||||
use OC\DB\QueryBuilder\Sharded\ShardedQueryBuilder;
|
||||
use OCP\DB\IResult;
|
||||
use OCP\DB\QueryBuilder\ICompositeExpression;
|
||||
use OCP\DB\QueryBuilder\ILiteral;
|
||||
use OCP\DB\QueryBuilder\IParameter;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\DB\QueryBuilder\IQueryFunction;
|
||||
use OCP\IDBConnection;
|
||||
use Override;
|
||||
|
||||
/**
|
||||
* A special query builder that automatically splits queries that span across multiple database partitions[1].
|
||||
@@ -45,7 +41,7 @@ class PartitionedQueryBuilder extends ShardedQueryBuilder {
|
||||
/** @var list<PartitionSplit> */
|
||||
private array $partitions = [];
|
||||
|
||||
/** @var array{'select': string|IQueryFunction|IParameter|ILiteral, 'alias': ?string}[] */
|
||||
/** @var array{'select': string|array, 'alias': ?string}[] */
|
||||
private array $selects = [];
|
||||
private ?PartitionSplit $mainPartition = null;
|
||||
private bool $hasPositionalParameter = false;
|
||||
@@ -79,7 +75,7 @@ class PartitionedQueryBuilder extends ShardedQueryBuilder {
|
||||
}
|
||||
|
||||
// we need to save selects until we know all the table aliases
|
||||
public function select(...$selects): self {
|
||||
public function select(...$selects) {
|
||||
if (count($selects) === 1 && is_array($selects[0])) {
|
||||
$selects = $selects[0];
|
||||
}
|
||||
@@ -88,13 +84,15 @@ class PartitionedQueryBuilder extends ShardedQueryBuilder {
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addSelect(...$select): self {
|
||||
$select = array_map(static fn ($select) => ['select' => $select, 'alias' => null], $select);
|
||||
public function addSelect(...$select) {
|
||||
$select = array_map(function ($select) {
|
||||
return ['select' => $select, 'alias' => null];
|
||||
}, $select);
|
||||
$this->selects = array_merge($this->selects, $select);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function selectAlias(string|IQueryFunction|IParameter|ILiteral $select, string $alias): self {
|
||||
public function selectAlias($select, $alias) {
|
||||
$this->selects[] = ['select' => $select, 'alias' => $alias];
|
||||
return $this;
|
||||
}
|
||||
@@ -103,6 +101,9 @@ class PartitionedQueryBuilder extends ShardedQueryBuilder {
|
||||
* Ensure that a column is being selected by the query
|
||||
*
|
||||
* This is mainly used to ensure that the returned rows from both sides of a partition contains the columns of the join predicate
|
||||
*
|
||||
* @param string|IQueryFunction $column
|
||||
* @return void
|
||||
*/
|
||||
private function ensureSelect(string|IQueryFunction $column, ?string $alias = null): void {
|
||||
$checkColumn = $alias ?: $column;
|
||||
@@ -189,30 +190,25 @@ class PartitionedQueryBuilder extends ShardedQueryBuilder {
|
||||
return null;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function from($from, $alias = null): self {
|
||||
public function from($from, $alias = null) {
|
||||
if (is_string($from) && $partition = $this->getPartition($from)) {
|
||||
$this->mainPartition = $partition;
|
||||
if ($alias) {
|
||||
$this->mainPartition->addAlias($from, $alias);
|
||||
}
|
||||
}
|
||||
parent::from($from, $alias);
|
||||
return $this;
|
||||
return parent::from($from, $alias);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function innerJoin(string $fromAlias, string|IQueryFunction $join, ?string $alias, string|ICompositeExpression|null $condition = null): self {
|
||||
public function innerJoin($fromAlias, $join, $alias, $condition = null): self {
|
||||
return $this->join($fromAlias, $join, $alias, $condition);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function leftJoin(string $fromAlias, string|IQueryFunction $join, ?string $alias, string|ICompositeExpression|null $condition = null): self {
|
||||
public function leftJoin($fromAlias, $join, $alias, $condition = null): self {
|
||||
return $this->join($fromAlias, $join, $alias, $condition, PartitionQuery::JOIN_MODE_LEFT);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function join(string $fromAlias, string|IQueryFunction $join, ?string $alias, string|ICompositeExpression|null $condition = null, string $joinMode = PartitionQuery::JOIN_MODE_INNER): self {
|
||||
public function join($fromAlias, $join, $alias, $condition = null, $joinMode = PartitionQuery::JOIN_MODE_INNER): self {
|
||||
if ($join instanceof IQueryFunction) {
|
||||
$partition = null;
|
||||
$fromPartition = null;
|
||||
@@ -225,7 +221,7 @@ class PartitionedQueryBuilder extends ShardedQueryBuilder {
|
||||
/** @var string $join */
|
||||
// join from the main db to a partition
|
||||
|
||||
$joinCondition = JoinCondition::parse((string)$condition, $join, $alias, $fromAlias);
|
||||
$joinCondition = JoinCondition::parse($condition, $join, $alias, $fromAlias);
|
||||
$partition->addAlias($join, $alias);
|
||||
|
||||
if (!isset($this->splitQueries[$partition->name])) {
|
||||
@@ -252,7 +248,7 @@ class PartitionedQueryBuilder extends ShardedQueryBuilder {
|
||||
/** @var string $join */
|
||||
// join from partition, to the main db
|
||||
|
||||
$joinCondition = JoinCondition::parse((string)$condition, $join, $alias, $fromAlias);
|
||||
$joinCondition = JoinCondition::parse($condition, $join, $alias, $fromAlias);
|
||||
if (str_starts_with($fromPartition->name, 'from_')) {
|
||||
$partitionName = $fromPartition->name;
|
||||
} else {
|
||||
@@ -285,14 +281,11 @@ class PartitionedQueryBuilder extends ShardedQueryBuilder {
|
||||
} else {
|
||||
// join within the main db or a partition
|
||||
if ($joinMode === PartitionQuery::JOIN_MODE_INNER) {
|
||||
parent::innerJoin($fromAlias, $join, $alias, $condition);
|
||||
return $this;
|
||||
return parent::innerJoin($fromAlias, $join, $alias, $condition);
|
||||
} elseif ($joinMode === PartitionQuery::JOIN_MODE_LEFT) {
|
||||
parent::leftJoin($fromAlias, $join, $alias, $condition);
|
||||
return $this;
|
||||
return parent::leftJoin($fromAlias, $join, $alias, $condition);
|
||||
} elseif ($joinMode === PartitionQuery::JOIN_MODE_RIGHT) {
|
||||
parent::rightJoin($fromAlias, $join, $alias, $condition);
|
||||
return $this;
|
||||
return parent::rightJoin($fromAlias, $join, $alias, $condition);
|
||||
} else {
|
||||
throw new \InvalidArgumentException("Invalid join mode: $joinMode");
|
||||
}
|
||||
@@ -340,11 +333,11 @@ class PartitionedQueryBuilder extends ShardedQueryBuilder {
|
||||
return $partitionPredicates;
|
||||
}
|
||||
|
||||
public function where(...$predicates): self {
|
||||
public function where(...$predicates) {
|
||||
return $this->andWhere(...$predicates);
|
||||
}
|
||||
|
||||
public function andWhere(...$where): self {
|
||||
public function andWhere(...$where) {
|
||||
if ($where) {
|
||||
foreach ($this->splitPredicatesByParts($where) as $alias => $predicates) {
|
||||
if (isset($this->splitQueries[$alias])) {
|
||||
@@ -387,35 +380,30 @@ class PartitionedQueryBuilder extends ShardedQueryBuilder {
|
||||
return null;
|
||||
}
|
||||
|
||||
public function update(string $update, ?string $alias = null): self {
|
||||
parent::update($update, $alias);
|
||||
return $this;
|
||||
public function update($update = null, $alias = null) {
|
||||
return parent::update($update, $alias);
|
||||
}
|
||||
|
||||
public function insert(string $insert): self {
|
||||
parent::insert($insert);
|
||||
return $this;
|
||||
public function insert($insert = null) {
|
||||
return parent::insert($insert);
|
||||
}
|
||||
|
||||
public function delete(string $delete, ?string $alias = null): self {
|
||||
parent::delete($delete, $alias);
|
||||
return $this;
|
||||
public function delete($delete = null, $alias = null) {
|
||||
return parent::delete($delete, $alias);
|
||||
}
|
||||
|
||||
public function setMaxResults(?int $maxResults): self {
|
||||
if ($maxResults !== null && $maxResults > 0) {
|
||||
$this->limit = $maxResults;
|
||||
public function setMaxResults($maxResults) {
|
||||
if ($maxResults > 0) {
|
||||
$this->limit = (int)$maxResults;
|
||||
}
|
||||
parent::setMaxResults($maxResults);
|
||||
return $this;
|
||||
return parent::setMaxResults($maxResults);
|
||||
}
|
||||
|
||||
public function setFirstResult(int $firstResult): self {
|
||||
public function setFirstResult($firstResult) {
|
||||
if ($firstResult > 0) {
|
||||
$this->offset = $firstResult;
|
||||
$this->offset = (int)$firstResult;
|
||||
}
|
||||
parent::setFirstResult($firstResult);
|
||||
return $this;
|
||||
return parent::setFirstResult($firstResult);
|
||||
}
|
||||
|
||||
public function executeQuery(?IDBConnection $connection = null): IResult {
|
||||
@@ -456,7 +444,7 @@ class PartitionedQueryBuilder extends ShardedQueryBuilder {
|
||||
return parent::executeStatement($connection);
|
||||
}
|
||||
|
||||
public function getSQL(): string {
|
||||
public function getSQL() {
|
||||
$this->applySelects();
|
||||
return parent::getSQL();
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -12,7 +12,11 @@ use OCP\DB\QueryBuilder\IParameter;
|
||||
use OCP\DB\QueryBuilder\IQueryFunction;
|
||||
|
||||
class QuoteHelper {
|
||||
public function quoteColumnNames(array|string|ILiteral|IParameter|IQueryFunction $strings): array|string {
|
||||
/**
|
||||
* @param array|string|ILiteral|IParameter|IQueryFunction $strings string, Literal or Parameter
|
||||
* @return array|string
|
||||
*/
|
||||
public function quoteColumnNames($strings) {
|
||||
if (!is_array($strings)) {
|
||||
return $this->quoteColumnName($strings);
|
||||
}
|
||||
@@ -25,18 +29,26 @@ class QuoteHelper {
|
||||
return $return;
|
||||
}
|
||||
|
||||
public function quoteColumnName(string|ILiteral|IParameter|IQueryFunction $string): string {
|
||||
/**
|
||||
* @param string|ILiteral|IParameter|IQueryFunction $string string, Literal or Parameter
|
||||
* @return string
|
||||
*/
|
||||
public function quoteColumnName($string) {
|
||||
if ($string instanceof IParameter || $string instanceof ILiteral || $string instanceof IQueryFunction) {
|
||||
return (string)$string;
|
||||
}
|
||||
|
||||
if ($string === 'null' || $string === '*') {
|
||||
if ($string === null || $string === 'null' || $string === '*') {
|
||||
return $string;
|
||||
}
|
||||
|
||||
if (!is_string($string)) {
|
||||
throw new \InvalidArgumentException('Only strings, Literals and Parameters are allowed');
|
||||
}
|
||||
|
||||
$string = str_replace(' AS ', ' as ', $string);
|
||||
if (substr_count($string, ' as ')) {
|
||||
return implode(' as ', array_map($this->quoteColumnName(...), explode(' as ', $string, 2)));
|
||||
return implode(' as ', array_map([$this, 'quoteColumnName'], explode(' as ', $string, 2)));
|
||||
}
|
||||
|
||||
if (substr_count($string, '.')) {
|
||||
|
||||
@@ -12,13 +12,8 @@ use OC\DB\QueryBuilder\CompositeExpression;
|
||||
use OC\DB\QueryBuilder\ExtendedQueryBuilder;
|
||||
use OC\DB\QueryBuilder\Parameter;
|
||||
use OCP\DB\IResult;
|
||||
use OCP\DB\QueryBuilder\ICompositeExpression;
|
||||
use OCP\DB\QueryBuilder\ILiteral;
|
||||
use OCP\DB\QueryBuilder\IParameter;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\DB\QueryBuilder\IQueryFunction;
|
||||
use OCP\IDBConnection;
|
||||
use Override;
|
||||
|
||||
/**
|
||||
* A special query builder that automatically distributes queries over multiple database shards.
|
||||
@@ -88,13 +83,11 @@ class ShardedQueryBuilder extends ExtendedQueryBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function where(...$predicates): self {
|
||||
public function where(...$predicates) {
|
||||
return $this->andWhere(...$predicates);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function andWhere(...$where): self {
|
||||
public function andWhere(...$where) {
|
||||
if ($where) {
|
||||
foreach ($where as $predicate) {
|
||||
$this->tryLoadShardKey($predicate);
|
||||
@@ -165,18 +158,14 @@ class ShardedQueryBuilder extends ExtendedQueryBuilder {
|
||||
return [];
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function set($key, $value): self {
|
||||
public function set($key, $value) {
|
||||
if ($this->shardDefinition && $key === $this->shardDefinition->shardKey) {
|
||||
// TODO dead code?
|
||||
$updateShardKey = $value;
|
||||
}
|
||||
parent::set($key, $value);
|
||||
return $this;
|
||||
return parent::set($key, $value);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function setValue(string $column, ILiteral|IParameter|IQueryFunction|string $value): self {
|
||||
public function setValue($column, $value) {
|
||||
if ($this->shardDefinition) {
|
||||
if ($this->shardDefinition->isKey($column)) {
|
||||
$this->primaryKeys[] = $value;
|
||||
@@ -185,12 +174,10 @@ class ShardedQueryBuilder extends ExtendedQueryBuilder {
|
||||
$this->shardKeys[] = $value;
|
||||
}
|
||||
}
|
||||
parent::setValue($column, $value);
|
||||
return $this;
|
||||
return parent::setValue($column, $value);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function values(array $values): self {
|
||||
public function values(array $values) {
|
||||
foreach ($values as $column => $value) {
|
||||
$this->setValue($column, $value);
|
||||
}
|
||||
@@ -206,35 +193,33 @@ class ShardedQueryBuilder extends ExtendedQueryBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function from(string|IQueryFunction $from, ?string $alias = null): self {
|
||||
if (is_string($from)) {
|
||||
public function from($from, $alias = null) {
|
||||
if (is_string($from) && $from) {
|
||||
$this->actOnTable($from);
|
||||
}
|
||||
parent::from($from, $alias);
|
||||
return $this;
|
||||
return parent::from($from, $alias);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function update(string $update, ?string $alias = null): self {
|
||||
$this->actOnTable($update);
|
||||
parent::update($update, $alias);
|
||||
return $this;
|
||||
public function update($update = null, $alias = null) {
|
||||
if (is_string($update) && $update) {
|
||||
$this->actOnTable($update);
|
||||
}
|
||||
return parent::update($update, $alias);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function insert(string $insert): self {
|
||||
$this->insertTable = $insert;
|
||||
$this->actOnTable($insert);
|
||||
parent::insert($insert);
|
||||
return $this;
|
||||
public function insert($insert = null) {
|
||||
if (is_string($insert) && $insert) {
|
||||
$this->insertTable = $insert;
|
||||
$this->actOnTable($insert);
|
||||
}
|
||||
return parent::insert($insert);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function delete(string $delete, ?string $alias = null): self {
|
||||
$this->actOnTable($delete);
|
||||
parent::delete($delete, $alias);
|
||||
return $this;
|
||||
public function delete($delete = null, $alias = null) {
|
||||
if (is_string($delete) && $delete) {
|
||||
$this->actOnTable($delete);
|
||||
}
|
||||
return parent::delete($delete, $alias);
|
||||
}
|
||||
|
||||
private function checkJoin(string $table): void {
|
||||
@@ -250,83 +235,67 @@ class ShardedQueryBuilder extends ExtendedQueryBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function innerJoin(string $fromAlias, string|IQueryFunction $join, ?string $alias, string|ICompositeExpression|null $condition = null): self {
|
||||
public function innerJoin($fromAlias, $join, $alias, $condition = null) {
|
||||
if (is_string($join)) {
|
||||
$this->checkJoin($join);
|
||||
}
|
||||
parent::innerJoin($fromAlias, $join, $alias, $condition);
|
||||
return $this;
|
||||
return parent::innerJoin($fromAlias, $join, $alias, $condition);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function leftJoin(string $fromAlias, string|IQueryFunction $join, ?string $alias, string|ICompositeExpression|null $condition = null): self {
|
||||
public function leftJoin($fromAlias, $join, $alias, $condition = null) {
|
||||
if (is_string($join)) {
|
||||
$this->checkJoin($join);
|
||||
}
|
||||
parent::leftJoin($fromAlias, $join, $alias, $condition);
|
||||
return $this;
|
||||
return parent::leftJoin($fromAlias, $join, $alias, $condition);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function rightJoin(string $fromAlias, string|IQueryFunction $join, ?string $alias, string|ICompositeExpression|null $condition = null): self {
|
||||
public function rightJoin($fromAlias, $join, $alias, $condition = null) {
|
||||
if ($this->shardDefinition) {
|
||||
throw new InvalidShardedQueryException("Sharded query on {$this->shardDefinition->table} isn't allowed to right join");
|
||||
}
|
||||
parent::rightJoin($fromAlias, $join, $alias, $condition);
|
||||
return $this;
|
||||
return parent::rightJoin($fromAlias, $join, $alias, $condition);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function join(string $fromAlias, string|IQueryFunction $join, ?string $alias, string|ICompositeExpression|null $condition = null): self {
|
||||
$this->innerJoin($fromAlias, $join, $alias, $condition);
|
||||
return $this;
|
||||
public function join($fromAlias, $join, $alias, $condition = null) {
|
||||
return $this->innerJoin($fromAlias, $join, $alias, $condition);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function setMaxResults(?int $maxResults): self {
|
||||
if ($maxResults !== null && $maxResults > 0) {
|
||||
$this->limit = $maxResults;
|
||||
public function setMaxResults($maxResults) {
|
||||
if ($maxResults > 0) {
|
||||
$this->limit = (int)$maxResults;
|
||||
}
|
||||
parent::setMaxResults($maxResults);
|
||||
return $this;
|
||||
return parent::setMaxResults($maxResults);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function setFirstResult(int $firstResult): self {
|
||||
public function setFirstResult($firstResult) {
|
||||
if ($firstResult > 0) {
|
||||
$this->offset = $firstResult;
|
||||
$this->offset = (int)$firstResult;
|
||||
}
|
||||
if ($this->shardDefinition && count($this->shardDefinition->shards) > 1) {
|
||||
// we have to emulate offset
|
||||
return $this;
|
||||
} else {
|
||||
parent::setFirstResult($firstResult);
|
||||
return $this;
|
||||
return parent::setFirstResult($firstResult);
|
||||
}
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function addOrderBy($sort, $order = null): self {
|
||||
public function addOrderBy($sort, $order = null) {
|
||||
if ($order !== null && !in_array(strtoupper((string)$order), ['ASC', 'DESC'], true)) {
|
||||
$order = null;
|
||||
}
|
||||
|
||||
$this->registerOrder((string)$sort, (string)($order ?? 'ASC'));
|
||||
parent::addOrderBy($sort, $order);
|
||||
return $this;
|
||||
return parent::addOrderBy($sort, $order);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function orderBy($sort, $order = null): self {
|
||||
public function orderBy($sort, $order = null) {
|
||||
if ($order !== null && !in_array(strtoupper((string)$order), ['ASC', 'DESC'], true)) {
|
||||
$order = null;
|
||||
}
|
||||
|
||||
$this->sortList = [];
|
||||
$this->registerOrder((string)$sort, (string)($order ?? 'ASC'));
|
||||
parent::orderBy($sort, $order);
|
||||
return $this;
|
||||
return parent::orderBy($sort, $order);
|
||||
}
|
||||
|
||||
private function registerOrder(string $column, string $order): void {
|
||||
@@ -339,7 +308,6 @@ class ShardedQueryBuilder extends ExtendedQueryBuilder {
|
||||
];
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function hintShardKey(string $column, mixed $value, bool $overwrite = false): self {
|
||||
if ($overwrite) {
|
||||
$this->primaryKeys = [];
|
||||
@@ -354,7 +322,6 @@ class ShardedQueryBuilder extends ExtendedQueryBuilder {
|
||||
return $this;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function runAcrossAllShards(): self {
|
||||
$this->allShards = true;
|
||||
return $this;
|
||||
@@ -397,7 +364,6 @@ class ShardedQueryBuilder extends ExtendedQueryBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function executeQuery(?IDBConnection $connection = null): IResult {
|
||||
$this->validate();
|
||||
if ($this->shardDefinition) {
|
||||
@@ -407,7 +373,6 @@ class ShardedQueryBuilder extends ExtendedQueryBuilder {
|
||||
return parent::executeQuery($connection);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function executeStatement(?IDBConnection $connection = null): int {
|
||||
$this->validate();
|
||||
if ($this->shardDefinition) {
|
||||
@@ -438,7 +403,6 @@ class ShardedQueryBuilder extends ExtendedQueryBuilder {
|
||||
return parent::executeStatement($connection);
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function getLastInsertId(): int {
|
||||
if ($this->lastInsertId) {
|
||||
return $this->lastInsertId;
|
||||
@@ -450,4 +414,6 @@ class ShardedQueryBuilder extends ExtendedQueryBuilder {
|
||||
return parent::getLastInsertId();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
namespace OC\DB\QueryBuilder;
|
||||
|
||||
use OCP\DB\QueryBuilder\ITypedQueryBuilder;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* @psalm-suppress InvalidTemplateParam
|
||||
* @template-implements ITypedQueryBuilder<string>
|
||||
*/
|
||||
abstract class TypedQueryBuilder implements ITypedQueryBuilder {
|
||||
private function validateColumn(string $column): void {
|
||||
if (str_contains($column, '.') || trim($column) === '*') {
|
||||
throw new RuntimeException('Only column names are allowed, got: ' . $column);
|
||||
}
|
||||
}
|
||||
|
||||
public function selectColumns(string ...$columns): static {
|
||||
foreach ($columns as $column) {
|
||||
$this->validateColumn($column);
|
||||
}
|
||||
|
||||
/** @psalm-suppress InternalMethod */
|
||||
$this->select(...$columns);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function selectColumnsDistinct(string ...$columns): static {
|
||||
foreach ($columns as $column) {
|
||||
$this->validateColumn($column);
|
||||
}
|
||||
|
||||
/** @psalm-suppress InternalMethod */
|
||||
$this->selectDistinct($columns);
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -15,8 +15,6 @@ use PDO;
|
||||
|
||||
/**
|
||||
* Adapts DBAL 2.6 API for DBAL 3.x for backwards compatibility of a leaked type
|
||||
*
|
||||
* @template-implements IResult<string>
|
||||
*/
|
||||
class ResultAdapter implements IResult {
|
||||
public function __construct(
|
||||
|
||||
@@ -45,7 +45,7 @@ class CacheQueryBuilder extends ExtendedQueryBuilder {
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function selectFileCache(?string $alias = null, bool $joinExtendedCache = true): self {
|
||||
public function selectFileCache(?string $alias = null, bool $joinExtendedCache = true) {
|
||||
$name = $alias ?: 'filecache';
|
||||
$this->select("$name.fileid", 'storage', 'path', 'path_hash', "$name.parent", "$name.name", 'mimetype', 'mimepart', 'size', 'mtime',
|
||||
'storage_mtime', 'encrypted', "$name.etag", "$name.permissions", 'checksum', 'unencrypted_size')
|
||||
@@ -61,13 +61,13 @@ class CacheQueryBuilder extends ExtendedQueryBuilder {
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function whereStorageId(int $storageId): self {
|
||||
public function whereStorageId(int $storageId) {
|
||||
$this->andWhere($this->expr()->eq('storage', $this->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function whereFileId(int $fileId): self {
|
||||
public function whereFileId(int $fileId) {
|
||||
$alias = $this->alias;
|
||||
if ($alias) {
|
||||
$alias .= '.';
|
||||
@@ -86,7 +86,7 @@ class CacheQueryBuilder extends ExtendedQueryBuilder {
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function whereParent(int $parent): self {
|
||||
public function whereParent(int $parent) {
|
||||
$alias = $this->alias;
|
||||
if ($alias) {
|
||||
$alias .= '.';
|
||||
@@ -99,7 +99,7 @@ class CacheQueryBuilder extends ExtendedQueryBuilder {
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function whereParentInParameter(string $parameter): self {
|
||||
public function whereParentInParameter(string $parameter) {
|
||||
$alias = $this->alias;
|
||||
if ($alias) {
|
||||
$alias .= '.';
|
||||
|
||||
@@ -20,7 +20,6 @@ use OCP\Files\NotFoundException;
|
||||
class Manager implements IMountManager {
|
||||
/** @var array<string, IMountPoint> */
|
||||
private array $mounts = [];
|
||||
private array $mountsByProvider = [];
|
||||
private bool $areMountsSorted = false;
|
||||
/** @var list<string>|null $mountKeys */
|
||||
private ?array $mountKeys = null;
|
||||
@@ -37,11 +36,7 @@ class Manager implements IMountManager {
|
||||
}
|
||||
|
||||
public function addMount(IMountPoint $mount): void {
|
||||
$mountPoint = $mount->getMountPoint();
|
||||
$mountProvider = $mount->getMountProvider();
|
||||
$this->mounts[$mountPoint] = $mount;
|
||||
$this->mountsByProvider[$mountProvider] ??= [];
|
||||
$this->mountsByProvider[$mountProvider][$mountPoint] = $mount;
|
||||
$this->mounts[$mount->getMountPoint()] = $mount;
|
||||
$this->pathCache->clear();
|
||||
$this->inPathCache->clear();
|
||||
$this->areMountsSorted = false;
|
||||
@@ -172,7 +167,6 @@ class Manager implements IMountManager {
|
||||
|
||||
public function clear(): void {
|
||||
$this->mounts = [];
|
||||
$this->mountsByProvider = [];
|
||||
$this->pathCache->clear();
|
||||
$this->inPathCache->clear();
|
||||
}
|
||||
@@ -242,18 +236,15 @@ class Manager implements IMountManager {
|
||||
* @param string[] $mountProviders
|
||||
* @return array<string, IMountPoint>
|
||||
*/
|
||||
public function getMountsByMountProvider(string $path, array $mountProviders): array {
|
||||
public function getMountsByMountProvider(string $path, array $mountProviders) {
|
||||
$this->getSetupManager()->setupForProvider($path, $mountProviders);
|
||||
if (\in_array('', $mountProviders)) {
|
||||
if (in_array('', $mountProviders)) {
|
||||
return $this->mounts;
|
||||
} else {
|
||||
return array_filter($this->mounts, function ($mount) use ($mountProviders) {
|
||||
return in_array($mount->getMountProvider(), $mountProviders);
|
||||
});
|
||||
}
|
||||
|
||||
$mounts = [];
|
||||
foreach ($mountProviders as $mountProvider) {
|
||||
$mounts[] = $this->mountsByProvider[$mountProvider] ?? [];
|
||||
}
|
||||
|
||||
return array_merge(...$mounts);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -97,15 +97,11 @@ abstract class Common implements Storage, ILockingStorage, IWriteStreamStorage,
|
||||
}
|
||||
|
||||
public function filesize(string $path): int|float|false {
|
||||
$type = $this->filetype($path);
|
||||
if ($type === false) {
|
||||
return false;
|
||||
}
|
||||
if ($type !== 'file') {
|
||||
return 0;
|
||||
if ($this->is_dir($path)) {
|
||||
return 0; //by definition
|
||||
} else {
|
||||
$stat = $this->stat($path);
|
||||
return $stat['size'] ?? 0;
|
||||
return isset($stat['size']) ? $stat['size'] : 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -218,7 +218,7 @@ class Local extends Common {
|
||||
}
|
||||
|
||||
public function filetype(string $path): string|false {
|
||||
$filetype = @filetype($this->getSourcePath($path));
|
||||
$filetype = filetype($this->getSourcePath($path));
|
||||
if ($filetype === 'link') {
|
||||
$filetype = filetype(realpath($this->getSourcePath($path)));
|
||||
}
|
||||
@@ -226,11 +226,7 @@ class Local extends Common {
|
||||
}
|
||||
|
||||
public function filesize(string $path): int|float|false {
|
||||
$type = $this->filetype($path);
|
||||
if ($type === false) {
|
||||
return false;
|
||||
}
|
||||
if ($type !== 'file') {
|
||||
if (!$this->is_file($path)) {
|
||||
return 0;
|
||||
}
|
||||
$fullPath = $this->getSourcePath($path);
|
||||
|
||||
+10
-1
@@ -619,7 +619,16 @@ class Server extends ServerContainer implements IServerContainer {
|
||||
|
||||
$this->registerAlias(IURLGenerator::class, URLGenerator::class);
|
||||
|
||||
$this->registerAlias(ICache::class, Cache\File::class);
|
||||
$this->registerService(ICache::class, function ($c) {
|
||||
/** @var LoggerInterface $logger */
|
||||
$logger = $c->get(LoggerInterface::class);
|
||||
$logger->debug('The requested service "' . ICache::class . '" is deprecated. Please use "' . ICacheFactory::class . '" instead to create a cache. This service will be removed in a future Nextcloud version.', ['app' => 'serverDI']);
|
||||
|
||||
/** @var ICacheFactory $cacheFactory */
|
||||
$cacheFactory = $c->get(ICacheFactory::class);
|
||||
return $cacheFactory->isLocalCacheAvailable() ? $cacheFactory->createLocal() : $cacheFactory->createInMemory();
|
||||
});
|
||||
|
||||
$this->registerService(Factory::class, function (Server $c) {
|
||||
$profiler = $c->get(IProfiler::class);
|
||||
$logger = $c->get(LoggerInterface::class);
|
||||
|
||||
@@ -968,7 +968,7 @@ class DefaultShareProvider implements
|
||||
->setFirstResult(0);
|
||||
|
||||
if ($limit !== -1) {
|
||||
$qb->setMaxResults(max($limit - count($shares), 1));
|
||||
$qb->setMaxResults($limit - count($shares));
|
||||
}
|
||||
|
||||
// Filter by node if provided
|
||||
|
||||
@@ -302,7 +302,7 @@ class Manager implements IManager {
|
||||
if (!$share->getNoExpirationDate() || $isEnforced) {
|
||||
if ($expirationDate !== null) {
|
||||
$expirationDate->setTimezone($this->dateTimeZone->getTimeZone());
|
||||
$expirationDate->setTime(23, 59, 59);
|
||||
$expirationDate->setTime(0, 0, 0);
|
||||
|
||||
$date = new \DateTime('now', $this->dateTimeZone->getTimeZone());
|
||||
$date->setTime(0, 0, 0);
|
||||
@@ -321,7 +321,7 @@ class Manager implements IManager {
|
||||
|
||||
if ($fullId === null && $expirationDate === null && $defaultExpireDate) {
|
||||
$expirationDate = new \DateTime('now', $this->dateTimeZone->getTimeZone());
|
||||
$expirationDate->setTime(23, 59, 59);
|
||||
$expirationDate->setTime(0, 0, 0);
|
||||
$days = (int)$this->config->getAppValue('core', $configProp, (string)$defaultExpireDays);
|
||||
if ($days > $defaultExpireDays) {
|
||||
$days = $defaultExpireDays;
|
||||
@@ -336,7 +336,7 @@ class Manager implements IManager {
|
||||
}
|
||||
|
||||
$date = new \DateTime('now', $this->dateTimeZone->getTimeZone());
|
||||
$date->setTime(23, 59, 59);
|
||||
$date->setTime(0, 0, 0);
|
||||
$date->add(new \DateInterval('P' . $defaultExpireDays . 'D'));
|
||||
if ($date < $expirationDate) {
|
||||
throw new GenericShareException($this->l->n('Cannot set expiration date more than %n day in the future', 'Cannot set expiration date more than %n days in the future', $defaultExpireDays), code: 404);
|
||||
@@ -380,7 +380,7 @@ class Manager implements IManager {
|
||||
if (!($share->getNoExpirationDate() && !$isEnforced)) {
|
||||
if ($expirationDate !== null) {
|
||||
$expirationDate->setTimezone($this->dateTimeZone->getTimeZone());
|
||||
$expirationDate->setTime(23, 59, 59);
|
||||
$expirationDate->setTime(0, 0, 0);
|
||||
|
||||
$date = new \DateTime('now', $this->dateTimeZone->getTimeZone());
|
||||
$date->setTime(0, 0, 0);
|
||||
@@ -399,7 +399,7 @@ class Manager implements IManager {
|
||||
|
||||
if ($fullId === null && $expirationDate === null && $this->shareApiLinkDefaultExpireDate()) {
|
||||
$expirationDate = new \DateTime('now', $this->dateTimeZone->getTimeZone());
|
||||
$expirationDate->setTime(23, 59, 59);
|
||||
$expirationDate->setTime(0, 0, 0);
|
||||
|
||||
$days = (int)$this->config->getAppValue('core', 'link_defaultExpDays', (string)$this->shareApiLinkDefaultExpireDays());
|
||||
if ($days > $this->shareApiLinkDefaultExpireDays()) {
|
||||
@@ -415,7 +415,7 @@ class Manager implements IManager {
|
||||
}
|
||||
|
||||
$date = new \DateTime('now', $this->dateTimeZone->getTimeZone());
|
||||
$date->setTime(23, 59, 59);
|
||||
$date->setTime(0, 0, 0);
|
||||
$date->add(new \DateInterval('P' . $this->shareApiLinkDefaultExpireDays() . 'D'));
|
||||
if ($date < $expirationDate) {
|
||||
throw new GenericShareException(
|
||||
|
||||
@@ -9,7 +9,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace OC\Snowflake;
|
||||
|
||||
use OC_Util;
|
||||
use OCP\ITempManager;
|
||||
use Override;
|
||||
|
||||
@@ -28,7 +27,7 @@ class FileSequence implements ISequence {
|
||||
public function __construct(
|
||||
ITempManager $tempManager,
|
||||
) {
|
||||
$this->workDir = $tempManager->getTempBaseDir() . '/' . self::LOCK_FILE_DIRECTORY . '_' . OC_Util::getInstanceId();
|
||||
$this->workDir = $tempManager->getTempBaseDir() . '/' . self::LOCK_FILE_DIRECTORY;
|
||||
$this->ensureWorkdirExists();
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user