mirror of
https://github.com/appwrite/appwrite
synced 2026-05-22 16:38:32 +00:00
Merge pull request #8955 from appwrite/feat-bulk-updates
Feat bulk updates
This commit is contained in:
commit
6bbb522a87
13 changed files with 2310 additions and 981 deletions
|
|
@ -4638,6 +4638,112 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"patch": {
|
||||
"summary": "Update documents",
|
||||
"operationId": "databasesUpdateDocuments",
|
||||
"tags": [
|
||||
"databases"
|
||||
],
|
||||
"description": "Update all documents that match your queries, If none are submitted then all documents are updated. Using the patch method you can pass only specific fields that will get updated.",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Documents List",
|
||||
"content": {
|
||||
"application\/json": {
|
||||
"schema": {
|
||||
"$ref": "#\/components\/schemas\/documentList"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-appwrite": {
|
||||
"method": "updateDocuments",
|
||||
"weight": 113,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
"demo": "databases\/update-documents.md",
|
||||
"edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/update-documents.md",
|
||||
"rate-limit": 120,
|
||||
"rate-time": 60,
|
||||
"rate-key": "ip:{ip},method:{method},url:{url},userId:{userId}",
|
||||
"scope": "documents.write",
|
||||
"platforms": [
|
||||
"client",
|
||||
"server",
|
||||
"server"
|
||||
],
|
||||
"packaging": false,
|
||||
"offline-model": "\/databases\/{databaseId}\/collections\/{collectionId}\/documents",
|
||||
"offline-key": "",
|
||||
"offline-response-key": "$id",
|
||||
"auth": {
|
||||
"Project": []
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"Project": [],
|
||||
"Session": [],
|
||||
"JWT": []
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "databaseId",
|
||||
"description": "Database ID.",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"x-example": "<DATABASE_ID>"
|
||||
},
|
||||
"in": "path"
|
||||
},
|
||||
{
|
||||
"name": "collectionId",
|
||||
"description": "Collection ID.",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"x-example": "<COLLECTION_ID>"
|
||||
},
|
||||
"in": "path"
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application\/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "object",
|
||||
"description": "Document data as JSON object. Include only attribute and value pairs to be updated.",
|
||||
"x-example": "{}"
|
||||
},
|
||||
"permissions": {
|
||||
"type": "array",
|
||||
"description": "An array of permissions strings. By default, the current permissions are inherited. [Learn more about permissions](https:\/\/appwrite.io\/docs\/permissions).",
|
||||
"x-example": "[\"read(\"any\")\"]",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"queries": {
|
||||
"type": "array",
|
||||
"description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries). Maximum of 100 queries are allowed, each 4096 characters long.",
|
||||
"x-example": null,
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"summary": "Delete documents",
|
||||
"operationId": "databasesDeleteDocuments",
|
||||
|
|
@ -4647,12 +4753,19 @@
|
|||
"description": "Bulk delete documents using queries, if no queries are passed then all documents are deleted.",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "File"
|
||||
"description": "Documents List",
|
||||
"content": {
|
||||
"application\/json": {
|
||||
"schema": {
|
||||
"$ref": "#\/components\/schemas\/documentList"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-appwrite": {
|
||||
"method": "deleteDocuments",
|
||||
"weight": 114,
|
||||
"weight": 115,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -4945,7 +5058,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "deleteDocument",
|
||||
"weight": 113,
|
||||
"weight": 114,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -5031,7 +5144,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "listExecutions",
|
||||
"weight": 307,
|
||||
"weight": 308,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -5119,7 +5232,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "createExecution",
|
||||
"weight": 306,
|
||||
"weight": 307,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -5236,7 +5349,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "getExecution",
|
||||
"weight": 308,
|
||||
"weight": 309,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -5312,7 +5425,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "query",
|
||||
"weight": 332,
|
||||
"weight": 333,
|
||||
"cookies": false,
|
||||
"type": "graphql",
|
||||
"deprecated": false,
|
||||
|
|
@ -5366,7 +5479,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "mutation",
|
||||
"weight": 331,
|
||||
"weight": 332,
|
||||
"cookies": false,
|
||||
"type": "graphql",
|
||||
"deprecated": false,
|
||||
|
|
@ -5420,7 +5533,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "get",
|
||||
"weight": 118,
|
||||
"weight": 119,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -5474,7 +5587,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "listCodes",
|
||||
"weight": 119,
|
||||
"weight": 120,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -5528,7 +5641,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "listContinents",
|
||||
"weight": 123,
|
||||
"weight": 124,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -5582,7 +5695,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "listCountries",
|
||||
"weight": 120,
|
||||
"weight": 121,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -5636,7 +5749,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "listCountriesEU",
|
||||
"weight": 121,
|
||||
"weight": 122,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -5690,7 +5803,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "listCountriesPhones",
|
||||
"weight": 122,
|
||||
"weight": 123,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -5744,7 +5857,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "listCurrencies",
|
||||
"weight": 124,
|
||||
"weight": 125,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -5798,7 +5911,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "listLanguages",
|
||||
"weight": 125,
|
||||
"weight": 126,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -5852,7 +5965,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "createSubscriber",
|
||||
"weight": 383,
|
||||
"weight": 384,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -5937,7 +6050,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "deleteSubscriber",
|
||||
"weight": 387,
|
||||
"weight": 388,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -6014,7 +6127,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "listFiles",
|
||||
"weight": 209,
|
||||
"weight": 210,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -6102,7 +6215,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "createFile",
|
||||
"weight": 208,
|
||||
"weight": 209,
|
||||
"cookies": false,
|
||||
"type": "upload",
|
||||
"deprecated": false,
|
||||
|
|
@ -6202,7 +6315,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "getFile",
|
||||
"weight": 210,
|
||||
"weight": 211,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -6276,7 +6389,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "updateFile",
|
||||
"weight": 215,
|
||||
"weight": 216,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -6367,7 +6480,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "deleteFile",
|
||||
"weight": 216,
|
||||
"weight": 217,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -6436,7 +6549,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "getFileDownload",
|
||||
"weight": 212,
|
||||
"weight": 213,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"deprecated": false,
|
||||
|
|
@ -6505,7 +6618,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "getFilePreview",
|
||||
"weight": 211,
|
||||
"weight": 212,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"deprecated": false,
|
||||
|
|
@ -6723,7 +6836,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "getFileView",
|
||||
"weight": 213,
|
||||
"weight": 214,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"deprecated": false,
|
||||
|
|
@ -6799,7 +6912,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "list",
|
||||
"weight": 220,
|
||||
"weight": 221,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -6877,7 +6990,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "create",
|
||||
"weight": 219,
|
||||
"weight": 220,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -6964,7 +7077,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "get",
|
||||
"weight": 221,
|
||||
"weight": 222,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -7028,7 +7141,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "updateName",
|
||||
"weight": 223,
|
||||
"weight": 224,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -7104,7 +7217,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "delete",
|
||||
"weight": 225,
|
||||
"weight": 226,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -7170,7 +7283,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "listMemberships",
|
||||
"weight": 227,
|
||||
"weight": 228,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -7258,7 +7371,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "createMembership",
|
||||
"weight": 226,
|
||||
"weight": 227,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -7371,7 +7484,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "getMembership",
|
||||
"weight": 228,
|
||||
"weight": 229,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -7445,7 +7558,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "updateMembership",
|
||||
"weight": 229,
|
||||
"weight": 230,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -7534,7 +7647,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "deleteMembership",
|
||||
"weight": 231,
|
||||
"weight": 232,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -7610,7 +7723,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "updateMembershipStatus",
|
||||
"weight": 230,
|
||||
"weight": 231,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -7710,7 +7823,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "getPrefs",
|
||||
"weight": 222,
|
||||
"weight": 223,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -7773,7 +7886,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "updatePrefs",
|
||||
"weight": 224,
|
||||
"weight": 225,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -4803,28 +4803,135 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"patch": {
|
||||
"summary": "Update documents",
|
||||
"operationId": "databasesUpdateDocuments",
|
||||
"consumes": [
|
||||
"application\/json"
|
||||
],
|
||||
"produces": [
|
||||
"application\/json"
|
||||
],
|
||||
"tags": [
|
||||
"databases"
|
||||
],
|
||||
"description": "Update all documents that match your queries, If none are submitted then all documents are updated. Using the patch method you can pass only specific fields that will get updated.",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Documents List",
|
||||
"schema": {
|
||||
"$ref": "#\/definitions\/documentList"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-appwrite": {
|
||||
"method": "updateDocuments",
|
||||
"weight": 113,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
"demo": "databases\/update-documents.md",
|
||||
"edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/update-documents.md",
|
||||
"rate-limit": 120,
|
||||
"rate-time": 60,
|
||||
"rate-key": "ip:{ip},method:{method},url:{url},userId:{userId}",
|
||||
"scope": "documents.write",
|
||||
"platforms": [
|
||||
"client",
|
||||
"server",
|
||||
"server"
|
||||
],
|
||||
"packaging": false,
|
||||
"offline-model": "\/databases\/{databaseId}\/collections\/{collectionId}\/documents",
|
||||
"offline-key": "",
|
||||
"offline-response-key": "$id",
|
||||
"auth": {
|
||||
"Project": []
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"Project": [],
|
||||
"Session": [],
|
||||
"JWT": []
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "databaseId",
|
||||
"description": "Database ID.",
|
||||
"required": true,
|
||||
"type": "string",
|
||||
"x-example": "<DATABASE_ID>",
|
||||
"in": "path"
|
||||
},
|
||||
{
|
||||
"name": "collectionId",
|
||||
"description": "Collection ID.",
|
||||
"required": true,
|
||||
"type": "string",
|
||||
"x-example": "<COLLECTION_ID>",
|
||||
"in": "path"
|
||||
},
|
||||
{
|
||||
"name": "payload",
|
||||
"in": "body",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "object",
|
||||
"description": "Document data as JSON object. Include only attribute and value pairs to be updated.",
|
||||
"default": [],
|
||||
"x-example": "{}"
|
||||
},
|
||||
"permissions": {
|
||||
"type": "array",
|
||||
"description": "An array of permissions strings. By default, the current permissions are inherited. [Learn more about permissions](https:\/\/appwrite.io\/docs\/permissions).",
|
||||
"default": null,
|
||||
"x-example": "[\"read(\"any\")\"]",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"queries": {
|
||||
"type": "array",
|
||||
"description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries). Maximum of 100 queries are allowed, each 4096 characters long.",
|
||||
"default": [],
|
||||
"x-example": null,
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"delete": {
|
||||
"summary": "Delete documents",
|
||||
"operationId": "databasesDeleteDocuments",
|
||||
"consumes": [
|
||||
"application\/json"
|
||||
],
|
||||
"produces": [],
|
||||
"produces": [
|
||||
"application\/json"
|
||||
],
|
||||
"tags": [
|
||||
"databases"
|
||||
],
|
||||
"description": "Bulk delete documents using queries, if no queries are passed then all documents are deleted.",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "File",
|
||||
"description": "Documents List",
|
||||
"schema": {
|
||||
"type": "file"
|
||||
"$ref": "#\/definitions\/documentList"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-appwrite": {
|
||||
"method": "deleteDocuments",
|
||||
"weight": 114,
|
||||
"weight": 115,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -5107,7 +5214,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "deleteDocument",
|
||||
"weight": 113,
|
||||
"weight": 114,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -5189,7 +5296,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "listExecutions",
|
||||
"weight": 307,
|
||||
"weight": 308,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -5274,7 +5381,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "createExecution",
|
||||
"weight": 306,
|
||||
"weight": 307,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -5395,7 +5502,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "getExecution",
|
||||
"weight": 308,
|
||||
"weight": 309,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -5469,7 +5576,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "query",
|
||||
"weight": 332,
|
||||
"weight": 333,
|
||||
"cookies": false,
|
||||
"type": "graphql",
|
||||
"deprecated": false,
|
||||
|
|
@ -5545,7 +5652,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "mutation",
|
||||
"weight": 331,
|
||||
"weight": 332,
|
||||
"cookies": false,
|
||||
"type": "graphql",
|
||||
"deprecated": false,
|
||||
|
|
@ -5621,7 +5728,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "get",
|
||||
"weight": 118,
|
||||
"weight": 119,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -5677,7 +5784,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "listCodes",
|
||||
"weight": 119,
|
||||
"weight": 120,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -5733,7 +5840,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "listContinents",
|
||||
"weight": 123,
|
||||
"weight": 124,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -5789,7 +5896,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "listCountries",
|
||||
"weight": 120,
|
||||
"weight": 121,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -5845,7 +5952,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "listCountriesEU",
|
||||
"weight": 121,
|
||||
"weight": 122,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -5901,7 +6008,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "listCountriesPhones",
|
||||
"weight": 122,
|
||||
"weight": 123,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -5957,7 +6064,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "listCurrencies",
|
||||
"weight": 124,
|
||||
"weight": 125,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -6013,7 +6120,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "listLanguages",
|
||||
"weight": 125,
|
||||
"weight": 126,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -6069,7 +6176,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "createSubscriber",
|
||||
"weight": 383,
|
||||
"weight": 384,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -6158,7 +6265,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "deleteSubscriber",
|
||||
"weight": 387,
|
||||
"weight": 388,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -6233,7 +6340,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "listFiles",
|
||||
"weight": 209,
|
||||
"weight": 210,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -6318,7 +6425,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "createFile",
|
||||
"weight": 208,
|
||||
"weight": 209,
|
||||
"cookies": false,
|
||||
"type": "upload",
|
||||
"deprecated": false,
|
||||
|
|
@ -6412,7 +6519,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "getFile",
|
||||
"weight": 210,
|
||||
"weight": 211,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -6484,7 +6591,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "updateFile",
|
||||
"weight": 215,
|
||||
"weight": 216,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -6575,7 +6682,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "deleteFile",
|
||||
"weight": 216,
|
||||
"weight": 217,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -6649,7 +6756,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "getFileDownload",
|
||||
"weight": 212,
|
||||
"weight": 213,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"deprecated": false,
|
||||
|
|
@ -6723,7 +6830,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "getFilePreview",
|
||||
"weight": 211,
|
||||
"weight": 212,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"deprecated": false,
|
||||
|
|
@ -6924,7 +7031,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "getFileView",
|
||||
"weight": 213,
|
||||
"weight": 214,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"deprecated": false,
|
||||
|
|
@ -6998,7 +7105,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "list",
|
||||
"weight": 220,
|
||||
"weight": 221,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -7075,7 +7182,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "create",
|
||||
"weight": 219,
|
||||
"weight": 220,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -7169,7 +7276,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "get",
|
||||
"weight": 221,
|
||||
"weight": 222,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -7233,7 +7340,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "updateName",
|
||||
"weight": 223,
|
||||
"weight": 224,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -7310,7 +7417,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "delete",
|
||||
"weight": 225,
|
||||
"weight": 226,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -7376,7 +7483,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "listMemberships",
|
||||
"weight": 227,
|
||||
"weight": 228,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -7461,7 +7568,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "createMembership",
|
||||
"weight": 226,
|
||||
"weight": 227,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -7578,7 +7685,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "getMembership",
|
||||
"weight": 228,
|
||||
"weight": 229,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -7650,7 +7757,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "updateMembership",
|
||||
"weight": 229,
|
||||
"weight": 230,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -7738,7 +7845,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "deleteMembership",
|
||||
"weight": 231,
|
||||
"weight": 232,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -7812,7 +7919,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "updateMembershipStatus",
|
||||
"weight": 230,
|
||||
"weight": 231,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -7910,7 +8017,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "getPrefs",
|
||||
"weight": 222,
|
||||
"weight": 223,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
@ -7973,7 +8080,7 @@
|
|||
},
|
||||
"x-appwrite": {
|
||||
"method": "updatePrefs",
|
||||
"weight": 224,
|
||||
"weight": 225,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"deprecated": false,
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -3689,6 +3689,141 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum
|
|||
->setPayload($response->getPayload(), sensitive: $relationships);
|
||||
});
|
||||
|
||||
App::patch('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
->desc('Update documents')
|
||||
->groups(['api', 'database'])
|
||||
->label('scope', 'documents.write')
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('audits.event', 'documents.update')
|
||||
->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}')
|
||||
->label('abuse-key', 'ip:{ip},method:{method},url:{url},userId:{userId}')
|
||||
->label('abuse-limit', APP_LIMIT_WRITE_RATE_DEFAULT * 2)
|
||||
->label('abuse-time', APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT)
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'databases')
|
||||
->label('sdk.method', 'updateDocuments')
|
||||
->label('sdk.description', '/docs/references/databases/update-documents.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_DOCUMENT_LIST)
|
||||
->label('sdk.offline.model', '/databases/{databaseId}/collections/{collectionId}/documents')
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('collectionId', '', new UID(), 'Collection ID.')
|
||||
->param('data', [], new JSON(), 'Document data as JSON object. Include only attribute and value pairs to be updated.', true)
|
||||
->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE, [Database::PERMISSION_READ, Database::PERMISSION_UPDATE, Database::PERMISSION_DELETE, Database::PERMISSION_WRITE]), 'An array of permissions strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions).', true)
|
||||
->param('queries', [], new ArrayList(new Text(APP_LIMIT_ARRAY_ELEMENT_SIZE), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long.', true)
|
||||
->inject('requestTimestamp')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('project')
|
||||
->action(function (string $databaseId, string $collectionId, string|array $data, ?array $permissions, array $queries, ?\DateTime $requestTimestamp, Response $response, Database $dbForProject, Document $project) {
|
||||
$data = (\is_string($data)) ? \json_decode($data, true) : $data; // Cast to JSON array
|
||||
|
||||
if (empty($data) && \is_null($permissions)) {
|
||||
throw new Exception(Exception::DOCUMENT_MISSING_PAYLOAD);
|
||||
}
|
||||
|
||||
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
|
||||
|
||||
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
|
||||
|
||||
if ($database->isEmpty() || (!$database->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
|
||||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId));
|
||||
|
||||
if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$queries = Query::parseQueries($queries);
|
||||
|
||||
// Map aggregate permissions into the multiple permissions they represent.
|
||||
$permissions = Permission::aggregate($permissions, [
|
||||
Database::PERMISSION_READ,
|
||||
Database::PERMISSION_UPDATE,
|
||||
Database::PERMISSION_DELETE,
|
||||
]);
|
||||
|
||||
// Users can only manage their own roles, API keys and Admin users can manage any
|
||||
$roles = Authorization::getRoles();
|
||||
if (!$isAPIKey && !$isPrivilegedUser && !\is_null($permissions)) {
|
||||
foreach (Database::PERMISSIONS as $type) {
|
||||
foreach ($permissions as $permission) {
|
||||
$permission = Permission::parse($permission);
|
||||
if ($permission->getPermission() != $type) {
|
||||
continue;
|
||||
}
|
||||
$role = (new Role(
|
||||
$permission->getRole(),
|
||||
$permission->getIdentifier(),
|
||||
$permission->getDimension()
|
||||
))->toString();
|
||||
if (!Authorization::isRole($role)) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED, 'Permissions must be one of: (' . \implode(', ', $roles) . ')');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!\is_null($permissions)) {
|
||||
$data['$permissions'] = $permissions;
|
||||
}
|
||||
$partialDocument = new Document($data);
|
||||
|
||||
$documents = $dbForProject->withRequestTimestamp(
|
||||
$requestTimestamp,
|
||||
fn () => $dbForProject->updateDocuments(
|
||||
'database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(),
|
||||
$partialDocument,
|
||||
$queries
|
||||
)
|
||||
);
|
||||
|
||||
$processDocument = function (Document $collection, Document $document) use (&$processDocument, $dbForProject, $database) {
|
||||
$document->setAttribute('$databaseId', $database->getId());
|
||||
$document->setAttribute('$collectionId', $collection->getId());
|
||||
|
||||
$relationships = \array_filter(
|
||||
$collection->getAttribute('attributes', []),
|
||||
fn ($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP
|
||||
);
|
||||
|
||||
foreach ($relationships as $relationship) {
|
||||
$related = $document->getAttribute($relationship->getAttribute('key'));
|
||||
|
||||
if (empty($related)) {
|
||||
continue;
|
||||
}
|
||||
if (!\is_array($related)) {
|
||||
$related = [$related];
|
||||
}
|
||||
|
||||
$relatedCollectionId = $relationship->getAttribute('relatedCollection');
|
||||
$relatedCollection = Authorization::skip(
|
||||
fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId)
|
||||
);
|
||||
|
||||
foreach ($related as $relation) {
|
||||
if ($relation instanceof Document) {
|
||||
$processDocument($relatedCollection, $relation);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
foreach ($documents as $document) {
|
||||
$processDocument($collection, $document);
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'total' => \count($documents),
|
||||
'documents' => $documents
|
||||
]), Response::MODEL_DOCUMENT_LIST);
|
||||
});
|
||||
|
||||
App::delete('/v1/databases/:databaseId/collections/:collectionId/documents/:documentId')
|
||||
->alias('/v1/database/collections/:collectionId/documents/:documentId', ['databaseId' => 'default'])
|
||||
->desc('Delete document')
|
||||
|
|
|
|||
|
|
@ -96,6 +96,10 @@
|
|||
"config": {
|
||||
"platform": {
|
||||
"php": "8.3"
|
||||
},
|
||||
"allow-plugins": {
|
||||
"php-http/discovery": false,
|
||||
"tbachert/spi": false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
2
composer.lock
generated
2
composer.lock
generated
|
|
@ -8558,7 +8558,7 @@
|
|||
],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": {},
|
||||
"stability-flags": [],
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
|
|
|
|||
1
docs/references/databases/update-documents.md
Normal file
1
docs/references/databases/update-documents.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
Update all documents that match your queries, If none are submitted then all documents are updated. Using the patch method you can pass only specific fields that will get updated.
|
||||
10
package-lock.json
generated
Normal file
10
package-lock.json
generated
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"name": "@appwrite.io/repo",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@appwrite.io/repo"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5446,4 +5446,225 @@ trait DatabasesBase
|
|||
$this->assertEquals(200, $collection2docs['headers']['status-code']);
|
||||
$this->assertEquals(0, $collection2docs['body']['total']);
|
||||
}
|
||||
|
||||
public function testBulkUpdates(): void
|
||||
{
|
||||
// Create database
|
||||
$database = $this->client->call(Client::METHOD_POST, '/databases', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
], [
|
||||
'databaseId' => ID::unique(),
|
||||
'name' => 'Bulk Updates'
|
||||
]);
|
||||
|
||||
$this->assertNotEmpty($database['body']['$id']);
|
||||
|
||||
$databaseId = $database['body']['$id'];
|
||||
|
||||
$collection = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'collectionId' => ID::unique(),
|
||||
'name' => 'Bulk Updates',
|
||||
'documentSecurity' => true,
|
||||
'permissions' => [
|
||||
Permission::create(Role::any()),
|
||||
Permission::read(Role::any()),
|
||||
Permission::delete(Role::any()),
|
||||
Permission::update(Role::any()),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $collection['headers']['status-code']);
|
||||
|
||||
$data = [
|
||||
'$id' => $collection['body']['$id'],
|
||||
'databaseId' => $collection['body']['databaseId']
|
||||
];
|
||||
|
||||
// Await attribute
|
||||
$numberAttribute = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $data['$id'] . '/attributes/integer', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'number',
|
||||
'required' => true,
|
||||
]);
|
||||
|
||||
$this->assertEquals(202, $numberAttribute['headers']['status-code']);
|
||||
|
||||
// wait for database worker to create attributes
|
||||
sleep(2);
|
||||
|
||||
// Create documents
|
||||
$createBulkDocuments = function ($amount = 10) use ($data) {
|
||||
for ($x = 1; $x <= $amount; $x++) {
|
||||
$doc = $this->client->call(Client::METHOD_POST, '/databases/' . $data['databaseId'] . '/collections/' . $data['$id'] . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'documentId' => ID::unique(),
|
||||
'data' => [
|
||||
'number' => $x,
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $doc['headers']['status-code']);
|
||||
}
|
||||
};
|
||||
|
||||
$createBulkDocuments();
|
||||
|
||||
// TEST: Update all documents
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/databases/' . $data['databaseId'] . '/collections/' . $data['$id'] . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'data' => [
|
||||
'number' => 100
|
||||
],
|
||||
'permissions' => [
|
||||
Permission::read(Role::user($this->getUser()['$id'])),
|
||||
Permission::update(Role::user($this->getUser()['$id'])),
|
||||
Permission::delete(Role::user($this->getUser()['$id'])),
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertCount(10, $response['body']['documents']);
|
||||
|
||||
$documents = $this->client->call(Client::METHOD_GET, '/databases/' . $data['databaseId'] . '/collections/' . $data['$id'] . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
Query::equal('number', [100])->toString(),
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
$this->assertEquals(10, $documents['body']['total']);
|
||||
|
||||
foreach ($documents['body']['documents'] as $document) {
|
||||
$this->assertEquals([
|
||||
Permission::read(Role::user($this->getUser()['$id'])),
|
||||
Permission::update(Role::user($this->getUser()['$id'])),
|
||||
Permission::delete(Role::user($this->getUser()['$id'])),
|
||||
], $document['$permissions']);
|
||||
$this->assertEquals($collection['body']['$id'], $document['$collectionId']);
|
||||
$this->assertEquals($data['databaseId'], $document['$databaseId']);
|
||||
}
|
||||
|
||||
// TEST: Check permissions persist
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/databases/' . $data['databaseId'] . '/collections/' . $data['$id'] . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'data' => [
|
||||
'number' => 200
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertCount(10, $response['body']['documents']);
|
||||
|
||||
$documents = $this->client->call(Client::METHOD_GET, '/databases/' . $data['databaseId'] . '/collections/' . $data['$id'] . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
Query::equal('number', [200])->toString(),
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
$this->assertEquals(10, $documents['body']['total']);
|
||||
|
||||
foreach ($documents['body']['documents'] as $document) {
|
||||
$this->assertEquals([
|
||||
Permission::read(Role::user($this->getUser()['$id'])),
|
||||
Permission::update(Role::user($this->getUser()['$id'])),
|
||||
Permission::delete(Role::user($this->getUser()['$id'])),
|
||||
], $document['$permissions']);
|
||||
}
|
||||
|
||||
// TEST: Update documents with limit
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/databases/' . $data['databaseId'] . '/collections/' . $data['$id'] . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'data' => [
|
||||
'number' => 300
|
||||
],
|
||||
'queries' => [
|
||||
Query::limit(5)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertCount(5, $response['body']['documents']);
|
||||
|
||||
$documents = $this->client->call(Client::METHOD_GET, '/databases/' . $data['databaseId'] . '/collections/' . $data['$id'] . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::equal('number', [200])->toString()]
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
$this->assertEquals(5, $documents['body']['total']);
|
||||
|
||||
// TEST: Update documents with offset
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/databases/' . $data['databaseId'] . '/collections/' . $data['$id'] . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'data' => [
|
||||
'number' => 300
|
||||
],
|
||||
'queries' => [
|
||||
Query::offset(5)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertCount(5, $response['body']['documents']);
|
||||
|
||||
$documents = $this->client->call(Client::METHOD_GET, '/databases/' . $data['databaseId'] . '/collections/' . $data['$id'] . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::equal('number', [300])->toString()]
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
$this->assertEquals(10, $documents['body']['total']);
|
||||
|
||||
// TEST: Update documents with equals filter
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/databases/' . $data['databaseId'] . '/collections/' . $data['$id'] . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'data' => [
|
||||
'number' => 400
|
||||
],
|
||||
'queries' => [
|
||||
Query::equal('number', [300])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertCount(10, $response['body']['documents']);
|
||||
|
||||
$documents = $this->client->call(Client::METHOD_GET, '/databases/' . $data['databaseId'] . '/collections/' . $data['$id'] . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::equal('number', [400])->toString()]
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
$this->assertEquals(10, $documents['body']['total']);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ use Utopia\Database\Database;
|
|||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Database\Helpers\Permission;
|
||||
use Utopia\Database\Helpers\Role;
|
||||
use Utopia\Database\Query;
|
||||
|
||||
class DatabasesCustomClientTest extends Scope
|
||||
{
|
||||
|
|
@ -891,6 +892,291 @@ class DatabasesCustomClientTest extends Scope
|
|||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
}
|
||||
|
||||
// Bulk Updates
|
||||
public function testBulkUpdatesPermissions(): void
|
||||
{
|
||||
// Create database
|
||||
$database = $this->client->call(Client::METHOD_POST, '/databases', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
], [
|
||||
'databaseId' => ID::unique(),
|
||||
'name' => 'Bulk Update Perms'
|
||||
]);
|
||||
|
||||
$this->assertNotEmpty($database['body']['$id']);
|
||||
|
||||
$databaseId = $database['body']['$id'];
|
||||
$collection = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'collectionId' => ID::unique(),
|
||||
'name' => 'Bulk Updates Perms',
|
||||
'documentSecurity' => false,
|
||||
'permissions' => [
|
||||
Permission::create(Role::user($this->getUser()['$id']))
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $collection['headers']['status-code']);
|
||||
|
||||
$data = [
|
||||
'$id' => $collection['body']['$id'],
|
||||
'databaseId' => $collection['body']['databaseId']
|
||||
];
|
||||
|
||||
// Await attribute
|
||||
$numberAttribute = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $data['$id'] . '/attributes/integer', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'number',
|
||||
'required' => true,
|
||||
]);
|
||||
|
||||
$this->assertEquals(202, $numberAttribute['headers']['status-code']);
|
||||
|
||||
sleep(2);
|
||||
|
||||
// TEST: Update all documents with invalid collection level permissions
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/databases/' . $data['databaseId'] . '/collections/' . $data['$id'] . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'data' => [
|
||||
'number' => 100
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals(401, $response['headers']['status-code']);
|
||||
|
||||
$collection = $this->client->call(Client::METHOD_PUT, '/databases/' . $data['databaseId'] . '/collections/' . $data['$id'], array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'name' => 'Bulk Updates Perms',
|
||||
'documentSecurity' => true
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $collection['headers']['status-code']);
|
||||
|
||||
// TEST: Make sure we can update only documents we have permissions for
|
||||
for ($i = 0; $i < 6; $i++) {
|
||||
$doc = $this->client->call(Client::METHOD_POST, '/databases/' . $data['databaseId'] . '/collections/' . $data['$id'] . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'documentId' => ID::unique(),
|
||||
'data' => [
|
||||
'number' => $i,
|
||||
],
|
||||
'permissions' => [
|
||||
Permission::update(Role::user($this->getUser()['$id']))
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $doc['headers']['status-code']);
|
||||
}
|
||||
|
||||
$doc = $this->client->call(Client::METHOD_POST, '/databases/' . $data['databaseId'] . '/collections/' . $data['$id'] . '/documents', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
], [
|
||||
'documentId' => ID::unique(),
|
||||
'data' => [
|
||||
'number' => 6,
|
||||
],
|
||||
'permissions' => [
|
||||
Permission::update(Role::user('user2')),
|
||||
Permission::read(Role::user($this->getUser()['$id'])),
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $doc['headers']['status-code']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/databases/' . $data['databaseId'] . '/collections/' . $data['$id'] . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'data' => [
|
||||
'number' => 100
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertCount(6, $response['body']['documents']);
|
||||
|
||||
$documents = $this->client->call(Client::METHOD_GET, '/databases/' . $data['databaseId'] . '/collections/' . $data['$id'] . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id']
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [Query::notEqual('number', 100)->toString()]
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
$this->assertEquals(1, $documents['body']['total']);
|
||||
}
|
||||
|
||||
public function testBulkUpdatesRelationship()
|
||||
{
|
||||
$database = $this->client->call(Client::METHOD_POST, '/databases', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
], [
|
||||
'databaseId' => ID::unique(),
|
||||
'name' => 'Bulk Updates'
|
||||
]);
|
||||
|
||||
$this->assertNotEmpty($database['body']['$id']);
|
||||
|
||||
$databaseId = $database['body']['$id'];
|
||||
|
||||
$collection1 = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'collectionId' => ID::unique(),
|
||||
'name' => 'Collection1',
|
||||
'documentSecurity' => false,
|
||||
'permissions' => [
|
||||
Permission::create(Role::any()),
|
||||
Permission::read(Role::any()),
|
||||
Permission::delete(Role::any()),
|
||||
Permission::update(Role::any()),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $collection1['headers']['status-code']);
|
||||
|
||||
$collection2 = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'collectionId' => ID::unique(),
|
||||
'name' => 'Collection2',
|
||||
'documentSecurity' => false,
|
||||
'permissions' => [
|
||||
Permission::create(Role::any()),
|
||||
Permission::read(Role::any()),
|
||||
Permission::delete(Role::any()),
|
||||
Permission::update(Role::any()),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $collection1['headers']['status-code']);
|
||||
|
||||
$collection1 = $collection1['body']['$id'];
|
||||
$collection2 = $collection2['body']['$id'];
|
||||
|
||||
$this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collection1 . '/attributes/relationship', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'relatedCollectionId' => $collection2,
|
||||
'type' => Database::RELATION_ONE_TO_MANY,
|
||||
'key' => 'collection2',
|
||||
'onDelete' => Database::RELATION_MUTATE_RESTRICT,
|
||||
'twoWay' => true,
|
||||
'twoWayKey' => 'collection1',
|
||||
]);
|
||||
|
||||
$this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collection1 . '/attributes/string', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'name',
|
||||
'size' => 256,
|
||||
'required' => true,
|
||||
]);
|
||||
|
||||
$this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collection2 . '/attributes/string', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'name',
|
||||
'size' => 256,
|
||||
'required' => true,
|
||||
]);
|
||||
|
||||
sleep(3);
|
||||
|
||||
$document1 = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collection1 . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id']
|
||||
], $this->getHeaders()), [
|
||||
'documentId' => ID::unique(),
|
||||
'data' => [
|
||||
'name' => 'Document 1',
|
||||
'collection2' => [
|
||||
[
|
||||
'name' => 'Document 2',
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $document1['headers']['status-code']);
|
||||
$document1 = $document1['body']['$id'];
|
||||
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/databases/' . $databaseId . '/collections/' . $collection1 . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id']
|
||||
], $this->getHeaders()), [
|
||||
'data' => [
|
||||
'name' => 'Document 1 Updated',
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertCount(1, $response['body']['documents']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $collection2 . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id']
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
|
||||
$document2 = $response['body']['documents'][0];
|
||||
|
||||
$this->assertEquals('Document 2', $document2['name']);
|
||||
$this->assertEquals('Document 1 Updated', $document2['collection1']['name']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/databases/' . $databaseId . '/collections/' . $collection2 . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id']
|
||||
], $this->getHeaders()), [
|
||||
'data' => [
|
||||
'name' => 'Document 2 Updated',
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $collection1 . '/documents/' . $document1, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id']
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals('Document 1 Updated', $response['body']['name']);
|
||||
|
||||
$document2 = $response['body']['collection2'][0];
|
||||
$this->assertEquals('Document 2 Updated', $document2['name']);
|
||||
}
|
||||
|
||||
public function testBulkDeletesPermissions(): void
|
||||
{
|
||||
// Create database
|
||||
|
|
|
|||
Loading…
Reference in a new issue