-
Notifications
You must be signed in to change notification settings - Fork 26
feat: Android SDK update for version 11.3.0 #95
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughThis pull request releases version 11.3.0 of the Appwrite Android SDK. The changes introduce a new Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Pre-merge checks and finishing touches❌ Failed checks (1 inconclusive)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 9
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
docs/examples/java/databases/create-document.md (1)
17-22: Critical: Kotlin syntax in Java example.The
mapOf()function is Kotlin syntax and will not compile in Java. Java examples should use standard Java map construction. Replace with Java syntax likeMap.of()(Java 9+) ornew HashMap<>()/new LinkedHashMap<>().Apply this diff to fix the syntax:
databases.createDocument( "<DATABASE_ID>", // databaseId "<COLLECTION_ID>", // collectionId "<DOCUMENT_ID>", // documentId - mapOf( + Map.of( "username" to "walter.obrien", "email" to "[email protected]", "fullName" to "Walter O'Brien", "age" to 30, "isAdmin" to false - ), // data + ), // dataAlso replace the
tooperator with proper Java map entry syntax:- Map.of( + Map.ofEntries( - "username" to "walter.obrien", + Map.entry("username", "walter.obrien"), - "email" to "[email protected]", + Map.entry("email", "[email protected]"), - "fullName" to "Walter O'Brien", + Map.entry("fullName", "Walter O'Brien"), - "age" to 30, + Map.entry("age", 30), - "isAdmin" to false + Map.entry("isAdmin", false) - ), // data + ), // data
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (45)
CHANGELOG.md(1 hunks)README.md(2 hunks)docs/examples/java/account/list-identities.md(1 hunks)docs/examples/java/account/list-logs.md(1 hunks)docs/examples/java/databases/create-document.md(2 hunks)docs/examples/java/databases/list-documents.md(1 hunks)docs/examples/java/databases/update-document.md(2 hunks)docs/examples/java/databases/upsert-document.md(2 hunks)docs/examples/java/functions/list-executions.md(1 hunks)docs/examples/java/storage/create-file.md(2 hunks)docs/examples/java/storage/list-files.md(1 hunks)docs/examples/java/storage/update-file.md(2 hunks)docs/examples/java/tablesdb/create-row.md(2 hunks)docs/examples/java/tablesdb/list-rows.md(1 hunks)docs/examples/java/tablesdb/update-row.md(2 hunks)docs/examples/java/tablesdb/upsert-row.md(2 hunks)docs/examples/java/teams/list-memberships.md(1 hunks)docs/examples/java/teams/list.md(1 hunks)docs/examples/kotlin/account/list-identities.md(1 hunks)docs/examples/kotlin/account/list-logs.md(1 hunks)docs/examples/kotlin/databases/create-document.md(2 hunks)docs/examples/kotlin/databases/list-documents.md(1 hunks)docs/examples/kotlin/databases/update-document.md(2 hunks)docs/examples/kotlin/databases/upsert-document.md(2 hunks)docs/examples/kotlin/functions/list-executions.md(1 hunks)docs/examples/kotlin/storage/create-file.md(2 hunks)docs/examples/kotlin/storage/list-files.md(1 hunks)docs/examples/kotlin/storage/update-file.md(2 hunks)docs/examples/kotlin/tablesdb/create-row.md(2 hunks)docs/examples/kotlin/tablesdb/list-rows.md(1 hunks)docs/examples/kotlin/tablesdb/update-row.md(2 hunks)docs/examples/kotlin/tablesdb/upsert-row.md(2 hunks)docs/examples/kotlin/teams/list-memberships.md(1 hunks)docs/examples/kotlin/teams/list.md(1 hunks)library/src/main/java/io/appwrite/Client.kt(1 hunks)library/src/main/java/io/appwrite/Operator.kt(1 hunks)library/src/main/java/io/appwrite/Query.kt(3 hunks)library/src/main/java/io/appwrite/enums/ExecutionStatus.kt(1 hunks)library/src/main/java/io/appwrite/models/Execution.kt(1 hunks)library/src/main/java/io/appwrite/services/Account.kt(2 hunks)library/src/main/java/io/appwrite/services/Databases.kt(5 hunks)library/src/main/java/io/appwrite/services/Functions.kt(1 hunks)library/src/main/java/io/appwrite/services/Storage.kt(1 hunks)library/src/main/java/io/appwrite/services/TablesDb.kt(5 hunks)library/src/main/java/io/appwrite/services/Teams.kt(3 hunks)
🔇 Additional comments (35)
docs/examples/kotlin/teams/list.md (1)
14-14: LGTM!The new
totalparameter has been correctly added as an optional parameter with proper Kotlin named-argument syntax. Setting it tofalsealigns with the PR objective to optimize performance by skipping row count calculations. The inline comment clearly indicates this parameter is optional.docs/examples/kotlin/account/list-logs.md (1)
13-13: ✓ Documentation update looks good.The new
totalparameter is correctly added with proper Kotlin named-argument syntax and an appropriate default value (false) that demonstrates the performance optimization intent. The inline comment correctly marks it as optional.library/src/main/java/io/appwrite/enums/ExecutionStatus.kt (1)
13-15: LGTM! New SCHEDULED status added correctly.The new enum constant follows the same pattern as existing values and is properly annotated for JSON serialization. The syntax is correct with the comma after FAILED and semicolon terminator after SCHEDULED.
library/src/main/java/io/appwrite/models/Execution.kt (1)
55-55: LGTM! Documentation updated to reflect new status.The KDoc now correctly documents all possible execution status values, including the newly added "scheduled" state. This change is consistent with the ExecutionStatus enum update.
library/src/main/java/io/appwrite/Query.kt (1)
254-296: LGTM! Clean refactor that improves maintainability.The date-filter methods now delegate to existing helper functions (
lessThan,greaterThan,between) rather than duplicating query construction logic. This follows the DRY principle and makes the code easier to maintain. The behavior is preserved, and the special Appwrite attributes ($createdAt,$updatedAt) are correctly referenced.docs/examples/java/teams/list.md (1)
14-14: LGTM!The new
totalparameter is correctly documented and demonstrates the performance optimization feature mentioned in the changelog. Setting it tofalsein the example is a good choice as it shows the performance-optimized usage.docs/examples/java/tablesdb/update-row.md (1)
4-5: Excellent type safety improvement!The refactor from string-based permissions to typed
Permission.read(Role.any())objects provides compile-time safety and better IDE support. This prevents runtime errors from malformed permission strings.Also applies to: 18-18
library/src/main/java/io/appwrite/Client.kt (1)
90-90: LGTM!SDK version header correctly updated to 11.3.0, consistent with the version bump across the codebase.
README.md (1)
41-41: LGTM!Dependency versions correctly updated to 11.3.0 for both Gradle and Maven, consistent with the release version.
Also applies to: 52-52
CHANGELOG.md (1)
3-7: LGTM!The changelog entry properly documents the new features in version 11.3.0. The
totalparameter addition is clearly described and aligns with the performance optimization changes seen throughout the codebase.docs/examples/kotlin/databases/upsert-document.md (1)
4-5: LGTM!The typed permission objects provide compile-time safety and better developer experience. The implementation is consistent with the Java examples and follows proper Kotlin conventions.
Also applies to: 18-18
library/src/main/java/io/appwrite/services/Storage.kt (1)
25-25: Well-implemented performance optimization!The new
totalparameter is properly implemented with:
- Clear documentation explaining the performance benefit
- Optional nullable type (
Boolean?) withnulldefault for backward compatibility- Correct propagation to the API parameters map
@JvmOverloadsannotation ensures Java interoperabilityAlso applies to: 33-33, 41-41
library/src/main/java/io/appwrite/services/Account.kt (1)
186-186: Consistently implemented across both methods!The
totalparameter is properly added to bothlistIdentitiesandlistLogsmethods with:
- Consistent documentation and implementation pattern
- Optional nullable type for backward compatibility
- Correct API parameter propagation
@JvmOverloadsannotation for Java interoperabilityThe implementation matches the pattern in Storage.kt and other services.
Also applies to: 192-192, 198-198, 277-277, 283-283, 289-289
docs/examples/kotlin/tablesdb/list-rows.md (1)
16-16: LGTM!The addition of the optional
totalparameter is correctly placed and syntactically sound. This aligns with the PR's API changes to add performance optimization controls.docs/examples/kotlin/tablesdb/update-row.md (1)
4-5: LGTM!The imports for Permission and Role are correctly added, and the use of typed permission objects (Permission.read(Role.any())) is the proper pattern. This improves type safety over string-based permissions.
Also applies to: 18-18
docs/examples/java/databases/create-document.md (1)
4-5: LGTM on permission objects.The imports and use of typed Permission/Role objects are correct for Java. The pattern is consistent with the PR's modernization goals.
Also applies to: 24-24
docs/examples/kotlin/account/list-identities.md (1)
13-13: LGTM!The optional
totalparameter is correctly added to the listIdentities call. This matches the API changes and provides users with performance optimization control.docs/examples/java/databases/list-documents.md (1)
16-16: LGTM on parameter.The addition of the
totalparameter is correctly positioned and follows the API changes.docs/examples/java/storage/create-file.md (1)
5-6: LGTM on permission objects.The imports for Permission and Role and the use of typed permission objects are correct and follow the pattern established in the PR.
docs/examples/kotlin/tablesdb/upsert-row.md (1)
4-5: LGTM!The imports and use of typed permission objects are correct for Kotlin. This follows the PR's pattern of modernizing permission handling.
Also applies to: 18-18
docs/examples/kotlin/storage/update-file.md (1)
4-5: LGTM!The imports and use of typed permission objects are correctly implemented for Kotlin, consistent with the PR's modernization of permission handling patterns.
Also applies to: 17-17
docs/examples/kotlin/databases/list-documents.md (1)
16-16: LGTM!The total parameter is correctly added using Kotlin named parameter syntax and aligns with the 11.3.0 API changes.
docs/examples/kotlin/storage/list-files.md (1)
15-15: LGTM!The total parameter addition uses correct Kotlin named parameter syntax.
docs/examples/kotlin/databases/update-document.md (1)
4-5: LGTM!Permission and Role imports are correctly added, and the typed permission usage
Permission.read(Role.any())is idiomatic Kotlin and aligns with the PR's shift to typed permissions.Also applies to: 18-18
docs/examples/kotlin/functions/list-executions.md (1)
14-14: API parameter addition is correctly reflected. The newtotalparameter is properly added with idiomatic Kotlin named syntax and clear documentation.docs/examples/java/databases/upsert-document.md (1)
4-5: Permissions correctly typed and imports added. Transitioning from string-based permissions to typedPermissionandRoleobjects improves type safety and IDE support. All necessary imports are in place.Also applies to: 18-18
docs/examples/kotlin/tablesdb/create-row.md (1)
4-5: Permissions correctly updated to typed syntax. Import statements are properly added and the permission construction is idiomatic Kotlin. Example remains clear and correct.Also applies to: 24-24
docs/examples/java/tablesdb/upsert-row.md (1)
4-5: Permissions correctly typed with necessary imports. The change toPermission.read(Role.any())is consistent across all similar examples and provides type safety benefits.Also applies to: 18-18
docs/examples/kotlin/storage/create-file.md (1)
5-6: Permissions API usage correctly updated. New imports are properly positioned and typed permission construction is consistent with other Kotlin examples in the PR.Also applies to: 18-18
docs/examples/kotlin/databases/create-document.md (1)
4-5: Permission typing correctly applied. Imports are properly added and the syntax is consistent with other document creation examples in both Kotlin and Java.Also applies to: 24-24
docs/examples/java/account/list-logs.md (1)
13-13: New API parameter correctly added. Thetotalparameter is properly positioned in the method call and documented inline, consistent with other list method examples.docs/examples/java/tablesdb/list-rows.md (1)
16-16: API parameter addition is correct and consistently applied. Thetotalparameter is properly positioned in the method signature and documented, matching the pattern across all list methods in the PR.library/src/main/java/io/appwrite/services/Functions.kt (1)
22-36: LGTM! Clean implementation of thetotalparameter.The optional
totalparameter is properly implemented with:
- Clear KDoc documentation explaining its purpose
- Nullable Boolean type with sensible default (null)
- Correct forwarding to API parameters
- Backward compatibility via
@JvmOverloadsfor Java callerslibrary/src/main/java/io/appwrite/services/Databases.kt (2)
222-245: LGTM! Consistent implementation across overloads.The
totalparameter is properly added to the genericlistDocumentsmethod with correct KDoc, type signature, and API parameter mapping. The implementation maintains consistency with other services in this PR.
270-292: LGTM! Proper parameter delegation.The non-generic overload correctly forwards the
totalparameter to the generic implementation. Good practice to maintain consistency even for deprecated methods.
| Account account = new Account(client); | ||
|
|
||
| account.listIdentities( | ||
| listOf(), // queries (optional) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix Kotlin syntax in Java example: listOf() is not available.
Line 12 uses listOf(), which is a Kotlin stdlib function and will not compile in Java code.
Apply this diff to fix the Java syntax:
account.listIdentities(
- listOf(), // queries (optional)
+ Arrays.asList(), // queries (optional)
false, // total (optional)Alternatively, if targeting Java 9+:
- listOf(), // queries (optional)
+ List.of(), // queries (optional)Add the import if using Arrays.asList():
import java.util.Arrays;🤖 Prompt for AI Agents
In docs/examples/java/account/list-identities.md around line 12, the Java
example incorrectly uses Kotlin's listOf(); replace it with a Java-compatible
expression such as Collections.emptyList() or, for Java 9+, List.of(), or
Arrays.asList(...) if you need elements. If you choose Arrays.asList(), add the
import java.util.Arrays; if you use Collections.emptyList() or List.of(), ensure
the appropriate java.util imports (java.util.Collections or java.util.List) are
present.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems like a legit comment @abnegate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not a blocker for release rn, but maybe need a backlog task
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!
| databases.listDocuments( | ||
| "<DATABASE_ID>", // databaseId | ||
| "<COLLECTION_ID>", // collectionId | ||
| listOf(), // queries (optional) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical: Kotlin syntax in Java example.
The listOf() function is Kotlin syntax and will not compile in Java. Replace with Java syntax like List.of() (Java 9+) or Arrays.asList() for compatibility.
Apply this diff:
databases.listDocuments(
"<DATABASE_ID>", // databaseId
"<COLLECTION_ID>", // collectionId
- listOf(), // queries (optional)
+ List.of(), // queries (optional)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| listOf(), // queries (optional) | |
| List.of(), // queries (optional) |
🤖 Prompt for AI Agents
In docs/examples/java/databases/list-documents.md around line 14, the example
uses Kotlin's listOf(), which is invalid in Java; replace it with
Java-compatible syntax such as List.of(...) (Java 9+) or Arrays.asList(...) and
ensure the example imports or references java.util.List/Arrays appropriately so
the code compiles in Java.
| mapOf( "a" to "b" ), // data (optional) | ||
| listOf("read("any")"), // permissions (optional) | ||
| listOf(Permission.read(Role.any())), // permissions (optional) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix Kotlin syntax in Java example: mapOf() with to operator and listOf() are not available in Java.
Lines 17–18 use Kotlin-specific constructs that will not compile in Java:
mapOf("a" to "b")uses Kotlin'smapOf()function andtoinfix operatorlistOf(...)is a Kotlin stdlib function
Apply this diff to fix the Java syntax:
databases.updateDocument(
"<DATABASE_ID>", // databaseId
"<COLLECTION_ID>", // collectionId
"<DOCUMENT_ID>", // documentId
- mapOf( "a" to "b" ), // data (optional)
+ new HashMap<String, Object>() {{ put("a", "b"); }}, // data (optional)
- listOf(Permission.read(Role.any())), // permissions (optional)
+ Arrays.asList(Permission.read(Role.any())), // permissions (optional)
"<TRANSACTION_ID>", // transactionId (optional)Alternatively, if targeting Java 9+:
- mapOf( "a" to "b" ), // data (optional)
+ Map.of("a", "b"), // data (optional)
- listOf(Permission.read(Role.any())), // permissions (optional)
+ List.of(Permission.read(Role.any())), // permissions (optional)Add the imports:
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;🤖 Prompt for AI Agents
In docs/examples/java/databases/update-document.md around lines 17–18, the
snippet uses Kotlin-only constructs (mapOf("a" to "b") and listOf(...)) which
won't compile in Java; replace them with Java equivalents such as creating a Map
(e.g., new HashMap<>() and put("a","b") or Map.of("a","b") for Java 9+) and
creating a List (e.g., Arrays.asList(...) or List.of(...) for Java 9+), and add
the corresponding imports (java.util.Map, java.util.HashMap or java.util.Map.of,
java.util.Arrays or java.util.List.of) as needed so the example compiles in
Java.
|
|
||
| functions.listExecutions( | ||
| "<FUNCTION_ID>", // functionId | ||
| listOf(), // queries (optional) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix Kotlin syntax in Java example.
The example uses listOf(), which is a Kotlin function and won't compile in Java code.
Replace with valid Java syntax:
- listOf(), // queries (optional)
+ Arrays.asList(), // queries (optional)Or alternatively:
- listOf(), // queries (optional)
+ Collections.emptyList(), // queries (optional)You'll also need to add the appropriate import:
import java.util.Arrays;
// or
import java.util.Collections;🤖 Prompt for AI Agents
In docs/examples/java/functions/list-executions.md around line 13, the snippet
uses the Kotlin-only call `listOf()` which will not compile in Java; replace it
with a Java equivalent such as Arrays.asList(...) for a populated list or
Collections.emptyList() for an empty list and add the corresponding import
statement (import java.util.Arrays; or import java.util.Collections;) at the top
of the Java example.
| "<FILE_ID>", // fileId | ||
| InputFile.fromPath("file.png"), // file | ||
| listOf("read("any")"), // permissions (optional) | ||
| listOf(Permission.read(Role.any())), // permissions (optional) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical: Kotlin syntax in Java example.
The listOf() function is Kotlin syntax and will not compile in Java. Replace with List.of() (Java 9+) or Arrays.asList().
Apply this diff:
storage.createFile(
"<BUCKET_ID>", // bucketId
"<FILE_ID>", // fileId
InputFile.fromPath("file.png"), // file
- listOf(Permission.read(Role.any())), // permissions (optional)
+ List.of(Permission.read(Role.any())), // permissions (optional)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| listOf(Permission.read(Role.any())), // permissions (optional) | |
| List.of(Permission.read(Role.any())), // permissions (optional) |
🤖 Prompt for AI Agents
In docs/examples/java/storage/create-file.md around line 18, the example uses
Kotlin's listOf() which won't compile in Java; replace it with a Java collection
factory such as List.of(Permission.read(Role.any())) (Java 9+) or
Arrays.asList(Permission.read(Role.any()))) and ensure the corresponding import
(java.util.List or java.util.Arrays) is present at the top of the example.
|
|
||
| storage.listFiles( | ||
| "<BUCKET_ID>", // bucketId | ||
| listOf(), // queries (optional) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix Kotlin syntax in Java example: listOf() is not available.
Line 13 uses listOf(), which is a Kotlin stdlib function and will not compile in Java code. Use Java collection APIs instead.
Apply this diff to fix the Java syntax:
storage.listFiles(
"<BUCKET_ID>", // bucketId
- listOf(), // queries (optional)
+ Arrays.asList(), // queries (optional)
"<SEARCH>", // search (optional)
false, // total (optional)Alternatively, if targeting Java 9+, use List.of():
- listOf(), // queries (optional)
+ List.of(), // queries (optional)Add the import if using Arrays.asList():
import java.util.Arrays;🤖 Prompt for AI Agents
In docs/examples/java/storage/list-files.md around line 13, the example
incorrectly uses Kotlin's listOf(), which won't compile in Java; replace it with
a Java collection initializer such as Arrays.asList(...) and add the import
java.util.Arrays, or if the project targets Java 9+ use List.of(... ) instead
(and import java.util.List if needed); update the example call and imports
accordingly so the snippet compiles as Java.
| import io.appwrite.Permission; | ||
| import io.appwrite.Role; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix Kotlin syntax in Java example: listOf() is not available.
Imports for Permission and Role are correct, but line 17 uses listOf(), which is a Kotlin stdlib function and will not compile in Java code.
Apply this diff to fix the Java syntax:
storage.updateFile(
"<BUCKET_ID>", // bucketId
"<FILE_ID>", // fileId
"<NAME>", // name (optional)
- listOf(Permission.read(Role.any())), // permissions (optional)
+ Arrays.asList(Permission.read(Role.any())), // permissions (optional)
new CoroutineCallback<>((result, error) -> {Alternatively, if targeting Java 9+, use List.of():
- listOf(Permission.read(Role.any())), // permissions (optional)
+ List.of(Permission.read(Role.any())), // permissions (optional)Add the import if using Arrays.asList():
import java.util.Arrays;Also applies to: 17-17
🤖 Prompt for AI Agents
In docs/examples/java/storage/update-file.md around lines 4-5 (and line 17), the
example incorrectly uses Kotlin's listOf() in Java code; replace listOf(...)
with a Java equivalent (either Arrays.asList(...) and add import
java.util.Arrays;, or if targeting Java 9+, use List.of(...)) and ensure the
corresponding import is added when using Arrays.asList to make the example valid
Java.
| "isAdmin" to false | ||
| ), // data | ||
| listOf("read("any")"), // permissions (optional) | ||
| listOf(Permission.read(Role.any())), // permissions (optional) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix Kotlin syntax in Java example: listOf() is not available.
Line 24 uses listOf(), which is a Kotlin stdlib function and will not compile in Java code.
Apply this diff to fix the Java syntax:
), // data
- listOf(Permission.read(Role.any())), // permissions (optional)
+ Arrays.asList(Permission.read(Role.any())), // permissions (optional)
"<TRANSACTION_ID>", // transactionId (optional)Alternatively, if targeting Java 9+:
- listOf(Permission.read(Role.any())), // permissions (optional)
+ List.of(Permission.read(Role.any())), // permissions (optional)Add the import if using Arrays.asList():
import java.util.Arrays;🤖 Prompt for AI Agents
In docs/examples/java/tablesdb/create-row.md around line 24, the example uses
Kotlin's listOf() which is invalid in Java; replace it with a Java list factory
such as Arrays.asList(...) (and add import java.util.Arrays) or, for Java 9+,
use List.of(...), ensuring imports (java.util.List) are present as needed and
adjust the syntax to match Java generics.
| fun increment(value: Number = 1, max: Number? = null): String { | ||
| require(!value.toDouble().isNaN() && !value.toDouble().isInfinite()) { "Value cannot be NaN or Infinity" } | ||
| max?.let { require(!it.toDouble().isNaN() && !it.toDouble().isInfinite()) { "Max cannot be NaN or Infinity" } } | ||
| val values = mutableListOf<Any?>(value) | ||
| max?.let { values.add(it) } | ||
| return Operator("increment", values).toJson() | ||
| } | ||
|
|
||
| fun decrement(value: Number = 1, min: Number? = null): String { | ||
| require(!value.toDouble().isNaN() && !value.toDouble().isInfinite()) { "Value cannot be NaN or Infinity" } | ||
| min?.let { require(!it.toDouble().isNaN() && !it.toDouble().isInfinite()) { "Min cannot be NaN or Infinity" } } | ||
| val values = mutableListOf<Any?>(value) | ||
| min?.let { values.add(it) } | ||
| return Operator("decrement", values).toJson() | ||
| } | ||
|
|
||
| fun multiply(factor: Number, max: Number? = null): String { | ||
| require(!factor.toDouble().isNaN() && !factor.toDouble().isInfinite()) { "Factor cannot be NaN or Infinity" } | ||
| max?.let { require(!it.toDouble().isNaN() && !it.toDouble().isInfinite()) { "Max cannot be NaN or Infinity" } } | ||
| val values = mutableListOf<Any?>(factor) | ||
| max?.let { values.add(it) } | ||
| return Operator("multiply", values).toJson() | ||
| } | ||
|
|
||
| fun divide(divisor: Number, min: Number? = null): String { | ||
| require(!divisor.toDouble().isNaN() && !divisor.toDouble().isInfinite()) { "Divisor cannot be NaN or Infinity" } | ||
| min?.let { require(!it.toDouble().isNaN() && !it.toDouble().isInfinite()) { "Min cannot be NaN or Infinity" } } | ||
| require(divisor.toDouble() != 0.0) { "Divisor cannot be zero" } | ||
| val values = mutableListOf<Any?>(divisor) | ||
| min?.let { values.add(it) } | ||
| return Operator("divide", values).toJson() | ||
| } | ||
|
|
||
| fun modulo(divisor: Number): String { | ||
| require(!divisor.toDouble().isNaN() && !divisor.toDouble().isInfinite()) { "Divisor cannot be NaN or Infinity" } | ||
| require(divisor.toDouble() != 0.0) { "Divisor cannot be zero" } | ||
| return Operator("modulo", listOf(divisor)).toJson() | ||
| } | ||
|
|
||
| fun power(exponent: Number, max: Number? = null): String { | ||
| require(!exponent.toDouble().isNaN() && !exponent.toDouble().isInfinite()) { "Exponent cannot be NaN or Infinity" } | ||
| max?.let { require(!it.toDouble().isNaN() && !it.toDouble().isInfinite()) { "Max cannot be NaN or Infinity" } } | ||
| val values = mutableListOf<Any?>(exponent) | ||
| max?.let { values.add(it) } | ||
| return Operator("power", values).toJson() | ||
| } | ||
|
|
||
| fun arrayAppend(values: List<Any?>): String { | ||
| return Operator("arrayAppend", values).toJson() | ||
| } | ||
|
|
||
| fun arrayPrepend(values: List<Any?>): String { | ||
| return Operator("arrayPrepend", values).toJson() | ||
| } | ||
|
|
||
| fun arrayInsert(index: Int, value: Any): String { | ||
| return Operator("arrayInsert", listOf(index, value)).toJson() | ||
| } | ||
|
|
||
| fun arrayRemove(value: Any): String { | ||
| return Operator("arrayRemove", listOf(value)).toJson() | ||
| } | ||
|
|
||
| fun arrayUnique(): String { | ||
| return Operator("arrayUnique", emptyList()).toJson() | ||
| } | ||
|
|
||
| fun arrayIntersect(values: List<Any?>): String { | ||
| return Operator("arrayIntersect", values).toJson() | ||
| } | ||
|
|
||
| fun arrayDiff(values: List<Any?>): String { | ||
| return Operator("arrayDiff", values).toJson() | ||
| } | ||
|
|
||
| fun arrayFilter(condition: Condition, value: Any? = null): String { | ||
| val values = listOf<Any?>(condition.value, value) | ||
| return Operator("arrayFilter", values).toJson() | ||
| } | ||
|
|
||
| fun stringConcat(value: Any): String { | ||
| return Operator("stringConcat", listOf(value)).toJson() | ||
| } | ||
|
|
||
| fun stringReplace(search: String, replace: String): String { | ||
| return Operator("stringReplace", listOf(search, replace)).toJson() | ||
| } | ||
|
|
||
| fun toggle(): String { | ||
| return Operator("toggle", emptyList()).toJson() | ||
| } | ||
|
|
||
| fun dateAddDays(days: Int): String { | ||
| return Operator("dateAddDays", listOf(days)).toJson() | ||
| } | ||
|
|
||
| fun dateSubDays(days: Int): String { | ||
| return Operator("dateSubDays", listOf(days)).toJson() | ||
| } | ||
|
|
||
| fun dateSetNow(): String { | ||
| return Operator("dateSetNow", emptyList()).toJson() | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Return operators as structured objects, not JSON strings
Each factory currently calling .toJson() returns a raw string. When consumers place that value inside data/permissions maps, our serializer will emit it as a quoted string (e.g. "count":"{\"method\":\"increment\",\"values\":[1]}"), so the server never sees the expected object form and atomic updates break. We need these helpers to return Operator instances so the Gson (or equivalent) serializer can embed them as nested JSON objects.
Apply the pattern below across all factory methods:
- fun increment(value: Number = 1, max: Number? = null): String {
+ fun increment(value: Number = 1, max: Number? = null): Operator {
…
- return Operator("increment", values).toJson()
+ return Operator("increment", values)
}Do the same for decrement, multiply, divide, array/string/date helpers, etc., removing the .toJson() call and updating the return types to Operator.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| fun increment(value: Number = 1, max: Number? = null): String { | |
| require(!value.toDouble().isNaN() && !value.toDouble().isInfinite()) { "Value cannot be NaN or Infinity" } | |
| max?.let { require(!it.toDouble().isNaN() && !it.toDouble().isInfinite()) { "Max cannot be NaN or Infinity" } } | |
| val values = mutableListOf<Any?>(value) | |
| max?.let { values.add(it) } | |
| return Operator("increment", values).toJson() | |
| } | |
| fun decrement(value: Number = 1, min: Number? = null): String { | |
| require(!value.toDouble().isNaN() && !value.toDouble().isInfinite()) { "Value cannot be NaN or Infinity" } | |
| min?.let { require(!it.toDouble().isNaN() && !it.toDouble().isInfinite()) { "Min cannot be NaN or Infinity" } } | |
| val values = mutableListOf<Any?>(value) | |
| min?.let { values.add(it) } | |
| return Operator("decrement", values).toJson() | |
| } | |
| fun multiply(factor: Number, max: Number? = null): String { | |
| require(!factor.toDouble().isNaN() && !factor.toDouble().isInfinite()) { "Factor cannot be NaN or Infinity" } | |
| max?.let { require(!it.toDouble().isNaN() && !it.toDouble().isInfinite()) { "Max cannot be NaN or Infinity" } } | |
| val values = mutableListOf<Any?>(factor) | |
| max?.let { values.add(it) } | |
| return Operator("multiply", values).toJson() | |
| } | |
| fun divide(divisor: Number, min: Number? = null): String { | |
| require(!divisor.toDouble().isNaN() && !divisor.toDouble().isInfinite()) { "Divisor cannot be NaN or Infinity" } | |
| min?.let { require(!it.toDouble().isNaN() && !it.toDouble().isInfinite()) { "Min cannot be NaN or Infinity" } } | |
| require(divisor.toDouble() != 0.0) { "Divisor cannot be zero" } | |
| val values = mutableListOf<Any?>(divisor) | |
| min?.let { values.add(it) } | |
| return Operator("divide", values).toJson() | |
| } | |
| fun modulo(divisor: Number): String { | |
| require(!divisor.toDouble().isNaN() && !divisor.toDouble().isInfinite()) { "Divisor cannot be NaN or Infinity" } | |
| require(divisor.toDouble() != 0.0) { "Divisor cannot be zero" } | |
| return Operator("modulo", listOf(divisor)).toJson() | |
| } | |
| fun power(exponent: Number, max: Number? = null): String { | |
| require(!exponent.toDouble().isNaN() && !exponent.toDouble().isInfinite()) { "Exponent cannot be NaN or Infinity" } | |
| max?.let { require(!it.toDouble().isNaN() && !it.toDouble().isInfinite()) { "Max cannot be NaN or Infinity" } } | |
| val values = mutableListOf<Any?>(exponent) | |
| max?.let { values.add(it) } | |
| return Operator("power", values).toJson() | |
| } | |
| fun arrayAppend(values: List<Any?>): String { | |
| return Operator("arrayAppend", values).toJson() | |
| } | |
| fun arrayPrepend(values: List<Any?>): String { | |
| return Operator("arrayPrepend", values).toJson() | |
| } | |
| fun arrayInsert(index: Int, value: Any): String { | |
| return Operator("arrayInsert", listOf(index, value)).toJson() | |
| } | |
| fun arrayRemove(value: Any): String { | |
| return Operator("arrayRemove", listOf(value)).toJson() | |
| } | |
| fun arrayUnique(): String { | |
| return Operator("arrayUnique", emptyList()).toJson() | |
| } | |
| fun arrayIntersect(values: List<Any?>): String { | |
| return Operator("arrayIntersect", values).toJson() | |
| } | |
| fun arrayDiff(values: List<Any?>): String { | |
| return Operator("arrayDiff", values).toJson() | |
| } | |
| fun arrayFilter(condition: Condition, value: Any? = null): String { | |
| val values = listOf<Any?>(condition.value, value) | |
| return Operator("arrayFilter", values).toJson() | |
| } | |
| fun stringConcat(value: Any): String { | |
| return Operator("stringConcat", listOf(value)).toJson() | |
| } | |
| fun stringReplace(search: String, replace: String): String { | |
| return Operator("stringReplace", listOf(search, replace)).toJson() | |
| } | |
| fun toggle(): String { | |
| return Operator("toggle", emptyList()).toJson() | |
| } | |
| fun dateAddDays(days: Int): String { | |
| return Operator("dateAddDays", listOf(days)).toJson() | |
| } | |
| fun dateSubDays(days: Int): String { | |
| return Operator("dateSubDays", listOf(days)).toJson() | |
| } | |
| fun dateSetNow(): String { | |
| return Operator("dateSetNow", emptyList()).toJson() | |
| } | |
| fun increment(value: Number = 1, max: Number? = null): Operator { | |
| require(!value.toDouble().isNaN() && !value.toDouble().isInfinite()) { "Value cannot be NaN or Infinity" } | |
| max?.let { require(!it.toDouble().isNaN() && !it.toDouble().isInfinite()) { "Max cannot be NaN or Infinity" } } | |
| val values = mutableListOf<Any?>(value) | |
| max?.let { values.add(it) } | |
| return Operator("increment", values) | |
| } | |
| fun decrement(value: Number = 1, min: Number? = null): Operator { | |
| require(!value.toDouble().isNaN() && !value.toDouble().isInfinite()) { "Value cannot be NaN or Infinity" } | |
| min?.let { require(!it.toDouble().isNaN() && !it.toDouble().isInfinite()) { "Min cannot be NaN or Infinity" } } | |
| val values = mutableListOf<Any?>(value) | |
| min?.let { values.add(it) } | |
| return Operator("decrement", values) | |
| } | |
| fun multiply(factor: Number, max: Number? = null): Operator { | |
| require(!factor.toDouble().isNaN() && !factor.toDouble().isInfinite()) { "Factor cannot be NaN or Infinity" } | |
| max?.let { require(!it.toDouble().isNaN() && !it.toDouble().isInfinite()) { "Max cannot be NaN or Infinity" } } | |
| val values = mutableListOf<Any?>(factor) | |
| max?.let { values.add(it) } | |
| return Operator("multiply", values) | |
| } | |
| fun divide(divisor: Number, min: Number? = null): Operator { | |
| require(!divisor.toDouble().isNaN() && !divisor.toDouble().isInfinite()) { "Divisor cannot be NaN or Infinity" } | |
| min?.let { require(!it.toDouble().isNaN() && !it.toDouble().isInfinite()) { "Min cannot be NaN or Infinity" } } | |
| require(divisor.toDouble() != 0.0) { "Divisor cannot be zero" } | |
| val values = mutableListOf<Any?>(divisor) | |
| min?.let { values.add(it) } | |
| return Operator("divide", values) | |
| } | |
| fun modulo(divisor: Number): Operator { | |
| require(!divisor.toDouble().isNaN() && !divisor.toDouble().isInfinite()) { "Divisor cannot be NaN or Infinity" } | |
| require(divisor.toDouble() != 0.0) { "Divisor cannot be zero" } | |
| return Operator("modulo", listOf(divisor)) | |
| } | |
| fun power(exponent: Number, max: Number? = null): Operator { | |
| require(!exponent.toDouble().isNaN() && !exponent.toDouble().isInfinite()) { "Exponent cannot be NaN or Infinity" } | |
| max?.let { require(!it.toDouble().isNaN() && !it.toDouble().isInfinite()) { "Max cannot be NaN or Infinity" } } | |
| val values = mutableListOf<Any?>(exponent) | |
| max?.let { values.add(it) } | |
| return Operator("power", values) | |
| } | |
| fun arrayAppend(values: List<Any?>): Operator { | |
| return Operator("arrayAppend", values) | |
| } | |
| fun arrayPrepend(values: List<Any?>): Operator { | |
| return Operator("arrayPrepend", values) | |
| } | |
| fun arrayInsert(index: Int, value: Any): Operator { | |
| return Operator("arrayInsert", listOf(index, value)) | |
| } | |
| fun arrayRemove(value: Any): Operator { | |
| return Operator("arrayRemove", listOf(value)) | |
| } | |
| fun arrayUnique(): Operator { | |
| return Operator("arrayUnique", emptyList()) | |
| } | |
| fun arrayIntersect(values: List<Any?>): Operator { | |
| return Operator("arrayIntersect", values) | |
| } | |
| fun arrayDiff(values: List<Any?>): Operator { | |
| return Operator("arrayDiff", values) | |
| } | |
| fun arrayFilter(condition: Condition, value: Any? = null): Operator { | |
| val values = listOf<Any?>(condition.value, value) | |
| return Operator("arrayFilter", values) | |
| } | |
| fun stringConcat(value: Any): Operator { | |
| return Operator("stringConcat", listOf(value)) | |
| } | |
| fun stringReplace(search: String, replace: String): Operator { | |
| return Operator("stringReplace", listOf(search, replace)) | |
| } | |
| fun toggle(): Operator { | |
| return Operator("toggle", emptyList()) | |
| } | |
| fun dateAddDays(days: Int): Operator { | |
| return Operator("dateAddDays", listOf(days)) | |
| } | |
| fun dateSubDays(days: Int): Operator { | |
| return Operator("dateSubDays", listOf(days)) | |
| } | |
| fun dateSetNow(): Operator { | |
| return Operator("dateSetNow", emptyList()) | |
| } |
🤖 Prompt for AI Agents
library/src/main/java/io/appwrite/Operator.kt around lines 26 to 128: the
factory functions currently return JSON strings (they call .toJson() and have
return type String) which causes serializers to embed them as quoted strings;
change each factory to return the Operator instance instead of its JSON by
removing the .toJson() call and updating the function return type from String to
Operator for all methods (increment, decrement, multiply, divide, modulo, power,
array*, string*, toggle, date* and others in this block); ensure each function
constructs and returns Operator("name", values) directly so the client
serializer can embed it as a nested JSON object.
This PR contains updates to the Android SDK for version 11.3.0.
Summary by CodeRabbit
Release Notes - Version 11.3.0
totalparameter to list operations across Account, Databases, Functions, Storage, Teams, and TablesDb services to skip row counting for improved performance.