mirror of
https://github.com/appwrite/appwrite
synced 2026-05-24 01:18:37 +00:00
Merge branch '1.6.x' into chore-sync-1.6.x
This commit is contained in:
commit
5db1cff69f
5 changed files with 889 additions and 649 deletions
264
CHANGES.md
264
CHANGES.md
|
|
@ -1,3 +1,267 @@
|
||||||
|
# Version 1.6.2
|
||||||
|
|
||||||
|
## What's Changed
|
||||||
|
|
||||||
|
### Notable changes
|
||||||
|
|
||||||
|
* Delete git folder to reduce build size in [9076](https://github.com/appwrite/appwrite/pull/9076)
|
||||||
|
* Upgrade assistant in [9100](https://github.com/appwrite/appwrite/pull/9100)
|
||||||
|
* Use redis adapter for abuse in [9121](https://github.com/appwrite/appwrite/pull/9121)
|
||||||
|
* Set base specification CPUs to 0.5 again in [9146](https://github.com/appwrite/appwrite/pull/9146)
|
||||||
|
* Add new push message parameters in [9060](https://github.com/appwrite/appwrite/pull/9060)
|
||||||
|
* Update audits to include user type in [9211](https://github.com/appwrite/appwrite/pull/9211)
|
||||||
|
* Enable HEIC in [9251](https://github.com/appwrite/appwrite/pull/9251)
|
||||||
|
* Added teamName to membership redirect url in [9269](https://github.com/appwrite/appwrite/pull/9269)
|
||||||
|
* Add support endpoint url for S3 in [9303](https://github.com/appwrite/appwrite/pull/9303)
|
||||||
|
* Added RuPay Credit Card Icon in Avatars Service in [5046](https://github.com/appwrite/appwrite/pull/5046)
|
||||||
|
* Add figma oauth provider in [9623](https://github.com/appwrite/appwrite/pull/9623)
|
||||||
|
* Update console to version 5.2.58 in [9637](https://github.com/appwrite/appwrite/pull/9637)
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Remove failed attribute in [9032](https://github.com/appwrite/appwrite/pull/9032)
|
||||||
|
* Fix delete notFound attribute in [9038](https://github.com/appwrite/appwrite/pull/9038)
|
||||||
|
* 🇮🇸 Added missing Icelandic translations for email strings. in [4848](https://github.com/appwrite/appwrite/pull/4848)
|
||||||
|
* fix doc comment for filter method in [5769](https://github.com/appwrite/appwrite/pull/5769)
|
||||||
|
* Delete attribute No throwing Exception on not found in [9157](https://github.com/appwrite/appwrite/pull/9157)
|
||||||
|
* Fix VCS identity collision in [9138](https://github.com/appwrite/appwrite/pull/9138)
|
||||||
|
* Fix disabling of email-otp when user wants to in [9200](https://github.com/appwrite/appwrite/pull/9200)
|
||||||
|
* Ensure user can delete session in [9209](https://github.com/appwrite/appwrite/pull/9209)
|
||||||
|
* Fix resend invitation in [9218](https://github.com/appwrite/appwrite/pull/9218)
|
||||||
|
* Fix phone number parsing exception handling in [9246](https://github.com/appwrite/appwrite/pull/9246)
|
||||||
|
* Fix amazon oauth in [9253](https://github.com/appwrite/appwrite/pull/9253)
|
||||||
|
* Fix slack oauth scopes, and updated to v2 in [9228](https://github.com/appwrite/appwrite/pull/9228)
|
||||||
|
* Fix forwarded user agent in [9271](https://github.com/appwrite/appwrite/pull/9271)
|
||||||
|
* Fix WEBP File Preview Rendering Issue in [9321](https://github.com/appwrite/appwrite/pull/9321)
|
||||||
|
* Fix build memory specifications in [9360](https://github.com/appwrite/appwrite/pull/9360)
|
||||||
|
* Fix Self Hosting functions by adding missed config in [9373](https://github.com/appwrite/appwrite/pull/9373)
|
||||||
|
* Fix resend team invite if already accepted in [9348](https://github.com/appwrite/appwrite/pull/9348)
|
||||||
|
* Fix null errors on team invite in [9391](https://github.com/appwrite/appwrite/pull/9391)
|
||||||
|
* Fix email (smtp) to multiple recipients in [9243](https://github.com/appwrite/appwrite/pull/9243)
|
||||||
|
* Fix stats timing by using receivedAt date when available in [9428](https://github.com/appwrite/appwrite/pull/9428)
|
||||||
|
* Make min/max params optional for attribute update in [9387](https://github.com/appwrite/appwrite/pull/9387)
|
||||||
|
* Fix blocking of phone sessions when disabled on console in [9447](https://github.com/appwrite/appwrite/pull/9447)
|
||||||
|
* Fix logging config in [9467](https://github.com/appwrite/appwrite/pull/9467)
|
||||||
|
* Update audit timestamp origin in [9481](https://github.com/appwrite/appwrite/pull/9481)
|
||||||
|
* Fix certificates in deletes worker in [9466](https://github.com/appwrite/appwrite/pull/9466)
|
||||||
|
* Fix console audits delete in [9547](https://github.com/appwrite/appwrite/pull/9547)
|
||||||
|
* Fix migrations in [9633](https://github.com/appwrite/appwrite/pull/9633)
|
||||||
|
* Ensure all 4xx errors in OAuth redirect lead to the failure URL in [9679](https://github.com/appwrite/appwrite/pull/9679)
|
||||||
|
* Treat 0 as unlimited for CPUs and memory in [9638](https://github.com/appwrite/appwrite/pull/9638)
|
||||||
|
* Add contextual dispatch logic to fix high CPU usage in [9687](https://github.com/appwrite/appwrite/pull/9687)
|
||||||
|
|
||||||
|
### Miscellaneous
|
||||||
|
|
||||||
|
* Merge 1.6.x into feat-custom-cf-hostnames in [8904](https://github.com/appwrite/appwrite/pull/8904)
|
||||||
|
* Improve compression param checks in [8922](https://github.com/appwrite/appwrite/pull/8922)
|
||||||
|
* upgrade utopia storage in [8930](https://github.com/appwrite/appwrite/pull/8930)
|
||||||
|
* Feat migration in [8797](https://github.com/appwrite/appwrite/pull/8797)
|
||||||
|
* feat fix web routes in [8962](https://github.com/appwrite/appwrite/pull/8962)
|
||||||
|
* Fix no pool access in [9027](https://github.com/appwrite/appwrite/pull/9027)
|
||||||
|
* feat: use environment variable to check rules format in [9039](https://github.com/appwrite/appwrite/pull/9039)
|
||||||
|
* Update storage.php in [9037](https://github.com/appwrite/appwrite/pull/9037)
|
||||||
|
* Upgrade db 0.53.200 in [9050](https://github.com/appwrite/appwrite/pull/9050)
|
||||||
|
* Chore: upgrade utopia storage in [9066](https://github.com/appwrite/appwrite/pull/9066)
|
||||||
|
* Update usage-dump payload in [9085](https://github.com/appwrite/appwrite/pull/9085)
|
||||||
|
* GitHub Workflows security hardening in [3728](https://github.com/appwrite/appwrite/pull/3728)
|
||||||
|
* Update add-oauth2-provider.md in [4313](https://github.com/appwrite/appwrite/pull/4313)
|
||||||
|
* update readme-cn some doc in [5278](https://github.com/appwrite/appwrite/pull/5278)
|
||||||
|
* Add accessibility features in [7042](https://github.com/appwrite/appwrite/pull/7042)
|
||||||
|
* Add Appwrite Cloud to read me. in [5445](https://github.com/appwrite/appwrite/pull/5445)
|
||||||
|
* Migration throw error in [9092](https://github.com/appwrite/appwrite/pull/9092)
|
||||||
|
* Fix usage payload bug in [9097](https://github.com/appwrite/appwrite/pull/9097)
|
||||||
|
* chore: replace occurrences of dbForConsole to dbForPlatform in [9096](https://github.com/appwrite/appwrite/pull/9096)
|
||||||
|
* fix(realtime): decrement connectionCounter only if connection is known in [9055](https://github.com/appwrite/appwrite/pull/9055)
|
||||||
|
* payload bug fix in [9098](https://github.com/appwrite/appwrite/pull/9098)
|
||||||
|
* Fix usage payload bug in [9099](https://github.com/appwrite/appwrite/pull/9099)
|
||||||
|
* Usage payload debug in [9101](https://github.com/appwrite/appwrite/pull/9101)
|
||||||
|
* Usage payload debug in [9103](https://github.com/appwrite/appwrite/pull/9103)
|
||||||
|
* Usage payload debug in [9104](https://github.com/appwrite/appwrite/pull/9104)
|
||||||
|
* Feat: createFunction abuse labels in [9102](https://github.com/appwrite/appwrite/pull/9102)
|
||||||
|
* Docs-create-document in [9105](https://github.com/appwrite/appwrite/pull/9105)
|
||||||
|
* Docs: Create document and unknown attribute error messages. in [5427](https://github.com/appwrite/appwrite/pull/5427)
|
||||||
|
* Fix: update project accessed at from router and schedulers in [9109](https://github.com/appwrite/appwrite/pull/9109)
|
||||||
|
* chore: initial commit in [9111](https://github.com/appwrite/appwrite/pull/9111)
|
||||||
|
* chore: optimise webhooks payload in [9115](https://github.com/appwrite/appwrite/pull/9115)
|
||||||
|
* Revert "chore: initial commit" in [9117](https://github.com/appwrite/appwrite/pull/9117)
|
||||||
|
* chore: fix attribute name in [9118](https://github.com/appwrite/appwrite/pull/9118)
|
||||||
|
* Migrate to redis abuse in [9124](https://github.com/appwrite/appwrite/pull/9124)
|
||||||
|
* Added webhooks usage stats in [9125](https://github.com/appwrite/appwrite/pull/9125)
|
||||||
|
* chore remove abuse cleanup in [9137](https://github.com/appwrite/appwrite/pull/9137)
|
||||||
|
* fix: remove abuse delete trigger in [9139](https://github.com/appwrite/appwrite/pull/9139)
|
||||||
|
* Remove firebase OAuth API endpoints in [9144](https://github.com/appwrite/appwrite/pull/9144)
|
||||||
|
* chore: release client sdks in [9112](https://github.com/appwrite/appwrite/pull/9112)
|
||||||
|
* Update general.php in [9155](https://github.com/appwrite/appwrite/pull/9155)
|
||||||
|
* feat(swoole): allow configuration override of available cpus in [9177](https://github.com/appwrite/appwrite/pull/9177)
|
||||||
|
* Usage databases api read writes addition in [9142](https://github.com/appwrite/appwrite/pull/9142)
|
||||||
|
* Fix dead connections in [9190](https://github.com/appwrite/appwrite/pull/9190)
|
||||||
|
* Add hostname to audits in [9165](https://github.com/appwrite/appwrite/pull/9165)
|
||||||
|
* chore: shifted authphone usage tracking to api calls in [9191](https://github.com/appwrite/appwrite/pull/9191)
|
||||||
|
* Revert "Fix dead connections" in [9201](https://github.com/appwrite/appwrite/pull/9201)
|
||||||
|
* Add assertEventually to messaging provider logs test in [9192](https://github.com/appwrite/appwrite/pull/9192)
|
||||||
|
* feat project sms usage in [9198](https://github.com/appwrite/appwrite/pull/9198)
|
||||||
|
* chore: add audit labels to project resources in [9056](https://github.com/appwrite/appwrite/pull/9056)
|
||||||
|
* fix sms usage in [9207](https://github.com/appwrite/appwrite/pull/9207)
|
||||||
|
* Update database in [9202](https://github.com/appwrite/appwrite/pull/9202)
|
||||||
|
* Fix dead connections in [9213](https://github.com/appwrite/appwrite/pull/9213)
|
||||||
|
* Revert "Fix dead connections" in [9214](https://github.com/appwrite/appwrite/pull/9214)
|
||||||
|
* Add logs db init for consistency in [9163](https://github.com/appwrite/appwrite/pull/9163)
|
||||||
|
* Split the collection definitions in [9153](https://github.com/appwrite/appwrite/pull/9153)
|
||||||
|
* Log path with populated parameters in [9220](https://github.com/appwrite/appwrite/pull/9220)
|
||||||
|
* Add missing scope on function template in [9208](https://github.com/appwrite/appwrite/pull/9208)
|
||||||
|
* Add relatedCollection default in [9225](https://github.com/appwrite/appwrite/pull/9225)
|
||||||
|
* fix: function usage in [9235](https://github.com/appwrite/appwrite/pull/9235)
|
||||||
|
* feat: optimise events payloads in [9232](https://github.com/appwrite/appwrite/pull/9232)
|
||||||
|
* Optimise webhook events in [9168](https://github.com/appwrite/appwrite/pull/9168)
|
||||||
|
* fix: maintenance job missing type in [9238](https://github.com/appwrite/appwrite/pull/9238)
|
||||||
|
* Update Fetch to 0.3.0 in [9245](https://github.com/appwrite/appwrite/pull/9245)
|
||||||
|
* Fix maintenance job in [9247](https://github.com/appwrite/appwrite/pull/9247)
|
||||||
|
* chore: add missing case for executions in [9248](https://github.com/appwrite/appwrite/pull/9248)
|
||||||
|
* Add index dependency exception in [9226](https://github.com/appwrite/appwrite/pull/9226)
|
||||||
|
* chore: fix benchmarking test when made from fork in [9233](https://github.com/appwrite/appwrite/pull/9233)
|
||||||
|
* Update SDK Generator versions in [9188](https://github.com/appwrite/appwrite/pull/9188)
|
||||||
|
* chore: skipped job instead of throwing error in [9250](https://github.com/appwrite/appwrite/pull/9250)
|
||||||
|
* Implement new SDK Class on 1.6.x in [9237](https://github.com/appwrite/appwrite/pull/9237)
|
||||||
|
* Delete collection before Appwrite's attributes in [9256](https://github.com/appwrite/appwrite/pull/9256)
|
||||||
|
* Feat batch usage dump in [9255](https://github.com/appwrite/appwrite/pull/9255)
|
||||||
|
* Fix cloud tests in [9261](https://github.com/appwrite/appwrite/pull/9261)
|
||||||
|
* Usage: Databases reads writes in [9260](https://github.com/appwrite/appwrite/pull/9260)
|
||||||
|
* Update: Latest sdk specs in [9274](https://github.com/appwrite/appwrite/pull/9274)
|
||||||
|
* Revert "Feat batch usage dump" in [9276](https://github.com/appwrite/appwrite/pull/9276)
|
||||||
|
* feat: add fast2SMS adapter in [9263](https://github.com/appwrite/appwrite/pull/9263)
|
||||||
|
* Update Sdk Generator dependency in [9280](https://github.com/appwrite/appwrite/pull/9280)
|
||||||
|
* Transformed at addition in [9281](https://github.com/appwrite/appwrite/pull/9281)
|
||||||
|
* Docs: clarify update endpoints only work on draft messages in [9236](https://github.com/appwrite/appwrite/pull/9236)
|
||||||
|
* Update sdk generator dependency in [9282](https://github.com/appwrite/appwrite/pull/9282)
|
||||||
|
* Revert "Transformed at addition" in [9284](https://github.com/appwrite/appwrite/pull/9284)
|
||||||
|
* replaced init for cloud link in [9285](https://github.com/appwrite/appwrite/pull/9285)
|
||||||
|
* Add transformed at in [9289](https://github.com/appwrite/appwrite/pull/9289)
|
||||||
|
* Make migrations use Dynamic keys for destination in [9291](https://github.com/appwrite/appwrite/pull/9291)
|
||||||
|
* Make sessions limit tests assert eventually in [9298](https://github.com/appwrite/appwrite/pull/9298)
|
||||||
|
* Chore update database in [9306](https://github.com/appwrite/appwrite/pull/9306)
|
||||||
|
* feat: add AMQP queues in [9287](https://github.com/appwrite/appwrite/pull/9287)
|
||||||
|
* fix(test): use assertEventually instead of while(true) in [9308](https://github.com/appwrite/appwrite/pull/9308)
|
||||||
|
* fix(certificate worker): events are published without queue name in [9309](https://github.com/appwrite/appwrite/pull/9309)
|
||||||
|
* chore: update utopia-php/queue to 0.8.1 in [9311](https://github.com/appwrite/appwrite/pull/9311)
|
||||||
|
* chore: update utopia-php/queue to 0.8.2 in [9312](https://github.com/appwrite/appwrite/pull/9312)
|
||||||
|
* fix(schedule-tasks): revert back to direct pool usage in [9313](https://github.com/appwrite/appwrite/pull/9313)
|
||||||
|
* feat: custom app schemes in [9262](https://github.com/appwrite/appwrite/pull/9262)
|
||||||
|
* Revert "feat: custom app schemes" in [9319](https://github.com/appwrite/appwrite/pull/9319)
|
||||||
|
* Restore "feat: custom app schemes"" in [9320](https://github.com/appwrite/appwrite/pull/9320)
|
||||||
|
* Revert "Restore "feat: custom app schemes""" in [9323](https://github.com/appwrite/appwrite/pull/9323)
|
||||||
|
* chore: update dependencies in [9330](https://github.com/appwrite/appwrite/pull/9330)
|
||||||
|
* Feat: logs DB in [9272](https://github.com/appwrite/appwrite/pull/9272)
|
||||||
|
* Catch invalid index in [9329](https://github.com/appwrite/appwrite/pull/9329)
|
||||||
|
* Fix: missing call for image transformations counting in [9342](https://github.com/appwrite/appwrite/pull/9342)
|
||||||
|
* Fix drop abuse on shared table project delete in [9346](https://github.com/appwrite/appwrite/pull/9346)
|
||||||
|
* Only run all table mode tests on db update in [9338](https://github.com/appwrite/appwrite/pull/9338)
|
||||||
|
* Fix: missing periodic metric in [9350](https://github.com/appwrite/appwrite/pull/9350)
|
||||||
|
* feat(builds): check if function is blocked before building in [9332](https://github.com/appwrite/appwrite/pull/9332)
|
||||||
|
* feat: batch create audit logs in [9347](https://github.com/appwrite/appwrite/pull/9347)
|
||||||
|
* Chore: Update migrations in [9355](https://github.com/appwrite/appwrite/pull/9355)
|
||||||
|
* Fix: metric time was not being written to DB in [9354](https://github.com/appwrite/appwrite/pull/9354)
|
||||||
|
* Fix patch index validation in [9356](https://github.com/appwrite/appwrite/pull/9356)
|
||||||
|
* Fix image trnasformation metrics in [9370](https://github.com/appwrite/appwrite/pull/9370)
|
||||||
|
* Use batch delete in worker in [9375](https://github.com/appwrite/appwrite/pull/9375)
|
||||||
|
* Fix Model Platform is missing response key: store in [9361](https://github.com/appwrite/appwrite/pull/9361)
|
||||||
|
* Feat key segmented usage in [9336](https://github.com/appwrite/appwrite/pull/9336)
|
||||||
|
* Feat messaging metrics in [9353](https://github.com/appwrite/appwrite/pull/9353)
|
||||||
|
* Fix removed audits for shared v2 in [9388](https://github.com/appwrite/appwrite/pull/9388)
|
||||||
|
* chore: bump utopia-php/image to 0.8.0 in [9390](https://github.com/appwrite/appwrite/pull/9390)
|
||||||
|
* Fix outdated CLI commands in documentation in [9122](https://github.com/appwrite/appwrite/pull/9122)
|
||||||
|
* disable logs display in [9398](https://github.com/appwrite/appwrite/pull/9398)
|
||||||
|
* Log batches per project in [9403](https://github.com/appwrite/appwrite/pull/9403)
|
||||||
|
* Batch per project in [9410](https://github.com/appwrite/appwrite/pull/9410)
|
||||||
|
* Fix: stats resources only queue projects accessed in last 3 hours in [9411](https://github.com/appwrite/appwrite/pull/9411)
|
||||||
|
* Track options requests in [9397](https://github.com/appwrite/appwrite/pull/9397)
|
||||||
|
* chore: bump docker-base in [9406](https://github.com/appwrite/appwrite/pull/9406)
|
||||||
|
* refactor: migrate Realtime::send calls to queueForRealtime in [9325](https://github.com/appwrite/appwrite/pull/9325)
|
||||||
|
* Revert "Fix: stats resources only queue projects accessed in last 3 hours" in [9424](https://github.com/appwrite/appwrite/pull/9424)
|
||||||
|
* Remove usage and usage dump in favor of stats-usage and stats-usage-dump in [9339](https://github.com/appwrite/appwrite/pull/9339)
|
||||||
|
* Fix: disable dual writing in [9429](https://github.com/appwrite/appwrite/pull/9429)
|
||||||
|
* Disable transformedAt update for console users in [9425](https://github.com/appwrite/appwrite/pull/9425)
|
||||||
|
* chore: add image transformation stats to usage endpoint in [9393](https://github.com/appwrite/appwrite/pull/9393)
|
||||||
|
* chore: added timeout to deployment builds in tests in [9426](https://github.com/appwrite/appwrite/pull/9426)
|
||||||
|
* fix: model for image transformations in usage project in [9442](https://github.com/appwrite/appwrite/pull/9442)
|
||||||
|
* Feat: calculate database storage in stats-resources in [9443](https://github.com/appwrite/appwrite/pull/9443)
|
||||||
|
* Activities batch writes in [9438](https://github.com/appwrite/appwrite/pull/9438)
|
||||||
|
* chore: bump cache 0.12.x in [9412](https://github.com/appwrite/appwrite/pull/9412)
|
||||||
|
* chore: queue console project for maintenance delete in [9479](https://github.com/appwrite/appwrite/pull/9479)
|
||||||
|
* chore: added logsdb for deletes worker in [9462](https://github.com/appwrite/appwrite/pull/9462)
|
||||||
|
* Feat: calculate and log time taken for each project in [9491](https://github.com/appwrite/appwrite/pull/9491)
|
||||||
|
* chore: update initializing dbForLogs in [9494](https://github.com/appwrite/appwrite/pull/9494)
|
||||||
|
* Feat bulk audit delete in [9487](https://github.com/appwrite/appwrite/pull/9487)
|
||||||
|
* Prepare 1.6.2 release in [9499](https://github.com/appwrite/appwrite/pull/9499)
|
||||||
|
* Regenerate specs in [9497](https://github.com/appwrite/appwrite/pull/9497)
|
||||||
|
* Regenerate examples in [9498](https://github.com/appwrite/appwrite/pull/9498)
|
||||||
|
* chore: bump sdk in [9414](https://github.com/appwrite/appwrite/pull/9414)
|
||||||
|
* update queue to 0.9.* in [9505](https://github.com/appwrite/appwrite/pull/9505)
|
||||||
|
* Feat improve delete queries in [9507](https://github.com/appwrite/appwrite/pull/9507)
|
||||||
|
* Feat: Add rule attributes in [9508](https://github.com/appwrite/appwrite/pull/9508)
|
||||||
|
* Sync main into 1.6.x in [9496](https://github.com/appwrite/appwrite/pull/9496)
|
||||||
|
* Bump console to version 5.2.53 in [9495](https://github.com/appwrite/appwrite/pull/9495)
|
||||||
|
* Prepare 1.6.1 release in [9294](https://github.com/appwrite/appwrite/pull/9294)
|
||||||
|
* Improve delete ordering in [9512](https://github.com/appwrite/appwrite/pull/9512)
|
||||||
|
* Cleanups in [9511](https://github.com/appwrite/appwrite/pull/9511)
|
||||||
|
* Feat dynamic regions in [9408](https://github.com/appwrite/appwrite/pull/9408)
|
||||||
|
* Feat env vars to system lib in [9515](https://github.com/appwrite/appwrite/pull/9515)
|
||||||
|
* Feat: domains count in [9514](https://github.com/appwrite/appwrite/pull/9514)
|
||||||
|
* Migration read from db in [9529](https://github.com/appwrite/appwrite/pull/9529)
|
||||||
|
* feat: add pool telemetry in [9530](https://github.com/appwrite/appwrite/pull/9530)
|
||||||
|
* Disable PDO persistence since we manage our own pool in [9526](https://github.com/appwrite/appwrite/pull/9526)
|
||||||
|
* chore: set min operations to 1 for reads and writes in [9536](https://github.com/appwrite/appwrite/pull/9536)
|
||||||
|
* Remove default region in [9430](https://github.com/appwrite/appwrite/pull/9430)
|
||||||
|
* Use cursor pagination with bigger limit for maintenance project loop in [9546](https://github.com/appwrite/appwrite/pull/9546)
|
||||||
|
* chore: stop tests on failure in [9525](https://github.com/appwrite/appwrite/pull/9525)
|
||||||
|
* chore: only update total count for privileged users in [9554](https://github.com/appwrite/appwrite/pull/9554)
|
||||||
|
* refactor: initialization of audit retention in [9563](https://github.com/appwrite/appwrite/pull/9563)
|
||||||
|
* Delete worker queries fixes in [9523](https://github.com/appwrite/appwrite/pull/9523)
|
||||||
|
* Bump database 0.62.x in [9568](https://github.com/appwrite/appwrite/pull/9568)
|
||||||
|
* Fix: schedules region filtering in [9577](https://github.com/appwrite/appwrite/pull/9577)
|
||||||
|
* Deletes worker fix selects for pagination in [9578](https://github.com/appwrite/appwrite/pull/9578)
|
||||||
|
* Add $permissions for delete documents selects in [9579](https://github.com/appwrite/appwrite/pull/9579)
|
||||||
|
* chore(audits): return queue pre-fetch results in [9533](https://github.com/appwrite/appwrite/pull/9533)
|
||||||
|
* Revert "chore(audits): return queue pre-fetch results" in [9586](https://github.com/appwrite/appwrite/pull/9586)
|
||||||
|
* Feat multi tenant insert in [9573](https://github.com/appwrite/appwrite/pull/9573)
|
||||||
|
* Add order by for cursor in [9588](https://github.com/appwrite/appwrite/pull/9588)
|
||||||
|
* Feat update fetch in [9592](https://github.com/appwrite/appwrite/pull/9592)
|
||||||
|
* Fix tenant casting in [9598](https://github.com/appwrite/appwrite/pull/9598)
|
||||||
|
* Feat update ws in [9602](https://github.com/appwrite/appwrite/pull/9602)
|
||||||
|
* Update database in [9603](https://github.com/appwrite/appwrite/pull/9603)
|
||||||
|
* Fix: image transformation cache in [9608](https://github.com/appwrite/appwrite/pull/9608)
|
||||||
|
* Remove audit payload in [9610](https://github.com/appwrite/appwrite/pull/9610)
|
||||||
|
* Sample rate from DSN in [9559](https://github.com/appwrite/appwrite/pull/9559)
|
||||||
|
* Restrict role change for sole org owner in [9615](https://github.com/appwrite/appwrite/pull/9615)
|
||||||
|
* chore: update php image to 0.8.1 in [9616](https://github.com/appwrite/appwrite/pull/9616)
|
||||||
|
* feat: refactor executor setup in [9420](https://github.com/appwrite/appwrite/pull/9420)
|
||||||
|
* chore: update gitpod.yml config in [9561](https://github.com/appwrite/appwrite/pull/9561)
|
||||||
|
* chore: update dependencies in [9625](https://github.com/appwrite/appwrite/pull/9625)
|
||||||
|
* Update migrations lib in [9628](https://github.com/appwrite/appwrite/pull/9628)
|
||||||
|
* feat: cache telemetry in [9624](https://github.com/appwrite/appwrite/pull/9624)
|
||||||
|
* Bump console to version 5.2.56 in [9631](https://github.com/appwrite/appwrite/pull/9631)
|
||||||
|
* Multi region support in [8667](https://github.com/appwrite/appwrite/pull/8667)
|
||||||
|
* Revert "Multi region support" in [9632](https://github.com/appwrite/appwrite/pull/9632)
|
||||||
|
* Revert "Revert "Multi region support"" in [9636](https://github.com/appwrite/appwrite/pull/9636)
|
||||||
|
* Fix tasks in [9644](https://github.com/appwrite/appwrite/pull/9644)
|
||||||
|
* chore: updated the migration version to 8.6 in [9646](https://github.com/appwrite/appwrite/pull/9646)
|
||||||
|
* Fix: merge the working of StatsUsage and StatsUsageDump in [9585](https://github.com/appwrite/appwrite/pull/9585)
|
||||||
|
* Update database in [9643](https://github.com/appwrite/appwrite/pull/9643)
|
||||||
|
* chore: fix error logging for CLI tasks in [9651](https://github.com/appwrite/appwrite/pull/9651)
|
||||||
|
* fix: usage test assertion in [9653](https://github.com/appwrite/appwrite/pull/9653)
|
||||||
|
* Fix keys in [9656](https://github.com/appwrite/appwrite/pull/9656)
|
||||||
|
* Feat: multi tenant dual writing in [9583](https://github.com/appwrite/appwrite/pull/9583)
|
||||||
|
* Fix/throwing 400 for null order attributes in [9657](https://github.com/appwrite/appwrite/pull/9657)
|
||||||
|
* feat: sdk group attribute in [9596](https://github.com/appwrite/appwrite/pull/9596)
|
||||||
|
* Add configurable function and build size in [9648](https://github.com/appwrite/appwrite/pull/9648)
|
||||||
|
* feat: update API endpoint in the code examples in [8933](https://github.com/appwrite/appwrite/pull/8933)
|
||||||
|
* chore: abstract token secret hiding to response model in [9574](https://github.com/appwrite/appwrite/pull/9574)
|
||||||
|
* chore: update sdks in [9655](https://github.com/appwrite/appwrite/pull/9655)
|
||||||
|
* feat: allow non-critical events to ignore exceptions when enqueuing the event in [9680](https://github.com/appwrite/appwrite/pull/9680)
|
||||||
|
* Revert "Add configurable function and build size" in [9681](https://github.com/appwrite/appwrite/pull/9681)
|
||||||
|
* core: introduce endpoint.docs in specs in [9685](https://github.com/appwrite/appwrite/pull/9685)
|
||||||
|
* fix: remove content-type header from get request specs in [9666](https://github.com/appwrite/appwrite/pull/9666)
|
||||||
|
* chore: update flutter sdk in [9691](https://github.com/appwrite/appwrite/pull/9691)
|
||||||
|
|
||||||
# Version 1.6.1
|
# Version 1.6.1
|
||||||
|
|
||||||
## What's Changed
|
## What's Changed
|
||||||
|
|
|
||||||
|
|
@ -82,9 +82,9 @@ abstract class Migration
|
||||||
'1.5.11' => 'V20',
|
'1.5.11' => 'V20',
|
||||||
'1.6.0' => 'V21',
|
'1.6.0' => 'V21',
|
||||||
'1.6.1' => 'V21',
|
'1.6.1' => 'V21',
|
||||||
'1.6.2' => 'V22',
|
'1.6.2' => 'V21',
|
||||||
'1.7.0-RC1' => 'V23',
|
'1.7.0-RC1' => 'V22',
|
||||||
'1.7.0' => 'V23',
|
'1.7.0' => 'V22',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -385,6 +385,10 @@ abstract class Migration
|
||||||
default => 'projects',
|
default => 'projects',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if ($from === 'files') {
|
||||||
|
$collectionType = 'buckets';
|
||||||
|
}
|
||||||
|
|
||||||
$collection = $this->collections[$collectionType][$from] ?? null;
|
$collection = $this->collections[$collectionType][$from] ?? null;
|
||||||
|
|
||||||
if ($collection === null) {
|
if ($collection === null) {
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,27 @@ class V21 extends Migration
|
||||||
Console::warning("'accessedAt' from {$id}: {$th->getMessage()}");
|
Console::warning("'accessedAt' from {$id}: {$th->getMessage()}");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'rules':
|
||||||
|
$attributesToCreate = ['owner', 'region'];
|
||||||
|
foreach ($attributesToCreate as $attribute) {
|
||||||
|
// Create attribute
|
||||||
|
try {
|
||||||
|
$this->createAttributeFromCollection($this->dbForProject, $id, $attribute);
|
||||||
|
} catch (Throwable $th) {
|
||||||
|
Console::warning("'$attribute' from {$id}: {$th->getMessage()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$indexesToCreate = ['_key_owner', '_key_region'];
|
||||||
|
foreach ($indexesToCreate as $index) {
|
||||||
|
// Create index
|
||||||
|
try {
|
||||||
|
$this->createIndexFromCollection($this->dbForProject, $id, $index);
|
||||||
|
} catch (Throwable $th) {
|
||||||
|
Console::warning("'$index' from {$id}: {$th->getMessage()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'platforms':
|
case 'platforms':
|
||||||
// Increase 'type' length to 255
|
// Increase 'type' length to 255
|
||||||
try {
|
try {
|
||||||
|
|
@ -82,6 +103,17 @@ class V21 extends Migration
|
||||||
Console::warning("'type' from {$id}: {$th->getMessage()}");
|
Console::warning("'type' from {$id}: {$th->getMessage()}");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'installations':
|
||||||
|
$attributesToCreate = ['personalAccessToken', 'personalAccessTokenExpiry', 'personalRefreshToken'];
|
||||||
|
foreach ($attributesToCreate as $attribute) {
|
||||||
|
// Create attribute
|
||||||
|
try {
|
||||||
|
$this->createAttributeFromCollection($this->dbForProject, $id, $attribute);
|
||||||
|
} catch (Throwable $th) {
|
||||||
|
Console::warning("'$attribute' from {$id}: {$th->getMessage()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'migrations':
|
case 'migrations':
|
||||||
// Create destination attribute
|
// Create destination attribute
|
||||||
try {
|
try {
|
||||||
|
|
@ -197,11 +229,15 @@ class V21 extends Migration
|
||||||
$document->setAttribute('accessedAt', DateTime::now());
|
$document->setAttribute('accessedAt', DateTime::now());
|
||||||
break;
|
break;
|
||||||
case 'functions':
|
case 'functions':
|
||||||
// Add scopes attribute
|
// Set scopes attribute
|
||||||
$document->setAttribute('scopes', []);
|
if (empty($document->getAttribute('scopes', []))) {
|
||||||
|
$document->setAttribute('scopes', []);
|
||||||
|
}
|
||||||
|
|
||||||
// Add size attribute
|
// Set specification attribute
|
||||||
$document->setAttribute('specification', APP_COMPUTE_SPECIFICATION_DEFAULT);
|
if (empty($document->getAttribute('specification'))) {
|
||||||
|
$document->setAttribute('specification', APP_COMPUTE_SPECIFICATION_DEFAULT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $document;
|
return $document;
|
||||||
|
|
@ -214,15 +250,34 @@ class V21 extends Migration
|
||||||
*/
|
*/
|
||||||
private function migrateBuckets(): void
|
private function migrateBuckets(): void
|
||||||
{
|
{
|
||||||
foreach ($this->documentsIterator('buckets') as $bucket) {
|
$this->dbForProject->forEach('buckets', function (Document $bucket) {
|
||||||
$bucketId = 'bucket_' . $bucket['$internalId'];
|
$bucketId = 'bucket_' . $bucket['$internalId'];
|
||||||
|
|
||||||
|
Console::log("Migrating Bucket {$bucketId} {$bucket->getId()} ({$bucket->getAttribute('name')})");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$this->dbForProject->updateAttribute($bucketId, 'metadata', size: 65534);
|
$this->dbForProject->updateAttribute($bucketId, 'metadata', size: 65534);
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
Console::warning("'metadata' from {$bucketId}: {$th->getMessage()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$this->createAttributeFromCollection($this->dbForProject, $bucketId, 'transformedAt', 'files');
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
Console::warning("'transformedAt' from {$bucketId}: {$th->getMessage()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$this->createIndexFromCollection($this->dbForProject, $bucketId, '_key_transformedAt', 'files');
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
Console::warning("'_key_transformedAt' from {$bucketId}: {$th->getMessage()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
$this->dbForProject->purgeCachedCollection($bucketId);
|
$this->dbForProject->purgeCachedCollection($bucketId);
|
||||||
} catch (\Throwable $th) {
|
} catch (\Throwable $th) {
|
||||||
Console::warning("'bucketId' from {$bucketId}: {$th->getMessage()}");
|
Console::warning("purging {$bucketId}: {$th->getMessage()}");
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,13 @@ use Exception;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
use Utopia\CLI\Console;
|
use Utopia\CLI\Console;
|
||||||
use Utopia\Database\Database;
|
use Utopia\Database\Database;
|
||||||
|
use Utopia\Database\Document;
|
||||||
|
use Utopia\Database\Exception\Conflict;
|
||||||
|
use Utopia\Database\Exception\Structure;
|
||||||
|
use Utopia\Database\Exception\Timeout;
|
||||||
|
use Utopia\Database\Query;
|
||||||
|
|
||||||
class V22 extends Migration
|
class V23 extends Migration
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @throws Throwable
|
* @throws Throwable
|
||||||
|
|
@ -16,9 +21,9 @@ class V22 extends Migration
|
||||||
public function execute(): void
|
public function execute(): void
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Disable SubQueries for Performance.
|
* Disable SubQueries for Performance.
|
||||||
*/
|
*/
|
||||||
foreach (['subQueryIndexes', 'subQueryPlatforms', 'subQueryDomains', 'subQueryKeys', 'subQueryWebhooks', 'subQuerySessions', 'subQueryTokens', 'subQueryMemberships', 'subQueryVariables', 'subQueryChallenges', 'subQueryProjectVariables', 'subQueryTargets', 'subQueryTopicTargets'] as $name) {
|
foreach (['subQueryIndexes', 'subQueryPlatforms', 'subQueryDomains', 'subQueryKeys', 'subQueryDevKeys', 'subQueryWebhooks', 'subQuerySessions', 'subQueryTokens', 'subQueryMemberships', 'subQueryVariables', 'subQueryChallenges', 'subQueryProjectVariables', 'subQueryTargets', 'subQueryTopicTargets'] as $name) {
|
||||||
Database::addFilter(
|
Database::addFilter(
|
||||||
$name,
|
$name,
|
||||||
fn () => null,
|
fn () => null,
|
||||||
|
|
@ -26,8 +31,14 @@ class V22 extends Migration
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Console::info('Migrating Collections');
|
Console::info('Migrating collections');
|
||||||
$this->migrateCollections();
|
$this->migrateCollections();
|
||||||
|
|
||||||
|
Console::info('Migrating documents');
|
||||||
|
$this->forEachDocument($this->migrateDocument(...));
|
||||||
|
|
||||||
|
Console::info('Cleaning up collections');
|
||||||
|
$this->cleanCollections();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -38,8 +49,428 @@ class V22 extends Migration
|
||||||
*/
|
*/
|
||||||
private function migrateCollections(): void
|
private function migrateCollections(): void
|
||||||
{
|
{
|
||||||
$internalProjectId = $this->project->getInternalId();
|
$projectInternalId = $this->project->getInternalId();
|
||||||
$collectionType = match ($internalProjectId) {
|
|
||||||
|
if (empty($projectInternalId)) {
|
||||||
|
throw new Exception('Project ID is null');
|
||||||
|
}
|
||||||
|
|
||||||
|
$collectionType = match ($projectInternalId) {
|
||||||
|
'console' => 'console',
|
||||||
|
default => 'projects',
|
||||||
|
};
|
||||||
|
|
||||||
|
$collections = $this->collections[$collectionType];
|
||||||
|
|
||||||
|
foreach ($collections as $collection) {
|
||||||
|
$id = $collection['$id'];
|
||||||
|
|
||||||
|
if (empty($id)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console::log("Migrating collection \"{$id}\"");
|
||||||
|
|
||||||
|
switch ($id) {
|
||||||
|
case '_metadata':
|
||||||
|
$this->createCollection('sites');
|
||||||
|
$this->createCollection('resourceTokens');
|
||||||
|
if ($projectInternalId === 'console') {
|
||||||
|
$this->createCollection('devKeys');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'identities':
|
||||||
|
$attributes = [
|
||||||
|
'scopes',
|
||||||
|
'expire',
|
||||||
|
];
|
||||||
|
try {
|
||||||
|
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
||||||
|
}
|
||||||
|
$this->dbForProject->purgeCachedCollection($id);
|
||||||
|
break;
|
||||||
|
case 'projects':
|
||||||
|
try {
|
||||||
|
$attributes = [
|
||||||
|
'devKeys',
|
||||||
|
];
|
||||||
|
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
||||||
|
}
|
||||||
|
$this->dbForProject->purgeCachedCollection($id);
|
||||||
|
break;
|
||||||
|
case 'rules':
|
||||||
|
$attributes = [
|
||||||
|
'type',
|
||||||
|
'trigger',
|
||||||
|
'redirectUrl',
|
||||||
|
'redirectStatusCode',
|
||||||
|
'deploymentResourceType',
|
||||||
|
'deploymentId',
|
||||||
|
'deploymentInternalId',
|
||||||
|
'deploymentResourceId',
|
||||||
|
'deploymentResourceInternalId',
|
||||||
|
'deploymentVcsProviderBranch',
|
||||||
|
'search'
|
||||||
|
];
|
||||||
|
try {
|
||||||
|
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
$indexes = [
|
||||||
|
'_key_search',
|
||||||
|
'_key_type',
|
||||||
|
'_key_trigger',
|
||||||
|
'_key_deploymentResourceType',
|
||||||
|
'_key_deploymentResourceId',
|
||||||
|
'_key_deploymentResourceInternalId',
|
||||||
|
'_key_deploymentId',
|
||||||
|
'_key_deploymentInternalId',
|
||||||
|
'_key_deploymentVcsProviderBranch',
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($indexes as $index) {
|
||||||
|
try {
|
||||||
|
$this->createIndexFromCollection($this->dbForProject, $id, $index);
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
Console::warning("Failed to create index \"$index\" from {$id}: {$th->getMessage()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->dbForProject->purgeCachedCollection($id);
|
||||||
|
break;
|
||||||
|
case 'memberships':
|
||||||
|
$indexes = [
|
||||||
|
'_key_roles',
|
||||||
|
];
|
||||||
|
foreach ($indexes as $index) {
|
||||||
|
try {
|
||||||
|
$this->createIndexFromCollection($this->dbForProject, $id, $index);
|
||||||
|
} catch (Throwable $th) {
|
||||||
|
Console::warning("Failed to create index \"$index\" from {$id}: {$th->getMessage()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->dbForProject->purgeCachedCollection($id);
|
||||||
|
break;
|
||||||
|
case 'migrations':
|
||||||
|
$attributes = [
|
||||||
|
'options',
|
||||||
|
'resourceId',
|
||||||
|
'resourceType'
|
||||||
|
];
|
||||||
|
try {
|
||||||
|
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
$indexes = [
|
||||||
|
'_key_resource_id',
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($indexes as $index) {
|
||||||
|
try {
|
||||||
|
$this->createIndexFromCollection($this->dbForProject, $id, $index);
|
||||||
|
} catch (Throwable $th) {
|
||||||
|
Console::warning("Failed to create index \"$index\" from {$id}: {$th->getMessage()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->dbForProject->purgeCachedCollection($id);
|
||||||
|
break;
|
||||||
|
case 'functions':
|
||||||
|
$attributes = [
|
||||||
|
'deploymentId',
|
||||||
|
'deploymentCreatedAt',
|
||||||
|
'latestDeploymentId',
|
||||||
|
'latestDeploymentInternalId',
|
||||||
|
'latestDeploymentCreatedAt',
|
||||||
|
'latestDeploymentStatus',
|
||||||
|
];
|
||||||
|
try {
|
||||||
|
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
$indexes = [
|
||||||
|
'_key_deploymentId',
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($indexes as $index) {
|
||||||
|
try {
|
||||||
|
$this->createIndexFromCollection($this->dbForProject, $id, $index);
|
||||||
|
} catch (Throwable $th) {
|
||||||
|
Console::warning("Failed to create index \"$index\" from {$id}: {$th->getMessage()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->dbForProject->purgeCachedCollection($id);
|
||||||
|
break;
|
||||||
|
case 'deployments':
|
||||||
|
$attributes = [
|
||||||
|
'buildCommands',
|
||||||
|
'sourcePath',
|
||||||
|
'buildOutput',
|
||||||
|
'adapter',
|
||||||
|
'fallbackFile',
|
||||||
|
'sourceSize',
|
||||||
|
'sourceMetadata',
|
||||||
|
'sourceChunksTotal',
|
||||||
|
'sourceChunksUploaded',
|
||||||
|
'screenshotLight',
|
||||||
|
'screenshotDark',
|
||||||
|
'buildStartedAt',
|
||||||
|
'buildEndedAt',
|
||||||
|
'buildDuration',
|
||||||
|
'buildSize',
|
||||||
|
'status',
|
||||||
|
'buildPath',
|
||||||
|
'buildLogs',
|
||||||
|
'totalSize',
|
||||||
|
];
|
||||||
|
try {
|
||||||
|
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
$indexes = [
|
||||||
|
'_key_sourceSize',
|
||||||
|
'_key_buildSize',
|
||||||
|
'_key_totalSize',
|
||||||
|
'_key_buildDuration',
|
||||||
|
'_key_type',
|
||||||
|
'_key_status',
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($indexes as $index) {
|
||||||
|
try {
|
||||||
|
$this->createIndexFromCollection($this->dbForProject, $id, $index);
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
Console::warning("Failed to create index \"$index\" from {$id}: {$th->getMessage()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->dbForProject->purgeCachedCollection($id);
|
||||||
|
break;
|
||||||
|
case 'executions':
|
||||||
|
$attributes = [
|
||||||
|
'resourceInternalId',
|
||||||
|
'resourceId',
|
||||||
|
'resourceType'
|
||||||
|
];
|
||||||
|
try {
|
||||||
|
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
$indexes = [
|
||||||
|
'_key_resource',
|
||||||
|
];
|
||||||
|
foreach ($indexes as $index) {
|
||||||
|
try {
|
||||||
|
$this->createIndexFromCollection($this->dbForProject, $id, $index);
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
Console::warning("Failed to create index \"$index\" from {$id}: {$th->getMessage()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->dbForProject->purgeCachedCollection($id);
|
||||||
|
break;
|
||||||
|
case 'variables':
|
||||||
|
$attributes = [
|
||||||
|
'secret',
|
||||||
|
];
|
||||||
|
try {
|
||||||
|
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->dbForProject->purgeCachedCollection($id);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fix run on each document
|
||||||
|
*
|
||||||
|
* @param Document $document
|
||||||
|
* @return Document
|
||||||
|
* @throws Conflict
|
||||||
|
* @throws Structure
|
||||||
|
* @throws Timeout
|
||||||
|
* @throws \Utopia\Database\Exception
|
||||||
|
* @throws \Utopia\Database\Exception\Authorization
|
||||||
|
* @throws \Utopia\Database\Exception\Query
|
||||||
|
*/
|
||||||
|
private function migrateDocument(Document $document): Document
|
||||||
|
{
|
||||||
|
switch ($document->getCollection()) {
|
||||||
|
case 'rules':
|
||||||
|
/*
|
||||||
|
1. Convert "resourceType" to "type". Convert "function" to "deployment"
|
||||||
|
2. Convert "resourceId" to "deploymentResourceId"
|
||||||
|
3. Convert "resourceInternalId" to "deploymentResourceInternalId"
|
||||||
|
4. Fill "trigger" with "manual"
|
||||||
|
5. Fill "deploymentResourceType". If "resourceType" is "function", set "deploymentResourceType" to "function"
|
||||||
|
6. Fill "search" with "{$id} {domain}"
|
||||||
|
7. Fill "deploymentId" and "deploymentInternalId". If "deploymentResourceType" is "function", get project DB, and find function with ID "resourceId". Then fill rule's "deploymentId" with function's "deployment", and "deploymentId" as backup
|
||||||
|
*/
|
||||||
|
|
||||||
|
$deploymentResourceType = null;
|
||||||
|
|
||||||
|
$type = $document->getAttribute('resourceType', $document->getAttribute('type', ''));
|
||||||
|
if ($type === 'function') {
|
||||||
|
$type = 'deployment';
|
||||||
|
$deploymentResourceType = 'function';
|
||||||
|
}
|
||||||
|
|
||||||
|
$resourceId = $document->getAttribute('resourceId', $document->getAttribute('deploymentResourceId'));
|
||||||
|
$resourceInternalId = $document->getAttribute('resourceInternalId', $document->getAttribute('deploymentResourceInternalId'));
|
||||||
|
|
||||||
|
$document
|
||||||
|
->setAttribute('type', $type)
|
||||||
|
->setAttribute('trigger', 'manual')
|
||||||
|
->setAttribute('deploymentResourceId', $resourceId)
|
||||||
|
->setAttribute('deploymentResourceInternalId', $resourceInternalId)
|
||||||
|
->setAttribute('deploymentResourceType', $document->getAttribute('deploymentResourceType', $deploymentResourceType))
|
||||||
|
->setAttribute('search', \implode(' ', [$document->getId(), $document->getAttribute('domain', '')]));
|
||||||
|
|
||||||
|
if ($deploymentResourceType === 'function') {
|
||||||
|
$project = $this->dbForProject->getDocument('projects', $document->getAttribute('projectId'));
|
||||||
|
$dbForOwnerProject = ($this->getProjectDB)($project);
|
||||||
|
$function = $dbForOwnerProject->getDocument('functions', $resourceId);
|
||||||
|
$deploymentId = $function->getAttribute('deployment', $function->getAttribute('deploymentId', $document->getAttribute('deploymentId')));
|
||||||
|
$deploymentInternalId = $function->getAttribute('deploymentInternalId', $document->getAttribute('deploymentInternalId', ''));
|
||||||
|
|
||||||
|
$document
|
||||||
|
->setAttribute('deploymentId', $deploymentId)
|
||||||
|
->setAttribute('deploymentInternalId', $deploymentInternalId);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'variables':
|
||||||
|
/*
|
||||||
|
1. Fill "secret" with "false"
|
||||||
|
*/
|
||||||
|
$document->setAttribute('secret', $document->getAttribute('secret', false));
|
||||||
|
break;
|
||||||
|
case 'executions':
|
||||||
|
/*
|
||||||
|
1. Convert "functionInternalId" to "resourceInternalId"
|
||||||
|
2. Convert "functionId" to "resourceId"
|
||||||
|
3. Fill "resourceType" with "functions"
|
||||||
|
*/
|
||||||
|
$document
|
||||||
|
->setAttribute('resourceInternalId', $document->getAttribute('functionInternalId', $document->getAttribute('resourceInternalId')))
|
||||||
|
->setAttribute('resourceId', $document->getAttribute('functionId', $document->getAttribute('resourceId', '')))
|
||||||
|
->setAttribute('resourceType', $document->getAttribute('resourceType', 'functions'));
|
||||||
|
break;
|
||||||
|
case 'functions':
|
||||||
|
/*
|
||||||
|
1. Convert "deployment" to "deploymentId"
|
||||||
|
--- Fetch activeDeployment from "deploymentId"
|
||||||
|
2. Fill "deploymentCreatedAt" with deployment's "$createdAt"
|
||||||
|
--- Fetch latestDeployment using find()
|
||||||
|
3. Fill latestDeploymentId with latestDeployment's "$id"
|
||||||
|
4. Fill latestDeploymentInternalId with latestDeployment's "$internalId"
|
||||||
|
5. Fill latestDeploymentCreatedAt with latestDeployment's "$createdAt"
|
||||||
|
6. Fill latestDeploymentStatus with latestDeployment's build's "status"
|
||||||
|
*/
|
||||||
|
if ($document->getAttribute('deployment')) {
|
||||||
|
$document->setAttribute('deploymentId', $document->getAttribute('deployment', $document->getAttribute('deploymentId', '')));
|
||||||
|
}
|
||||||
|
|
||||||
|
$deploymentId = $document->getAttribute('deploymentId');
|
||||||
|
$deployment = $this->dbForProject->getDocument('deployments', $deploymentId);
|
||||||
|
$document->setAttribute('deploymentCreatedAt', $deployment->getCreatedAt());
|
||||||
|
|
||||||
|
$latestDeployment = $this->dbForProject->findOne('deployments', [
|
||||||
|
Query::orderDesc(),
|
||||||
|
Query::equal('resourceId', [$document->getId()]),
|
||||||
|
Query::equal('resourceType', ['functions']),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$latestBuild = $this->dbForProject->getDocument('builds', $latestDeployment->getAttribute('buildId', ''));
|
||||||
|
|
||||||
|
$document
|
||||||
|
->setAttribute('latestDeploymentId', $latestDeployment->getId())
|
||||||
|
->setAttribute('latestDeploymentInternalId', $latestDeployment->getInternalId())
|
||||||
|
->setAttribute('latestDeploymentCreatedAt', $latestDeployment->getCreatedAt())
|
||||||
|
->setAttribute('latestDeploymentStatus', $latestBuild->getAttribute('status', $document->getAttribute('latestDeploymentStatus', '')));
|
||||||
|
break;
|
||||||
|
case 'deployments':
|
||||||
|
/*
|
||||||
|
6. Convert "commands" to "buildCommands"
|
||||||
|
7. Convert "path" to "sourcePath"
|
||||||
|
8. Convert "size" to "sourceSize"
|
||||||
|
9. Convert "metadata" to "sourceMetadata"
|
||||||
|
10. Convert "chunksTotal" to "sourceChunksTotal"
|
||||||
|
11. Convert "chunksUploaded" to "sourceChunksUploaded"
|
||||||
|
--- Get build of deployment
|
||||||
|
12. Convert build's "startTime" to "buildStartedAt"
|
||||||
|
13. Convert build's "endTime" to "buildEndedAt"
|
||||||
|
14. Convert build's "duration" to "buildDuration"
|
||||||
|
15. Convert build's "size" to "buildSize"
|
||||||
|
16. Convert build's "status" to "status"
|
||||||
|
17. Convert build's "path" to "buildPath"
|
||||||
|
18. Convert build's "logs" to "buildLogs"
|
||||||
|
19. Fill "totalSize" with "buildSize" plus "sourceSize"
|
||||||
|
*/
|
||||||
|
|
||||||
|
$document
|
||||||
|
->setAttribute('buildCommands', $document->getAttribute('commands', $document->getAttribute('buildCommands', '')))
|
||||||
|
->setAttribute('sourcePath', $document->getAttribute('path', $document->getAttribute('sourcePath', '')))
|
||||||
|
->setAttribute('sourceSize', $document->getAttribute('size', $document->getAttribute('sourceSize', 0)))
|
||||||
|
->setAttribute('sourceMetadata', $document->getAttribute('metadata', $document->getAttribute('sourceMetadata', [])))
|
||||||
|
->setAttribute('sourceChunksTotal', $document->getAttribute('chunksTotal', $document->getAttribute('sourceChunksTotal', 0)))
|
||||||
|
->setAttribute('sourceChunksUploaded', $document->getAttribute('chunksUploaded', $document->getAttribute('sourceChunksUploaded', 0)));
|
||||||
|
|
||||||
|
$build = new Document();
|
||||||
|
if (!empty($document->getAttribute('buildId'))) {
|
||||||
|
$build = $this->dbForProject->getDocument('builds', $document->getAttribute('buildId'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$document
|
||||||
|
->setAttribute('buildStartedAt', $build->getAttribute('startTime', $document->getAttribute('buildStartTime', '')))
|
||||||
|
->setAttribute('buildEndedAt', $build->getAttribute('endTime', $document->getAttribute('buildEndTime', '')))
|
||||||
|
->setAttribute('buildDuration', $build->getAttribute('duration', $document->getAttribute('buildDuration', 0)))
|
||||||
|
->setAttribute('buildSize', $build->getAttribute('size', $document->getAttribute('buildSize', 0)))
|
||||||
|
->setAttribute('status', $build->getAttribute('status', $document->getAttribute('status', '')))
|
||||||
|
->setAttribute('buildPath', $build->getAttribute('path', $document->getAttribute('buildPath', '')))
|
||||||
|
->setAttribute('buildLogs', $build->getAttribute('logs', $document->getAttribute('buildLogs', '')));
|
||||||
|
|
||||||
|
$totalSize = $document->getAttribute('buildSize', 0)
|
||||||
|
+ $document->getAttribute('sourceSize', 0);
|
||||||
|
|
||||||
|
$document->setAttribute('totalSize', $totalSize);
|
||||||
|
break;
|
||||||
|
case 'migrations':
|
||||||
|
/*
|
||||||
|
1. Fill "options" with "[]"
|
||||||
|
*/
|
||||||
|
$document->setAttribute('options', $document->getAttribute('options', []));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return $document;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function cleanCollections(): void
|
||||||
|
{
|
||||||
|
$projectInternalId = $this->project->getInternalId();
|
||||||
|
|
||||||
|
$collectionType = match ($projectInternalId) {
|
||||||
'console' => 'console',
|
'console' => 'console',
|
||||||
default => 'projects',
|
default => 'projects',
|
||||||
};
|
};
|
||||||
|
|
@ -48,36 +479,129 @@ class V22 extends Migration
|
||||||
foreach ($collections as $collection) {
|
foreach ($collections as $collection) {
|
||||||
$id = $collection['$id'];
|
$id = $collection['$id'];
|
||||||
|
|
||||||
Console::log("Migrating Collection \"{$id}\"");
|
Console::log("Cleaning up collection \"{$id}\"");
|
||||||
|
|
||||||
$this->dbForProject->setNamespace("_$internalProjectId");
|
|
||||||
|
|
||||||
switch ($id) {
|
switch ($id) {
|
||||||
case 'installations':
|
case '_metadata':
|
||||||
// Create personalAccessToken attribute
|
if (!$this->dbForProject->getCollection('builds')->isEmpty()) {
|
||||||
try {
|
$this->dbForProject->deleteCollection('builds');
|
||||||
$this->createAttributeFromCollection($this->dbForProject, $id, 'personalAccessToken');
|
|
||||||
} catch (Throwable $th) {
|
|
||||||
Console::warning("'personalAccessToken' from {$id}: {$th->getMessage()}");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create personalAccessTokenExpiry attribute
|
|
||||||
try {
|
|
||||||
$this->createAttributeFromCollection($this->dbForProject, $id, 'personalAccessTokenExpiry');
|
|
||||||
} catch (Throwable $th) {
|
|
||||||
Console::warning("'personalAccessTokenExpiry' from {$id}: {$th->getMessage()}");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create personalRefreshToken attribute
|
|
||||||
try {
|
|
||||||
$this->createAttributeFromCollection($this->dbForProject, $id, 'personalRefreshToken');
|
|
||||||
} catch (Throwable $th) {
|
|
||||||
Console::warning("'personalRefreshToken' from {$id}: {$th->getMessage()}");
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
case 'rules':
|
||||||
|
$attributes = [
|
||||||
|
'resourceId',
|
||||||
|
'resourceInternalId',
|
||||||
|
'resourceType',
|
||||||
|
];
|
||||||
|
foreach ($attributes as $attribute) {
|
||||||
|
try {
|
||||||
|
$this->dbForProject->deleteAttribute($id, $attribute);
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
Console::warning("Failed to delete attribute \"$attribute\" from collection {$id}: {$th->getMessage()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
usleep(50000);
|
$indexesToDelete = [
|
||||||
|
'_key_resourceId',
|
||||||
|
'_key_resourceInternalId',
|
||||||
|
'_key_resourceType',
|
||||||
|
];
|
||||||
|
foreach ($indexesToDelete as $index) {
|
||||||
|
try {
|
||||||
|
$this->dbForProject->deleteIndex($id, $index);
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
Console::warning("Failed to delete index \"$index\" from collection {$id}: {$th->getMessage()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->dbForProject->purgeCachedCollection($id);
|
||||||
|
break;
|
||||||
|
case 'functions':
|
||||||
|
try {
|
||||||
|
$this->dbForProject->deleteAttribute($id, 'deployment');
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
Console::warning("Failed to delete attribute \"deployment\" from collection {$id}: {$th->getMessage()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
$indexesToDelete = [
|
||||||
|
'_key_deployment'
|
||||||
|
];
|
||||||
|
foreach ($indexesToDelete as $index) {
|
||||||
|
try {
|
||||||
|
$this->dbForProject->deleteIndex($id, $index);
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
Console::warning("Failed to delete index \"$index\" from collection {$id}: {$th->getMessage()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->dbForProject->purgeCachedCollection($id);
|
||||||
|
break;
|
||||||
|
case 'deployments':
|
||||||
|
$attributes = [
|
||||||
|
'buildInternalId',
|
||||||
|
'buildId',
|
||||||
|
'commands',
|
||||||
|
'path',
|
||||||
|
'size',
|
||||||
|
'metadata',
|
||||||
|
'chunksTotal',
|
||||||
|
'chunksUploaded',
|
||||||
|
'search'
|
||||||
|
];
|
||||||
|
foreach ($attributes as $attribute) {
|
||||||
|
try {
|
||||||
|
$this->dbForProject->deleteAttribute($id, $attribute);
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
Console::warning("Failed to delete attribute \"$attribute\" from collection {$id}: {$th->getMessage()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$indexesToDelete = [
|
||||||
|
'_key_buildId',
|
||||||
|
'_key_size',
|
||||||
|
'_key_search'
|
||||||
|
];
|
||||||
|
foreach ($indexesToDelete as $index) {
|
||||||
|
try {
|
||||||
|
$this->dbForProject->deleteIndex($id, $index);
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
Console::warning("Failed to delete index \"$index\" from collection {$id}: {$th->getMessage()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->dbForProject->purgeCachedCollection($id);
|
||||||
|
break;
|
||||||
|
case 'executions':
|
||||||
|
$attributes = [
|
||||||
|
'functionId',
|
||||||
|
'functionInternalId',
|
||||||
|
'search'
|
||||||
|
];
|
||||||
|
foreach ($attributes as $attribute) {
|
||||||
|
try {
|
||||||
|
$this->dbForProject->deleteAttribute($id, $attribute);
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
Console::warning("Failed to delete attribute \"$attribute\" from collection {$id}: {$th->getMessage()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$indexesToDelete = [
|
||||||
|
'_key_function',
|
||||||
|
'_fulltext_search'
|
||||||
|
];
|
||||||
|
foreach ($indexesToDelete as $index) {
|
||||||
|
try {
|
||||||
|
$this->dbForProject->deleteIndex($id, $index);
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
Console::warning("Failed to delete index \"$index\" from collection {$id}: {$th->getMessage()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->dbForProject->purgeCachedCollection($id);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,607 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Appwrite\Migration\Version;
|
|
||||||
|
|
||||||
use Appwrite\Migration\Migration;
|
|
||||||
use Exception;
|
|
||||||
use Throwable;
|
|
||||||
use Utopia\CLI\Console;
|
|
||||||
use Utopia\Database\Database;
|
|
||||||
use Utopia\Database\Document;
|
|
||||||
use Utopia\Database\Exception\Conflict;
|
|
||||||
use Utopia\Database\Exception\Structure;
|
|
||||||
use Utopia\Database\Exception\Timeout;
|
|
||||||
use Utopia\Database\Query;
|
|
||||||
|
|
||||||
class V23 extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @throws Throwable
|
|
||||||
*/
|
|
||||||
public function execute(): void
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Disable SubQueries for Performance.
|
|
||||||
*/
|
|
||||||
foreach (['subQueryIndexes', 'subQueryPlatforms', 'subQueryDomains', 'subQueryKeys', 'subQueryDevKeys', 'subQueryWebhooks', 'subQuerySessions', 'subQueryTokens', 'subQueryMemberships', 'subQueryVariables', 'subQueryChallenges', 'subQueryProjectVariables', 'subQueryTargets', 'subQueryTopicTargets'] as $name) {
|
|
||||||
Database::addFilter(
|
|
||||||
$name,
|
|
||||||
fn () => null,
|
|
||||||
fn () => []
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Console::info('Migrating collections');
|
|
||||||
$this->migrateCollections();
|
|
||||||
|
|
||||||
Console::info('Migrating documents');
|
|
||||||
$this->forEachDocument($this->migrateDocument(...));
|
|
||||||
|
|
||||||
Console::info('Cleaning up collections');
|
|
||||||
$this->cleanCollections();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Migrate Collections.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
* @throws Exception|Throwable
|
|
||||||
*/
|
|
||||||
private function migrateCollections(): void
|
|
||||||
{
|
|
||||||
$projectInternalId = $this->project->getInternalId();
|
|
||||||
|
|
||||||
if (empty($projectInternalId)) {
|
|
||||||
throw new Exception('Project ID is null');
|
|
||||||
}
|
|
||||||
|
|
||||||
$collectionType = match ($projectInternalId) {
|
|
||||||
'console' => 'console',
|
|
||||||
default => 'projects',
|
|
||||||
};
|
|
||||||
|
|
||||||
$collections = $this->collections[$collectionType];
|
|
||||||
|
|
||||||
foreach ($collections as $collection) {
|
|
||||||
$id = $collection['$id'];
|
|
||||||
|
|
||||||
if (empty($id)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Console::log("Migrating collection \"{$id}\"");
|
|
||||||
|
|
||||||
switch ($id) {
|
|
||||||
case '_metadata':
|
|
||||||
$this->createCollection('sites');
|
|
||||||
$this->createCollection('resourceTokens');
|
|
||||||
if ($projectInternalId === 'console') {
|
|
||||||
$this->createCollection('devKeys');
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'identities':
|
|
||||||
$attributes = [
|
|
||||||
'scopes',
|
|
||||||
'expire',
|
|
||||||
];
|
|
||||||
try {
|
|
||||||
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
|
||||||
} catch (\Throwable $th) {
|
|
||||||
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
|
||||||
}
|
|
||||||
$this->dbForProject->purgeCachedCollection($id);
|
|
||||||
break;
|
|
||||||
case 'projects':
|
|
||||||
try {
|
|
||||||
$attributes = [
|
|
||||||
'devKeys',
|
|
||||||
];
|
|
||||||
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
|
||||||
} catch (\Throwable $th) {
|
|
||||||
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
|
||||||
}
|
|
||||||
$this->dbForProject->purgeCachedCollection($id);
|
|
||||||
break;
|
|
||||||
case 'rules':
|
|
||||||
$attributes = [
|
|
||||||
'type',
|
|
||||||
'trigger',
|
|
||||||
'redirectUrl',
|
|
||||||
'redirectStatusCode',
|
|
||||||
'deploymentResourceType',
|
|
||||||
'deploymentId',
|
|
||||||
'deploymentInternalId',
|
|
||||||
'deploymentResourceId',
|
|
||||||
'deploymentResourceInternalId',
|
|
||||||
'deploymentVcsProviderBranch',
|
|
||||||
'search'
|
|
||||||
];
|
|
||||||
try {
|
|
||||||
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
|
||||||
} catch (\Throwable $th) {
|
|
||||||
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
|
||||||
}
|
|
||||||
|
|
||||||
$indexes = [
|
|
||||||
'_key_search',
|
|
||||||
'_key_type',
|
|
||||||
'_key_trigger',
|
|
||||||
'_key_deploymentResourceType',
|
|
||||||
'_key_deploymentResourceId',
|
|
||||||
'_key_deploymentResourceInternalId',
|
|
||||||
'_key_deploymentId',
|
|
||||||
'_key_deploymentInternalId',
|
|
||||||
'_key_deploymentVcsProviderBranch',
|
|
||||||
];
|
|
||||||
|
|
||||||
foreach ($indexes as $index) {
|
|
||||||
try {
|
|
||||||
$this->createIndexFromCollection($this->dbForProject, $id, $index);
|
|
||||||
} catch (\Throwable $th) {
|
|
||||||
Console::warning("Failed to create index \"$index\" from {$id}: {$th->getMessage()}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$this->dbForProject->purgeCachedCollection($id);
|
|
||||||
break;
|
|
||||||
case 'memberships':
|
|
||||||
$indexes = [
|
|
||||||
'_key_roles',
|
|
||||||
];
|
|
||||||
foreach ($indexes as $index) {
|
|
||||||
try {
|
|
||||||
$this->createIndexFromCollection($this->dbForProject, $id, $index);
|
|
||||||
} catch (Throwable $th) {
|
|
||||||
Console::warning("Failed to create index \"$index\" from {$id}: {$th->getMessage()}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$this->dbForProject->purgeCachedCollection($id);
|
|
||||||
break;
|
|
||||||
case 'migrations':
|
|
||||||
$attributes = [
|
|
||||||
'options',
|
|
||||||
'resourceId',
|
|
||||||
'resourceType'
|
|
||||||
];
|
|
||||||
try {
|
|
||||||
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
|
||||||
} catch (\Throwable $th) {
|
|
||||||
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
|
||||||
}
|
|
||||||
|
|
||||||
$indexes = [
|
|
||||||
'_key_resource_id',
|
|
||||||
];
|
|
||||||
|
|
||||||
foreach ($indexes as $index) {
|
|
||||||
try {
|
|
||||||
$this->createIndexFromCollection($this->dbForProject, $id, $index);
|
|
||||||
} catch (Throwable $th) {
|
|
||||||
Console::warning("Failed to create index \"$index\" from {$id}: {$th->getMessage()}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->dbForProject->purgeCachedCollection($id);
|
|
||||||
break;
|
|
||||||
case 'functions':
|
|
||||||
$attributes = [
|
|
||||||
'deploymentId',
|
|
||||||
'deploymentCreatedAt',
|
|
||||||
'latestDeploymentId',
|
|
||||||
'latestDeploymentInternalId',
|
|
||||||
'latestDeploymentCreatedAt',
|
|
||||||
'latestDeploymentStatus',
|
|
||||||
];
|
|
||||||
try {
|
|
||||||
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
|
||||||
} catch (\Throwable $th) {
|
|
||||||
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
|
||||||
}
|
|
||||||
|
|
||||||
$indexes = [
|
|
||||||
'_key_deploymentId',
|
|
||||||
];
|
|
||||||
|
|
||||||
foreach ($indexes as $index) {
|
|
||||||
try {
|
|
||||||
$this->createIndexFromCollection($this->dbForProject, $id, $index);
|
|
||||||
} catch (Throwable $th) {
|
|
||||||
Console::warning("Failed to create index \"$index\" from {$id}: {$th->getMessage()}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->dbForProject->purgeCachedCollection($id);
|
|
||||||
break;
|
|
||||||
case 'deployments':
|
|
||||||
$attributes = [
|
|
||||||
'buildCommands',
|
|
||||||
'sourcePath',
|
|
||||||
'buildOutput',
|
|
||||||
'adapter',
|
|
||||||
'fallbackFile',
|
|
||||||
'sourceSize',
|
|
||||||
'sourceMetadata',
|
|
||||||
'sourceChunksTotal',
|
|
||||||
'sourceChunksUploaded',
|
|
||||||
'screenshotLight',
|
|
||||||
'screenshotDark',
|
|
||||||
'buildStartedAt',
|
|
||||||
'buildEndedAt',
|
|
||||||
'buildDuration',
|
|
||||||
'buildSize',
|
|
||||||
'status',
|
|
||||||
'buildPath',
|
|
||||||
'buildLogs',
|
|
||||||
'totalSize',
|
|
||||||
];
|
|
||||||
try {
|
|
||||||
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
|
||||||
} catch (\Throwable $th) {
|
|
||||||
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
|
||||||
}
|
|
||||||
|
|
||||||
$indexes = [
|
|
||||||
'_key_sourceSize',
|
|
||||||
'_key_buildSize',
|
|
||||||
'_key_totalSize',
|
|
||||||
'_key_buildDuration',
|
|
||||||
'_key_type',
|
|
||||||
'_key_status',
|
|
||||||
];
|
|
||||||
|
|
||||||
foreach ($indexes as $index) {
|
|
||||||
try {
|
|
||||||
$this->createIndexFromCollection($this->dbForProject, $id, $index);
|
|
||||||
} catch (\Throwable $th) {
|
|
||||||
Console::warning("Failed to create index \"$index\" from {$id}: {$th->getMessage()}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->dbForProject->purgeCachedCollection($id);
|
|
||||||
break;
|
|
||||||
case 'executions':
|
|
||||||
$attributes = [
|
|
||||||
'resourceInternalId',
|
|
||||||
'resourceId',
|
|
||||||
'resourceType'
|
|
||||||
];
|
|
||||||
try {
|
|
||||||
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
|
||||||
} catch (\Throwable $th) {
|
|
||||||
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
|
||||||
}
|
|
||||||
|
|
||||||
$indexes = [
|
|
||||||
'_key_resource',
|
|
||||||
];
|
|
||||||
foreach ($indexes as $index) {
|
|
||||||
try {
|
|
||||||
$this->createIndexFromCollection($this->dbForProject, $id, $index);
|
|
||||||
} catch (\Throwable $th) {
|
|
||||||
Console::warning("Failed to create index \"$index\" from {$id}: {$th->getMessage()}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->dbForProject->purgeCachedCollection($id);
|
|
||||||
break;
|
|
||||||
case 'variables':
|
|
||||||
$attributes = [
|
|
||||||
'secret',
|
|
||||||
];
|
|
||||||
try {
|
|
||||||
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
|
||||||
} catch (\Throwable $th) {
|
|
||||||
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->dbForProject->purgeCachedCollection($id);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fix run on each document
|
|
||||||
*
|
|
||||||
* @param Document $document
|
|
||||||
* @return Document
|
|
||||||
* @throws Conflict
|
|
||||||
* @throws Structure
|
|
||||||
* @throws Timeout
|
|
||||||
* @throws \Utopia\Database\Exception
|
|
||||||
* @throws \Utopia\Database\Exception\Authorization
|
|
||||||
* @throws \Utopia\Database\Exception\Query
|
|
||||||
*/
|
|
||||||
private function migrateDocument(Document $document): Document
|
|
||||||
{
|
|
||||||
switch ($document->getCollection()) {
|
|
||||||
case 'rules':
|
|
||||||
/*
|
|
||||||
1. Convert "resourceType" to "type". Convert "function" to "deployment"
|
|
||||||
2. Convert "resourceId" to "deploymentResourceId"
|
|
||||||
3. Convert "resourceInternalId" to "deploymentResourceInternalId"
|
|
||||||
4. Fill "trigger" with "manual"
|
|
||||||
5. Fill "deploymentResourceType". If "resourceType" is "function", set "deploymentResourceType" to "function"
|
|
||||||
6. Fill "search" with "{$id} {domain}"
|
|
||||||
7. Fill "deploymentId" and "deploymentInternalId". If "deploymentResourceType" is "function", get project DB, and find function with ID "resourceId". Then fill rule's "deploymentId" with function's "deployment", and "deploymentId" as backup
|
|
||||||
*/
|
|
||||||
|
|
||||||
$deploymentResourceType = null;
|
|
||||||
|
|
||||||
$type = $document->getAttribute('resourceType', $document->getAttribute('type', ''));
|
|
||||||
if ($type === 'function') {
|
|
||||||
$type = 'deployment';
|
|
||||||
$deploymentResourceType = 'function';
|
|
||||||
}
|
|
||||||
|
|
||||||
$resourceId = $document->getAttribute('resourceId', $document->getAttribute('deploymentResourceId'));
|
|
||||||
$resourceInternalId = $document->getAttribute('resourceInternalId', $document->getAttribute('deploymentResourceInternalId'));
|
|
||||||
|
|
||||||
$document
|
|
||||||
->setAttribute('type', $type)
|
|
||||||
->setAttribute('trigger', 'manual')
|
|
||||||
->setAttribute('deploymentResourceId', $resourceId)
|
|
||||||
->setAttribute('deploymentResourceInternalId', $resourceInternalId)
|
|
||||||
->setAttribute('deploymentResourceType', $document->getAttribute('deploymentResourceType', $deploymentResourceType))
|
|
||||||
->setAttribute('search', \implode(' ', [$document->getId(), $document->getAttribute('domain', '')]));
|
|
||||||
|
|
||||||
if ($deploymentResourceType === 'function') {
|
|
||||||
$project = $this->dbForProject->getDocument('projects', $document->getAttribute('projectId'));
|
|
||||||
$dbForOwnerProject = ($this->getProjectDB)($project);
|
|
||||||
$function = $dbForOwnerProject->getDocument('functions', $resourceId);
|
|
||||||
$deploymentId = $function->getAttribute('deployment', $function->getAttribute('deploymentId', $document->getAttribute('deploymentId')));
|
|
||||||
$deploymentInternalId = $function->getAttribute('deploymentInternalId', $document->getAttribute('deploymentInternalId', ''));
|
|
||||||
|
|
||||||
$document
|
|
||||||
->setAttribute('deploymentId', $deploymentId)
|
|
||||||
->setAttribute('deploymentInternalId', $deploymentInternalId);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'variables':
|
|
||||||
/*
|
|
||||||
1. Fill "secret" with "false"
|
|
||||||
*/
|
|
||||||
$document->setAttribute('secret', $document->getAttribute('secret', false));
|
|
||||||
break;
|
|
||||||
case 'executions':
|
|
||||||
/*
|
|
||||||
1. Convert "functionInternalId" to "resourceInternalId"
|
|
||||||
2. Convert "functionId" to "resourceId"
|
|
||||||
3. Fill "resourceType" with "functions"
|
|
||||||
*/
|
|
||||||
$document
|
|
||||||
->setAttribute('resourceInternalId', $document->getAttribute('functionInternalId', $document->getAttribute('resourceInternalId')))
|
|
||||||
->setAttribute('resourceId', $document->getAttribute('functionId', $document->getAttribute('resourceId', '')))
|
|
||||||
->setAttribute('resourceType', $document->getAttribute('resourceType', 'functions'));
|
|
||||||
break;
|
|
||||||
case 'functions':
|
|
||||||
/*
|
|
||||||
1. Convert "deployment" to "deploymentId"
|
|
||||||
--- Fetch activeDeployment from "deploymentId"
|
|
||||||
2. Fill "deploymentCreatedAt" with deployment's "$createdAt"
|
|
||||||
--- Fetch latestDeployment using find()
|
|
||||||
3. Fill latestDeploymentId with latestDeployment's "$id"
|
|
||||||
4. Fill latestDeploymentInternalId with latestDeployment's "$internalId"
|
|
||||||
5. Fill latestDeploymentCreatedAt with latestDeployment's "$createdAt"
|
|
||||||
6. Fill latestDeploymentStatus with latestDeployment's build's "status"
|
|
||||||
*/
|
|
||||||
if ($document->getAttribute('deployment')) {
|
|
||||||
$document->setAttribute('deploymentId', $document->getAttribute('deployment', $document->getAttribute('deploymentId', '')));
|
|
||||||
}
|
|
||||||
|
|
||||||
$deploymentId = $document->getAttribute('deploymentId');
|
|
||||||
$deployment = $this->dbForProject->getDocument('deployments', $deploymentId);
|
|
||||||
$document->setAttribute('deploymentCreatedAt', $deployment->getCreatedAt());
|
|
||||||
|
|
||||||
$latestDeployment = $this->dbForProject->findOne('deployments', [
|
|
||||||
Query::orderDesc(),
|
|
||||||
Query::equal('resourceId', [$document->getId()]),
|
|
||||||
Query::equal('resourceType', ['functions']),
|
|
||||||
]);
|
|
||||||
|
|
||||||
$latestBuild = $this->dbForProject->getDocument('builds', $latestDeployment->getAttribute('buildId', ''));
|
|
||||||
|
|
||||||
$document
|
|
||||||
->setAttribute('latestDeploymentId', $latestDeployment->getId())
|
|
||||||
->setAttribute('latestDeploymentInternalId', $latestDeployment->getInternalId())
|
|
||||||
->setAttribute('latestDeploymentCreatedAt', $latestDeployment->getCreatedAt())
|
|
||||||
->setAttribute('latestDeploymentStatus', $latestBuild->getAttribute('status', $document->getAttribute('latestDeploymentStatus', '')));
|
|
||||||
break;
|
|
||||||
case 'deployments':
|
|
||||||
/*
|
|
||||||
6. Convert "commands" to "buildCommands"
|
|
||||||
7. Convert "path" to "sourcePath"
|
|
||||||
8. Convert "size" to "sourceSize"
|
|
||||||
9. Convert "metadata" to "sourceMetadata"
|
|
||||||
10. Convert "chunksTotal" to "sourceChunksTotal"
|
|
||||||
11. Convert "chunksUploaded" to "sourceChunksUploaded"
|
|
||||||
--- Get build of deployment
|
|
||||||
12. Convert build's "startTime" to "buildStartedAt"
|
|
||||||
13. Convert build's "endTime" to "buildEndedAt"
|
|
||||||
14. Convert build's "duration" to "buildDuration"
|
|
||||||
15. Convert build's "size" to "buildSize"
|
|
||||||
16. Convert build's "status" to "status"
|
|
||||||
17. Convert build's "path" to "buildPath"
|
|
||||||
18. Convert build's "logs" to "buildLogs"
|
|
||||||
19. Fill "totalSize" with "buildSize" plus "sourceSize"
|
|
||||||
*/
|
|
||||||
|
|
||||||
$document
|
|
||||||
->setAttribute('buildCommands', $document->getAttribute('commands', $document->getAttribute('buildCommands', '')))
|
|
||||||
->setAttribute('sourcePath', $document->getAttribute('path', $document->getAttribute('sourcePath', '')))
|
|
||||||
->setAttribute('sourceSize', $document->getAttribute('size', $document->getAttribute('sourceSize', 0)))
|
|
||||||
->setAttribute('sourceMetadata', $document->getAttribute('metadata', $document->getAttribute('sourceMetadata', [])))
|
|
||||||
->setAttribute('sourceChunksTotal', $document->getAttribute('chunksTotal', $document->getAttribute('sourceChunksTotal', 0)))
|
|
||||||
->setAttribute('sourceChunksUploaded', $document->getAttribute('chunksUploaded', $document->getAttribute('sourceChunksUploaded', 0)));
|
|
||||||
|
|
||||||
$build = new Document();
|
|
||||||
if (!empty($document->getAttribute('buildId'))) {
|
|
||||||
$build = $this->dbForProject->getDocument('builds', $document->getAttribute('buildId'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$document
|
|
||||||
->setAttribute('buildStartedAt', $build->getAttribute('startTime', $document->getAttribute('buildStartTime', '')))
|
|
||||||
->setAttribute('buildEndedAt', $build->getAttribute('endTime', $document->getAttribute('buildEndTime', '')))
|
|
||||||
->setAttribute('buildDuration', $build->getAttribute('duration', $document->getAttribute('buildDuration', 0)))
|
|
||||||
->setAttribute('buildSize', $build->getAttribute('size', $document->getAttribute('buildSize', 0)))
|
|
||||||
->setAttribute('status', $build->getAttribute('status', $document->getAttribute('status', '')))
|
|
||||||
->setAttribute('buildPath', $build->getAttribute('path', $document->getAttribute('buildPath', '')))
|
|
||||||
->setAttribute('buildLogs', $build->getAttribute('logs', $document->getAttribute('buildLogs', '')));
|
|
||||||
|
|
||||||
$totalSize = $document->getAttribute('buildSize', 0)
|
|
||||||
+ $document->getAttribute('sourceSize', 0);
|
|
||||||
|
|
||||||
$document->setAttribute('totalSize', $totalSize);
|
|
||||||
break;
|
|
||||||
case 'migrations':
|
|
||||||
/*
|
|
||||||
1. Fill "options" with "[]"
|
|
||||||
*/
|
|
||||||
$document->setAttribute('options', $document->getAttribute('options', []));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return $document;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function cleanCollections(): void
|
|
||||||
{
|
|
||||||
$projectInternalId = $this->project->getInternalId();
|
|
||||||
|
|
||||||
$collectionType = match ($projectInternalId) {
|
|
||||||
'console' => 'console',
|
|
||||||
default => 'projects',
|
|
||||||
};
|
|
||||||
|
|
||||||
$collections = $this->collections[$collectionType];
|
|
||||||
foreach ($collections as $collection) {
|
|
||||||
$id = $collection['$id'];
|
|
||||||
|
|
||||||
Console::log("Cleaning up collection \"{$id}\"");
|
|
||||||
|
|
||||||
switch ($id) {
|
|
||||||
case '_metadata':
|
|
||||||
if (!$this->dbForProject->getCollection('builds')->isEmpty()) {
|
|
||||||
$this->dbForProject->deleteCollection('builds');
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'rules':
|
|
||||||
$attributes = [
|
|
||||||
'resourceId',
|
|
||||||
'resourceInternalId',
|
|
||||||
'resourceType',
|
|
||||||
];
|
|
||||||
foreach ($attributes as $attribute) {
|
|
||||||
try {
|
|
||||||
$this->dbForProject->deleteAttribute($id, $attribute);
|
|
||||||
} catch (\Throwable $th) {
|
|
||||||
Console::warning("Failed to delete attribute \"$attribute\" from collection {$id}: {$th->getMessage()}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$indexesToDelete = [
|
|
||||||
'_key_resourceId',
|
|
||||||
'_key_resourceInternalId',
|
|
||||||
'_key_resourceType',
|
|
||||||
];
|
|
||||||
foreach ($indexesToDelete as $index) {
|
|
||||||
try {
|
|
||||||
$this->dbForProject->deleteIndex($id, $index);
|
|
||||||
} catch (\Throwable $th) {
|
|
||||||
Console::warning("Failed to delete index \"$index\" from collection {$id}: {$th->getMessage()}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->dbForProject->purgeCachedCollection($id);
|
|
||||||
break;
|
|
||||||
case 'functions':
|
|
||||||
try {
|
|
||||||
$this->dbForProject->deleteAttribute($id, 'deployment');
|
|
||||||
} catch (\Throwable $th) {
|
|
||||||
Console::warning("Failed to delete attribute \"deployment\" from collection {$id}: {$th->getMessage()}");
|
|
||||||
}
|
|
||||||
|
|
||||||
$indexesToDelete = [
|
|
||||||
'_key_deployment'
|
|
||||||
];
|
|
||||||
foreach ($indexesToDelete as $index) {
|
|
||||||
try {
|
|
||||||
$this->dbForProject->deleteIndex($id, $index);
|
|
||||||
} catch (\Throwable $th) {
|
|
||||||
Console::warning("Failed to delete index \"$index\" from collection {$id}: {$th->getMessage()}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->dbForProject->purgeCachedCollection($id);
|
|
||||||
break;
|
|
||||||
case 'deployments':
|
|
||||||
$attributes = [
|
|
||||||
'buildInternalId',
|
|
||||||
'buildId',
|
|
||||||
'commands',
|
|
||||||
'path',
|
|
||||||
'size',
|
|
||||||
'metadata',
|
|
||||||
'chunksTotal',
|
|
||||||
'chunksUploaded',
|
|
||||||
'search'
|
|
||||||
];
|
|
||||||
foreach ($attributes as $attribute) {
|
|
||||||
try {
|
|
||||||
$this->dbForProject->deleteAttribute($id, $attribute);
|
|
||||||
} catch (\Throwable $th) {
|
|
||||||
Console::warning("Failed to delete attribute \"$attribute\" from collection {$id}: {$th->getMessage()}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$indexesToDelete = [
|
|
||||||
'_key_buildId',
|
|
||||||
'_key_size',
|
|
||||||
'_key_search'
|
|
||||||
];
|
|
||||||
foreach ($indexesToDelete as $index) {
|
|
||||||
try {
|
|
||||||
$this->dbForProject->deleteIndex($id, $index);
|
|
||||||
} catch (\Throwable $th) {
|
|
||||||
Console::warning("Failed to delete index \"$index\" from collection {$id}: {$th->getMessage()}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->dbForProject->purgeCachedCollection($id);
|
|
||||||
break;
|
|
||||||
case 'executions':
|
|
||||||
$attributes = [
|
|
||||||
'functionId',
|
|
||||||
'functionInternalId',
|
|
||||||
'search'
|
|
||||||
];
|
|
||||||
foreach ($attributes as $attribute) {
|
|
||||||
try {
|
|
||||||
$this->dbForProject->deleteAttribute($id, $attribute);
|
|
||||||
} catch (\Throwable $th) {
|
|
||||||
Console::warning("Failed to delete attribute \"$attribute\" from collection {$id}: {$th->getMessage()}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$indexesToDelete = [
|
|
||||||
'_key_function',
|
|
||||||
'_fulltext_search'
|
|
||||||
];
|
|
||||||
foreach ($indexesToDelete as $index) {
|
|
||||||
try {
|
|
||||||
$this->dbForProject->deleteIndex($id, $index);
|
|
||||||
} catch (\Throwable $th) {
|
|
||||||
Console::warning("Failed to delete index \"$index\" from collection {$id}: {$th->getMessage()}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->dbForProject->purgeCachedCollection($id);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in a new issue