Merge remote-tracking branch 'upstream/1.8.x' into spatial-type-attributes

This commit is contained in:
ArnabChatterjee20k 2025-09-02 23:04:12 +05:30
commit b01f146b1c
31 changed files with 368 additions and 219 deletions

View file

@ -5146,7 +5146,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update a document", "summary": "Upsert a document",
"operationId": "databasesUpsertDocument", "operationId": "databasesUpsertDocument",
"tags": [ "tags": [
"databases" "databases"
@ -5881,7 +5881,7 @@
}, },
"method": { "method": {
"type": "string", "type": "string",
"description": "HTTP method of execution. Default value is GET.", "description": "HTTP method of execution. Default value is POST.",
"x-example": "GET", "x-example": "GET",
"enum": [ "enum": [
"GET", "GET",
@ -5889,7 +5889,8 @@
"PUT", "PUT",
"PATCH", "PATCH",
"DELETE", "DELETE",
"OPTIONS" "OPTIONS",
"HEAD"
], ],
"x-enum-name": "ExecutionMethod", "x-enum-name": "ExecutionMethod",
"x-enum-keys": [] "x-enum-keys": []
@ -7624,7 +7625,7 @@
} }
], ],
"description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/create-row.md" "demo": "tablesdb\/create-row.md"
} }
], ],
"auth": { "auth": {
@ -7799,7 +7800,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update a row", "summary": "Upsert a row",
"operationId": "tablesDBUpsertRow", "operationId": "tablesDBUpsertRow",
"tags": [ "tags": [
"tablesDB" "tablesDB"
@ -7866,7 +7867,7 @@
} }
], ],
"description": "Create or update a Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create or update a Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/upsert-row.md" "demo": "tablesdb\/upsert-row.md"
} }
], ],
"auth": { "auth": {

View file

@ -8940,7 +8940,7 @@
} }
}, },
"put": { "put": {
"summary": "Create or update documents", "summary": "Upsert documents",
"operationId": "databasesUpsertDocuments", "operationId": "databasesUpsertDocuments",
"tags": [ "tags": [
"databases" "databases"
@ -9360,7 +9360,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update a document", "summary": "Upsert a document",
"operationId": "databasesUpsertDocument", "operationId": "databasesUpsertDocument",
"tags": [ "tags": [
"databases" "databases"
@ -12791,7 +12791,7 @@
}, },
"method": { "method": {
"type": "string", "type": "string",
"description": "HTTP method of execution. Default value is GET.", "description": "HTTP method of execution. Default value is POST.",
"x-example": "GET", "x-example": "GET",
"enum": [ "enum": [
"GET", "GET",
@ -12799,7 +12799,8 @@
"PUT", "PUT",
"PATCH", "PATCH",
"DELETE", "DELETE",
"OPTIONS" "OPTIONS",
"HEAD"
], ],
"x-enum-name": "ExecutionMethod", "x-enum-name": "ExecutionMethod",
"x-enum-keys": [] "x-enum-keys": []
@ -32188,7 +32189,7 @@
} }
], ],
"description": "List usage metrics and statistics for all databases in the project. You can view the total number of databases, tables, rows, and storage usage. The response includes both current totals and historical data over time. Use the optional range parameter to specify the time window for historical data: 24h (last 24 hours), 30d (last 30 days), or 90d (last 90 days). If not specified, range defaults to 30 days.", "description": "List usage metrics and statistics for all databases in the project. You can view the total number of databases, tables, rows, and storage usage. The response includes both current totals and historical data over time. Use the optional range parameter to specify the time window for historical data: 24h (last 24 hours), 30d (last 30 days), or 90d (last 90 days). If not specified, range defaults to 30 days.",
"demo": "tables-db\/list-usage.md" "demo": "tablesdb\/list-usage.md"
} }
], ],
"auth": { "auth": {
@ -32445,7 +32446,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "listTables", "method": "listTables",
"group": null, "group": "tables",
"weight": 382, "weight": 382,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -32531,7 +32532,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "createTable", "method": "createTable",
"group": null, "group": "tables",
"weight": 378, "weight": 378,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -32638,7 +32639,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "getTable", "method": "getTable",
"group": null, "group": "tables",
"weight": 379, "weight": 379,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -32710,7 +32711,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "updateTable", "method": "updateTable",
"group": null, "group": "tables",
"weight": 380, "weight": 380,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -32812,7 +32813,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "deleteTable", "method": "deleteTable",
"group": null, "group": "tables",
"weight": 381, "weight": 381,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -36081,7 +36082,7 @@
} }
], ],
"description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/create-row.md" "demo": "tablesdb\/create-row.md"
}, },
{ {
"name": "createRows", "name": "createRows",
@ -36107,7 +36108,7 @@
} }
], ],
"description": "Create new Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create new Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/create-rows.md" "demo": "tablesdb\/create-rows.md"
} }
], ],
"auth": { "auth": {
@ -36182,7 +36183,7 @@
} }
}, },
"put": { "put": {
"summary": "Create or update rows", "summary": "Upsert rows",
"operationId": "tablesDBUpsertRows", "operationId": "tablesDBUpsertRows",
"tags": [ "tags": [
"tablesDB" "tablesDB"
@ -36246,7 +36247,7 @@
} }
], ],
"description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n", "description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n",
"demo": "tables-db\/upsert-rows.md" "demo": "tablesdb\/upsert-rows.md"
} }
], ],
"auth": { "auth": {
@ -36594,7 +36595,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update a row", "summary": "Upsert a row",
"operationId": "tablesDBUpsertRow", "operationId": "tablesDBUpsertRow",
"tags": [ "tags": [
"tablesDB" "tablesDB"
@ -36661,7 +36662,7 @@
} }
], ],
"description": "Create or update a Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create or update a Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/upsert-row.md" "demo": "tablesdb\/upsert-row.md"
} }
], ],
"auth": { "auth": {
@ -37409,7 +37410,7 @@
} }
], ],
"description": "Get usage metrics and statistics for a database. You can view the total number of tables, rows, and storage usage. The response includes both current totals and historical data over time. Use the optional range parameter to specify the time window for historical data: 24h (last 24 hours), 30d (last 30 days), or 90d (last 90 days). If not specified, range defaults to 30 days.", "description": "Get usage metrics and statistics for a database. You can view the total number of tables, rows, and storage usage. The response includes both current totals and historical data over time. Use the optional range parameter to specify the time window for historical data: 24h (last 24 hours), 30d (last 30 days), or 90d (last 90 days). If not specified, range defaults to 30 days.",
"demo": "tables-db\/get-usage.md" "demo": "tablesdb\/get-usage.md"
} }
], ],
"auth": { "auth": {

View file

@ -8416,7 +8416,7 @@
} }
}, },
"put": { "put": {
"summary": "Create or update documents", "summary": "Upsert documents",
"operationId": "databasesUpsertDocuments", "operationId": "databasesUpsertDocuments",
"tags": [ "tags": [
"databases" "databases"
@ -8842,7 +8842,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update a document", "summary": "Upsert a document",
"operationId": "databasesUpsertDocument", "operationId": "databasesUpsertDocument",
"tags": [ "tags": [
"databases" "databases"
@ -11576,7 +11576,7 @@
}, },
"method": { "method": {
"type": "string", "type": "string",
"description": "HTTP method of execution. Default value is GET.", "description": "HTTP method of execution. Default value is POST.",
"x-example": "GET", "x-example": "GET",
"enum": [ "enum": [
"GET", "GET",
@ -11584,7 +11584,8 @@
"PUT", "PUT",
"PATCH", "PATCH",
"DELETE", "DELETE",
"OPTIONS" "OPTIONS",
"HEAD"
], ],
"x-enum-name": "ExecutionMethod", "x-enum-name": "ExecutionMethod",
"x-enum-keys": [] "x-enum-keys": []
@ -22852,7 +22853,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "listTables", "method": "listTables",
"group": null, "group": "tables",
"weight": 382, "weight": 382,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -22939,7 +22940,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "createTable", "method": "createTable",
"group": null, "group": "tables",
"weight": 378, "weight": 378,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -23047,7 +23048,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "getTable", "method": "getTable",
"group": null, "group": "tables",
"weight": 379, "weight": 379,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -23120,7 +23121,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "updateTable", "method": "updateTable",
"group": null, "group": "tables",
"weight": 380, "weight": 380,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -23223,7 +23224,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "deleteTable", "method": "deleteTable",
"group": null, "group": "tables",
"weight": 381, "weight": 381,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -26437,7 +26438,7 @@
} }
], ],
"description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/create-row.md" "demo": "tablesdb\/create-row.md"
}, },
{ {
"name": "createRows", "name": "createRows",
@ -26464,7 +26465,7 @@
} }
], ],
"description": "Create new Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create new Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/create-rows.md" "demo": "tablesdb\/create-rows.md"
} }
], ],
"auth": { "auth": {
@ -26541,7 +26542,7 @@
} }
}, },
"put": { "put": {
"summary": "Create or update rows", "summary": "Upsert rows",
"operationId": "tablesDBUpsertRows", "operationId": "tablesDBUpsertRows",
"tags": [ "tags": [
"tablesDB" "tablesDB"
@ -26606,7 +26607,7 @@
} }
], ],
"description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n", "description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n",
"demo": "tables-db\/upsert-rows.md" "demo": "tablesdb\/upsert-rows.md"
} }
], ],
"auth": { "auth": {
@ -26959,7 +26960,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update a row", "summary": "Upsert a row",
"operationId": "tablesDBUpsertRow", "operationId": "tablesDBUpsertRow",
"tags": [ "tags": [
"tablesDB" "tablesDB"
@ -27027,7 +27028,7 @@
} }
], ],
"description": "Create or update a Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create or update a Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/upsert-row.md" "demo": "tablesdb\/upsert-row.md"
} }
], ],
"auth": { "auth": {

View file

@ -5146,7 +5146,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update a document", "summary": "Upsert a document",
"operationId": "databasesUpsertDocument", "operationId": "databasesUpsertDocument",
"tags": [ "tags": [
"databases" "databases"
@ -5881,7 +5881,7 @@
}, },
"method": { "method": {
"type": "string", "type": "string",
"description": "HTTP method of execution. Default value is GET.", "description": "HTTP method of execution. Default value is POST.",
"x-example": "GET", "x-example": "GET",
"enum": [ "enum": [
"GET", "GET",
@ -5889,7 +5889,8 @@
"PUT", "PUT",
"PATCH", "PATCH",
"DELETE", "DELETE",
"OPTIONS" "OPTIONS",
"HEAD"
], ],
"x-enum-name": "ExecutionMethod", "x-enum-name": "ExecutionMethod",
"x-enum-keys": [] "x-enum-keys": []
@ -7624,7 +7625,7 @@
} }
], ],
"description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/create-row.md" "demo": "tablesdb\/create-row.md"
} }
], ],
"auth": { "auth": {
@ -7799,7 +7800,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update a row", "summary": "Upsert a row",
"operationId": "tablesDBUpsertRow", "operationId": "tablesDBUpsertRow",
"tags": [ "tags": [
"tablesDB" "tablesDB"
@ -7866,7 +7867,7 @@
} }
], ],
"description": "Create or update a Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create or update a Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/upsert-row.md" "demo": "tablesdb\/upsert-row.md"
} }
], ],
"auth": { "auth": {

View file

@ -8940,7 +8940,7 @@
} }
}, },
"put": { "put": {
"summary": "Create or update documents", "summary": "Upsert documents",
"operationId": "databasesUpsertDocuments", "operationId": "databasesUpsertDocuments",
"tags": [ "tags": [
"databases" "databases"
@ -9360,7 +9360,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update a document", "summary": "Upsert a document",
"operationId": "databasesUpsertDocument", "operationId": "databasesUpsertDocument",
"tags": [ "tags": [
"databases" "databases"
@ -12791,7 +12791,7 @@
}, },
"method": { "method": {
"type": "string", "type": "string",
"description": "HTTP method of execution. Default value is GET.", "description": "HTTP method of execution. Default value is POST.",
"x-example": "GET", "x-example": "GET",
"enum": [ "enum": [
"GET", "GET",
@ -12799,7 +12799,8 @@
"PUT", "PUT",
"PATCH", "PATCH",
"DELETE", "DELETE",
"OPTIONS" "OPTIONS",
"HEAD"
], ],
"x-enum-name": "ExecutionMethod", "x-enum-name": "ExecutionMethod",
"x-enum-keys": [] "x-enum-keys": []
@ -32188,7 +32189,7 @@
} }
], ],
"description": "List usage metrics and statistics for all databases in the project. You can view the total number of databases, tables, rows, and storage usage. The response includes both current totals and historical data over time. Use the optional range parameter to specify the time window for historical data: 24h (last 24 hours), 30d (last 30 days), or 90d (last 90 days). If not specified, range defaults to 30 days.", "description": "List usage metrics and statistics for all databases in the project. You can view the total number of databases, tables, rows, and storage usage. The response includes both current totals and historical data over time. Use the optional range parameter to specify the time window for historical data: 24h (last 24 hours), 30d (last 30 days), or 90d (last 90 days). If not specified, range defaults to 30 days.",
"demo": "tables-db\/list-usage.md" "demo": "tablesdb\/list-usage.md"
} }
], ],
"auth": { "auth": {
@ -32445,7 +32446,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "listTables", "method": "listTables",
"group": null, "group": "tables",
"weight": 382, "weight": 382,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -32531,7 +32532,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "createTable", "method": "createTable",
"group": null, "group": "tables",
"weight": 378, "weight": 378,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -32638,7 +32639,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "getTable", "method": "getTable",
"group": null, "group": "tables",
"weight": 379, "weight": 379,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -32710,7 +32711,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "updateTable", "method": "updateTable",
"group": null, "group": "tables",
"weight": 380, "weight": 380,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -32812,7 +32813,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "deleteTable", "method": "deleteTable",
"group": null, "group": "tables",
"weight": 381, "weight": 381,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -36081,7 +36082,7 @@
} }
], ],
"description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/create-row.md" "demo": "tablesdb\/create-row.md"
}, },
{ {
"name": "createRows", "name": "createRows",
@ -36107,7 +36108,7 @@
} }
], ],
"description": "Create new Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create new Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/create-rows.md" "demo": "tablesdb\/create-rows.md"
} }
], ],
"auth": { "auth": {
@ -36182,7 +36183,7 @@
} }
}, },
"put": { "put": {
"summary": "Create or update rows", "summary": "Upsert rows",
"operationId": "tablesDBUpsertRows", "operationId": "tablesDBUpsertRows",
"tags": [ "tags": [
"tablesDB" "tablesDB"
@ -36246,7 +36247,7 @@
} }
], ],
"description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n", "description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n",
"demo": "tables-db\/upsert-rows.md" "demo": "tablesdb\/upsert-rows.md"
} }
], ],
"auth": { "auth": {
@ -36594,7 +36595,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update a row", "summary": "Upsert a row",
"operationId": "tablesDBUpsertRow", "operationId": "tablesDBUpsertRow",
"tags": [ "tags": [
"tablesDB" "tablesDB"
@ -36661,7 +36662,7 @@
} }
], ],
"description": "Create or update a Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create or update a Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/upsert-row.md" "demo": "tablesdb\/upsert-row.md"
} }
], ],
"auth": { "auth": {
@ -37409,7 +37410,7 @@
} }
], ],
"description": "Get usage metrics and statistics for a database. You can view the total number of tables, rows, and storage usage. The response includes both current totals and historical data over time. Use the optional range parameter to specify the time window for historical data: 24h (last 24 hours), 30d (last 30 days), or 90d (last 90 days). If not specified, range defaults to 30 days.", "description": "Get usage metrics and statistics for a database. You can view the total number of tables, rows, and storage usage. The response includes both current totals and historical data over time. Use the optional range parameter to specify the time window for historical data: 24h (last 24 hours), 30d (last 30 days), or 90d (last 90 days). If not specified, range defaults to 30 days.",
"demo": "tables-db\/get-usage.md" "demo": "tablesdb\/get-usage.md"
} }
], ],
"auth": { "auth": {

View file

@ -8416,7 +8416,7 @@
} }
}, },
"put": { "put": {
"summary": "Create or update documents", "summary": "Upsert documents",
"operationId": "databasesUpsertDocuments", "operationId": "databasesUpsertDocuments",
"tags": [ "tags": [
"databases" "databases"
@ -8842,7 +8842,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update a document", "summary": "Upsert a document",
"operationId": "databasesUpsertDocument", "operationId": "databasesUpsertDocument",
"tags": [ "tags": [
"databases" "databases"
@ -11576,7 +11576,7 @@
}, },
"method": { "method": {
"type": "string", "type": "string",
"description": "HTTP method of execution. Default value is GET.", "description": "HTTP method of execution. Default value is POST.",
"x-example": "GET", "x-example": "GET",
"enum": [ "enum": [
"GET", "GET",
@ -11584,7 +11584,8 @@
"PUT", "PUT",
"PATCH", "PATCH",
"DELETE", "DELETE",
"OPTIONS" "OPTIONS",
"HEAD"
], ],
"x-enum-name": "ExecutionMethod", "x-enum-name": "ExecutionMethod",
"x-enum-keys": [] "x-enum-keys": []
@ -22852,7 +22853,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "listTables", "method": "listTables",
"group": null, "group": "tables",
"weight": 382, "weight": 382,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -22939,7 +22940,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "createTable", "method": "createTable",
"group": null, "group": "tables",
"weight": 378, "weight": 378,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -23047,7 +23048,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "getTable", "method": "getTable",
"group": null, "group": "tables",
"weight": 379, "weight": 379,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -23120,7 +23121,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "updateTable", "method": "updateTable",
"group": null, "group": "tables",
"weight": 380, "weight": 380,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -23223,7 +23224,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "deleteTable", "method": "deleteTable",
"group": null, "group": "tables",
"weight": 381, "weight": 381,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -26437,7 +26438,7 @@
} }
], ],
"description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/create-row.md" "demo": "tablesdb\/create-row.md"
}, },
{ {
"name": "createRows", "name": "createRows",
@ -26464,7 +26465,7 @@
} }
], ],
"description": "Create new Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create new Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/create-rows.md" "demo": "tablesdb\/create-rows.md"
} }
], ],
"auth": { "auth": {
@ -26541,7 +26542,7 @@
} }
}, },
"put": { "put": {
"summary": "Create or update rows", "summary": "Upsert rows",
"operationId": "tablesDBUpsertRows", "operationId": "tablesDBUpsertRows",
"tags": [ "tags": [
"tablesDB" "tablesDB"
@ -26606,7 +26607,7 @@
} }
], ],
"description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n", "description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n",
"demo": "tables-db\/upsert-rows.md" "demo": "tablesdb\/upsert-rows.md"
} }
], ],
"auth": { "auth": {
@ -26959,7 +26960,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update a row", "summary": "Upsert a row",
"operationId": "tablesDBUpsertRow", "operationId": "tablesDBUpsertRow",
"tags": [ "tags": [
"tablesDB" "tablesDB"
@ -27027,7 +27028,7 @@
} }
], ],
"description": "Create or update a Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create or update a Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/upsert-row.md" "demo": "tablesdb\/upsert-row.md"
} }
], ],
"auth": { "auth": {

View file

@ -5273,7 +5273,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update a document", "summary": "Upsert a document",
"operationId": "databasesUpsertDocument", "operationId": "databasesUpsertDocument",
"consumes": [ "consumes": [
"application\/json" "application\/json"
@ -5978,7 +5978,7 @@
}, },
"method": { "method": {
"type": "string", "type": "string",
"description": "HTTP method of execution. Default value is GET.", "description": "HTTP method of execution. Default value is POST.",
"default": "POST", "default": "POST",
"x-example": "GET", "x-example": "GET",
"enum": [ "enum": [
@ -5987,7 +5987,8 @@
"PUT", "PUT",
"PATCH", "PATCH",
"DELETE", "DELETE",
"OPTIONS" "OPTIONS",
"HEAD"
], ],
"x-enum-name": "ExecutionMethod", "x-enum-name": "ExecutionMethod",
"x-enum-keys": [] "x-enum-keys": []
@ -7701,7 +7702,7 @@
} }
], ],
"description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/create-row.md" "demo": "tablesdb\/create-row.md"
} }
], ],
"auth": { "auth": {
@ -7866,7 +7867,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update a row", "summary": "Upsert a row",
"operationId": "tablesDBUpsertRow", "operationId": "tablesDBUpsertRow",
"consumes": [ "consumes": [
"application\/json" "application\/json"
@ -7934,7 +7935,7 @@
} }
], ],
"description": "Create or update a Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create or update a Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/upsert-row.md" "demo": "tablesdb\/upsert-row.md"
} }
], ],
"auth": { "auth": {

View file

@ -9058,7 +9058,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update documents", "summary": "Upsert documents",
"operationId": "databasesUpsertDocuments", "operationId": "databasesUpsertDocuments",
"consumes": [ "consumes": [
"application\/json" "application\/json"
@ -9462,7 +9462,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update a document", "summary": "Upsert a document",
"operationId": "databasesUpsertDocument", "operationId": "databasesUpsertDocument",
"consumes": [ "consumes": [
"application\/json" "application\/json"
@ -12836,7 +12836,7 @@
}, },
"method": { "method": {
"type": "string", "type": "string",
"description": "HTTP method of execution. Default value is GET.", "description": "HTTP method of execution. Default value is POST.",
"default": "POST", "default": "POST",
"x-example": "GET", "x-example": "GET",
"enum": [ "enum": [
@ -12845,7 +12845,8 @@
"PUT", "PUT",
"PATCH", "PATCH",
"DELETE", "DELETE",
"OPTIONS" "OPTIONS",
"HEAD"
], ],
"x-enum-name": "ExecutionMethod", "x-enum-name": "ExecutionMethod",
"x-enum-keys": [] "x-enum-keys": []
@ -32372,7 +32373,7 @@
} }
], ],
"description": "List usage metrics and statistics for all databases in the project. You can view the total number of databases, tables, rows, and storage usage. The response includes both current totals and historical data over time. Use the optional range parameter to specify the time window for historical data: 24h (last 24 hours), 30d (last 30 days), or 90d (last 90 days). If not specified, range defaults to 30 days.", "description": "List usage metrics and statistics for all databases in the project. You can view the total number of databases, tables, rows, and storage usage. The response includes both current totals and historical data over time. Use the optional range parameter to specify the time window for historical data: 24h (last 24 hours), 30d (last 30 days), or 90d (last 90 days). If not specified, range defaults to 30 days.",
"demo": "tables-db\/list-usage.md" "demo": "tablesdb\/list-usage.md"
} }
], ],
"auth": { "auth": {
@ -32627,7 +32628,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "listTables", "method": "listTables",
"group": null, "group": "tables",
"weight": 382, "weight": 382,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -32710,7 +32711,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "createTable", "method": "createTable",
"group": null, "group": "tables",
"weight": 378, "weight": 378,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -32818,7 +32819,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "getTable", "method": "getTable",
"group": null, "group": "tables",
"weight": 379, "weight": 379,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -32888,7 +32889,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "updateTable", "method": "updateTable",
"group": null, "group": "tables",
"weight": 380, "weight": 380,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -32992,7 +32993,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "deleteTable", "method": "deleteTable",
"group": null, "group": "tables",
"weight": 381, "weight": 381,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -36206,7 +36207,7 @@
} }
], ],
"description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/create-row.md" "demo": "tablesdb\/create-row.md"
}, },
{ {
"name": "createRows", "name": "createRows",
@ -36232,7 +36233,7 @@
} }
], ],
"description": "Create new Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create new Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/create-rows.md" "demo": "tablesdb\/create-rows.md"
} }
], ],
"auth": { "auth": {
@ -36305,7 +36306,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update rows", "summary": "Upsert rows",
"operationId": "tablesDBUpsertRows", "operationId": "tablesDBUpsertRows",
"consumes": [ "consumes": [
"application\/json" "application\/json"
@ -36371,7 +36372,7 @@
} }
], ],
"description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n", "description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n",
"demo": "tables-db\/upsert-rows.md" "demo": "tablesdb\/upsert-rows.md"
} }
], ],
"auth": { "auth": {
@ -36701,7 +36702,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update a row", "summary": "Upsert a row",
"operationId": "tablesDBUpsertRow", "operationId": "tablesDBUpsertRow",
"consumes": [ "consumes": [
"application\/json" "application\/json"
@ -36769,7 +36770,7 @@
} }
], ],
"description": "Create or update a Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create or update a Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/upsert-row.md" "demo": "tablesdb\/upsert-row.md"
} }
], ],
"auth": { "auth": {
@ -37476,7 +37477,7 @@
} }
], ],
"description": "Get usage metrics and statistics for a database. You can view the total number of tables, rows, and storage usage. The response includes both current totals and historical data over time. Use the optional range parameter to specify the time window for historical data: 24h (last 24 hours), 30d (last 30 days), or 90d (last 90 days). If not specified, range defaults to 30 days.", "description": "Get usage metrics and statistics for a database. You can view the total number of tables, rows, and storage usage. The response includes both current totals and historical data over time. Use the optional range parameter to specify the time window for historical data: 24h (last 24 hours), 30d (last 30 days), or 90d (last 90 days). If not specified, range defaults to 30 days.",
"demo": "tables-db\/get-usage.md" "demo": "tablesdb\/get-usage.md"
} }
], ],
"auth": { "auth": {

View file

@ -8524,7 +8524,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update documents", "summary": "Upsert documents",
"operationId": "databasesUpsertDocuments", "operationId": "databasesUpsertDocuments",
"consumes": [ "consumes": [
"application\/json" "application\/json"
@ -8934,7 +8934,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update a document", "summary": "Upsert a document",
"operationId": "databasesUpsertDocument", "operationId": "databasesUpsertDocument",
"consumes": [ "consumes": [
"application\/json" "application\/json"
@ -11646,7 +11646,7 @@
}, },
"method": { "method": {
"type": "string", "type": "string",
"description": "HTTP method of execution. Default value is GET.", "description": "HTTP method of execution. Default value is POST.",
"default": "POST", "default": "POST",
"x-example": "GET", "x-example": "GET",
"enum": [ "enum": [
@ -11655,7 +11655,8 @@
"PUT", "PUT",
"PATCH", "PATCH",
"DELETE", "DELETE",
"OPTIONS" "OPTIONS",
"HEAD"
], ],
"x-enum-name": "ExecutionMethod", "x-enum-name": "ExecutionMethod",
"x-enum-keys": [] "x-enum-keys": []
@ -23089,7 +23090,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "listTables", "method": "listTables",
"group": null, "group": "tables",
"weight": 382, "weight": 382,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -23173,7 +23174,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "createTable", "method": "createTable",
"group": null, "group": "tables",
"weight": 378, "weight": 378,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -23282,7 +23283,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "getTable", "method": "getTable",
"group": null, "group": "tables",
"weight": 379, "weight": 379,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -23353,7 +23354,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "updateTable", "method": "updateTable",
"group": null, "group": "tables",
"weight": 380, "weight": 380,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -23458,7 +23459,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "deleteTable", "method": "deleteTable",
"group": null, "group": "tables",
"weight": 381, "weight": 381,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -26622,7 +26623,7 @@
} }
], ],
"description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/create-row.md" "demo": "tablesdb\/create-row.md"
}, },
{ {
"name": "createRows", "name": "createRows",
@ -26649,7 +26650,7 @@
} }
], ],
"description": "Create new Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create new Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/create-rows.md" "demo": "tablesdb\/create-rows.md"
} }
], ],
"auth": { "auth": {
@ -26724,7 +26725,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update rows", "summary": "Upsert rows",
"operationId": "tablesDBUpsertRows", "operationId": "tablesDBUpsertRows",
"consumes": [ "consumes": [
"application\/json" "application\/json"
@ -26791,7 +26792,7 @@
} }
], ],
"description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n", "description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n",
"demo": "tables-db\/upsert-rows.md" "demo": "tablesdb\/upsert-rows.md"
} }
], ],
"auth": { "auth": {
@ -27126,7 +27127,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update a row", "summary": "Upsert a row",
"operationId": "tablesDBUpsertRow", "operationId": "tablesDBUpsertRow",
"consumes": [ "consumes": [
"application\/json" "application\/json"
@ -27195,7 +27196,7 @@
} }
], ],
"description": "Create or update a Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create or update a Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/upsert-row.md" "demo": "tablesdb\/upsert-row.md"
} }
], ],
"auth": { "auth": {

View file

@ -5273,7 +5273,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update a document", "summary": "Upsert a document",
"operationId": "databasesUpsertDocument", "operationId": "databasesUpsertDocument",
"consumes": [ "consumes": [
"application\/json" "application\/json"
@ -5978,7 +5978,7 @@
}, },
"method": { "method": {
"type": "string", "type": "string",
"description": "HTTP method of execution. Default value is GET.", "description": "HTTP method of execution. Default value is POST.",
"default": "POST", "default": "POST",
"x-example": "GET", "x-example": "GET",
"enum": [ "enum": [
@ -5987,7 +5987,8 @@
"PUT", "PUT",
"PATCH", "PATCH",
"DELETE", "DELETE",
"OPTIONS" "OPTIONS",
"HEAD"
], ],
"x-enum-name": "ExecutionMethod", "x-enum-name": "ExecutionMethod",
"x-enum-keys": [] "x-enum-keys": []
@ -7701,7 +7702,7 @@
} }
], ],
"description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/create-row.md" "demo": "tablesdb\/create-row.md"
} }
], ],
"auth": { "auth": {
@ -7866,7 +7867,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update a row", "summary": "Upsert a row",
"operationId": "tablesDBUpsertRow", "operationId": "tablesDBUpsertRow",
"consumes": [ "consumes": [
"application\/json" "application\/json"
@ -7934,7 +7935,7 @@
} }
], ],
"description": "Create or update a Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create or update a Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/upsert-row.md" "demo": "tablesdb\/upsert-row.md"
} }
], ],
"auth": { "auth": {

View file

@ -9058,7 +9058,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update documents", "summary": "Upsert documents",
"operationId": "databasesUpsertDocuments", "operationId": "databasesUpsertDocuments",
"consumes": [ "consumes": [
"application\/json" "application\/json"
@ -9462,7 +9462,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update a document", "summary": "Upsert a document",
"operationId": "databasesUpsertDocument", "operationId": "databasesUpsertDocument",
"consumes": [ "consumes": [
"application\/json" "application\/json"
@ -12836,7 +12836,7 @@
}, },
"method": { "method": {
"type": "string", "type": "string",
"description": "HTTP method of execution. Default value is GET.", "description": "HTTP method of execution. Default value is POST.",
"default": "POST", "default": "POST",
"x-example": "GET", "x-example": "GET",
"enum": [ "enum": [
@ -12845,7 +12845,8 @@
"PUT", "PUT",
"PATCH", "PATCH",
"DELETE", "DELETE",
"OPTIONS" "OPTIONS",
"HEAD"
], ],
"x-enum-name": "ExecutionMethod", "x-enum-name": "ExecutionMethod",
"x-enum-keys": [] "x-enum-keys": []
@ -32372,7 +32373,7 @@
} }
], ],
"description": "List usage metrics and statistics for all databases in the project. You can view the total number of databases, tables, rows, and storage usage. The response includes both current totals and historical data over time. Use the optional range parameter to specify the time window for historical data: 24h (last 24 hours), 30d (last 30 days), or 90d (last 90 days). If not specified, range defaults to 30 days.", "description": "List usage metrics and statistics for all databases in the project. You can view the total number of databases, tables, rows, and storage usage. The response includes both current totals and historical data over time. Use the optional range parameter to specify the time window for historical data: 24h (last 24 hours), 30d (last 30 days), or 90d (last 90 days). If not specified, range defaults to 30 days.",
"demo": "tables-db\/list-usage.md" "demo": "tablesdb\/list-usage.md"
} }
], ],
"auth": { "auth": {
@ -32627,7 +32628,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "listTables", "method": "listTables",
"group": null, "group": "tables",
"weight": 382, "weight": 382,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -32710,7 +32711,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "createTable", "method": "createTable",
"group": null, "group": "tables",
"weight": 378, "weight": 378,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -32818,7 +32819,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "getTable", "method": "getTable",
"group": null, "group": "tables",
"weight": 379, "weight": 379,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -32888,7 +32889,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "updateTable", "method": "updateTable",
"group": null, "group": "tables",
"weight": 380, "weight": 380,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -32992,7 +32993,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "deleteTable", "method": "deleteTable",
"group": null, "group": "tables",
"weight": 381, "weight": 381,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -36206,7 +36207,7 @@
} }
], ],
"description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/create-row.md" "demo": "tablesdb\/create-row.md"
}, },
{ {
"name": "createRows", "name": "createRows",
@ -36232,7 +36233,7 @@
} }
], ],
"description": "Create new Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create new Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/create-rows.md" "demo": "tablesdb\/create-rows.md"
} }
], ],
"auth": { "auth": {
@ -36305,7 +36306,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update rows", "summary": "Upsert rows",
"operationId": "tablesDBUpsertRows", "operationId": "tablesDBUpsertRows",
"consumes": [ "consumes": [
"application\/json" "application\/json"
@ -36371,7 +36372,7 @@
} }
], ],
"description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n", "description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n",
"demo": "tables-db\/upsert-rows.md" "demo": "tablesdb\/upsert-rows.md"
} }
], ],
"auth": { "auth": {
@ -36701,7 +36702,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update a row", "summary": "Upsert a row",
"operationId": "tablesDBUpsertRow", "operationId": "tablesDBUpsertRow",
"consumes": [ "consumes": [
"application\/json" "application\/json"
@ -36769,7 +36770,7 @@
} }
], ],
"description": "Create or update a Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create or update a Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/upsert-row.md" "demo": "tablesdb\/upsert-row.md"
} }
], ],
"auth": { "auth": {
@ -37476,7 +37477,7 @@
} }
], ],
"description": "Get usage metrics and statistics for a database. You can view the total number of tables, rows, and storage usage. The response includes both current totals and historical data over time. Use the optional range parameter to specify the time window for historical data: 24h (last 24 hours), 30d (last 30 days), or 90d (last 90 days). If not specified, range defaults to 30 days.", "description": "Get usage metrics and statistics for a database. You can view the total number of tables, rows, and storage usage. The response includes both current totals and historical data over time. Use the optional range parameter to specify the time window for historical data: 24h (last 24 hours), 30d (last 30 days), or 90d (last 90 days). If not specified, range defaults to 30 days.",
"demo": "tables-db\/get-usage.md" "demo": "tablesdb\/get-usage.md"
} }
], ],
"auth": { "auth": {

View file

@ -8524,7 +8524,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update documents", "summary": "Upsert documents",
"operationId": "databasesUpsertDocuments", "operationId": "databasesUpsertDocuments",
"consumes": [ "consumes": [
"application\/json" "application\/json"
@ -8934,7 +8934,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update a document", "summary": "Upsert a document",
"operationId": "databasesUpsertDocument", "operationId": "databasesUpsertDocument",
"consumes": [ "consumes": [
"application\/json" "application\/json"
@ -11646,7 +11646,7 @@
}, },
"method": { "method": {
"type": "string", "type": "string",
"description": "HTTP method of execution. Default value is GET.", "description": "HTTP method of execution. Default value is POST.",
"default": "POST", "default": "POST",
"x-example": "GET", "x-example": "GET",
"enum": [ "enum": [
@ -11655,7 +11655,8 @@
"PUT", "PUT",
"PATCH", "PATCH",
"DELETE", "DELETE",
"OPTIONS" "OPTIONS",
"HEAD"
], ],
"x-enum-name": "ExecutionMethod", "x-enum-name": "ExecutionMethod",
"x-enum-keys": [] "x-enum-keys": []
@ -23089,7 +23090,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "listTables", "method": "listTables",
"group": null, "group": "tables",
"weight": 382, "weight": 382,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -23173,7 +23174,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "createTable", "method": "createTable",
"group": null, "group": "tables",
"weight": 378, "weight": 378,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -23282,7 +23283,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "getTable", "method": "getTable",
"group": null, "group": "tables",
"weight": 379, "weight": 379,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -23353,7 +23354,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "updateTable", "method": "updateTable",
"group": null, "group": "tables",
"weight": 380, "weight": 380,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -23458,7 +23459,7 @@
"deprecated": false, "deprecated": false,
"x-appwrite": { "x-appwrite": {
"method": "deleteTable", "method": "deleteTable",
"group": null, "group": "tables",
"weight": 381, "weight": 381,
"cookies": false, "cookies": false,
"type": "", "type": "",
@ -26622,7 +26623,7 @@
} }
], ],
"description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/create-row.md" "demo": "tablesdb\/create-row.md"
}, },
{ {
"name": "createRows", "name": "createRows",
@ -26649,7 +26650,7 @@
} }
], ],
"description": "Create new Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create new Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/create-rows.md" "demo": "tablesdb\/create-rows.md"
} }
], ],
"auth": { "auth": {
@ -26724,7 +26725,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update rows", "summary": "Upsert rows",
"operationId": "tablesDBUpsertRows", "operationId": "tablesDBUpsertRows",
"consumes": [ "consumes": [
"application\/json" "application\/json"
@ -26791,7 +26792,7 @@
} }
], ],
"description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n", "description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n",
"demo": "tables-db\/upsert-rows.md" "demo": "tablesdb\/upsert-rows.md"
} }
], ],
"auth": { "auth": {
@ -27126,7 +27127,7 @@
] ]
}, },
"put": { "put": {
"summary": "Create or update a row", "summary": "Upsert a row",
"operationId": "tablesDBUpsertRow", "operationId": "tablesDBUpsertRow",
"consumes": [ "consumes": [
"application\/json" "application\/json"
@ -27195,7 +27196,7 @@
} }
], ],
"description": "Create or update a Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", "description": "Create or update a Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.",
"demo": "tables-db\/upsert-row.md" "demo": "tablesdb\/upsert-row.md"
} }
], ],
"auth": { "auth": {

View file

@ -810,12 +810,6 @@ App::shutdown()
} }
if (!empty($queueForDatabase->getType())) { if (!empty($queueForDatabase->getType())) {
Console::info("Triggering database event: \n" . \json_encode([
'projectId' => $project->getId(),
'databaseId' => $queueForDatabase->getDatabase()?->getId(),
'tableId' => $queueForDatabase->getTable()?->getId() ?? $queueForDatabase->getCollection()?->getId(),
'rowId' => $queueForDatabase->getRow()?->getId() ?? $queueForDatabase->getDocument()?->getId(),
]));
$queueForDatabase->trigger(); $queueForDatabase->trigger();
} }

12
composer.lock generated
View file

@ -3638,16 +3638,16 @@
}, },
{ {
"name": "utopia-php/database", "name": "utopia-php/database",
"version": "1.3.0", "version": "1.2.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/utopia-php/database.git", "url": "https://github.com/utopia-php/database.git",
"reference": "06ffa2b1c977f5451200a1ee82a500be1390a789" "reference": "8a536fead840d9da6ee819fe6b80e0f047997f69"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/utopia-php/database/zipball/06ffa2b1c977f5451200a1ee82a500be1390a789", "url": "https://api.github.com/repos/utopia-php/database/zipball/8a536fead840d9da6ee819fe6b80e0f047997f69",
"reference": "06ffa2b1c977f5451200a1ee82a500be1390a789", "reference": "8a536fead840d9da6ee819fe6b80e0f047997f69",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3688,9 +3688,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/utopia-php/database/issues", "issues": "https://github.com/utopia-php/database/issues",
"source": "https://github.com/utopia-php/database/tree/1.3.0" "source": "https://github.com/utopia-php/database/tree/1.2.3"
}, },
"time": "2025-09-02T16:20:02+00:00" "time": "2025-08-27T11:47:04+00:00"
}, },
{ {
"name": "utopia-php/detector", "name": "utopia-php/detector",

View file

@ -85,4 +85,11 @@ class StatsUsage extends Event
}), }),
]; ];
} }
public function reset(): Event
{
$this->metrics = [];
parent::reset();
return $this;
}
} }

View file

@ -39,7 +39,7 @@ class Upsert extends Action
$this $this
->setHttpMethod(self::HTTP_REQUEST_METHOD_PUT) ->setHttpMethod(self::HTTP_REQUEST_METHOD_PUT)
->setHttpPath('/v1/databases/:databaseId/collections/:collectionId/documents') ->setHttpPath('/v1/databases/:databaseId/collections/:collectionId/documents')
->desc('Create or update documents') ->desc('Upsert documents')
->groups(['api', 'database']) ->groups(['api', 'database'])
->label('scope', 'documents.write') ->label('scope', 'documents.write')
->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('resourceType', RESOURCE_TYPE_DATABASES)

View file

@ -45,7 +45,7 @@ class Upsert extends Action
$this $this
->setHttpMethod(self::HTTP_REQUEST_METHOD_PUT) ->setHttpMethod(self::HTTP_REQUEST_METHOD_PUT)
->setHttpPath('/v1/databases/:databaseId/collections/:collectionId/documents/:documentId') ->setHttpPath('/v1/databases/:databaseId/collections/:collectionId/documents/:documentId')
->desc('Create or update a document') ->desc('Upsert a document')
->groups(['api', 'database']) ->groups(['api', 'database'])
->label('event', 'databases.[databaseId].collections.[collectionId].documents.[documentId].upsert') ->label('event', 'databases.[databaseId].collections.[collectionId].documents.[documentId].upsert')
->label('scope', 'documents.write') ->label('scope', 'documents.write')

View file

@ -41,7 +41,7 @@ class Create extends CollectionCreate
->label('audits.resource', 'database/{request.databaseId}/table/{response.$id}') ->label('audits.resource', 'database/{request.databaseId}/table/{response.$id}')
->label('sdk', new Method( ->label('sdk', new Method(
namespace: $this->getSdkNamespace(), namespace: $this->getSdkNamespace(),
group: null, group: 'tables',
name: self::getName(), name: self::getName(),
description: '/docs/references/tablesdb/create-table.md', description: '/docs/references/tablesdb/create-table.md',
auth: [AuthType::KEY], auth: [AuthType::KEY],

View file

@ -37,7 +37,7 @@ class Delete extends CollectionDelete
->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}')
->label('sdk', new Method( ->label('sdk', new Method(
namespace: $this->getSdkNamespace(), namespace: $this->getSdkNamespace(),
group: null, group: 'tables',
name: self::getName(), name: self::getName(),
description: '/docs/references/tablesdb/delete-table.md', description: '/docs/references/tablesdb/delete-table.md',
auth: [AuthType::KEY], auth: [AuthType::KEY],

View file

@ -34,7 +34,7 @@ class Get extends CollectionGet
->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('resourceType', RESOURCE_TYPE_DATABASES)
->label('sdk', new Method( ->label('sdk', new Method(
namespace: $this->getSdkNamespace(), namespace: $this->getSdkNamespace(),
group: null, group: 'tables',
name: self::getName(), name: self::getName(),
description: '/docs/references/tablesdb/get-table.md', description: '/docs/references/tablesdb/get-table.md',
auth: [AuthType::KEY], auth: [AuthType::KEY],

View file

@ -30,7 +30,7 @@ class Upsert extends DocumentsUpsert
$this $this
->setHttpMethod(self::HTTP_REQUEST_METHOD_PUT) ->setHttpMethod(self::HTTP_REQUEST_METHOD_PUT)
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/rows') ->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/rows')
->desc('Create or update rows') ->desc('Upsert rows')
->groups(['api', 'database']) ->groups(['api', 'database'])
->label('scope', ['rows.write', 'documents.write']) ->label('scope', ['rows.write', 'documents.write'])
->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('resourceType', RESOURCE_TYPE_DATABASES)

View file

@ -31,7 +31,7 @@ class Upsert extends DocumentUpsert
$this $this
->setHttpMethod(self::HTTP_REQUEST_METHOD_PUT) ->setHttpMethod(self::HTTP_REQUEST_METHOD_PUT)
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/rows/:rowId') ->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/rows/:rowId')
->desc('Create or update a row') ->desc('Upsert a row')
->groups(['api', 'database']) ->groups(['api', 'database'])
->label('event', 'databases.[databaseId].tables.[tableId].rows.[rowId].upsert') ->label('event', 'databases.[databaseId].tables.[tableId].rows.[rowId].upsert')
->label('scope', ['rows.write', 'documents.write']) ->label('scope', ['rows.write', 'documents.write'])

View file

@ -40,7 +40,7 @@ class Update extends CollectionUpdate
->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}')
->label('sdk', new Method( ->label('sdk', new Method(
namespace: $this->getSdkNamespace(), namespace: $this->getSdkNamespace(),
group: null, group: 'tables',
name: self::getName(), name: self::getName(),
description: '/docs/references/tablesdb/update-table.md', description: '/docs/references/tablesdb/update-table.md',
auth: [AuthType::KEY], auth: [AuthType::KEY],

View file

@ -36,7 +36,7 @@ class XList extends CollectionXList
->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('resourceType', RESOURCE_TYPE_DATABASES)
->label('sdk', new Method( ->label('sdk', new Method(
namespace: $this->getSdkNamespace(), namespace: $this->getSdkNamespace(),
group: null, group: 'tables',
name: self::getName(), name: self::getName(),
description: '/docs/references/tablesdb/list-tables.md', description: '/docs/references/tablesdb/list-tables.md',
auth: [AuthType::KEY], auth: [AuthType::KEY],

View file

@ -64,14 +64,6 @@ class Databases extends Action
$collection = new Document($payload['table'] ?? $payload['collection'] ?? []); $collection = new Document($payload['table'] ?? $payload['collection'] ?? []);
$database = new Document($payload['database'] ?? []); $database = new Document($payload['database'] ?? []);
Console::info("Processing database operation: \n" . \json_encode([
'type' => $type,
'projectId' => $project->getId(),
'databaseId' => $database->getId(),
'collectionId' => $collection->getId(),
'documentId' => $document->getId(),
], JSON_PRETTY_PRINT));
$log->addTag('projectId', $project->getId()); $log->addTag('projectId', $project->getId());
$log->addTag('type', $type); $log->addTag('type', $type);

View file

@ -80,7 +80,7 @@ class Create extends Base
->param('body', '', new Text(10485760, 0), 'HTTP body of execution. Default value is empty string.', true) ->param('body', '', new Text(10485760, 0), 'HTTP body of execution. Default value is empty string.', true)
->param('async', false, new Boolean(true), 'Execute code in the background. Default value is false.', true) ->param('async', false, new Boolean(true), 'Execute code in the background. Default value is false.', true)
->param('path', '/', new Text(2048), 'HTTP path of execution. Path can include query params. Default value is /', true) ->param('path', '/', new Text(2048), 'HTTP path of execution. Path can include query params. Default value is /', true)
->param('method', 'POST', new Whitelist(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'], true), 'HTTP method of execution. Default value is POST.', true) ->param('method', 'POST', new Whitelist(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS', 'HEAD'], true), 'HTTP method of execution. Default value is POST.', true)
->param('headers', [], new AnyOf([new Assoc(), new Text(65535)], AnyOf::TYPE_MIXED), 'HTTP headers of execution. Defaults to empty.', true) ->param('headers', [], new AnyOf([new Assoc(), new Text(65535)], AnyOf::TYPE_MIXED), 'HTTP headers of execution. Defaults to empty.', true)
->param('scheduledAt', null, new Text(100), 'Scheduled execution time in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future with precision in minutes.', true) ->param('scheduledAt', null, new Text(100), 'Scheduled execution time in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future with precision in minutes.', true)
->inject('response') ->inject('response')

View file

@ -4,6 +4,7 @@ namespace Appwrite\Platform\Workers;
use Ahc\Jwt\JWT; use Ahc\Jwt\JWT;
use Appwrite\Event\Realtime; use Appwrite\Event\Realtime;
use Appwrite\Event\StatsUsage;
use Exception; use Exception;
use Utopia\CLI\Console; use Utopia\CLI\Console;
use Utopia\Config\Config; use Utopia\Config\Config;
@ -13,9 +14,14 @@ use Utopia\Database\Exception\Authorization;
use Utopia\Database\Exception\Conflict; use Utopia\Database\Exception\Conflict;
use Utopia\Database\Exception\Restricted; use Utopia\Database\Exception\Restricted;
use Utopia\Database\Exception\Structure; use Utopia\Database\Exception\Structure;
use Utopia\Database\Validator\Authorization as AuthorizationValidator;
use Utopia\Migration\Destination; use Utopia\Migration\Destination;
use Utopia\Migration\Destinations\Appwrite as DestinationAppwrite; use Utopia\Migration\Destinations\Appwrite as DestinationAppwrite;
use Utopia\Migration\Exception as MigrationException; use Utopia\Migration\Exception as MigrationException;
use Utopia\Migration\Resource;
use Utopia\Migration\Resources\Database\Database as ResourceDatabase;
use Utopia\Migration\Resources\Database\Row as ResourceRow;
use Utopia\Migration\Resources\Database\Table as ResourceTable;
use Utopia\Migration\Source; use Utopia\Migration\Source;
use Utopia\Migration\Sources\Appwrite as SourceAppwrite; use Utopia\Migration\Sources\Appwrite as SourceAppwrite;
use Utopia\Migration\Sources\CSV; use Utopia\Migration\Sources\CSV;
@ -45,6 +51,7 @@ class Migrations extends Action
*/ */
protected array $sourceReport = []; protected array $sourceReport = [];
private string $source;
/** /**
* @var callable * @var callable
*/ */
@ -69,13 +76,14 @@ class Migrations extends Action
->inject('logError') ->inject('logError')
->inject('queueForRealtime') ->inject('queueForRealtime')
->inject('deviceForImports') ->inject('deviceForImports')
->inject('queueForStatsUsage')
->callback($this->action(...)); ->callback($this->action(...));
} }
/** /**
* @throws Exception * @throws Exception
*/ */
public function action(Message $message, Document $project, Database $dbForProject, Database $dbForPlatform, callable $logError, Realtime $queueForRealtime, Device $deviceForImports): void public function action(Message $message, Document $project, Database $dbForProject, Database $dbForPlatform, callable $logError, Realtime $queueForRealtime, Device $deviceForImports, StatsUsage $queueForStatsUsage): void
{ {
$payload = $message->getPayload() ?? []; $payload = $message->getPayload() ?? [];
$this->deviceForImports = $deviceForImports; $this->deviceForImports = $deviceForImports;
@ -103,7 +111,7 @@ class Migrations extends Action
return; return;
} }
$this->processMigration($migration, $queueForRealtime); $this->processMigration($migration, $queueForRealtime, $queueForStatsUsage);
} }
/** /**
@ -267,7 +275,7 @@ class Migrations extends Action
* @throws \Utopia\Database\Exception * @throws \Utopia\Database\Exception
* @throws Exception * @throws Exception
*/ */
protected function processMigration(Document $migration, Realtime $queueForRealtime): void protected function processMigration(Document $migration, Realtime $queueForRealtime, StatsUsage $queueForStatsUsage): void
{ {
$project = $this->project; $project = $this->project;
$projectDocument = $this->dbForPlatform->getDocument('projects', $project->getId()); $projectDocument = $this->dbForPlatform->getDocument('projects', $project->getId());
@ -301,6 +309,7 @@ class Migrations extends Action
$destination $destination
); );
$aggregatedResources = [];
/** Start Transfer */ /** Start Transfer */
if (empty($source->getErrors())) { if (empty($source->getErrors())) {
$migration->setAttribute('stage', 'migrating'); $migration->setAttribute('stage', 'migrating');
@ -308,9 +317,40 @@ class Migrations extends Action
$transfer->run( $transfer->run(
$migration->getAttribute('resources'), $migration->getAttribute('resources'),
function () use ($migration, $transfer, $projectDocument, $queueForRealtime) { function ($resources) use ($migration, $transfer, $projectDocument, $queueForRealtime, &$aggregatedResources) {
$migration->setAttribute('resourceData', json_encode($transfer->getCache())); $migration->setAttribute('resourceData', json_encode($transfer->getCache()));
$migration->setAttribute('statusCounters', json_encode($transfer->getStatusCounters())); $migration->setAttribute('statusCounters', json_encode($transfer->getStatusCounters()));
if (!empty($resources)) {
/**
* @var Resource $resource
*/
$resource = $resources[0];
$count = count($resources);
$databaseId = null;
$tableId = null;
switch ($resource->getName()) {
case ResourceTable::getName():
/** @var ResourceTable $resource */
$databaseId = $resource->getDatabase()->getSequence();
break;
case ResourceRow::getName():
/** @var ResourceRow $resource */
$table = $resource->getTable();
$databaseId = $table->getDatabase()->getSequence();
$tableId = $table->getSequence();
break;
default:
break;
}
$aggregatedResources[] = [
'name' => $resource->getName(),
'count' => $count,
'databaseId' => $databaseId,
'tableId' => $tableId
];
}
$this->updateMigrationDocument($migration, $projectDocument, $queueForRealtime); $this->updateMigrationDocument($migration, $projectDocument, $queueForRealtime);
}, },
$migration->getAttribute('resourceId'), $migration->getAttribute('resourceId'),
@ -412,9 +452,71 @@ class Migrations extends Action
} }
if ($migration->getAttribute('status', '') === 'completed') { if ($migration->getAttribute('status', '') === 'completed') {
foreach ($aggregatedResources as $resource) {
$this->processMigrationResourceStats(
$resource,
$queueForStatsUsage,
$projectDocument,
$migration->getAttribute('source'),
$migration->getAttribute('resourceId')
);
}
$destination?->success(); $destination?->success();
$source?->success(); $source?->success();
} }
} }
} }
private function processMigrationResourceStats(array $resources, StatsUsage $queueForStatsUsage, Document $projectDocument, string $source, ?string $resourceId)
{
$resourceName = $resources['name'];
$count = $resources['count'];
$databaseInternalId = $resources['databaseId'];
$tableInternalId = $resources['tableId'];
if ($source === CSV::getName()) {
[$databaseId, $tableId] = explode(':', $resourceId);
$database = AuthorizationValidator::skip(fn () => $this->dbForProject->getDocument('databases', $databaseId));
$table = AuthorizationValidator::skip(fn () => $this->dbForProject->getDocument('database_' . $database->getSequence(), $tableId));
$databaseInternalId = (int) $database->getSequence();
$tableInternalId = (int) $table->getSequence();
}
switch ($resourceName) {
case ResourceDatabase::getName():
$queueForStatsUsage->addMetric(METRIC_DATABASES, $count);
break;
case ResourceTable::getName():
$queueForStatsUsage
->addMetric(METRIC_COLLECTIONS, $count)
->addMetric(
str_replace('{databaseInternalId}', $databaseInternalId, METRIC_DATABASE_ID_COLLECTIONS),
$count
);
break;
case ResourceRow::getName():
$queueForStatsUsage
->addMetric(
str_replace(
['{databaseInternalId}','{collectionInternalId}'],
[$databaseInternalId, $tableInternalId],
METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS
),
$count
)
->addMetric(
str_replace('{databaseInternalId}', $databaseInternalId, METRIC_DATABASE_ID_DOCUMENTS),
$count
);
break;
default:
break;
}
$queueForStatsUsage->setProject($projectDocument)->trigger();
$queueForStatsUsage->reset();
}
} }

View file

@ -221,7 +221,7 @@ class OpenAPI3 extends Format
'required' => [], 'required' => [],
'responses' => [], 'responses' => [],
'description' => ($desc) ? \file_get_contents($desc) : '', 'description' => ($desc) ? \file_get_contents($desc) : '',
'demo' => Template::fromCamelCaseToDash($namespace) . '/' . Template::fromCamelCaseToDash($methodObj->getMethodName()) . '.md', 'demo' => \strtolower($namespace) . '/' . Template::fromCamelCaseToDash($methodObj->getMethodName()) . '.md',
]; ];
// add deprecation only if method has it! // add deprecation only if method has it!

View file

@ -230,7 +230,7 @@ class Swagger2 extends Format
'required' => [], 'required' => [],
'responses' => [], 'responses' => [],
'description' => ($desc) ? \file_get_contents($desc) : '', 'description' => ($desc) ? \file_get_contents($desc) : '',
'demo' => Template::fromCamelCaseToDash($namespace) . '/' . Template::fromCamelCaseToDash($methodObj->getMethodName()) . '.md', 'demo' => \strtolower($namespace) . '/' . Template::fromCamelCaseToDash($methodObj->getMethodName()) . '.md',
]; ];
// add deprecation only if method has it! // add deprecation only if method has it!

View file

@ -32,59 +32,67 @@ class V20 extends Filter
*/ */
protected function manageSelectQueries(array $content): array protected function manageSelectQueries(array $content): array
{ {
$hasWildcard = false;
if (!isset($content['queries'])) { if (!isset($content['queries'])) {
$hasWildcard = true; $content['queries'] = [];
// only query, make it json encoded! }
$content['queries'] = [Query::select(['*'])->toString()];
// Handle case where queries is an array but empty
if (\is_array($content['queries'])) {
$content['queries'] = \array_filter($content['queries'], function ($q) {
if (\is_object($q) && empty((array)$q)) {
return false;
}
if (\is_string($q) && \trim($q) === '') {
return false;
}
if (empty($q)) {
return false;
}
return true;
});
} }
try { try {
$parsed = Query::parseQueries($content['queries']); $parsed = Query::parseQueries($content['queries']);
} catch (QueryException) { } catch (QueryException) {
// don't crash!
return $content; return $content;
} }
$selections = Query::groupByType($parsed)['selections'] ?? []; $selections = Query::groupByType($parsed)['selections'] ?? [];
// If there are no select queries at all, add wildcard // Check if we need to add wildcard + relationships
if (empty($selections)) { // This happens when:
$hasWildcard = true; // 1. No select queries exist, OR
$parsed[] = Query::select(['*']); // 2. A wildcard select exists
} elseif (!$hasWildcard) { $needsRelationships = empty($selections);
// check if any select includes a wildcard as we added one above if (!$needsRelationships) {
foreach ($selections as $select) { foreach ($selections as $select) {
if (\in_array('*', $select->getValues(), true)) { if (\in_array('*', $select->getValues(), true)) {
$hasWildcard = true; $needsRelationships = true;
break; break;
} }
} }
} }
/** /**
* Add `keys.*` for all model types! * Add wildcard and relationship selects for backward compatibility
*/ */
if ($hasWildcard) { if ($needsRelationships) {
$relatedKeys = $this->getRelatedCollectionKeys(); $relatedKeys = $this->getRelatedCollectionKeys();
$selects = \array_values(\array_unique(\array_merge(['*'], $relatedKeys)));
if (! empty($relatedKeys)) { // Remove any existing select queries
$selects = \array_values(\array_unique(\array_merge(['*'], $relatedKeys))); $parsed = \array_filter(
$parsed,
fn ($query) => $query->getMethod() !== Query::TYPE_SELECT
);
// remove previous select queries // Add wildcard + relationship(s) selects
$parsed = \array_filter( $parsed[] = Query::select($selects);
$parsed,
fn ($query) => $query->getMethod() !== Query::TYPE_SELECT
);
// add wildcard + relationship(s) selects
$parsed[] = Query::select($selects);
}
} }
$resolvedQueries = []; $resolvedQueries = [];
foreach ($parsed as $query) { foreach ($parsed as $query) {
// make em json encoded!
$resolvedQueries[] = $query->toString(); $resolvedQueries[] = $query->toString();
} }
@ -95,12 +103,15 @@ class V20 extends Filter
/** /**
* Returns all relationship attribute keys in `key.*` format for use with `Query::select`. * Returns all relationship attribute keys in `key.*` format for use with `Query::select`.
* Recursively includes nested relationships up to 3 levels deep.
* Prevents infinite loops by tracking all visited collections in the current path.
*/ */
private function getRelatedCollectionKeys( private function getRelatedCollectionKeys(
?string $databaseId = null, ?string $databaseId = null,
?string $collectionId = null, ?string $collectionId = null,
?string $prefix = null, ?string $prefix = null,
int $depth = 1, int $depth = 1,
array $visited = []
): array { ): array {
$databaseId ??= $this->getParamValue('databaseId'); $databaseId ??= $this->getParamValue('databaseId');
$collectionId ??= $this->getParamValue('collectionId'); $collectionId ??= $this->getParamValue('collectionId');
@ -113,6 +124,13 @@ class V20 extends Filter
return []; return [];
} }
// Check if we've already visited this collection in the current path to prevent cycles
if (in_array($collectionId, $visited)) {
return [];
}
$visited[] = $collectionId;
$dbForProject = $this->getDbForProject(); $dbForProject = $this->getDbForProject();
if ($dbForProject === null) { if ($dbForProject === null) {
return []; return [];
@ -144,20 +162,24 @@ class V20 extends Filter
$key = $attr['key']; $key = $attr['key'];
$fullKey = $prefix ? $prefix . '.' . $key : $key; $fullKey = $prefix ? $prefix . '.' . $key : $key;
$relatedCollectionId = $attr['relatedCollection'] ?? null;
// Skip this relationship entirely if it points to an already visited collection
if ($relatedCollectionId && in_array($relatedCollectionId, $visited)) {
continue;
}
// Add the wildcard select for this relationship // Add the wildcard select for this relationship
$relationshipKeys[] = $fullKey . '.*'; $relationshipKeys[] = $fullKey . '.*';
// Get the related collection for nested relationships // Continue recursively if we have a related collection
$relatedCollectionId = $attr['relatedCollection'] ?? null;
if ($relatedCollectionId) { if ($relatedCollectionId) {
// Recursively get nested relationship keys
$nestedKeys = $this->getRelatedCollectionKeys( $nestedKeys = $this->getRelatedCollectionKeys(
$databaseId, $databaseId,
$relatedCollectionId, $relatedCollectionId,
$fullKey, $fullKey,
$depth + 1, $depth + 1,
$visited
); );
$relationshipKeys = \array_merge($relationshipKeys, $nestedKeys); $relationshipKeys = \array_merge($relationshipKeys, $nestedKeys);

View file

@ -925,6 +925,26 @@ class FunctionsCustomServerTest extends Scope
$executionId = $execution['body']['$id'] ?? ''; $executionId = $execution['body']['$id'] ?? '';
/** Test create execution with HEAD method */
$execution = $this->createExecution($data['functionId'], [
'async' => 'false',
'method' => 'HEAD',
]);
$this->assertEquals(201, $execution['headers']['status-code']);
$this->assertEquals('completed', $execution['body']['status']);
$this->assertEquals(200, $execution['body']['responseStatusCode']);
$this->assertIsArray($execution['body']['responseHeaders']);
$this->assertEmpty($execution['body']['responseBody']); // For HEAD requests, response body is empty
/** Delete execution */
$execution = $this->client->call(Client::METHOD_DELETE, '/functions/' . $data['functionId'] . '/executions/' . $execution['body']['$id'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(204, $execution['headers']['status-code']);
/** Test create execution with 400 status code */
$execution = $this->createExecution($data['functionId'], [ $execution = $this->createExecution($data['functionId'], [
'async' => 'false', 'async' => 'false',
'path' => '/?code=400' 'path' => '/?code=400'
@ -934,11 +954,11 @@ class FunctionsCustomServerTest extends Scope
$this->assertEquals('completed', $execution['body']['status']); $this->assertEquals('completed', $execution['body']['status']);
$this->assertEquals(400, $execution['body']['responseStatusCode']); $this->assertEquals(400, $execution['body']['responseStatusCode']);
/** Delete execution */
$execution = $this->client->call(Client::METHOD_DELETE, '/functions/' . $data['functionId'] . '/executions/' . $execution['body']['$id'], array_merge([ $execution = $this->client->call(Client::METHOD_DELETE, '/functions/' . $data['functionId'] . '/executions/' . $execution['body']['$id'], array_merge([
'content-type' => 'application/json', 'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []); ], $this->getHeaders()), []);
$this->assertEquals(204, $execution['headers']['status-code']); $this->assertEquals(204, $execution['headers']['status-code']);
return array_merge($data, ['executionId' => $executionId]); return array_merge($data, ['executionId' => $executionId]);