-
Notifications
You must be signed in to change notification settings - Fork 188
added spatial type queries #1177
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
WalkthroughAdds 12 query-builder methods across SDK templates: four distance-based methods (distanceEqual, distanceNotEqual, distanceGreaterThan, distanceLessThan) accepting attribute, values, distance and an optional meters flag (values encoded as [values, distance, meters]); and eight spatial-predicate methods (intersects, notIntersects, crosses, notCrosses, overlaps, notOverlaps, touches, notTouches) accepting attribute and values. Implementations were added to Android, Dart (identical block duplicated in file), Deno, .NET, Go, Kotlin, PHP, Python, React Native, Ruby, Swift (also adds QueryValue.array and nested-array conversion), and Web. Tests expanded across all language test suites. 📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 💡 Knowledge Base configuration:
You can enable these sources in your CodeRabbit configuration. 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
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: 4
🧹 Nitpick comments (6)
templates/web/src/query.ts.twig (3)
350-357
: Add minimal validation for distance inputs.Guard against negative or non-finite distances to fail fast.
static distanceEqual = (attribute: string, values: GeometryValues, distance: number): string => - new Query("distanceEqual", attribute, [values, distance]).toString(); + (Number.isFinite(distance) && distance >= 0) + ? new Query("distanceEqual", attribute, [values, distance]).toString() + : (() => { throw new Error("distance must be a non-negative finite number"); })();(Repeat for the other distance methods.)
401-472
: Tighten geometry param typing for spatial predicates.Prefer a named alias over
any[]
for clarity and to keep parity with distance methods.- static intersects = (attribute: string, values: any[]): string => + static intersects = (attribute: string, values: GeometryValues): string => new Query("intersects", attribute, values).toString(); - static notIntersects = (attribute: string, values: any[]): string => + static notIntersects = (attribute: string, values: GeometryValues): string => new Query("notIntersects", attribute, values).toString(); - static crosses = (attribute: string, values: any[]): string => + static crosses = (attribute: string, values: GeometryValues): string => new Query("crosses", attribute, values).toString(); - static notCrosses = (attribute: string, values: any[]): string => + static notCrosses = (attribute: string, values: GeometryValues): string => new Query("notCrosses", attribute, values).toString(); - static overlaps = (attribute: string, values: any[]): string => + static overlaps = (attribute: string, values: GeometryValues): string => new Query("overlaps", attribute, values).toString(); - static notOverlaps = (attribute: string, values: any[]): string => + static notOverlaps = (attribute: string, values: GeometryValues): string => new Query("notOverlaps", attribute, values).toString(); - static touches = (attribute: string, values: any[]): string => + static touches = (attribute: string, values: GeometryValues): string => new Query("touches", attribute, values).toString(); - static notTouches = (attribute: string, values: any[]): string => + static notTouches = (attribute: string, values: GeometryValues): string => new Query("notTouches", attribute, values).toString();
351-356
: Clarify JSDoc: specify value format and units.State expected coordinate/geometry format (e.g., [lon, lat] in WGS84 or GeoJSON) and distance units (meters? kilometers?), plus geodesic vs planar behavior.
templates/react-native/src/query.ts.twig (3)
211-214
: Fix JSDoc param type mismatch (values).Doc says
@param {number[]} values
but the signature usesany[]
. Align the doc to avoid misleading users.- * @param {number[]} values + * @param {any[]} values
248-319
: Use GeometryValues alias for spatial predicates.Keep consistency with distance methods and improve readability.
- static intersects = (attribute: string, values: any[]): string => + static intersects = (attribute: string, values: GeometryValues): string => new Query("intersects", attribute, values).toString(); - static notIntersects = (attribute: string, values: any[]): string => + static notIntersects = (attribute: string, values: GeometryValues): string => new Query("notIntersects", attribute, values).toString(); - static crosses = (attribute: string, values: any[]): string => + static crosses = (attribute: string, values: GeometryValues): string => new Query("crosses", attribute, values).toString(); - static notCrosses = (attribute: string, values: any[]): string => + static notCrosses = (attribute: string, values: GeometryValues): string => new Query("notCrosses", attribute, values).toString(); - static overlaps = (attribute: string, values: any[]): string => + static overlaps = (attribute: string, values: GeometryValues): string => new Query("overlaps", attribute, values).toString(); - static notOverlaps = (attribute: string, values: any[]): string => + static notOverlaps = (attribute: string, values: GeometryValues): string => new Query("notOverlaps", attribute, values).toString(); - static touches = (attribute: string, values: any[]): string => + static touches = (attribute: string, values: GeometryValues): string => new Query("touches", attribute, values).toString(); - static notTouches = (attribute: string, values: any[]): string => + static notTouches = (attribute: string, values: GeometryValues): string => new Query("notTouches", attribute, values).toString();
197-239
: Optional: validate distance inputs.Same guard as proposed for web template.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (12)
templates/android/library/src/main/java/io/package/Query.kt.twig
(1 hunks)templates/dart/lib/query.dart.twig
(1 hunks)templates/deno/src/query.ts.twig
(1 hunks)templates/dotnet/Package/Query.cs.twig
(1 hunks)templates/go/query.go.twig
(1 hunks)templates/kotlin/src/main/kotlin/io/appwrite/Query.kt.twig
(1 hunks)templates/php/src/Query.php.twig
(1 hunks)templates/python/package/query.py.twig
(1 hunks)templates/react-native/src/query.ts.twig
(1 hunks)templates/ruby/lib/container/query.rb.twig
(1 hunks)templates/swift/Sources/Query.swift.twig
(1 hunks)templates/web/src/query.ts.twig
(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (19)
- GitHub Check: build (8.3, Python311)
- GitHub Check: build (8.3, Deno1303)
- GitHub Check: build (8.3, WebChromium)
- GitHub Check: build (8.3, Ruby27)
- GitHub Check: build (8.3, Swift56)
- GitHub Check: build (8.3, AppleSwift56)
- GitHub Check: build (8.3, Python310)
- GitHub Check: build (8.3, PHP83)
- GitHub Check: build (8.3, Python312)
- GitHub Check: build (8.3, PHP80)
- GitHub Check: build (8.3, Node18)
- GitHub Check: build (8.3, KotlinJava8)
- GitHub Check: build (8.3, KotlinJava17)
- GitHub Check: build (8.3, KotlinJava11)
- GitHub Check: build (8.3, FlutterStable)
- GitHub Check: build (8.3, FlutterBeta)
- GitHub Check: build (8.3, DotNet60)
- GitHub Check: build (8.3, Android5Java17)
- GitHub Check: build (8.3, Android14Java17)
🔇 Additional comments (13)
templates/python/package/query.py.twig (1)
146-192
: LGTM: Python spatial/distance query helpers match existing patterns and payload shapes.
Consistent snake_case API and correct [values, distance] packaging.templates/ruby/lib/container/query.rb.twig (1)
155-201
: LGTM: Ruby DSL adds spatial/distance methods with correct serialization and parity.
Constructor args and [values, distance] structure look good.templates/kotlin/src/main/kotlin/io/appwrite/Query.kt.twig (1)
76-98
: LGTM: Kotlin additions mirror existing factories and preserve JSON shape.
Use of Number for distance and listOf(values, distance) is appropriate.templates/dotnet/Package/Query.cs.twig (1)
205-263
: LGTM: .NET methods correctly emit nested payload [values, distance].
Signatures and ToString() usage are consistent with the rest of the class.templates/php/src/Query.php.twig (2)
456-549
: Spatial predicates block looks good.Signatures, docs, and serialization mirror existing patterns. No issues from a PHP standpoint.
411-414
: The script above will accurately detect the extra nesting in the PHP template and confirm whether dotnet and Swift templates have the same issue. Once we have those results, we can finalize the diff to remove the double brackets and ensure consistency across all SDKs.templates/swift/Sources/Query.swift.twig (1)
433-495
: Spatial/distance API looks good; depends on serializer fix above.Signatures and payload shapes align with other SDKs. After adding array support to QueryValue, these builders should serialize correctly.
You can spot-check with a playground by calling distanceEqual("loc", values: [[10.0, 20.0]], distance: 1000) and ensuring "values":[[[10.0,20.0]],1000] appears in description.
templates/android/library/src/main/java/io/package/Query.kt.twig (1)
289-399
: LGTM on new spatial/distance builders.Signatures, docs, and payload shapes match the cross-language pattern. No issues found.
templates/go/query.go.twig (1)
321-415
: LGTM on Go helpers.Functions produce the expected nested payload ([]interface{}{values, distance}) and mirror existing parseQuery usage. No issues found.
templates/dart/lib/query.dart.twig (1)
170-216
: LGTM on Dart additions.APIs and payload shapes align with other SDKs; jsonEncode will handle nested lists correctly.
templates/web/src/query.ts.twig (1)
349-473
: API surface LGTM overall.Additions are consistent with existing
Query
API and serialization approach.templates/react-native/src/query.ts.twig (2)
196-319
: API surface LGTM overall.Additions match the existing pattern and serialization contract.
196-319
: Spatial filter methods parity verified
All 12 spatial‐filter methods are present in every SDK template and the React Native docs consistently useany[]
(no straynumber[]
).
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.
Looks good, let's update the tests too
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: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
templates/go/query.go.twig (1)
251-255
: Syntax error: extra closing brace in OrderDescThere’s an extra “}” after parseQuery, which will fail to compile.
- return parseQuery(queryOptions{ - Method: "orderDesc", - Attribute: &attribute, - })} + return parseQuery(queryOptions{ + Method: "orderDesc", + Attribute: &attribute, + })
♻️ Duplicate comments (2)
templates/deno/src/query.ts.twig (1)
200-246
: Remove unsafe casts: widen types to model distance payloadsThe new helpers cast [[values, distance, meters]] to QueryTypesList, which doesn’t cover that shape. Define a tuple type and update Query.values to accept it; then drop the casts.
Apply these diffs:
- Types and class field/signature:
-type QueryTypesSingle = string | number | boolean; -export type QueryTypesList = string[] | number[] | boolean[] | Query[]; -export type QueryTypes = QueryTypesSingle | QueryTypesList; +type QueryTypesSingle = string | number | boolean; +export type QueryTypesList = string[] | number[] | boolean[] | Query[]; +export type QueryTypes = QueryTypesSingle | QueryTypesList; +// New: support distance payloads [[values, distance, meters]] +export type DistancePayload = [any[], number, boolean]; +export type QueryValues = QueryTypesList | DistancePayload[]; @@ export class Query { method: string; attribute: AttributesTypes | undefined; - values: QueryTypesList | undefined; + values: QueryValues | undefined; @@ - constructor( + constructor( method: string, attribute?: AttributesTypes, - values?: QueryTypes + values?: QueryTypes | DistancePayload[] ) { @@ - this.values = [values] as QueryTypesList; + this.values = [values] as QueryValues;
- Drop casts in distance helpers:
- static distanceEqual = (attribute: string, values: any[], distance: number, meters: boolean = false): string => - new Query("distanceEqual", attribute, [[values, distance, meters]] as QueryTypesList).toString(); + static distanceEqual = (attribute: string, values: any[], distance: number, meters: boolean = false): string => + new Query("distanceEqual", attribute, [[values, distance, meters]]).toString(); @@ - static distanceNotEqual = (attribute: string, values: any[], distance: number, meters: boolean = false): string => - new Query("distanceNotEqual", attribute, [[values, distance, meters]] as QueryTypesList).toString(); + static distanceNotEqual = (attribute: string, values: any[], distance: number, meters: boolean = false): string => + new Query("distanceNotEqual", attribute, [[values, distance, meters]]).toString(); @@ - static distanceGreaterThan = (attribute: string, values: any[], distance: number, meters: boolean = false): string => - new Query("distanceGreaterThan", attribute, [[values, distance, meters]] as QueryTypesList).toString(); + static distanceGreaterThan = (attribute: string, values: any[], distance: number, meters: boolean = false): string => + new Query("distanceGreaterThan", attribute, [[values, distance, meters]]).toString(); @@ - static distanceLessThan = (attribute: string, values: any[], distance: number, meters: boolean = false): string => - new Query("distanceLessThan", attribute, [[values, distance, meters]] as QueryTypesList).toString(); + static distanceLessThan = (attribute: string, values: any[], distance: number, meters: boolean = false): string => + new Query("distanceLessThan", attribute, [[values, distance, meters]]).toString();templates/swift/Sources/Query.swift.twig (1)
401-431
: Swift: values for distance methods will be dropped at serialization. Add array support to QueryValue.
values: [[values, distance, meters]]
is a nested heterogeneous array, butQueryValue
cannot encode arrays, sovalues
becomes nil and is omitted.Apply the following changes outside this block to support arrays and recursive conversion:
@@ enum QueryValue: Codable { - case string(String) - case int(Int) - case double(Double) - case bool(Bool) - case query(Query) + case string(String) + case int(Int) + case double(Double) + case bool(Bool) + case query(Query) + case array([QueryValue]) @@ init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() // Attempt to decode each type if let stringValue = try? container.decode(String.self) { self = .string(stringValue) } else if let intValue = try? container.decode(Int.self) { self = .int(intValue) } else if let doubleValue = try? container.decode(Double.self) { self = .double(doubleValue) } else if let boolValue = try? container.decode(Bool.self) { self = .bool(boolValue) } else if let queryValue = try? container.decode(Query.self) { self = .query(queryValue) + } else if let arrayValue = try? container.decode([QueryValue].self) { + self = .array(arrayValue) } else { throw DecodingError.dataCorruptedError(in: container, debugDescription: "QueryValue cannot be decoded") } } @@ func encode(to encoder: Encoder) throws { var container = encoder.singleValueContainer() switch self { case .string(let value): try container.encode(value) case .int(let value): try container.encode(value) case .double(let value): try container.encode(value) case .bool(let value): try container.encode(value) case .query(let value): try container.encode(value) + case .array(let value): + try container.encode(value) } } @@ - private static func convertToQueryValueArray(_ values: Any?) -> [QueryValue]? { + private static func convertToQueryValueArray(_ values: Any?) -> [QueryValue]? { switch values { case let valueArray as [QueryValue]: return valueArray case let stringArray as [String]: return stringArray.map { .string($0) } case let intArray as [Int]: return intArray.map { .int($0) } case let doubleArray as [Double]: return doubleArray.map { .double($0) } case let boolArray as [Bool]: return boolArray.map { .bool($0) } case let queryArray as [Query]: return queryArray.map { .query($0) } + case let anyArray as [Any]: + return anyArray.compactMap { convertAnyToQueryValue($0) } case let stringValue as String: return [.string(stringValue)] case let intValue as Int: return [.int(intValue)] case let doubleValue as Double: return [.double(doubleValue)] case let boolValue as Bool: return [.bool(boolValue)] case let queryValue as Query: return [.query(queryValue)] default: return nil } } + + private static func convertAnyToQueryValue(_ value: Any) -> QueryValue? { + switch value { + case let v as String: return .string(v) + case let v as Int: return .int(v) + case let v as Double: return .double(v) + case let v as Bool: return .bool(v) + case let v as Query: return .query(v) + case let v as [Any]: + let mapped = v.compactMap { convertAnyToQueryValue($0) } + return .array(mapped) + default: + return nil + } + }This also fixes the geometry helpers below.
🧹 Nitpick comments (12)
templates/go/query.go.twig (2)
321-351
: DRY the four distance helpers via a shared builderEach function repeats the same payload construction. Introduce a small helper and call it for consistency and easier maintenance.
Apply within this range:
-func DistanceEqual(attribute string, values []interface{}, distance float64, meters bool) string { - return parseQuery(queryOptions{ - Method: "distanceEqual", - Attribute: &attribute, - Values: &[]interface{}{[]interface{}{values, distance, meters}}, - }) -} +func DistanceEqual(attribute string, values []interface{}, distance float64, meters bool) string { + return distanceQuery("distanceEqual", attribute, values, distance, meters) +} -func DistanceNotEqual(attribute string, values []interface{}, distance float64, meters bool) string { - return parseQuery(queryOptions{ - Method: "distanceNotEqual", - Attribute: &attribute, - Values: &[]interface{}{[]interface{}{values, distance, meters}}, - }) -} +func DistanceNotEqual(attribute string, values []interface{}, distance float64, meters bool) string { + return distanceQuery("distanceNotEqual", attribute, values, distance, meters) +} -func DistanceGreaterThan(attribute string, values []interface{}, distance float64, meters bool) string { - return parseQuery(queryOptions{ - Method: "distanceGreaterThan", - Attribute: &attribute, - Values: &[]interface{}{[]interface{}{values, distance, meters}}, - }) -} +func DistanceGreaterThan(attribute string, values []interface{}, distance float64, meters bool) string { + return distanceQuery("distanceGreaterThan", attribute, values, distance, meters) +} -func DistanceLessThan(attribute string, values []interface{}, distance float64, meters bool) string { - return parseQuery(queryOptions{ - Method: "distanceLessThan", - Attribute: &attribute, - Values: &[]interface{}{[]interface{}{values, distance, meters}}, - }) -} +func DistanceLessThan(attribute string, values []interface{}, distance float64, meters bool) string { + return distanceQuery("distanceLessThan", attribute, values, distance, meters) +}Add this helper (outside the changed hunk):
func distanceQuery(method, attribute string, values []interface{}, distance float64, meters bool) string { return parseQuery(queryOptions{ Method: method, Attribute: &attribute, Values: &[]interface{}{[]interface{}{values, distance, meters}}, }) }
353-414
: Factor the 8 spatial helpers through a single builderThese methods are identical aside from the method string. Reduce duplication with a tiny helper.
Within this range:
-func Intersects(attribute string, values []interface{}) string { - return parseQuery(queryOptions{ - Method: "intersects", - Attribute: &attribute, - Values: &values, - }) -} +func Intersects(attribute string, values []interface{}) string { + return spatialQuery("intersects", attribute, values) +} @@ -func NotTouches(attribute string, values []interface{}) string { - return parseQuery(queryOptions{ - Method: "notTouches", - Attribute: &attribute, - Values: &values, - }) -} +func NotTouches(attribute string, values []interface{}) string { + return spatialQuery("notTouches", attribute, values) +}Add once (outside the changed hunk):
func spatialQuery(method, attribute string, values []interface{}) string { return parseQuery(queryOptions{ Method: method, Attribute: &attribute, Values: &values, }) }templates/ruby/lib/container/query.rb.twig (2)
155-169
: Deduplicate distance_ with a private helper*All four methods differ only by the method string. Use a single builder to reduce repetition and risk of divergence.
Within this range:
-def distance_equal(attribute, values, distance, meters = false) - return Query.new("distanceEqual", attribute, [[values, distance, meters]]).to_s -end +def distance_equal(attribute, values, distance, meters = false) + return distance_query("distanceEqual", attribute, values, distance, meters) +end @@ -def distance_not_equal(attribute, values, distance, meters = false) - return Query.new("distanceNotEqual", attribute, [[values, distance, meters]]).to_s -end +def distance_not_equal(attribute, values, distance, meters = false) + return distance_query("distanceNotEqual", attribute, values, distance, meters) +end @@ -def distance_greater_than(attribute, values, distance, meters = false) - return Query.new("distanceGreaterThan", attribute, [[values, distance, meters]]).to_s -end +def distance_greater_than(attribute, values, distance, meters = false) + return distance_query("distanceGreaterThan", attribute, values, distance, meters) +end @@ -def distance_less_than(attribute, values, distance, meters = false) - return Query.new("distanceLessThan", attribute, [[values, distance, meters]]).to_s -end +def distance_less_than(attribute, values, distance, meters = false) + return distance_query("distanceLessThan", attribute, values, distance, meters) +endAdd once in this class’ singleton scope:
private def distance_query(method, attribute, values, distance, meters) Query.new(method, attribute, [[values, distance, meters]]).to_s end
171-201
: Optional: add brief YARD docs for new methodsShort comments for parameters (attribute, values, distance, meters) would align with surrounding public API docs and ease SDK consumers’ usage.
templates/dart/lib/query.dart.twig (1)
170-185
: Add lightweight input guards for distance helpersGuarding obvious invalid inputs (negative/NaN distance, empty coordinates) improves DX without runtime cost in release (asserts stripped).
-static String distanceEqual(String attribute, List<dynamic> values, double distance, [bool meters = false]) => - Query._('distanceEqual', attribute, [[values, distance, meters]]).toString(); +static String distanceEqual(String attribute, List<dynamic> values, double distance, [bool meters = false]) { + assert(values.isNotEmpty, 'values must not be empty'); + assert(distance.isFinite && distance >= 0, 'distance must be a non-negative finite number'); + return Query._('distanceEqual', attribute, [[values, distance, meters]]).toString(); +}Replicate the same pattern for the other three distance methods in this hunk.
templates/kotlin/src/main/kotlin/io/appwrite/Query.kt.twig (2)
76-118
: Fix KDoc tag: use @return (not @returns)KDoc recognizes @return; current @returns won’t render properly.
- * @returns The query string. + * @return The query string.Apply to all four distance KDoc blocks in this hunk.
120-134
: Optional: share distance builder to avoid duplicationA tiny helper keeps method bodies uniform.
Example:
private fun distanceQuery(method: String, attribute: String, values: List<Any>, distance: Number, meters: Boolean) = Query(method, attribute, listOf(listOf(values, distance, meters))).toJson() // Usage: fun distanceEqual(attribute: String, values: List<Any>, distance: Number, meters: Boolean = false) = distanceQuery("distanceEqual", attribute, values, distance, meters)templates/deno/src/query.ts.twig (1)
1-5
: Optional: tighten attribute/values docsConsider documenting the expected geometry format (e.g., [lng, lat], GeoJSON arrays) to reduce ambiguity for SDK users.
templates/android/library/src/main/java/io/package/Query.kt.twig (2)
289-331
: Confirm serializer supports nested heterogeneous arrays for distance queries.
values
is serialized as [[values, distance, meters]] (List containing a nested List with mixed types). IftoJson
isn’t robust to nested mixed arrays, payload may drop or mis-encode. Add a unit test for one happy-path example and verify equivalence with server expectations.Example quick check to add to tests (pseudocode):
- distanceEqual("geo", listOf(1.0, 2.0), 1000, true) should JSON-encode values as [[[1.0,2.0],1000,true]]
333-404
: Tighten docs and consider a geometry alias for clarity.The spatial methods accept
values: List<Any>
, which is flexible but opaque. Considertypealias Geometry = List<Any>
and clarify accepted shapes (e.g., [lon, lat], LineString, Polygon rings) in KDoc to reduce misuse.- * @param values The coordinate values. + * @param values Geometry coordinates (e.g., [lon, lat] or GeoJSON-like arrays).templates/react-native/src/query.ts.twig (2)
196-244
: Type-safety: replace any[] and casts; model distance args explicitly.Drop
as QueryTypesList
and define Geometry/Distance tuple types so nested arrays are typed and safe.Apply within this block:
- static distanceEqual = (attribute: string, values: any[], distance: number, meters: boolean = false): string => - new Query("distanceEqual", attribute, [[values, distance, meters]] as QueryTypesList).toString(); + static distanceEqual = (attribute: string, values: GeometryValues, distance: number, meters: boolean = false): string => + new Query("distanceEqual", attribute, [[values, distance, meters]]).toString(); - static distanceNotEqual = (attribute: string, values: any[], distance: number, meters: boolean = false): string => - new Query("distanceNotEqual", attribute, [[values, distance, meters]] as QueryTypesList).toString(); + static distanceNotEqual = (attribute: string, values: GeometryValues, distance: number, meters: boolean = false): string => + new Query("distanceNotEqual", attribute, [[values, distance, meters]]).toString(); - static distanceGreaterThan = (attribute: string, values: any[], distance: number, meters: boolean = false): string => - new Query("distanceGreaterThan", attribute, [[values, distance, meters]] as QueryTypesList).toString(); + static distanceGreaterThan = (attribute: string, values: GeometryValues, distance: number, meters: boolean = false): string => + new Query("distanceGreaterThan", attribute, [[values, distance, meters]]).toString(); - static distanceLessThan = (attribute: string, values: any[], distance: number, meters: boolean = false): string => - new Query("distanceLessThan", attribute, [[values, distance, meters]] as QueryTypesList).toString(); + static distanceLessThan = (attribute: string, values: GeometryValues, distance: number, meters: boolean = false): string => + new Query("distanceLessThan", attribute, [[values, distance, meters]]).toString();And at the top (types):
type QueryTypesSingle = string | number | boolean; -export type QueryTypesList = string[] | number[] | boolean[] | Query[]; +export type GeometryValues = unknown[]; // e.g., [lon, lat] or nested coords +export type DistanceArgs = [GeometryValues, number, boolean?]; +export type QueryTypesList = + | string[] + | number[] + | boolean[] + | Query[] + | GeometryValues + | DistanceArgs[]; export type QueryTypes = QueryTypesSingle | QueryTypesList;
245-324
: Also type geometry relations methods (avoid any[]).Mirror the GeometryValues type to these methods.
- static intersects = (attribute: string, values: any[]): string => + static intersects = (attribute: string, values: GeometryValues): string => new Query("intersects", attribute, values).toString(); - static notIntersects = (attribute: string, values: any[]): string => + static notIntersects = (attribute: string, values: GeometryValues): string => new Query("notIntersects", attribute, values).toString(); - static crosses = (attribute: string, values: any[]): string => + static crosses = (attribute: string, values: GeometryValues): string => new Query("crosses", attribute, values).toString(); - static notCrosses = (attribute: string, values: any[]): string => + static notCrosses = (attribute: string, values: GeometryValues): string => new Query("notCrosses", attribute, values).toString(); - static overlaps = (attribute: string, values: any[]): string => + static overlaps = (attribute: string, values: GeometryValues): string => new Query("overlaps", attribute, values).toString(); - static notOverlaps = (attribute: string, values: any[]): string => + static notOverlaps = (attribute: string, values: GeometryValues): string => new Query("notOverlaps", attribute, values).toString(); - static touches = (attribute: string, values: any[]): string => + static touches = (attribute: string, values: GeometryValues): string => new Query("touches", attribute, values).toString(); - static notTouches = (attribute: string, values: any[]): string => + static notTouches = (attribute: string, values: GeometryValues): string => new Query("notTouches", attribute, values).toString();
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (12)
templates/android/library/src/main/java/io/package/Query.kt.twig
(1 hunks)templates/dart/lib/query.dart.twig
(1 hunks)templates/deno/src/query.ts.twig
(1 hunks)templates/dotnet/Package/Query.cs.twig
(1 hunks)templates/go/query.go.twig
(1 hunks)templates/kotlin/src/main/kotlin/io/appwrite/Query.kt.twig
(1 hunks)templates/php/src/Query.php.twig
(1 hunks)templates/python/package/query.py.twig
(1 hunks)templates/react-native/src/query.ts.twig
(1 hunks)templates/ruby/lib/container/query.rb.twig
(1 hunks)templates/swift/Sources/Query.swift.twig
(1 hunks)templates/web/src/query.ts.twig
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
- templates/python/package/query.py.twig
- templates/php/src/Query.php.twig
- templates/dotnet/Package/Query.cs.twig
- templates/web/src/query.ts.twig
🔇 Additional comments (3)
templates/dart/lib/query.dart.twig (1)
186-216
: LGTM on spatial helpersSignatures and payload shape match existing conventions.
templates/deno/src/query.ts.twig (1)
248-326
: LGTM on spatial helpersSignatures and serialization align with existing conventions.
templates/swift/Sources/Query.swift.twig (1)
433-495
: Geometry helpers depend on the array support fix above.Without the
QueryValue.array
/recursive conversion,[Any]
payloads here will also be lost. Re-test after applying the encoder changes.
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: 3
♻️ Duplicate comments (4)
templates/deno/src/query.ts.twig (1)
209-246
: Remove unsafe casts and widen types for distance payloadsCurrent casts to QueryTypesList are unsound; model the payload explicitly and drop the casts.
- static distanceEqual = (attribute: string, values: any[], distance: number, meters: boolean = false): string => - new Query("distanceEqual", attribute, [[values, distance, meters]] as QueryTypesList).toString(); + static distanceEqual = (attribute: string, values: any[], distance: number, meters: boolean = false): string => + new Query("distanceEqual", attribute, [[values, distance, meters]]).toString(); - static distanceNotEqual = (attribute: string, values: any[], distance: number, meters: boolean = false): string => - new Query("distanceNotEqual", attribute, [[values, distance, meters]] as QueryTypesList).toString(); + static distanceNotEqual = (attribute: string, values: any[], distance: number, meters: boolean = false): string => + new Query("distanceNotEqual", attribute, [[values, distance, meters]]).toString(); - static distanceGreaterThan = (attribute: string, values: any[], distance: number, meters: boolean = false): string => - new Query("distanceGreaterThan", attribute, [[values, distance, meters]] as QueryTypesList).toString(); + static distanceGreaterThan = (attribute: string, values: any[], distance: number, meters: boolean = false): string => + new Query("distanceGreaterThan", attribute, [[values, distance, meters]]).toString(); - static distanceLessThan = (attribute: string, values: any[], distance: number, meters: boolean = false): string => - new Query("distanceLessThan", attribute, [[values, distance, meters]] as QueryTypesList).toString(); + static distanceLessThan = (attribute: string, values: any[], distance: number, meters: boolean = false): string => + new Query("distanceLessThan", attribute, [[values, distance, meters]]).toString();Additions required outside this hunk (type support for the new payload):
// At top-level types: export type DistancePayload = [any[], number, boolean]; export type QueryValues = QueryTypesList | DistancePayload[]; // In class: values: QueryValues | undefined; constructor(method: string, attribute?: AttributesTypes, values?: QueryValues) { /* rest unchanged */ }templates/web/src/query.ts.twig (1)
359-396
: Remove unsafe casts; add GeometryValues/DistancePayload types and tighten method signatures.The
as QueryTypesList
casts are unsound, andany[]
leaks type-safety. Define explicit tuple/geometry types and remove the casts. Also keep the outer array (list of one payload) to stay consistent with other SDKs.Apply within this block:
- static distanceEqual = (attribute: string, values: any[], distance: number, meters: boolean = false): string => - new Query("distanceEqual", attribute, [[values, distance, meters]] as QueryTypesList).toString(); + static distanceEqual = (attribute: string, values: GeometryValues, distance: number, meters: boolean = false): string => + new Query("distanceEqual", attribute, [[values, distance, meters] as DistancePayload]).toString(); - static distanceNotEqual = (attribute: string, values: any[], distance: number, meters: boolean = false): string => - new Query("distanceNotEqual", attribute, [[values, distance, meters]] as QueryTypesList).toString(); + static distanceNotEqual = (attribute: string, values: GeometryValues, distance: number, meters: boolean = false): string => + new Query("distanceNotEqual", attribute, [[values, distance, meters] as DistancePayload]).toString(); - static distanceGreaterThan = (attribute: string, values: any[], distance: number, meters: boolean = false): string => - new Query("distanceGreaterThan", attribute, [[values, distance, meters]] as QueryTypesList).toString(); + static distanceGreaterThan = (attribute: string, values: GeometryValues, distance: number, meters: boolean = false): string => + new Query("distanceGreaterThan", attribute, [[values, distance, meters] as DistancePayload]).toString(); - static distanceLessThan = (attribute: string, values: any[], distance: number, meters: boolean = false): string => - new Query("distanceLessThan", attribute, [[values, distance, meters]] as QueryTypesList).toString(); + static distanceLessThan = (attribute: string, values: GeometryValues, distance: number, meters: boolean = false): string => + new Query("distanceLessThan", attribute, [[values, distance, meters] as DistancePayload]).toString();Add these type defs near the top (outside the changed block):
export type GeometryValues = unknown[]; // e.g., coordinates or GeoJSON export type DistancePayload = [GeometryValues, number, boolean];And widen the list union to accept these payloads (outside the changed block):
export type QueryTypesList = | string[] | number[] | boolean[] | Query[] | GeometryValues | DistancePayload[];templates/swift/Sources/Query.swift.twig (1)
401-431
: Swift encoder drops nested/heterogeneous arrays; distance values will be omitted.*
values: [[values, distance, meters]]
becomes[Any]
of nested arrays whichconvertToQueryValueArray
can’t encode; JSON omitsvalues
.Implement array support and recursive conversion:
// 1) Extend QueryValue enum QueryValue: Codable { case string(String) case int(Int) case double(Double) case bool(Bool) case query(Query) case array([QueryValue]) // NEW init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() if let v = try? container.decode(String.self) { self = .string(v) } else if let v = try? container.decode(Int.self) { self = .int(v) } else if let v = try? container.decode(Double.self) { self = .double(v) } else if let v = try? container.decode(Bool.self) { self = .bool(v) } else if let v = try? container.decode(Query.self) { self = .query(v) } else if let v = try? container.decode([QueryValue].self) { self = .array(v) } // NEW else { throw DecodingError.dataCorruptedError(in: container, debugDescription: "QueryValue cannot be decoded") } } func encode(to encoder: Encoder) throws { var container = encoder.singleValueContainer() switch self { case .string(let v): try container.encode(v) case .int(let v): try container.encode(v) case .double(let v): try container.encode(v) case .bool(let v): try container.encode(v) case .query(let v): try container.encode(v) case .array(let v): try container.encode(v) // NEW } } } // 2) Teach converter to handle [Any] recursively private static func convertToQueryValueArray(_ values: Any?) -> [QueryValue]? { switch values { case let valueArray as [QueryValue]: return valueArray case let stringArray as [String]: return stringArray.map { .string($0) } case let intArray as [Int]: return intArray.map { .int($0) } case let doubleArray as [Double]: return doubleArray.map { .double($0) } case let boolArray as [Bool]: return boolArray.map { .bool($0) } case let queryArray as [Query]: return queryArray.map { .query($0) } case let anyArray as [Any]: return anyArray.compactMap { convertAnyToQueryValue($0) } // NEW case let stringValue as String: return [.string(stringValue)] case let intValue as Int: return [.int(intValue)] case let doubleValue as Double: return [.double(doubleValue)] case let boolValue as Bool: return [.bool(boolValue)] case let queryValue as Query: return [.query(queryValue)] default: return nil } } // 3) Helper for recursive mapping private static func convertAnyToQueryValue(_ value: Any) -> QueryValue? { switch value { case let v as String: return .string(v) case let v as Int: return .int(v) case let v as Double: return .double(v) case let v as Bool: return .bool(v) case let v as Query: return .query(v) case let v as [Any]: let mapped = v.compactMap { convertAnyToQueryValue($0) } return .array(mapped) default: return nil } }Please add a simple unit test asserting
distanceEqual(_:values:distance:meters:)
produces a JSON whosevalues
is a non-empty array with the nested triplet.templates/react-native/src/query.ts.twig (1)
206-208
: Fix payload shape and drop unsafe casts for distance queries.The extra outer array turns the payload into
[[values, distance, meters]]
instead of[values, distance, meters]
. That’s a wire-format/contract bug. Also,any[]
+as QueryTypesList
bypasses type-safety.Apply this diff within these methods:
- static distanceEqual = (attribute: string, values: any[], distance: number, meters: boolean = false): string => - new Query("distanceEqual", attribute, [[values, distance, meters]] as QueryTypesList).toString(); + static distanceEqual = (attribute: string, values: GeometryValues, distance: number, meters: boolean = false): string => + new Query("distanceEqual", attribute, [values, distance, meters]).toString(); - static distanceNotEqual = (attribute: string, values: any[], distance: number, meters: boolean = false): string => - new Query("distanceNotEqual", attribute, [[values, distance, meters]] as QueryTypesList).toString(); + static distanceNotEqual = (attribute: string, values: GeometryValues, distance: number, meters: boolean = false): string => + new Query("distanceNotEqual", attribute, [values, distance, meters]).toString(); - static distanceGreaterThan = (attribute: string, values: any[], distance: number, meters: boolean = false): string => - new Query("distanceGreaterThan", attribute, [[values, distance, meters]] as QueryTypesList).toString(); + static distanceGreaterThan = (attribute: string, values: GeometryValues, distance: number, meters: boolean = false): string => + new Query("distanceGreaterThan", attribute, [values, distance, meters]).toString(); - static distanceLessThan = (attribute: string, values: any[], distance: number, meters: boolean = false): string => - new Query("distanceLessThan", attribute, [[values, distance, meters]] as QueryTypesList).toString(); + static distanceLessThan = (attribute: string, values: GeometryValues, distance: number, meters: boolean = false): string => + new Query("distanceLessThan", attribute, [values, distance, meters]).toString();Additionally (outside the changed hunk), update type defs near the top to make this type-safe and remove casts:
type QueryTypesSingle = string | number | boolean; -export type QueryTypesList = string[] | number[] | boolean[] | Query[]; +export type GeometryValues = unknown[]; +export type DistanceValues = [GeometryValues, number] | [GeometryValues, number, boolean]; +export type QueryTypesList = string[] | number[] | boolean[] | Query[] | GeometryValues | DistanceValues; export type QueryTypes = QueryTypesSingle | QueryTypesList;Run to confirm parity with the web template and catch shape/cast mismatches:
#!/bin/bash # Compare RN vs Web templates for distance helpers rg -n "distance(Equal|NotEqual|GreaterThan|LessThan)" templates/{react-native,web}/src/query.ts.twig -C2 # Inspect presence of 'meters' and ensure no nested brackets `[[` in RN distance payloads rg -n "distance(Equal|NotEqual|GreaterThan|LessThan).*\\[\\[" templates/react-native/src/query.ts.twig -C1Also applies to: 218-220, 230-232, 242-244
🧹 Nitpick comments (11)
templates/python/package/query.py.twig (1)
162-192
: Add minimal usage docs/types for new spatial predicatesAdd brief docstrings to clarify accepted geometry formats (GeoJSON, [lon, lat], WKT?) and whether multiple geometries are supported in one call.
Example:
@staticmethod - def intersects(attribute, values): + def intersects(attribute, values): + """Return spatial intersects query. + values: GeoJSON geometry or list of geometries.""" return str(Query("intersects", attribute, values))I can open a follow-up PR to add docstrings/tests across templates.
templates/ruby/lib/container/query.rb.twig (1)
171-201
: Optional: support splat for single/multiple geometriesAllow passing either a single geometry or multiple without array-wrapping.
- def intersects(attribute, values) - return Query.new("intersects", attribute, values).to_s + def intersects(attribute, *values) + vals = values.length == 1 ? values.first : values + return Query.new("intersects", attribute, vals).to_s endApply similarly to not_intersects, crosses, not_crosses, overlaps, not_overlaps, touches, not_touches.
Please confirm if multiple geometries per predicate are supported by the API before merging this change.
templates/kotlin/src/main/kotlin/io/appwrite/Query.kt.twig (2)
76-118
: Fix KDoc tag: use @return (not @returns) in all distance docsKeeps docs consistent with KDoc.
@@ - * @returns The query string. + * @return The query string. @@ - * @returns The query string. + * @return The query string. @@ - * @returns The query string. + * @return The query string. @@ - * @returns The query string. + * @return The query string.
120-134
: Add brief KDoc for spatial predicatesThe new spatial helpers lack KDoc while distance ones have it. Add 1–2 line summaries for parity.
templates/dart/lib/query.dart.twig (2)
171-184
: Allow integer distances: use num instead of doubleMatches Kotlin’s Number and PHP’s int|float; avoids forcing callers to cast.
- static String distanceEqual(String attribute, List<dynamic> values, double distance, [bool meters = false]) => + static String distanceEqual(String attribute, List<dynamic> values, num distance, [bool meters = false]) => @@ - static String distanceNotEqual(String attribute, List<dynamic> values, double distance, [bool meters = false]) => + static String distanceNotEqual(String attribute, List<dynamic> values, num distance, [bool meters = false]) => @@ - static String distanceGreaterThan(String attribute, List<dynamic> values, double distance, [bool meters = false]) => + static String distanceGreaterThan(String attribute, List<dynamic> values, num distance, [bool meters = false]) => @@ - static String distanceLessThan(String attribute, List<dynamic> values, double distance, [bool meters = false]) => + static String distanceLessThan(String attribute, List<dynamic> values, num distance, [bool meters = false]) =>
170-186
: Document meters parameter in Dart docsAdd a short sentence noting units toggle to reduce ambiguity.
templates/php/src/Query.php.twig (1)
403-454
: Docblocks: add missing $meters parameterThree distance docs omit the meters param; add for consistency.
@@ - * @param int|float $distance + * @param int|float $distance + * @param bool $meters @@ - * @param int|float $distance + * @param int|float $distance + * @param bool $meters @@ - * @param int|float $distance + * @param int|float $distance + * @param bool $meterstemplates/web/src/query.ts.twig (1)
405-476
: Replace any[] with GeometryValues for spatial predicates.Improve type-safety and documentation for geometry inputs.
- static intersects = (attribute: string, values: any[]): string => + static intersects = (attribute: string, values: GeometryValues): string => new Query("intersects", attribute, values).toString(); - static notIntersects = (attribute: string, values: any[]): string => + static notIntersects = (attribute: string, values: GeometryValues): string => new Query("notIntersects", attribute, values).toString(); - static crosses = (attribute: string, values: any[]): string => + static crosses = (attribute: string, values: GeometryValues): string => new Query("crosses", attribute, values).toString(); - static notCrosses = (attribute: string, values: any[]): string => + static notCrosses = (attribute: string, values: GeometryValues): string => new Query("notCrosses", attribute, values).toString(); - static overlaps = (attribute: string, values: any[]): string => + static overlaps = (attribute: string, values: GeometryValues): string => new Query("overlaps", attribute, values).toString(); - static notOverlaps = (attribute: string, values: any[]): string => + static notOverlaps = (attribute: string, values: GeometryValues): string => new Query("notOverlaps", attribute, values).toString(); - static touches = (attribute: string, values: any[]): string => + static touches = (attribute: string, values: GeometryValues): string => new Query("touches", attribute, values).toString(); - static notTouches = (attribute: string, values: any[]): string => + static notTouches = (attribute: string, values: GeometryValues): string => new Query("notTouches", attribute, values).toString();templates/android/library/src/main/java/io/package/Query.kt.twig (1)
298-331
: Add @jvmoverloads to distance for Java consumers.*Default params aren’t visible to Java; add overloads for better interop.
- fun distanceEqual(attribute: String, values: List<Any>, distance: Number, meters: Boolean = false) = Query("distanceEqual", attribute, listOf(listOf(values, distance, meters))).toJson() + @JvmOverloads + fun distanceEqual(attribute: String, values: List<Any>, distance: Number, meters: Boolean = false) = + Query("distanceEqual", attribute, listOf(listOf(values, distance, meters))).toJson() - fun distanceNotEqual(attribute: String, values: List<Any>, distance: Number, meters: Boolean = false) = Query("distanceNotEqual", attribute, listOf(listOf(values, distance, meters))).toJson() + @JvmOverloads + fun distanceNotEqual(attribute: String, values: List<Any>, distance: Number, meters: Boolean = false) = + Query("distanceNotEqual", attribute, listOf(listOf(values, distance, meters))).toJson() - fun distanceGreaterThan(attribute: String, values: List<Any>, distance: Number, meters: Boolean = false) = Query("distanceGreaterThan", attribute, listOf(listOf(values, distance, meters))).toJson() + @JvmOverloads + fun distanceGreaterThan(attribute: String, values: List<Any>, distance: Number, meters: Boolean = false) = + Query("distanceGreaterThan", attribute, listOf(listOf(values, distance, meters))).toJson() - fun distanceLessThan(attribute: String, values: List<Any>, distance: Number, meters: Boolean = false) = Query("distanceLessThan", attribute, listOf(listOf(values, distance, meters))).toJson() + @JvmOverloads + fun distanceLessThan(attribute: String, values: List<Any>, distance: Number, meters: Boolean = false) = + Query("distanceLessThan", attribute, listOf(listOf(values, distance, meters))).toJson()templates/react-native/src/query.ts.twig (2)
252-324
: Tighten geometry method signatures: avoidany[]
, use a sharedGeometryValues
type.Keeps parity with the web template and improves DX without hiding errors.
Apply this diff:
- static intersects = (attribute: string, values: any[]): string => + static intersects = (attribute: string, values: GeometryValues): string => new Query("intersects", attribute, values).toString(); - static notIntersects = (attribute: string, values: any[]): string => + static notIntersects = (attribute: string, values: GeometryValues): string => new Query("notIntersects", attribute, values).toString(); - static crosses = (attribute: string, values: any[]): string => + static crosses = (attribute: string, values: GeometryValues): string => new Query("crosses", attribute, values).toString(); - static notCrosses = (attribute: string, values: any[]): string => + static notCrosses = (attribute: string, values: GeometryValues): string => new Query("notCrosses", attribute, values).toString(); - static overlaps = (attribute: string, values: any[]): string => + static overlaps = (attribute: string, values: GeometryValues): string => new Query("overlaps", attribute, values).toString(); - static notOverlaps = (attribute: string, values: any[]): string => + static notOverlaps = (attribute: string, values: GeometryValues): string => new Query("notOverlaps", attribute, values).toString(); - static touches = (attribute: string, values: any[]): string => + static touches = (attribute: string, values: GeometryValues): string => new Query("touches", attribute, values).toString(); - static notTouches = (attribute: string, values: any[]): string => + static notTouches = (attribute: string, values: GeometryValues): string => new Query("notTouches", attribute, values).toString();
197-205
: Clarify docs: shape and units.Document that:
- values is a geometry/coordinates array (state expected coordinate order).
- distance must be non-negative.
- meters defaults to false (and what false means).
Example tweak:
- * @param {any[]} values - * @param {number} distance - * @param {boolean} meters + * @param {GeometryValues} values Coordinates/geometry (e.g. [lon, lat] or polygon ring) + * @param {number} distance Non-negative distance value + * @param {boolean} meters If true, distance is in meters; otherwise default unit (e.g., kilometers)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (12)
templates/android/library/src/main/java/io/package/Query.kt.twig
(1 hunks)templates/dart/lib/query.dart.twig
(1 hunks)templates/deno/src/query.ts.twig
(1 hunks)templates/dotnet/Package/Query.cs.twig
(1 hunks)templates/go/query.go.twig
(1 hunks)templates/kotlin/src/main/kotlin/io/appwrite/Query.kt.twig
(1 hunks)templates/php/src/Query.php.twig
(1 hunks)templates/python/package/query.py.twig
(1 hunks)templates/react-native/src/query.ts.twig
(1 hunks)templates/ruby/lib/container/query.rb.twig
(1 hunks)templates/swift/Sources/Query.swift.twig
(1 hunks)templates/web/src/query.ts.twig
(1 hunks)
🔇 Additional comments (7)
templates/go/query.go.twig (1)
353-415
: Accept single geometry or slice in geometry predicates
Update the eight geometry functions (Intersects, NotIntersects, Crosses, NotCrosses, Overlaps, NotOverlaps, Touches, NotTouches) to match other helpers by acceptingvalue interface{}
and callingtoArray(value)
internally:-func Intersects(attribute string, values []interface{}) string { - return parseQuery(queryOptions{ - Method: "intersects", - Attribute: &attribute, - Values: &values, - }) -} +func Intersects(attribute string, value interface{}) string { + values := toArray(value) + return parseQuery(queryOptions{ + Method: "intersects", + Attribute: &attribute, + Values: &values, + }) +}Repeat for all eight predicates. Ensure a matching
toArray
helper exists and behaves like other helpers. Add unit tests to round-trip the JSON and assert the shape ofValues
for single vs. multiple geometries.templates/kotlin/src/main/kotlin/io/appwrite/Query.kt.twig (1)
85-118
: Confirm backend distance operator payload shape
Validate that the API contract expects a nested-array payload—[[values, distance, meters]]
—for all distance filters, including themeters
flag.templates/dotnet/Package/Query.cs.twig (2)
205-223
: LGTM: correct shape and parity for distance helpersThe nested List { List { values, distance, meters } } matches other templates.
225-263
: LGTM: spatial predicates mirror existing patternConstructors and return shape are consistent with the rest of the class.
templates/php/src/Query.php.twig (1)
456-550
: LGTM: spatial predicates mirror existing API and serializationNaming, signatures, and return values are consistent with prior helpers.
templates/web/src/query.ts.twig (1)
359-396
: Define and document a custom geo-distance payload
Appwrite has no native distance operator, so thesedistance*
methods are purely client-side conventions. Choose a stable tuple shape (e.g.[coordinates, distance]
or[coordinates, distance, "m"]
), implement matching server-side support or a dedicated endpoint, and document the format in the SDK.Likely an incorrect or invalid review comment.
templates/android/library/src/main/java/io/package/Query.kt.twig (1)
298-331
: Verify backend supports 3-element distance tuple
All client SDKs emit geospatial queries as["distanceEqual", attribute, [[values, distance, meters]]]
(e.g. Query.kt.twig:298) and PostGIS’s geography signatureST_DWithin(geography, geography, distance_meters, use_spheroid)
accepts an optional boolean (use_spheroid=false
is valid) (postgis.net). Confirm Appwrite’s server correctly handles the 3-argument form (treating the third element as the meters/use_spheroid flag) or gracefully falls back to the 2-argument geometry form to avoid breaking existing deployments.
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: 6
🧹 Nitpick comments (27)
tests/languages/go/tests.go (2)
223-231
: DRY up: reuse shared coords and distance to reduce repetition.
Define variables once and use them in all Distance* calls for readability and easier updates.Apply this diff:
// Spatial Distance query tests -fmt.Println(query.DistanceEqual("location", []interface{}{40.7128, -74.0060}, 1000, false)) - fmt.Println(query.DistanceEqual("location", []interface{}{40.7128, -74.0060}, 1000, true)) - fmt.Println(query.DistanceNotEqual("location", []interface{}{40.7128, -74.0060}, 1000, false)) - fmt.Println(query.DistanceNotEqual("location", []interface{}{40.7128, -74.0060}, 1000, true)) - fmt.Println(query.DistanceGreaterThan("location", []interface{}{40.7128, -74.0060}, 1000, false)) - fmt.Println(query.DistanceGreaterThan("location", []interface{}{40.7128, -74.0060}, 1000, true)) - fmt.Println(query.DistanceLessThan("location", []interface{}{40.7128, -74.0060}, 1000, false)) - fmt.Println(query.DistanceLessThan("location", []interface{}{40.7128, -74.0060}, 1000, true)) +loc := []interface{}{40.7128, -74.0060} +dist := 1000 +fmt.Println(query.DistanceEqual("location", loc, dist, false)) +fmt.Println(query.DistanceEqual("location", loc, dist, true)) +fmt.Println(query.DistanceNotEqual("location", loc, dist, false)) +fmt.Println(query.DistanceNotEqual("location", loc, dist, true)) +fmt.Println(query.DistanceGreaterThan("location", loc, dist, false)) +fmt.Println(query.DistanceGreaterThan("location", loc, dist, true)) +fmt.Println(query.DistanceLessThan("location", loc, dist, false)) +fmt.Println(query.DistanceLessThan("location", loc, dist, true))
233-241
: Point geometry for Crosses/Overlaps/Touches may be underspecified—consider adding line/polygon cases.
These predicates are typically defined for linear/areal geometries. Add at least one example with a LineString and Polygon to catch encoding issues for complex shapes.For example (coordinate order per your API):
// Spatial query tests -fmt.Println(query.Intersects("location", []interface{}{40.7128, -74.0060})) +fmt.Println(query.Intersects("location", loc)) fmt.Println(query.NotIntersects("location", []interface{}{40.7128, -74.0060})) -fmt.Println(query.Crosses("location", []interface{}{40.7128, -74.0060})) +line := []interface{}{[]interface{}{-74.01, 40.70}, []interface{}{-74.00, 40.72}} +fmt.Println(query.Crosses("location", line)) fmt.Println(query.NotCrosses("location", []interface{}{40.7128, -74.0060})) -fmt.Println(query.Overlaps("location", []interface{}{40.7128, -74.0060})) +polygon := []interface{}{ + []interface{}{-74.01, 40.70}, []interface{}{-74.01, 40.72}, + []interface{}{-74.00, 40.72}, []interface{}{-74.00, 40.70}, + []interface{}{-74.01, 40.70}, +} +fmt.Println(query.Overlaps("location", polygon)) fmt.Println(query.NotOverlaps("location", []interface{}{40.7128, -74.0060})) fmt.Println(query.Touches("location", []interface{}{40.7128, -74.0060})) fmt.Println(query.NotTouches("location", []interface{}{40.7128, -74.0060}))tests/languages/flutter/tests.dart (1)
198-207
: Distance queries: add explicit meters=false and fractional-distance tests; confirm coord order.
- Add tests for fractional distance (e.g., 1.5) and explicit meters=false to cover both parameter states.
- Verify whether coordinate order is [lat, lon] or [lon, lat] in documentation/templates to ensure consistency.
// Spatial Distance query tests print(Query.distanceEqual("location", [40.7128, -74.0060], 1000)); + // explicit meters=false and fractional distance checks + print(Query.distanceEqual("location", [40.7128, -74.0060], 1.5)); + print(Query.distanceEqual("location", [40.7128, -74.0060], 1500, false)); print(Query.distanceEqual("location", [40.7128, -74.0060], 1000, true));tests/languages/dart/tests.dart (2)
183-191
: Use representative geometries for spatial predicates; point-only may not meaningfully exercise crosses/overlaps/touchesIntersects with a point is fine; crosses/overlaps/touches typically involve LineString/Polygon. Add at least one Polygon/LineString case if supported to catch encoding/serialization issues.
Example addition within this block:
+ final polygon = { + "type": "Polygon", + "coordinates": [ + [ + [-74.01, 40.71], [-74.01, 40.72], + [-74.00, 40.72], [-74.00, 40.71], + [-74.01, 40.71] + ] + ] + }; + print(Query.intersects("location", polygon)); + // If supported: + // print(Query.overlaps("location", polygon));
193-197
: Duplicate OR test — remove or repurpose to cover spatial + scalar compositionThis OR is identical to the one above (Lines 164–167). It adds noise without extra coverage.
Apply:
- print(Query.or([ - Query.equal("released", true), - Query.lessThan("releasedYear", 1990) - ]));Optional replacement to exercise spatial composition:
+ print(Query.or([ + Query.distanceLessThan("location", [40.7128, -74.0060], 1000), + Query.equal("released", true) + ]));tests/languages/kotlin/Tests.kt (2)
191-200
: Add explicit meters=false coverage and DRY the coordinates.Covers both overloads today (3-arg, 4-arg with true), but missing an explicit false path. Also, the repeated literal coordinates can be factored to reduce duplication and cut copy/paste errors.
// Spatial Distance query tests + val coords = listOf(40.7128, -74.0060) - writeToFile(Query.distanceEqual("location", listOf(40.7128, -74.0060), 1000)) - writeToFile(Query.distanceEqual("location", listOf(40.7128, -74.0060), 1000, true)) - writeToFile(Query.distanceNotEqual("location", listOf(40.7128, -74.0060), 1000)) - writeToFile(Query.distanceNotEqual("location", listOf(40.7128, -74.0060), 1000, true)) - writeToFile(Query.distanceGreaterThan("location", listOf(40.7128, -74.0060), 1000)) - writeToFile(Query.distanceGreaterThan("location", listOf(40.7128, -74.0060), 1000, true)) - writeToFile(Query.distanceLessThan("location", listOf(40.7128, -74.0060), 1000)) - writeToFile(Query.distanceLessThan("location", listOf(40.7128, -74.0060), 1000, true)) + writeToFile(Query.distanceEqual("location", coords, 1000)) + writeToFile(Query.distanceEqual("location", coords, 1000, true)) + writeToFile(Query.distanceEqual("location", coords, 1000, false)) + writeToFile(Query.distanceNotEqual("location", coords, 1000)) + writeToFile(Query.distanceNotEqual("location", coords, 1000, true)) + writeToFile(Query.distanceNotEqual("location", coords, 1000, false)) + writeToFile(Query.distanceGreaterThan("location", coords, 1000)) + writeToFile(Query.distanceGreaterThan("location", coords, 1000, true)) + writeToFile(Query.distanceGreaterThan("location", coords, 1000, false)) + writeToFile(Query.distanceLessThan("location", coords, 1000)) + writeToFile(Query.distanceLessThan("location", coords, 1000, true)) + writeToFile(Query.distanceLessThan("location", coords, 1000, false)) + // numeric type variance + writeToFile(Query.distanceEqual("location", coords, 1000.0))
210-210
: Add a composition case to ensure new predicates play well with AND/OR.One combined example catches serialization of nested new queries inside logical combinators.
writeToFile(Query.notTouches("location", listOf(40.7128, -74.0060))) + // Composition with logical operators + writeToFile( + Query.and( + listOf( + Query.distanceLessThan("location", listOf(40.7128, -74.0060), 1000), + Query.intersects("location", listOf(40.7128, -74.0060)) + ) + ) + )tests/languages/python/tests.py (1)
160-169
: Use geometry-shaped values for spatial predicates.Point arrays work syntactically but don’t exercise realistic inputs for intersects/crosses/overlaps/touches, which typically involve line/polygon geometry. Add a small line and polygon to better cover encoding and serialization.
Apply this diff:
-# Spatial query tests -print(Query.intersects("location", [40.7128, -74.0060])) -print(Query.not_intersects("location", [40.7128, -74.0060])) -print(Query.crosses("location", [40.7128, -74.0060])) -print(Query.not_crosses("location", [40.7128, -74.0060])) -print(Query.overlaps("location", [40.7128, -74.0060])) -print(Query.not_overlaps("location", [40.7128, -74.0060])) -print(Query.touches("location", [40.7128, -74.0060])) -print(Query.not_touches("location", [40.7128, -74.0060])) +# Spatial query tests +# NOTE: Replace coordinate order with [lon, lat] if the spec requires GeoJSON order. +point = [-74.0060, 40.7128] +line = [[-74.01, 40.70], [-74.00, 40.72]] +polygon = [[ + [-74.02, 40.70], [-74.00, 40.70], [-74.00, 40.72], [-74.02, 40.72], [-74.02, 40.70] +]] +print(Query.intersects("location", polygon)) +print(Query.not_intersects("location", polygon)) +print(Query.crosses("location", line)) +print(Query.not_crosses("location", line)) +print(Query.overlaps("location", polygon)) +print(Query.not_overlaps("location", polygon)) +print(Query.touches("location", point)) +print(Query.not_touches("location", point))If other language tests already standardize on point arrays for these predicates, keep parity and skip this change. The grep script above will surface that.
tests/languages/web/node.js (2)
200-209
: DRY the repeated literals for readabilityFactor the location and distance into constants to reduce noise and prevent typos.
-// Spatial Distance query tests -console.log(Query.distanceEqual("location", [40.7128, -74.0060], 1000)); -console.log(Query.distanceEqual("location", [40.7128, -74.0060], 1000, true)); -console.log(Query.distanceNotEqual("location", [40.7128, -74.0060], 1000)); -console.log(Query.distanceNotEqual("location", [40.7128, -74.0060], 1000, true)); -console.log(Query.distanceGreaterThan("location", [40.7128, -74.0060], 1000)); -console.log(Query.distanceGreaterThan("location", [40.7128, -74.0060], 1000, true)); -console.log(Query.distanceLessThan("location", [40.7128, -74.0060], 1000)); -console.log(Query.distanceLessThan("location", [40.7128, -74.0060], 1000, true)); +// Spatial Distance query tests +const attr = "location"; +const loc = [40.7128, -74.0060]; +const dist = 1000; +console.log(Query.distanceEqual(attr, loc, dist)); +console.log(Query.distanceEqual(attr, loc, dist, true)); +console.log(Query.distanceNotEqual(attr, loc, dist)); +console.log(Query.distanceNotEqual(attr, loc, dist, true)); +console.log(Query.distanceGreaterThan(attr, loc, dist)); +console.log(Query.distanceGreaterThan(attr, loc, dist, true)); +console.log(Query.distanceLessThan(attr, loc, dist)); +console.log(Query.distanceLessThan(attr, loc, dist, true));
210-219
: Same DRY tweak for spatial predicatesKeeps the block concise and consistent with the distance section.
-// Spatial query tests -console.log(Query.intersects("location", [40.7128, -74.0060])); -console.log(Query.notIntersects("location", [40.7128, -74.0060])); -console.log(Query.crosses("location", [40.7128, -74.0060])); -console.log(Query.notCrosses("location", [40.7128, -74.0060])); -console.log(Query.overlaps("location", [40.7128, -74.0060])); -console.log(Query.notOverlaps("location", [40.7128, -74.0060])); -console.log(Query.touches("location", [40.7128, -74.0060])); -console.log(Query.notTouches("location", [40.7128, -74.0060])); +// Spatial query tests +console.log(Query.intersects(attr, loc)); +console.log(Query.notIntersects(attr, loc)); +console.log(Query.crosses(attr, loc)); +console.log(Query.notCrosses(attr, loc)); +console.log(Query.overlaps(attr, loc)); +console.log(Query.notOverlaps(attr, loc)); +console.log(Query.touches(attr, loc)); +console.log(Query.notTouches(attr, loc));tests/languages/php/test.php (2)
165-173
: Reduce duplication with local vars for attribute/coords/distanceImproves readability and keeps the series consistent.
-// Spatial Distance query tests -echo Query::distanceEqual('location', [40.7128, -74.0060], 1000) . "\n"; -echo Query::distanceEqual('location', [40.7128, -74.0060], 1000, true) . "\n"; -echo Query::distanceNotEqual('location', [40.7128, -74.0060], 1000) . "\n"; -echo Query::distanceNotEqual('location', [40.7128, -74.0060], 1000, true) . "\n"; -echo Query::distanceGreaterThan('location', [40.7128, -74.0060], 1000) . "\n"; -echo Query::distanceGreaterThan('location', [40.7128, -74.0060], 1000, true) . "\n"; -echo Query::distanceLessThan('location', [40.7128, -74.0060], 1000) . "\n"; -echo Query::distanceLessThan('location', [40.7128, -74.0060], 1000, true) . "\n"; +// Spatial Distance query tests +$attr = 'location'; +$loc = [40.7128, -74.0060]; +$dist = 1000; +echo Query::distanceEqual($attr, $loc, $dist) . "\n"; +echo Query::distanceEqual($attr, $loc, $dist, true) . "\n"; +echo Query::distanceNotEqual($attr, $loc, $dist) . "\n"; +echo Query::distanceNotEqual($attr, $loc, $dist, true) . "\n"; +echo Query::distanceGreaterThan($attr, $loc, $dist) . "\n"; +echo Query::distanceGreaterThan($attr, $loc, $dist, true) . "\n"; +echo Query::distanceLessThan($attr, $loc, $dist) . "\n"; +echo Query::distanceLessThan($attr, $loc, $dist, true) . "\n";
175-184
: Apply the same DRY approach to spatial predicatesMatches the distance section and reduces repetition.
-// Spatial query tests -echo Query::intersects('location', [40.7128, -74.0060]) . "\n"; -echo Query::notIntersects('location', [40.7128, -74.0060]) . "\n"; -echo Query::crosses('location', [40.7128, -74.0060]) . "\n"; -echo Query::notCrosses('location', [40.7128, -74.0060]) . "\n"; -echo Query::overlaps('location', [40.7128, -74.0060]) . "\n"; -echo Query::notOverlaps('location', [40.7128, -74.0060]) . "\n"; -echo Query::touches('location', [40.7128, -74.0060]) . "\n"; -echo Query::notTouches('location', [40.7128, -74.0060]) . "\n"; +// Spatial query tests +echo Query::intersects($attr, $loc) . "\n"; +echo Query::notIntersects($attr, $loc) . "\n"; +echo Query::crosses($attr, $loc) . "\n"; +echo Query::notCrosses($attr, $loc) . "\n"; +echo Query::overlaps($attr, $loc) . "\n"; +echo Query::notOverlaps($attr, $loc) . "\n"; +echo Query::touches($attr, $loc) . "\n"; +echo Query::notTouches($attr, $loc) . "\n";tests/languages/node/test.js (1)
275-283
: DRY the inputs and add lightweight assertions instead of only logging.Cuts duplication and gives minimal safety without coupling to exact payload format.
Apply this diff in-place:
- // Spatial Distance query tests - console.log(Query.distanceEqual("location", [40.7128, -74.0060], 1000)); - console.log(Query.distanceEqual("location", [40.7128, -74.0060], 1000, true)); - console.log(Query.distanceNotEqual("location", [40.7128, -74.0060], 1000)); - console.log(Query.distanceNotEqual("location", [40.7128, -74.0060], 1000, true)); - console.log(Query.distanceGreaterThan("location", [40.7128, -74.0060], 1000)); - console.log(Query.distanceGreaterThan("location", [40.7128, -74.0060], 1000, true)); - console.log(Query.distanceLessThan("location", [40.7128, -74.0060], 1000)); - console.log(Query.distanceLessThan("location", [40.7128, -74.0060], 1000, true)); + // Spatial Distance query tests + const coords = [40.7128, -74.0060]; + const radius = 1000; + let s; + s = Query.distanceEqual("location", coords, radius); + console.log(s); console.assert(typeof s === 'string' && s.includes('distanceEqual'), 'distanceEqual should serialize'); + console.log(Query.distanceEqual("location", coords, radius, true)); + s = Query.distanceNotEqual("location", coords, radius); + console.log(s); console.assert(s.includes('distanceNotEqual'), 'distanceNotEqual should serialize'); + console.log(Query.distanceNotEqual("location", coords, radius, true)); + s = Query.distanceGreaterThan("location", coords, radius); + console.log(s); console.assert(s.includes('distanceGreaterThan'), 'distanceGreaterThan should serialize'); + console.log(Query.distanceGreaterThan("location", coords, radius, true)); + s = Query.distanceLessThan("location", coords, radius); + console.log(s); console.assert(s.includes('distanceLessThan'), 'distanceLessThan should serialize'); + console.log(Query.distanceLessThan("location", coords, radius, true));tests/languages/apple/Tests.swift (2)
198-207
: Add light assertions for distance queries (keep prints) + cover meters=false.Right now these are smoke prints only. Add a couple of cheap string checks to catch regressions and explicitly exercise
meters: false
.Apply this diff:
- print(Query.distanceEqual("location", values: [40.7128, -74.0060], distance: 1000)) - print(Query.distanceEqual("location", values: [40.7128, -74.0060], distance: 1000, meters: true)) + let dEq = Query.distanceEqual("location", values: [40.7128, -74.0060], distance: 1000) + print(dEq) + XCTAssertTrue(dEq.contains("distanceEqual") && dEq.contains("location") && dEq.contains("1000")) + let dEqMeters = Query.distanceEqual("location", values: [40.7128, -74.0060], distance: 1000, meters: true) + print(dEqMeters) + XCTAssertTrue(dEqMeters.contains("distanceEqual") && dEqMeters.contains("true")) + // Explicit meters: false sanity check + let dEqMetersFalse = Query.distanceEqual("location", values: [40.7128, -74.0060], distance: 1000, meters: false) + XCTAssertTrue(dEqMetersFalse.contains("distanceEqual")) print(Query.distanceNotEqual("location", values: [40.7128, -74.0060], distance: 1000)) print(Query.distanceNotEqual("location", values: [40.7128, -74.0060], distance: 1000, meters: true)) print(Query.distanceGreaterThan("location", values: [40.7128, -74.0060], distance: 1000)) print(Query.distanceGreaterThan("location", values: [40.7128, -74.0060], distance: 1000, meters: true)) print(Query.distanceLessThan("location", values: [40.7128, -74.0060], distance: 1000)) print(Query.distanceLessThan("location", values: [40.7128, -74.0060], distance: 1000, meters: true))
208-217
: Basic assertions for spatial predicates + double-check argument shape.Add minimal checks for 1–2 ops; keep the rest as prints. Also confirm whether these ops expect a point or a geometry (e.g., LineString/Polygon) to avoid false positives.
Apply this diff:
- print(Query.intersects("location", values: [40.7128, -74.0060])) - print(Query.notIntersects("location", values: [40.7128, -74.0060])) + let sIntersects = Query.intersects("location", values: [40.7128, -74.0060]) + print(sIntersects) + XCTAssertTrue(sIntersects.contains("intersects") && sIntersects.contains("location")) + let sNotIntersects = Query.notIntersects("location", values: [40.7128, -74.0060]) + print(sNotIntersects) + XCTAssertTrue(sNotIntersects.contains("notIntersects")) print(Query.crosses("location", values: [40.7128, -74.0060])) print(Query.notCrosses("location", values: [40.7128, -74.0060])) print(Query.overlaps("location", values: [40.7128, -74.0060])) print(Query.notOverlaps("location", values: [40.7128, -74.0060])) print(Query.touches("location", values: [40.7128, -74.0060])) print(Query.notTouches("location", values: [40.7128, -74.0060]))If docs require [lon, lat] (GeoJSON) rather than [lat, lon], adjust the order in tests for correctness.
tests/languages/deno/tests.ts (1)
190-209
: Minor DRY: reuse a coords constant.Reduces repetition and improves readability without changing output.
Apply within this block:
// Spatial Distance query tests - console.log(Query.distanceEqual("location", [40.7128, -74.0060], 1000)); - console.log(Query.distanceEqual("location", [40.7128, -74.0060], 1000, true)); - console.log(Query.distanceNotEqual("location", [40.7128, -74.0060], 1000)); - console.log(Query.distanceNotEqual("location", [40.7128, -74.0060], 1000, true)); - console.log(Query.distanceGreaterThan("location", [40.7128, -74.0060], 1000)); - console.log(Query.distanceGreaterThan("location", [40.7128, -74.0060], 1000, true)); - console.log(Query.distanceLessThan("location", [40.7128, -74.0060], 1000)); - console.log(Query.distanceLessThan("location", [40.7128, -74.0060], 1000, true)); + const coords = [40.7128, -74.0060]; + console.log(Query.distanceEqual("location", coords, 1000)); + console.log(Query.distanceEqual("location", coords, 1000, true)); + console.log(Query.distanceNotEqual("location", coords, 1000)); + console.log(Query.distanceNotEqual("location", coords, 1000, true)); + console.log(Query.distanceGreaterThan("location", coords, 1000)); + console.log(Query.distanceGreaterThan("location", coords, 1000, true)); + console.log(Query.distanceLessThan("location", coords, 1000)); + console.log(Query.distanceLessThan("location", coords, 1000, true)); // Spatial query tests - console.log(Query.intersects("location", [40.7128, -74.0060])); - console.log(Query.notIntersects("location", [40.7128, -74.0060])); - console.log(Query.crosses("location", [40.7128, -74.0060])); - console.log(Query.notCrosses("location", [40.7128, -74.0060])); - console.log(Query.overlaps("location", [40.7128, -74.0060])); - console.log(Query.notOverlaps("location", [40.7128, -74.0060])); - console.log(Query.touches("location", [40.7128, -74.0060])); - console.log(Query.notTouches("location", [40.7128, -74.0060])); + console.log(Query.intersects("location", coords)); + console.log(Query.notIntersects("location", coords)); + console.log(Query.crosses("location", coords)); + console.log(Query.notCrosses("location", coords)); + console.log(Query.overlaps("location", coords)); + console.log(Query.notOverlaps("location", coords)); + console.log(Query.touches("location", coords)); + console.log(Query.notTouches("location", coords));tests/languages/ruby/tests.rb (2)
165-173
: Cover both unit modes and fractional distances.Add one case with meters=false explicitly and one with fractional distance to ensure encoding is stable.
# Spatial Distance query tests puts Query.distance_equal("location", [40.7128, -74.0060], 1000) +puts Query.distance_equal("location", [40.7128, -74.0060], 1500, false) +puts Query.distance_equal("location", [40.7128, -74.0060], 1.25) puts Query.distance_equal("location", [40.7128, -74.0060], 1000, true)
175-183
: Use non-point geometries for relation predicates.crosses/overlaps/touches semantics are clearer with LineString/Polygon inputs; consider adding at least one example for each to validate serialization of nested arrays.
Example shapes (adjust to the format expected by the backend):
- LineString: [[-74.01, 40.70], [-73.99, 40.72]]
- Polygon: [[[-74.02, 40.70], [-74.02, 40.72], [-73.98, 40.72], [-73.98, 40.70], [-74.02, 40.70]]]
tests/languages/swift/Tests.swift (3)
189-196
: Units: clarify default whenmeters
is omitted.If the default unit isn’t meters (e.g., kilometers),
distance: 1000
may unintentionally mean 1000 km. Consider either passingmeters: true
everywhere or using a distance that clearly matches the default unit.
199-206
: Use geometry types that match predicate semantics.Predicates like crosses/overlaps/touches are generally non-meaningful for a point. Add a line and polygon case to exercise these predicates realistically.
Example:
let line: [[Double]] = [[-74.0060, 40.7128], [-73.9352, 40.7306]] let poly: [[[Double]]] = [[ [-74.02, 40.70], [-74.00, 40.70], [-74.00, 40.72], [-74.02, 40.72], [-74.02, 40.70] ]] print(Query.crosses("location", values: line)) print(Query.overlaps("location", values: poly)) print(Query.touches("location", values: line))
188-197
: DRY up repeated literals for readability.Extract the coordinates and distance to constants to reduce duplication and typos.
- // Spatial Distance query tests - print(Query.distanceEqual("location", values: [40.7128, -74.0060], distance: 1000)) - print(Query.distanceEqual("location", values: [40.7128, -74.0060], distance: 1000, meters: true)) - print(Query.distanceNotEqual("location", values: [40.7128, -74.0060], distance: 1000)) - print(Query.distanceNotEqual("location", values: [40.7128, -74.0060], distance: 1000, meters: true)) - print(Query.distanceGreaterThan("location", values: [40.7128, -74.0060], distance: 1000)) - print(Query.distanceGreaterThan("location", values: [40.7128, -74.0060], distance: 1000, meters: true)) - print(Query.distanceLessThan("location", values: [40.7128, -74.0060], distance: 1000)) - print(Query.distanceLessThan("location", values: [40.7128, -74.0060], distance: 1000, meters: true)) + // Spatial Distance query tests + let nyc: [Double] = [40.7128, -74.0060] // verify order per spec + let d: Double = 1000 + print(Query.distanceEqual("location", values: nyc, distance: d)) + print(Query.distanceEqual("location", values: nyc, distance: d, meters: true)) + print(Query.distanceNotEqual("location", values: nyc, distance: d)) + print(Query.distanceNotEqual("location", values: nyc, distance: d, meters: true)) + print(Query.distanceGreaterThan("location", values: nyc, distance: d)) + print(Query.distanceGreaterThan("location", values: nyc, distance: d, meters: true)) + print(Query.distanceLessThan("location", values: nyc, distance: d)) + print(Query.distanceLessThan("location", values: nyc, distance: d, meters: true))tests/languages/android/Tests.kt (4)
225-243
: DRY the repeated coordinates into a constant for readability.- // Spatial Distance query tests - writeToFile(Query.distanceEqual("location", listOf(40.7128, -74.0060), 1000)) - writeToFile(Query.distanceEqual("location", listOf(40.7128, -74.0060), 1000, true)) - writeToFile(Query.distanceNotEqual("location", listOf(40.7128, -74.0060), 1000)) - writeToFile(Query.distanceNotEqual("location", listOf(40.7128, -74.0060), 1000, true)) - writeToFile(Query.distanceGreaterThan("location", listOf(40.7128, -74.0060), 1000)) - writeToFile(Query.distanceGreaterThan("location", listOf(40.7128, -74.0060), 1000, true)) - writeToFile(Query.distanceLessThan("location", listOf(40.7128, -74.0060), 1000)) - writeToFile(Query.distanceLessThan("location", listOf(40.7128, -74.0060), 1000, true)) + // Spatial Distance query tests + val nyc = listOf(40.7128, -74.0060) // verify order per spec + writeToFile(Query.distanceEqual("location", nyc, 1000)) + writeToFile(Query.distanceEqual("location", nyc, 1000, true)) + writeToFile(Query.distanceNotEqual("location", nyc, 1000)) + writeToFile(Query.distanceNotEqual("location", nyc, 1000, true)) + writeToFile(Query.distanceGreaterThan("location", nyc, 1000)) + writeToFile(Query.distanceGreaterThan("location", nyc, 1000, true)) + writeToFile(Query.distanceLessThan("location", nyc, 1000)) + writeToFile(Query.distanceLessThan("location", nyc, 1000, true)) @@ - // Spatial query tests - writeToFile(Query.intersects("location", listOf(40.7128, -74.0060))) - writeToFile(Query.notIntersects("location", listOf(40.7128, -74.0060))) - writeToFile(Query.crosses("location", listOf(40.7128, -74.0060))) - writeToFile(Query.notCrosses("location", listOf(40.7128, -74.0060))) - writeToFile(Query.overlaps("location", listOf(40.7128, -74.0060))) - writeToFile(Query.notOverlaps("location", listOf(40.7128, -74.0060))) - writeToFile(Query.touches("location", listOf(40.7128, -74.0060))) - writeToFile(Query.notTouches("location", listOf(40.7128, -74.0060))) + // Spatial query tests + writeToFile(Query.intersects("location", nyc)) + writeToFile(Query.notIntersects("location", nyc)) + writeToFile(Query.crosses("location", nyc)) + writeToFile(Query.notCrosses("location", nyc)) + writeToFile(Query.overlaps("location", nyc)) + writeToFile(Query.notOverlaps("location", nyc)) + writeToFile(Query.touches("location", nyc)) + writeToFile(Query.notTouches("location", nyc))
225-232
: Add edge cases: decimal radius, zero radius, and explicit meters=false.Catches serialization/typing regressions for Number vs Double and boolean flag handling.
writeToFile(Query.distanceLessThan("location", nyc, 1000, true)) + + // Edge cases + writeToFile(Query.distanceEqual("location", nyc, 0)) + writeToFile(Query.distanceEqual("location", nyc, 1000.5)) + writeToFile(Query.distanceGreaterThan("location", nyc, 999.9, false)) + writeToFile(Query.distanceLessThan("location", nyc, 1000.1, false))
234-242
: Include at least one polygon/line geometry to exercise nested array encoding.Point-only inputs don’t stress the serializer for crosses/overlaps/touches; polygons/lines will.
writeToFile(Query.notTouches("location", nyc)) + + // Additional geometry inputs + val square: List<List<List<Double>>> = listOf( + listOf( + listOf(-74.01, 40.70), listOf(-74.00, 40.70), + listOf(-74.00, 40.71), listOf(-74.01, 40.71), + listOf(-74.01, 40.70) + ) + ) + val line: List<List<Double>> = listOf( + listOf(-74.01, 40.705), listOf(-74.00, 40.705) + ) + writeToFile(Query.intersects("location", square)) + writeToFile(Query.overlaps("location", square)) + writeToFile(Query.crosses("location", line))
223-243
: Optional: assert minimal structure to catch regressions, not just log.Keep file logging, but add a couple of substring assertions to verify operator names and bracket structure.
- writeToFile(Query.distanceEqual("location", nyc, 1000)) + val q = Query.distanceEqual("location", nyc, 1000) + org.junit.Assert.assertTrue(q.startsWith("distanceEqual(")) + writeToFile(q)tests/languages/dotnet/Tests.cs (2)
172-181
: Prefer strong typing and avoid repetition in distance testsUse List and reuse a single coordinates/radius instance for clarity and better overload resolution.
- // Spatial Distance query tests - TestContext.WriteLine(Query.DistanceEqual("location", new List<object> { 40.7128, -74.0060 }, 1000)); - TestContext.WriteLine(Query.DistanceEqual("location", new List<object> { 40.7128, -74.0060 }, 1000, true)); - TestContext.WriteLine(Query.DistanceNotEqual("location", new List<object> { 40.7128, -74.0060 }, 1000)); - TestContext.WriteLine(Query.DistanceNotEqual("location", new List<object> { 40.7128, -74.0060 }, 1000, true)); - TestContext.WriteLine(Query.DistanceGreaterThan("location", new List<object> { 40.7128, -74.0060 }, 1000)); - TestContext.WriteLine(Query.DistanceGreaterThan("location", new List<object> { 40.7128, -74.0060 }, 1000, true)); - TestContext.WriteLine(Query.DistanceLessThan("location", new List<object> { 40.7128, -74.0060 }, 1000)); - TestContext.WriteLine(Query.DistanceLessThan("location", new List<object> { 40.7128, -74.0060 }, 1000, true)); + // Spatial Distance query tests + var coords = new List<double> { 40.7128, -74.0060 }; + var radius = 1000; + TestContext.WriteLine(Query.DistanceEqual("location", coords, radius)); + TestContext.WriteLine(Query.DistanceEqual("location", coords, radius, true)); + TestContext.WriteLine(Query.DistanceNotEqual("location", coords, radius)); + TestContext.WriteLine(Query.DistanceNotEqual("location", coords, radius, true)); + TestContext.WriteLine(Query.DistanceGreaterThan("location", coords, radius)); + TestContext.WriteLine(Query.DistanceGreaterThan("location", coords, radius, true)); + TestContext.WriteLine(Query.DistanceLessThan("location", coords, radius)); + TestContext.WriteLine(Query.DistanceLessThan("location", coords, radius, true));
183-191
: Reuse typed coordinates for spatial predicatesKeep consistency with the distance block and avoid recreating lists.
- // Spatial query tests - TestContext.WriteLine(Query.Intersects("location", new List<object> { 40.7128, -74.0060 })); - TestContext.WriteLine(Query.NotIntersects("location", new List<object> { 40.7128, -74.0060 })); - TestContext.WriteLine(Query.Crosses("location", new List<object> { 40.7128, -74.0060 })); - TestContext.WriteLine(Query.NotCrosses("location", new List<object> { 40.7128, -74.0060 })); - TestContext.WriteLine(Query.Overlaps("location", new List<object> { 40.7128, -74.0060 })); - TestContext.WriteLine(Query.NotOverlaps("location", new List<object> { 40.7128, -74.0060 })); - TestContext.WriteLine(Query.Touches("location", new List<object> { 40.7128, -74.0060 })); - TestContext.WriteLine(Query.NotTouches("location", new List<object> { 40.7128, -74.0060 })); + // Spatial query tests + TestContext.WriteLine(Query.Intersects("location", coords)); + TestContext.WriteLine(Query.NotIntersects("location", coords)); + TestContext.WriteLine(Query.Crosses("location", coords)); + TestContext.WriteLine(Query.NotCrosses("location", coords)); + TestContext.WriteLine(Query.Overlaps("location", coords)); + TestContext.WriteLine(Query.NotOverlaps("location", coords)); + TestContext.WriteLine(Query.Touches("location", coords)); + TestContext.WriteLine(Query.NotTouches("location", coords));
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (15)
tests/Base.php
(1 hunks)tests/languages/android/Tests.kt
(1 hunks)tests/languages/apple/Tests.swift
(1 hunks)tests/languages/dart/tests.dart
(1 hunks)tests/languages/deno/tests.ts
(1 hunks)tests/languages/dotnet/Tests.cs
(1 hunks)tests/languages/flutter/tests.dart
(1 hunks)tests/languages/go/tests.go
(1 hunks)tests/languages/kotlin/Tests.kt
(1 hunks)tests/languages/node/test.js
(1 hunks)tests/languages/php/test.php
(1 hunks)tests/languages/python/tests.py
(1 hunks)tests/languages/ruby/tests.rb
(1 hunks)tests/languages/swift/Tests.swift
(1 hunks)tests/languages/web/node.js
(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
tests/languages/android/Tests.kt (1)
tests/languages/kotlin/Tests.kt (1)
writeToFile
(235-238)
tests/languages/kotlin/Tests.kt (1)
tests/languages/android/Tests.kt (1)
writeToFile
(268-271)
🔇 Additional comments (16)
tests/languages/go/tests.go (2)
223-241
: LGTM: added spatial distance and predicate query coverage fits the new builders.
223-241
: Confirm coordinate order and units semantics.
Many spatial APIs expect [lon, lat] (GeoJSON) while others use [lat, lon]. Also, clarify what the bool flag toggles (meters vs kilometers). Ensure the test data matches the builder’s expected shape so the serialized strings are correct; adjust the order or add a short comment if needed.tests/languages/flutter/tests.dart (1)
208-217
: Add polygon and line test cases and verify coordinate ordering
- Single-point tests don’t cover complex geometries—include a small polygon (e.g., box around NYC) and a line crossing it to validate shape encoding.
- GeoJSON expects [longitude, latitude]; ensure the Flutter SDK handles coord order consistently with other languages.
tests/languages/dart/tests.dart (1)
173-182
: DRY constants & confirm coordinate order
- Optional: hoist
[40.7128, -74.0060]
and1000
intofinal location
andconst radius
to reduce repetition.- Confirm expected coordinate ordering (
[latitude, longitude]
vs[longitude, latitude]
).- All existing language tests cover only the default (no flag) and explicit
true
cases; adding an explicitfalse
in Dart alone breaks parity—either omit it here or introduce false-case tests across all languages.tests/languages/kotlin/Tests.kt (2)
191-210
: Baseline coverage for new methods looks good.Both overloads are exercised and aligned with existing query helper test style.
202-210
: Exercise polygon inputs for spatial predicates
Add a closed‐ring polygon example to Tests.kt to ensure nested arrays serialize correctly, for example:// Simple polygon around lower Manhattan (closed ring) val polygon = listOf( listOf( listOf(-74.018, 40.700), listOf(-74.018, 40.740), listOf(-73.990, 40.740), listOf(-73.990, 40.700), listOf(-74.018, 40.700) ) ) writeToFile(Query.intersects("location", polygon)) writeToFile(Query.overlaps("location", polygon))Confirm the expected coordinate order (lon, lat vs. lat, lon) in the Kotlin template before merging.
tests/languages/node/test.js (2)
275-293
: LGTM: good coverage for new spatial query APIs.The added calls exercise all four distance and eight spatial predicates. This helps validate serialization for both default and explicit meters flags.
285-293
: Verify coordinate order in Node spatial predicates
Tests at tests/languages/node/test.js lines 286–293 use [40.7128, -74.0060] (lat, lon); confirm the SDK expects [lon, lat] or GeoJSON geometries, and add a non-point (e.g. polygon or linestring) example if supported.tests/languages/apple/Tests.swift (1)
198-207
: SwiftQuery
distance methods use correct parameter labels
Confirmed thatdistanceEqual
,distanceNotEqual
,distanceGreaterThan
, anddistanceLessThan
inQuery.swift
are defined with thevalues:
,distance:
, andmeters:
labels, matching the test invocations.tests/languages/deno/tests.ts (3)
191-209
: Cross-language parity verified. Deno test calls for spatial queries match other SDKs in method names, argument order, and default handling.
201-208
: Ignore geometry type validation for spatial predicates. Appwrite’s SDK methods forintersects
,crosses
,overlaps
, etc., simply serialize whatever JSON is passed and the backend currently has no built-in spatial operators or GeoJSON requirements; using point arrays is consistent across all language SDKs.Likely an incorrect or invalid review comment.
191-198
: Confirm default meters flag and serialized payload shape for all distance helpers*
- Omitting the 4th argument must default to false.
- Queries should serialize as
[[values, distance, meters]]
, with the meters boolean always present and in the third position.tests/languages/swift/Tests.swift (2)
188-207
: Spatial query tests added — LGTM.Good coverage of the new distance and spatial predicates, consistent with existing print-style tests in this file.
188-207
: Ignore thevalues:
vs.value:
warning for spatial methods; they correctly usevalues:
to accept multiple coordinates.Likely an incorrect or invalid review comment.
tests/languages/dotnet/Tests.cs (2)
172-191
: Spatial tests addition looks goodCovers both default and meters=true paths for distance, and all predicate variants. Nice parity with other language suites.
172-191
: Verify geospatial parameter semantics
Confirm that theDistance*
query methods expect coordinates in[longitude, latitude]
order (not[latitude, longitude]
) and validate whethermeters=false
defaults to kilometers (andtrue
to meters) against the server implementation to avoid mismatched queries.
tests/Base.php
Outdated
'{"method":"distanceEqual","attribute":"location","values":[[[40.7128,-74.0060],1000,false]]}', | ||
'{"method":"distanceEqual","attribute":"location","values":[[[40.7128,-74.0060],1000,true]]}', | ||
'{"method":"distanceNotEqual","attribute":"location","values":[[[40.7128,-74.0060],1000,false]]}', | ||
'{"method":"distanceNotEqual","attribute":"location","values":[[[40.7128,-74.0060],1000,true]]}', | ||
'{"method":"distanceGreaterThan","attribute":"location","values":[[[40.7128,-74.0060],1000,false]]}', | ||
'{"method":"distanceGreaterThan","attribute":"location","values":[[[40.7128,-74.0060],1000,true]]}', | ||
'{"method":"distanceLessThan","attribute":"location","values":[[[40.7128,-74.0060],1000,false]]}', | ||
'{"method":"distanceLessThan","attribute":"location","values":[[[40.7128,-74.0060],1000,true]]}', | ||
'{"method":"intersects","attribute":"location","values":[[40.7128,-74.0060]]}', | ||
'{"method":"notIntersects","attribute":"location","values":[[40.7128,-74.0060]]}', | ||
'{"method":"crosses","attribute":"location","values":[[40.7128,-74.0060]]}', | ||
'{"method":"notCrosses","attribute":"location","values":[[40.7128,-74.0060]]}', | ||
'{"method":"overlaps","attribute":"location","values":[[40.7128,-74.0060]]}', | ||
'{"method":"notOverlaps","attribute":"location","values":[[40.7128,-74.0060]]}', | ||
'{"method":"touches","attribute":"location","values":[[40.7128,-74.0060]]}', | ||
'{"method":"notTouches","attribute":"location","values":[[40.7128,-74.0060]]}', |
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.
💡 Verification agent
🧩 Analysis chain
Distance/spatial expected payloads look consistent; verify meters flag and coord order across SDKs
Good additions. Two asks to avoid flaky cross-language failures:
- Ensure every SDK always serializes distance tuple as [[coords, distance, meters]] even when meters is omitted (should default to false and still be emitted).
- Confirm the coordinate order is the intended one for Appwrite (you use [40.7128, -74.0060] = [lat, lon]). If the platform expects GeoJSON order [lon, lat], adjust tests/templates accordingly.
Run this to spot-check templates for explicit meters handling and surface occurrences to review:
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Distance methods across templates:"
rg -nP -C2 '(distanceEqual|distanceNotEqual|distanceGreaterThan|distanceLessThan)' templates
echo -e "\nMeters flag usage across templates:"
rg -nP -C2 '\bmeters\b' templates
echo -e "\nDistance method calls in tests (3-arg vs 4-arg):"
rg -nP -n 'distance(Equal|NotEqual|GreaterThan|LessThan)\s*\(' tests/languages -g '!**/node_modules/**'
Length of output: 65030
🌐 Web query:
For Appwrite Database spatial queries, what is the authoritative coordinate order for points in Query helpers (latitude, longitude vs longitude, latitude)?
💡 Result:
Authoritative order is longitude, latitude (x, y) — follow the GeoJSON / RFC 7946 convention. [1][2]
Note: Appwrite docs don't clearly state a different canonical order; community threads show Appwrite users storing separate latitude/longitude fields. If you use GeoJSON-style positions or any spatial helpers that follow common GIS conventions, send coordinates as [longitude, latitude]. [3][4]
Sources:
- RFC 7946 (GeoJSON: "first two elements are longitude and latitude"). [1]
- GeoJSON explainer (summary of lon,lat order). [2]
- Appwrite forum thread discussing GeoPoint usage / storing lat & lon. [3]
- Appwrite threads about location queries and bounding calculations. [4]
Swap coordinate order to [longitude, latitude] per GeoJSON compliance
Default meters
flag is already emitted across all SDKs and requires no changes. Update all test payloads and examples (e.g. tests/Base.php lines 121–136 and tests/languages/*) to use [-74.0060, 40.7128]
instead of [40.7128, -74.0060]
, aligning with the GeoJSON (RFC 7946) [lon, lat]
convention.
🤖 Prompt for AI Agents
In tests/Base.php around lines 121 to 136, the geolocation coordinate arrays are
using [latitude, longitude] (e.g. [40.7128,-74.0060]) but must follow GeoJSON
RFC 7946 [longitude, latitude]; update every occurrence in this block to swap
the two values to [-74.0060,40.7128] (and do the same for similar examples under
tests/languages/*), ensuring all test payload strings retain their original
structure and flags but with coordinates reordered to [lon, lat].
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.
@ArnabChatterjee20k Is this legit 🤔 should we flip them?
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!
07581a7
to
89804f6
Compare
89804f6
to
b5b22bd
Compare
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: 1
♻️ Duplicate comments (1)
templates/deno/src/query.ts.twig (1)
1-15
: Type hole: QueryTypes/QueryTypesList don’t allow the distance payload tuple.The new distance helpers pass [any[], number, boolean], which isn’t assignable to QueryTypes or QueryTypesList and will fail TS type-checking. Introduce a dedicated tuple type and widen the class to accept it.
type QueryTypesSingle = string | number | boolean; -export type QueryTypesList = string[] | number[] | boolean[] | Query[]; -export type QueryTypes = QueryTypesSingle | QueryTypesList; +export type QueryTypesList = string[] | number[] | boolean[] | Query[]; +export type QueryTypes = QueryTypesSingle | QueryTypesList; +// Distance payload: [coordinates/geometry, distance, meters?] +export type DistancePayload = [any[], number, boolean]; +export type QueryValues = QueryTypesList | DistancePayload; export class Query { method: string; attribute: AttributesTypes | undefined; - values: QueryTypesList | undefined; + values: QueryValues | undefined; constructor( method: string, attribute?: AttributesTypes, - values?: QueryTypes + values?: QueryValues ) {
🧹 Nitpick comments (2)
templates/dart/lib/query.dart.twig (1)
170-184
: Dedup the 4 distance helpers with a tiny private helper.Reduces repetition and keeps payload shape consistent.
- /// Filter resources where [attribute] is at a specific distance from the given coordinates. - static String distanceEqual(String attribute, List<dynamic> values, double distance, [bool meters = false]) => - Query._('distanceEqual', attribute, [values, distance, meters]).toString(); + static String _distance(String op, String attribute, List<dynamic> values, double distance, [bool meters = false]) => + Query._(op, attribute, [values, distance, meters]).toString(); + + /// Filter resources where [attribute] is at a specific distance from the given coordinates. + static String distanceEqual(String attribute, List<dynamic> values, double distance, [bool meters = false]) => + _distance('distanceEqual', attribute, values, distance, meters); /// Filter resources where [attribute] is not at a specific distance from the given coordinates. - static String distanceNotEqual(String attribute, List<dynamic> values, double distance, [bool meters = false]) => - Query._('distanceNotEqual', attribute, [values, distance, meters]).toString(); + static String distanceNotEqual(String attribute, List<dynamic> values, double distance, [bool meters = false]) => + _distance('distanceNotEqual', attribute, values, distance, meters); /// Filter resources where [attribute] is at a distance greater than the specified value from the given coordinates. - static String distanceGreaterThan(String attribute, List<dynamic> values, double distance, [bool meters = false]) => - Query._('distanceGreaterThan', attribute, [values, distance, meters]).toString(); + static String distanceGreaterThan(String attribute, List<dynamic> values, double distance, [bool meters = false]) => + _distance('distanceGreaterThan', attribute, values, distance, meters); /// Filter resources where [attribute] is at a distance less than the specified value from the given coordinates. - static String distanceLessThan(String attribute, List<dynamic> values, double distance, [bool meters = false]) => - Query._('distanceLessThan', attribute, [values, distance, meters]).toString(); + static String distanceLessThan(String attribute, List<dynamic> values, double distance, [bool meters = false]) => + _distance('distanceLessThan', attribute, values, distance, meters);templates/android/library/src/main/java/io/package/Query.kt.twig (1)
289-332
: Factor a private distance builder to remove repetition; clarify units in KDoc.Keeps payload stable and improves readability; briefly note what meters=false means.
- fun distanceEqual(attribute: String, values: List<Any>, distance: Number, meters: Boolean = false) = Query("distanceEqual", attribute, listOf(values, distance, meters)).toJson() + private fun distance(op: String, attribute: String, values: List<Any>, distance: Number, meters: Boolean = false) = + Query(op, attribute, listOf(values, distance, meters)).toJson() + /** Filter where attribute is at a specific distance from coordinates. meters=false: document unit the server expects (clarify). */ + fun distanceEqual(attribute: String, values: List<Any>, distance: Number, meters: Boolean = false) = + distance("distanceEqual", attribute, values, distance, meters) - fun distanceNotEqual(attribute: String, values: List<Any>, distance: Number, meters: Boolean = false) = Query("distanceNotEqual", attribute, listOf(values, distance, meters)).toJson() + fun distanceNotEqual(attribute: String, values: List<Any>, distance: Number, meters: Boolean = false) = + distance("distanceNotEqual", attribute, values, distance, meters) - fun distanceGreaterThan(attribute: String, values: List<Any>, distance: Number, meters: Boolean = false) = Query("distanceGreaterThan", attribute, listOf(values, distance, meters)).toJson() + fun distanceGreaterThan(attribute: String, values: List<Any>, distance: Number, meters: Boolean = false) = + distance("distanceGreaterThan", attribute, values, distance, meters) - fun distanceLessThan(attribute: String, values: List<Any>, distance: Number, meters: Boolean = false) = Query("distanceLessThan", attribute, listOf(values, distance, meters)).toJson() + fun distanceLessThan(attribute: String, values: List<Any>, distance: Number, meters: Boolean = false) = + distance("distanceLessThan", attribute, values, distance, meters)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (12)
templates/android/library/src/main/java/io/package/Query.kt.twig
(1 hunks)templates/dart/lib/query.dart.twig
(1 hunks)templates/deno/src/query.ts.twig
(1 hunks)templates/go/query.go.twig
(1 hunks)templates/kotlin/src/main/kotlin/io/appwrite/Query.kt.twig
(1 hunks)templates/php/src/Query.php.twig
(1 hunks)templates/python/package/query.py.twig
(1 hunks)templates/react-native/src/query.ts.twig
(1 hunks)templates/ruby/lib/container/query.rb.twig
(1 hunks)templates/swift/Sources/Query.swift.twig
(1 hunks)templates/web/src/query.ts.twig
(1 hunks)tests/Base.php
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (9)
- templates/react-native/src/query.ts.twig
- templates/web/src/query.ts.twig
- templates/python/package/query.py.twig
- tests/Base.php
- templates/swift/Sources/Query.swift.twig
- templates/ruby/lib/container/query.rb.twig
- templates/php/src/Query.php.twig
- templates/go/query.go.twig
- templates/kotlin/src/main/kotlin/io/appwrite/Query.kt.twig
🔇 Additional comments (3)
templates/dart/lib/query.dart.twig (1)
186-216
: Spatial relation helpers look good.Payloads and naming are consistent with the rest of the template.
templates/deno/src/query.ts.twig (1)
248-326
: Spatial relation helpers: consistent and fine.No type issues; payload is any[] which matches existing patterns.
templates/android/library/src/main/java/io/package/Query.kt.twig (1)
334-403
: Spatial relation helpers look consistent and correct.Names and payloads align with other SDKs.
f0d2467
to
e32b5ea
Compare
e32b5ea
to
986a2f2
Compare
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: 0
♻️ Duplicate comments (2)
templates/swift/Sources/Query.swift.twig (2)
11-27
: Add Codable support for.array
and fix non-exhaustive switch (compile-time error).
.array
was added toQueryValue
butinit(from:)
andencode(to:)
don’t handle it. Encoding will not compile, and decodingor/and
payloads with nested arrays will fail.Apply:
@@ init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() @@ - } else if let queryValue = try? container.decode(Query.self) { - self = .query(queryValue) + } else if let queryValue = try? container.decode(Query.self) { + self = .query(queryValue) + } else if let arrayValue = try? container.decode([QueryValue].self) { + self = .array(arrayValue) } else { throw DecodingError.dataCorruptedError(in: container, debugDescription: "QueryValue cannot be decoded") } } @@ func encode(to encoder: Encoder) throws { var container = encoder.singleValueContainer() switch self { @@ case .query(let value): try container.encode(value) + case .array(let value): + try container.encode(value) } }Also applies to: 29-43
89-91
: Fix[Any]
mapping: doublereturn
+ scalars incorrectly wrapped as arrays.Current code won’t compile and turns numbers/bools into
.array([.double/.bool])
. Replace with recursive element mapping plus a helper.Apply:
- case let anyArray as [Any]: - return return [.array(anyArray.compactMap { convertToQueryValueArray($0).map { .array($0) } })] + case let anyArray as [Any]: + return anyArray.compactMap { convertAnyToQueryValue($0) }Add this helper inside
Query
(belowconvertToQueryValueArray
):private static func convertAnyToQueryValue(_ value: Any) -> QueryValue? { switch value { case let v as String: return .string(v) case let v as Int: return .int(v) case let v as Double: return .double(v) case let v as Bool: return .bool(v) case let v as Query: return .query(v) case let v as [Any]: let mapped = v.compactMap { convertAnyToQueryValue($0) } return .array(mapped) default: return nil } }
🧹 Nitpick comments (4)
templates/swift/Sources/Query.swift.twig (2)
404-434
: Distance payload shape OK; relies on heterogeneous/nested array support.Once the converter/
Codable
fixes land, these will serialize as[values, distance, meters]
as intended. Optionally assert non-negativedistance
to catch misuse early.Example:
- public static func distanceEqual(_ attribute: String, values: [Any], distance: Double, meters: Bool = false) -> String { + public static func distanceEqual(_ attribute: String, values: [Any], distance: Double, meters: Bool = false) -> String { + precondition(distance >= 0, "distance must be non-negative") return Query( method: "distanceEqual", attribute: attribute, values: [values, distance, meters] ).description }
436-498
: Spatial predicate methods look good; depend on recursive array conversion.As long as values are arrays (e.g., coordinates/rings), serialization will work after the converter fix. If GeoJSON objects are expected, we’ll need dictionary support; otherwise we’re fine.
If GeoJSON dictionaries are needed, confirm and I’ll extend
QueryValue
/converter to support[String: Any]
safely.tests/languages/dart/tests.dart (2)
174-182
: Spatial predicate tests added — consider one complex geometry example.Point inputs are fine for exercising builders, but a polygon/linestring case would also validate nested array serialization (useful for overlaps/crosses). Optional.
192-192
: Strip trailing whitespace on blank line.Tiny formatting nit to keep diffs clean.
- +
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
templates/swift/Sources/Query.swift.twig
(3 hunks)tests/languages/dart/tests.dart
(2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (19)
- GitHub Check: build (8.3, Ruby31)
- GitHub Check: build (8.3, WebNode)
- GitHub Check: build (8.3, WebChromium)
- GitHub Check: build (8.3, Python311)
- GitHub Check: build (8.3, AppleSwift56)
- GitHub Check: build (8.3, Swift56)
- GitHub Check: build (8.3, PHP80)
- GitHub Check: build (8.3, Python39)
- GitHub Check: build (8.3, Node18)
- GitHub Check: build (8.3, Python313)
- GitHub Check: build (8.3, PHP83)
- GitHub Check: build (8.3, KotlinJava17)
- GitHub Check: build (8.3, Go112)
- GitHub Check: build (8.3, KotlinJava11)
- GitHub Check: build (8.3, FlutterStable)
- GitHub Check: build (8.3, FlutterBeta)
- GitHub Check: build (8.3, DartStable)
- GitHub Check: build (8.3, Android14Java17)
- GitHub Check: build (8.3, Android5Java17)
🔇 Additional comments (1)
tests/languages/dart/tests.dart (1)
164-173
: Distance query tests approved – positional signatures and[values, distance, meters]
payload order match template
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: 0
♻️ Duplicate comments (2)
templates/swift/Sources/Query.swift.twig (2)
9-9
: Enum case added but Codable not updated — arrays still won’t encode/decode.
.array([QueryValue])
is introduced butinit(from:)
andencode(to:)
don’t handle it, so nested arrays used by distance/spatial queries won’t serialize and will be dropped on round-trip.Apply:
enum QueryValue: Codable { @@ init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() // Attempt to decode each type if let stringValue = try? container.decode(String.self) { self = .string(stringValue) } else if let intValue = try? container.decode(Int.self) { self = .int(intValue) } else if let doubleValue = try? container.decode(Double.self) { self = .double(doubleValue) } else if let boolValue = try? container.decode(Bool.self) { self = .bool(boolValue) } else if let queryValue = try? container.decode(Query.self) { self = .query(queryValue) + } else if let arrayValue = try? container.decode([QueryValue].self) { + self = .array(arrayValue) } else { throw DecodingError.dataCorruptedError(in: container, debugDescription: "QueryValue cannot be decoded") } } @@ func encode(to encoder: Encoder) throws { var container = encoder.singleValueContainer() switch self { case .string(let value): try container.encode(value) case .int(let value): try container.encode(value) case .double(let value): try container.encode(value) case .bool(let value): try container.encode(value) case .query(let value): try container.encode(value) + case .array(let value): + try container.encode(value) } }
89-91
: [Any] conversion is incorrect — produces double-nested.array
and collapses elements.Current code returns a single-element
[.array([... .array(...) ...])]
. Map eachAny
to aQueryValue
instead.- case let anyArray as [Any]: - return [.array(anyArray.compactMap { convertToQueryValueArray($0).map { .array($0) } })] + case let anyArray as [Any]: + return anyArray.compactMap { convertAnyToQueryValue($0) }Add helper (outside the selected range, inside
Query
):private static func convertAnyToQueryValue(_ value: Any) -> QueryValue? { switch value { case let v as String: return .string(v) case let v as Int: return .int(v) case let v as Double: return .double(v) case let v as Bool: return .bool(v) case let v as Query: return .query(v) case let v as [Any]: return .array(v.compactMap { convertAnyToQueryValue($0) }) default: return nil } }
🧹 Nitpick comments (3)
templates/swift/Sources/Query.swift.twig (1)
436-498
: Clarify/extend support for Geo payload shapes.If callers may pass GeoJSON objects (dictionaries),
QueryValue
lacks a dictionary/object case; today only scalars/arrays work. Either document thatvalues
must be arrays of scalars/arrays, or add an.object([String: QueryValue])
case plus converter support.tests/languages/web/index.html (2)
277-285
: Spatial predicates: add a polygon/linestring case and parameterize logsCurrent calls use a single point array. Add at least one polygon/linestring input to exercise encoding for non-point geometries, and parameterize to avoid repetition.
- // Spatial query tests - console.log(Query.intersects("location", [40.7128, -74])); - console.log(Query.notIntersects("location", [40.7128, -74])); - console.log(Query.crosses("location", [40.7128, -74])); - console.log(Query.notCrosses("location", [40.7128, -74])); - console.log(Query.overlaps("location", [40.7128, -74])); - console.log(Query.notOverlaps("location", [40.7128, -74])); - console.log(Query.touches("location", [40.7128, -74])); - console.log(Query.notTouches("location", [40.7128, -74])); + // Spatial predicate tests + const point = [40.7128, -74]; + const polygon = [[[-74.02,40.70],[-74.00,40.70],[-74.00,40.72],[-74.02,40.72],[-74.02,40.70]]]; + [ + Query.intersects("location", point), + Query.notIntersects("location", point), + Query.crosses("location", point), + Query.notCrosses("location", point), + Query.overlaps("location", polygon), + Query.notOverlaps("location", polygon), + Query.touches("location", point), + Query.notTouches("location", point), + ].forEach(q => console.log(q));Please also confirm lat/lon order expected by the builder (here we use [lat, lon]). If the API expects [lon, lat] or GeoJSON geometry, adjust inputs accordingly.
267-276
: Distance query tests: dedupe logs, add assertions & verify helpers
- Replace the eight repetitive
console.log(Query.distance… )
calls in tests/languages/web/index.html (lines 267–276) with an array of Query invocations and.forEach
to reduce duplication.- Add a
console.assert
to catch regressions, e.g.
console.assert(Query.distanceEqual("location", pt, radius) !== Query.distanceEqual("location", pt, radius, true), "Expected meters flag to alter serialization");
- Confirm that the static methods
Query.distanceEqual/NotEqual/GreaterThan/LessThan
are implemented and exported in the JS SDK.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
templates/swift/Sources/Query.swift.twig
(3 hunks)tests/languages/web/index.html
(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (17)
- GitHub Check: build (8.3, AppleSwift56)
- GitHub Check: build (8.3, Swift56)
- GitHub Check: build (8.3, WebChromium)
- GitHub Check: build (8.3, WebNode)
- GitHub Check: build (8.3, Go118)
- GitHub Check: build (8.3, Ruby30)
- GitHub Check: build (8.3, KotlinJava11)
- GitHub Check: build (8.3, Python311)
- GitHub Check: build (8.3, PHP83)
- GitHub Check: build (8.3, Python39)
- GitHub Check: build (8.3, Node18)
- GitHub Check: build (8.3, FlutterBeta)
- GitHub Check: build (8.3, FlutterStable)
- GitHub Check: build (8.3, Go112)
- GitHub Check: build (8.3, DotNet90)
- GitHub Check: build (8.3, Android5Java17)
- GitHub Check: build (8.3, Android14Java17)
🔇 Additional comments (1)
templates/swift/Sources/Query.swift.twig (1)
404-434
: Distance builders rely on proper nested-array encoding — currently broken by converter/Codable gaps.Once the two fixes above land, these will serialize as
[ <values-array>, <distance>, <meters> ]
as intended. Please re-run Swift tests for these builders.Example to validate locally:
let q = Query.distanceLessThan("geo", values: [[10.0,20.0]], distance: 1000, meters: true) print(q) // expect: {"method":"distanceLessThan","attribute":"geo","values":[[[10,20]],1000,true]}
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: 3
♻️ Duplicate comments (3)
templates/swift/Sources/Query.swift.twig (1)
9-10
: Swift nested-array encoding fix looks good (resolves prior drop of values).Adding
case array([QueryValue])
with matching decode/encode handles heterogeneous/nested arrays required by distance queries. This addresses the earlier serialization gap.Also applies to: 24-26, 47-48
tests/languages/swift/Tests.swift (1)
189-206
: Swap to [longitude, latitude] in all spatial tests.Tests currently use
[lat, lon]
. Use[lon, lat]
to match GeoJSON order and avoid confusion when these examples are copied into real apps.- print(Query.distanceEqual("location", values: [[40.7128, -74], [40.7128, -74]], distance: 1000)) - print(Query.distanceEqual("location", values: [40.7128, -74], distance: 1000, meters: true)) - print(Query.distanceNotEqual("location", values: [40.7128, -74], distance: 1000)) - print(Query.distanceNotEqual("location", values: [40.7128, -74], distance: 1000, meters: true)) - print(Query.distanceGreaterThan("location", values: [40.7128, -74], distance: 1000)) - print(Query.distanceGreaterThan("location", values: [40.7128, -74], distance: 1000, meters: true)) - print(Query.distanceLessThan("location", values: [40.7128, -74], distance: 1000)) - print(Query.distanceLessThan("location", values: [40.7128, -74], distance: 1000, meters: true)) + print(Query.distanceEqual("location", values: [[-74.0, 40.7128], [-74.0, 40.7128]], distance: 1000)) + print(Query.distanceEqual("location", values: [-74.0, 40.7128], distance: 1000, meters: true)) + print(Query.distanceNotEqual("location", values: [-74.0, 40.7128], distance: 1000)) + print(Query.distanceNotEqual("location", values: [-74.0, 40.7128], distance: 1000, meters: true)) + print(Query.distanceGreaterThan("location", values: [-74.0, 40.7128], distance: 1000)) + print(Query.distanceGreaterThan("location", values: [-74.0, 40.7128], distance: 1000, meters: true)) + print(Query.distanceLessThan("location", values: [-74.0, 40.7128], distance: 1000)) + print(Query.distanceLessThan("location", values: [-74.0, 40.7128], distance: 1000, meters: true)) @@ - print(Query.intersects("location", values: [40.7128, -74])) - print(Query.notIntersects("location", values: [40.7128, -74])) - print(Query.crosses("location", values: [40.7128, -74])) - print(Query.notCrosses("location", values: [40.7128, -74])) - print(Query.overlaps("location", values: [40.7128, -74])) - print(Query.notOverlaps("location", values: [40.7128, -74])) - print(Query.touches("location", values: [40.7128, -74])) - print(Query.notTouches("location", values: [40.7128, -74])) + print(Query.intersects("location", values: [-74.0, 40.7128])) + print(Query.notIntersects("location", values: [-74.0, 40.7128])) + print(Query.crosses("location", values: [-74.0, 40.7128])) + print(Query.notCrosses("location", values: [-74.0, 40.7128])) + print(Query.overlaps("location", values: [-74.0, 40.7128])) + print(Query.notOverlaps("location", values: [-74.0, 40.7128])) + print(Query.touches("location", values: [-74.0, 40.7128])) + print(Query.notTouches("location", values: [-74.0, 40.7128]))templates/go/query.go.twig (1)
321-351
: Normalize input and build a typed payload slice before passing to parseQuery.Use toArray(values) for parity with existing helpers and to ensure single vs. multi inputs serialize consistently. Also pass a named slice instead of taking the address of a composite literal for clarity.
-func DistanceEqual(attribute string, values interface{}, distance float64, meters bool) string { - return parseQuery(queryOptions{ - Method: "distanceEqual", - Attribute: &attribute, - Values: &[]interface{}{values, distance, meters}, - }) -} +func DistanceEqual(attribute string, values interface{}, distance float64, meters bool) string { + coords := toArray(values) + payload := []interface{}{coords, distance, meters} + return parseQuery(queryOptions{ + Method: "distanceEqual", + Attribute: &attribute, + Values: &payload, + }) +} -func DistanceNotEqual(attribute string, values interface{}, distance float64, meters bool) string { - return parseQuery(queryOptions{ - Method: "distanceNotEqual", - Attribute: &attribute, - Values: &[]interface{}{values, distance, meters}, - }) -} +func DistanceNotEqual(attribute string, values interface{}, distance float64, meters bool) string { + coords := toArray(values) + payload := []interface{}{coords, distance, meters} + return parseQuery(queryOptions{ + Method: "distanceNotEqual", + Attribute: &attribute, + Values: &payload, + }) +} -func DistanceGreaterThan(attribute string, values interface{}, distance float64, meters bool) string { - return parseQuery(queryOptions{ - Method: "distanceGreaterThan", - Attribute: &attribute, - Values: &[]interface{}{values, distance, meters}, - }) -} +func DistanceGreaterThan(attribute string, values interface{}, distance float64, meters bool) string { + coords := toArray(values) + payload := []interface{}{coords, distance, meters} + return parseQuery(queryOptions{ + Method: "distanceGreaterThan", + Attribute: &attribute, + Values: &payload, + }) +} -func DistanceLessThan(attribute string, values interface{}, distance float64, meters bool) string { - return parseQuery(queryOptions{ - Method: "distanceLessThan", - Attribute: &attribute, - Values: &[]interface{}{values, distance, meters}, - }) -} +func DistanceLessThan(attribute string, values interface{}, distance float64, meters bool) string { + coords := toArray(values) + payload := []interface{}{coords, distance, meters} + return parseQuery(queryOptions{ + Method: "distanceLessThan", + Attribute: &attribute, + Values: &payload, + }) +}To confirm expected JSON shape for these helpers, run:
#!/bin/bash # Inspect test expectations for distance* queries rg -n -C2 -i 'distance(Equal|NotEqual|GreaterThan|LessThan)' tests
🧹 Nitpick comments (10)
templates/swift/Sources/Query.swift.twig (4)
96-119
: Preserve empty arrays instead of dropping them.
convertToQueryValueArray
returnsnil
whennestedValues
is empty, which omitsvalues
entirely. If an empty array is a valid, intentional signal, prefer encoding[]
to distinguish “empty” from “absent”.Apply:
- return nestedValues.isEmpty ? nil : nestedValues + return nestedValues
433-463
: Confirm wire contract for distance queries: [coords, distance, meters].Double-check backend expects the triplet in this exact order and that
meters
is a Bool flag (vs unit enum). Ensure parity with other SDKs in this PR.Optional: add brief docs to clarify units and coordinate order for users.
+ /// Returns a query filtering by distance from a coordinate or between two coordinates. + /// - Parameters: + /// - attribute: Field name. + /// - values: Either [lon, lat] or [[lon, lat], [lon, lat]]. + /// - distance: Radius or threshold distance. + /// - meters: When true, distance is in meters (otherwise default server unit).
465-527
: Document expected coordinate order and geometry shape.Spatial predicates typically expect GeoJSON order [longitude, latitude]. Add a short doc comment to prevent misuse. If polygons/lines are supported, specify the shape format.
+ /// Spatial predicate using GeoJSON-style coordinates. + /// - Parameters: + /// - attribute: Field name. + /// - values: Coordinates in [lon, lat] or geometry arrays (e.g., polygon).
529-535
: Minor: align numeric types for consistency.
parseValue(_:)
funnels primitives into[Any]
. Mixed Int/Double in the same coordinate array is fine in JSON, but consider normalizing toDouble
when values represent coordinates to avoid subtle test discrepancies.tests/languages/swift/Tests.swift (1)
189-197
: Optional: diversify distance test data.Using two identical points for
distanceEqual
doesn’t help spot regressions. Consider two distinct points to better exercise comparisons.- print(Query.distanceEqual("location", values: [[-74.0, 40.7128], [-74.0, 40.7128]], distance: 1000)) + print(Query.distanceEqual("location", values: [[-74.0060, 40.7128], [-73.9352, 40.7306]], distance: 1000))tests/languages/kotlin/Tests.kt (2)
201-210
: Use geometry-appropriate inputs for spatial predicates.
crosses/overlaps/touches
typically require line/polygon geometries; a point may be semantically weak. Consider adding polygon/line cases in addition to the point.Example additions (place after Line 210):
// Additional geometry cases for stronger coverage val line = listOf(listOf(40.7120, -74.0100), listOf(40.7150, -74.0000)) val polygon = listOf( listOf( listOf(40.7100, -74.0150), listOf(40.7100, -73.9950), listOf(40.7250, -73.9950), listOf(40.7250, -74.0150), listOf(40.7100, -74.0150) ) ) writeToFile(Query.intersects("location", polygon)) writeToFile(Query.crosses("location", line)) writeToFile(Query.overlaps("location", polygon)) writeToFile(Query.touches("location", polygon))
191-200
: Use Doubles for coordinates in Kotlin testsMixing
Double
andInt
literals (e.g.-74
vs-74.0
) can lead to inconsistent JSON across SDKs. Update all coordinate literals intests/languages/kotlin/Tests.kt
toDouble
:- writeToFile(Query.distanceEqual("location", listOf(listOf(40.7128, -74), listOf(40.7128, -74)), 1000)) + writeToFile(Query.distanceEqual("location", listOf(listOf(40.7128, -74.0), listOf(40.7128, -74.0)), 1000)) - writeToFile(Query.distanceEqual("location", listOf(40.7128, -74), 1000, true)) + writeToFile(Query.distanceEqual("location", listOf(40.7128, -74.0), 1000, true)) - writeToFile(Query.distanceNotEqual("location", listOf(40.7128, -74), 1000)) + writeToFile(Query.distanceNotEqual("location", listOf(40.7128, -74.0), 1000)) - writeToFile(Query.distanceNotEqual("location", listOf(40.7128, -74), 1000, true)) + writeToFile(Query.distanceNotEqual("location", listOf(40.7128, -74.0), 1000, true)) - writeToFile(Query.distanceGreaterThan("location", listOf(40.7128, -74), 1000)) + writeToFile(Query.distanceGreaterThan("location", listOf(40.7128, -74.0), 1000)) - writeToFile(Query.distanceGreaterThan("location", listOf(40.7128, -74), 1000, true)) + writeToFile(Query.distanceGreaterThan("location", listOf(40.7128, -74.0), 1000, true)) - writeToFile(Query.distanceLessThan("location", listOf(40.7128, -74), 1000)) + writeToFile(Query.distanceLessThan("location", listOf(40.7128, -74.0), 1000)) - writeToFile(Query.distanceLessThan("location", listOf(40.7128, -74), 1000, true)) + writeToFile(Query.distanceLessThan("location", listOf(40.7128, -74.0), 1000, true))Run to confirm no mixed-int coords remain:
rg -nP -C1 '40\.7128,\s*-74(\D)' tests/languages/kotlin/Tests.kt
tests/languages/dotnet/Tests.cs (3)
172-181
: Use [lon, lat] ordering and consistent numeric types for points; DRY the repeated coords.Likely the API expects GeoJSON order [longitude, latitude]. Current tests use [40.7128, -74] (lat, lon) and mix double/int, which can serialize inconsistently across locales. Also, the coordinate literal is repeated 8x.
Please confirm the expected coordinate order in the generator/API. If it is [lon, lat], consider this refactor for clarity and consistency:
- // Spatial Distance query tests - TestContext.WriteLine(Query.DistanceEqual("location", new List<List<object>> { new List<object> { 40.7128, -74 }, new List<object> { 40.7128, -74 } }, 1000)); - TestContext.WriteLine(Query.DistanceEqual("location", new List<object> { 40.7128, -74 }, 1000, true)); - TestContext.WriteLine(Query.DistanceNotEqual("location", new List<object> { 40.7128, -74 }, 1000)); - TestContext.WriteLine(Query.DistanceNotEqual("location", new List<object> { 40.7128, -74 }, 1000, true)); - TestContext.WriteLine(Query.DistanceGreaterThan("location", new List<object> { 40.7128, -74 }, 1000)); - TestContext.WriteLine(Query.DistanceGreaterThan("location", new List<object> { 40.7128, -74 }, 1000, true)); - TestContext.WriteLine(Query.DistanceLessThan("location", new List<object> { 40.7128, -74 }, 1000)); - TestContext.WriteLine(Query.DistanceLessThan("location", new List<object> { 40.7128, -74 }, 1000, true)); + // Spatial Distance query tests + var nyc = new List<object> { -74.0, 40.7128 }; // [lon, lat] + var nycPair = new List<List<object>> { nyc, nyc }; + TestContext.WriteLine(Query.DistanceEqual("location", nycPair, 1000)); + TestContext.WriteLine(Query.DistanceEqual("location", nyc, 1000, true)); + TestContext.WriteLine(Query.DistanceNotEqual("location", nyc, 1000)); + TestContext.WriteLine(Query.DistanceNotEqual("location", nyc, 1000, true)); + TestContext.WriteLine(Query.DistanceGreaterThan("location", nyc, 1000)); + TestContext.WriteLine(Query.DistanceGreaterThan("location", nyc, 1000, true)); + TestContext.WriteLine(Query.DistanceLessThan("location", nyc, 1000)); + TestContext.WriteLine(Query.DistanceLessThan("location", nyc, 1000, true));Additionally, if the last bool is a unit flag, prefer named argument usage once you confirm the parameter name (e.g., meters: true) to improve readability.
172-181
: Add at least one assertion to make the new tests meaningful beyond compile-time.Right now these lines only print. Add a minimal assertion to catch serialization regressions.
- TestContext.WriteLine(Query.DistanceLessThan("location", nyc, 1000, true)); + var distanceQuery = Query.DistanceLessThan("location", nyc, 1000, true); + TestContext.WriteLine(distanceQuery); + Assert.That(distanceQuery, Does.StartWith("distanceLessThan("));If you have a canonical expected string format, assert the full string instead.
182-191
: Reuse the extracted point and keep ordering consistent for spatial predicates.Mirror the same [lon, lat] ordering and avoid repeating literals.
- // Spatial query tests - TestContext.WriteLine(Query.Intersects("location", new List<object> { 40.7128, -74 })); - TestContext.WriteLine(Query.NotIntersects("location", new List<object> { 40.7128, -74 })); - TestContext.WriteLine(Query.Crosses("location", new List<object> { 40.7128, -74 })); - TestContext.WriteLine(Query.NotCrosses("location", new List<object> { 40.7128, -74 })); - TestContext.WriteLine(Query.Overlaps("location", new List<object> { 40.7128, -74 })); - TestContext.WriteLine(Query.NotOverlaps("location", new List<object> { 40.7128, -74 })); - TestContext.WriteLine(Query.Touches("location", new List<object> { 40.7128, -74 })); - TestContext.WriteLine(Query.NotTouches("location", new List<object> { 40.7128, -74 })); + // Spatial query tests + TestContext.WriteLine(Query.Intersects("location", nyc)); + TestContext.WriteLine(Query.NotIntersects("location", nyc)); + TestContext.WriteLine(Query.Crosses("location", nyc)); + TestContext.WriteLine(Query.NotCrosses("location", nyc)); + TestContext.WriteLine(Query.Overlaps("location", nyc)); + TestContext.WriteLine(Query.NotOverlaps("location", nyc)); + TestContext.WriteLine(Query.Touches("location", nyc)); + TestContext.WriteLine(Query.NotTouches("location", nyc));Optional: add one assertion here too (e.g., StartsWith("intersects(")).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (18)
templates/go/query.go.twig
(1 hunks)templates/swift/Sources/Query.swift.twig
(5 hunks)tests/Base.php
(1 hunks)tests/languages/android/Tests.kt
(1 hunks)tests/languages/apple/Tests.swift
(1 hunks)tests/languages/dart/tests.dart
(2 hunks)tests/languages/deno/tests.ts
(1 hunks)tests/languages/dotnet/Tests.cs
(1 hunks)tests/languages/flutter/tests.dart
(1 hunks)tests/languages/go/tests.go
(1 hunks)tests/languages/kotlin/Tests.kt
(1 hunks)tests/languages/node/test.js
(1 hunks)tests/languages/php/test.php
(1 hunks)tests/languages/python/tests.py
(1 hunks)tests/languages/ruby/tests.rb
(1 hunks)tests/languages/swift/Tests.swift
(1 hunks)tests/languages/web/index.html
(1 hunks)tests/languages/web/node.js
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (13)
- tests/languages/web/index.html
- tests/languages/node/test.js
- tests/languages/android/Tests.kt
- tests/languages/ruby/tests.rb
- tests/languages/apple/Tests.swift
- tests/Base.php
- tests/languages/flutter/tests.dart
- tests/languages/deno/tests.ts
- tests/languages/dart/tests.dart
- tests/languages/go/tests.go
- tests/languages/web/node.js
- tests/languages/python/tests.py
- tests/languages/php/test.php
🧰 Additional context used
🧬 Code graph analysis (1)
tests/languages/kotlin/Tests.kt (1)
tests/languages/android/Tests.kt (1)
writeToFile
(268-271)
🔇 Additional comments (1)
tests/languages/kotlin/Tests.kt (1)
191-200
: Confirm Kotlin spatial query overloads accept both single-point and multi-point inputs.
Tests use bothList<Double>
andList<List<Double>>
fordistanceEqual
(and related methods); please verify the method signatures inQuery.kt
and their serialization logic correctly handle both shapes.
tests/languages/dotnet/Tests.cs
Outdated
// Spatial Distance query tests | ||
TestContext.WriteLine(Query.DistanceEqual("location", new List<List<object>> { new List<object> { 40.7128, -74 }, new List<object> { 40.7128, -74 } }, 1000)); | ||
TestContext.WriteLine(Query.DistanceEqual("location", new List<object> { 40.7128, -74 }, 1000, true)); | ||
TestContext.WriteLine(Query.DistanceNotEqual("location", new List<object> { 40.7128, -74 }, 1000)); | ||
TestContext.WriteLine(Query.DistanceNotEqual("location", new List<object> { 40.7128, -74 }, 1000, true)); | ||
TestContext.WriteLine(Query.DistanceGreaterThan("location", new List<object> { 40.7128, -74 }, 1000)); | ||
TestContext.WriteLine(Query.DistanceGreaterThan("location", new List<object> { 40.7128, -74 }, 1000, true)); | ||
TestContext.WriteLine(Query.DistanceLessThan("location", new List<object> { 40.7128, -74 }, 1000)); | ||
TestContext.WriteLine(Query.DistanceLessThan("location", new List<object> { 40.7128, -74 }, 1000, true)); | ||
|
||
// Spatial query tests | ||
TestContext.WriteLine(Query.Intersects("location", new List<object> { 40.7128, -74 })); | ||
TestContext.WriteLine(Query.NotIntersects("location", new List<object> { 40.7128, -74 })); | ||
TestContext.WriteLine(Query.Crosses("location", new List<object> { 40.7128, -74 })); | ||
TestContext.WriteLine(Query.NotCrosses("location", new List<object> { 40.7128, -74 })); | ||
TestContext.WriteLine(Query.Overlaps("location", new List<object> { 40.7128, -74 })); | ||
TestContext.WriteLine(Query.NotOverlaps("location", new List<object> { 40.7128, -74 })); | ||
TestContext.WriteLine(Query.Touches("location", new List<object> { 40.7128, -74 })); | ||
TestContext.WriteLine(Query.NotTouches("location", new List<object> { 40.7128, -74 })); | ||
|
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.
💡 Verification agent
🧩 Analysis chain
Verify .NET method signatures and the meaning of the trailing bool.
Before merging, confirm the generated C# signatures match these call sites (esp. whether values accept both point and point[] for distance ops) and whether the trailing boolean indeed means “meters”.
Run this script to inspect the signatures and parameter names across the repo:
If point arrays must be [lon, lat], consider adding a short comment to the test explaining the ordering to future readers.
🏁 Script executed:
#!/bin/bash
# Find C# Query helpers and check spatial signatures/param names
fd -t f -e cs Query | xargs -r -n1 -I{} sh -c 'echo "== {} =="; rg -nP -C2 "(class\\s+Query\\b|Distance(Equal|NotEqual|GreaterThan|LessThan)\\s*\\(|Intersects\\s*\\(|NotIntersects\\s*\\(|Crosses\\s*\\(|NotCrosses\\s*\\(|Overlaps\\s*\\(|NotOverlaps\\s*\\(|Touches\\s*\\(|NotTouches\\s*\\()" "{}"'
# Specifically check for a named 'meters' (or similar) parameter
rg -nP -C1 --type=cs 'Distance(Equal|NotEqual|GreaterThan|LessThan)\s*\([^)]*?(meters|isMeters|useMeters)\s*:' || true
# Show these test call sites for context
rg -n -C2 'Distance(Equal|NotEqual|GreaterThan|LessThan)\(|Intersects\(' tests/languages/dotnet/Tests.cs
Length of output: 2191
🏁 Script executed:
#!/bin/bash
# Locate the Query class definition
rg -nP 'class\s+Query\b' -t cs -n -C2
# Inspect all Distance* overloads and their signatures
rg -nP 'public\s+static\s+\S+\s+DistanceEqual\(' -t cs -n -C2
rg -nP 'public\s+static\s+\S+\s+DistanceNotEqual\(' -t cs -n -C2
rg -nP 'public\s+static\s+\S+\s+DistanceGreaterThan\(' -t cs -n -C2
rg -nP 'public\s+static\s+\S+\s+DistanceLessThan\(' -t cs -n -C2
# Inspect spatial predicate signatures
rg -nP 'public\s+static\s+\S+\s+(Intersects|NotIntersects|Crosses|NotCrosses|Overlaps|NotOverlaps|Touches|NotTouches)\(' -t cs -n -C2
Length of output: 443
🏁 Script executed:
#!/bin/bash
# Show the Tests.cs header to identify imports and namespace
echo ">> Tests.cs header <<"
sed -n '1,50p' tests/languages/dotnet/Tests.cs
# Locate the Query class definition(s)
echo ">> Query class definitions <<"
rg -nP --no-ignore 'class\s+Query\b' -n -C2
# Find all static Distance* method definitions
echo ">> DistanceEqual definitions <<"
rg -nP 'public\s+static\s+\S+\s+DistanceEqual\(' -t cs -n -C2
echo ">> DistanceNotEqual definitions <<"
rg -nP 'public\s+static\s+\S+\s+DistanceNotEqual\(' -t cs -n -C2
echo ">> DistanceGreaterThan definitions <<"
rg -nP 'public\s+static\s+\S+\s+DistanceGreaterThan\(' -t cs -n -C2
echo ">> DistanceLessThan definitions <<"
rg -nP 'public\s+static\s+\S+\s+DistanceLessThan\(' -t cs -n -C2
# Find all static spatial predicate method definitions
for m in Intersects NotIntersects Crosses NotCrosses Overlaps NotOverlaps Touches NotTouches; do
echo ">> $m definitions <<"
rg -nP "public\s+static\s+\S+\s+$m\(" -t cs -n -C2
done
Length of output: 7535
🏁 Script executed:
#!/bin/bash
# Display the C# Query template to inspect spatial method signatures
sed -n '1,200p' templates/dotnet/Package/Query.cs.twig
Length of output: 6826
🏁 Script executed:
#!/bin/bash
# List all template files in the .NET Package directory
ls -R templates/dotnet/Package
Length of output: 617
🏁 Script executed:
#!/bin/bash
# Display the Extensions template for .NET to locate spatial methods
echo ">> templates/dotnet/Package/Extensions/Extensions.cs.twig <<"
sed -n '1,200p' templates/dotnet/Package/Extensions/Extensions.cs.twig
# Search for any Distance* definitions in the Extensions template
echo ">> Spatial methods in Extensions.cs.twig <<"
rg -nP 'public\s+static\s+\S+\s+Distance(Equal|NotEqual|GreaterThan|LessThan)\(' -n templates/dotnet/Package/Extensions/Extensions.cs.twig
# Search for Intersects/* in Extensions template
echo ">> Spatial predicates in Extensions.cs.twig <<"
rg -nP 'public\s+static\s+\S+\s+(Intersects|NotIntersects|Crosses|NotCrosses|Overlaps|NotOverlaps|Touches|NotTouches)\(' -n templates/dotnet/Package/Extensions/Extensions.cs.twig
Length of output: 9795
Implement missing spatial query methods in .NET Query class
Tests reference Query.DistanceEqual
, DistanceNotEqual
, DistanceGreaterThan
, DistanceLessThan
(both point and point‐array overloads, with optional bool), and spatial predicates (Intersects
, NotIntersects
, Crosses
, NotCrosses
, Overlaps
, NotOverlaps
, Touches
, NotTouches
), but none of these are defined in Query.cs.twig
. Add static methods matching these signatures (name the trailing bool parameter clearly, e.g. isMeters
) so the tests compile and behavior is documented.
🤖 Prompt for AI Agents
In tests/languages/dotnet/Tests.cs around lines 172-191, the tests call missing
spatial methods on the Query class; add static methods to Query.cs.twig for
DistanceEqual, DistanceNotEqual, DistanceGreaterThan, DistanceLessThan (each
with overloads accepting either List<object> (point) or List<List<object>>
(point array) and an optional trailing bool parameter named isMeters), and add
spatial predicate methods Intersects, NotIntersects, Crosses, NotCrosses,
Overlaps, NotOverlaps, Touches, NotTouches (each accepting the field name and a
point as List<object>). Implement each method to construct and return the same
query object shape used by existing Query methods (mirror naming/structure and
serialization conventions used elsewhere in Query.cs.twig) and include XML doc
comments describing parameters and behavior.
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: 0
♻️ Duplicate comments (2)
templates/go/query.go.twig (2)
353-415
: Accept interface{} + toArray for spatial predicates (parity and ergonomics).Requiring
[]interface{}
makes typical inputs like[]float64
unusable without manual conversion. Match other helpers: acceptinterface{}
and calltoArray
.-func Intersects(attribute string, values []interface{}) string { - return parseQuery(queryOptions{ - Method: "intersects", - Attribute: &attribute, - Values: &values, - }) -} +func Intersects(attribute string, value interface{}) string { + vals := toArray(value) + return parseQuery(queryOptions{ + Method: "intersects", + Attribute: &attribute, + Values: &vals, + }) +} -func NotIntersects(attribute string, values []interface{}) string { +func NotIntersects(attribute string, value interface{}) string { - return parseQuery(queryOptions{ - Method: "notIntersects", - Attribute: &attribute, - Values: &values, - }) + vals := toArray(value) + return parseQuery(queryOptions{ + Method: "notIntersects", + Attribute: &attribute, + Values: &vals, + }) } -func Crosses(attribute string, values []interface{}) string { +func Crosses(attribute string, value interface{}) string { - return parseQuery(queryOptions{ - Method: "crosses", - Attribute: &attribute, - Values: &values, - }) + vals := toArray(value) + return parseQuery(queryOptions{ + Method: "crosses", + Attribute: &attribute, + Values: &vals, + }) } -func NotCrosses(attribute string, values []interface{}) string { +func NotCrosses(attribute string, value interface{}) string { - return parseQuery(queryOptions{ - Method: "notCrosses", - Attribute: &attribute, - Values: &values, - }) + vals := toArray(value) + return parseQuery(queryOptions{ + Method: "notCrosses", + Attribute: &attribute, + Values: &vals, + }) } -func Overlaps(attribute string, values []interface{}) string { +func Overlaps(attribute string, value interface{}) string { - return parseQuery(queryOptions{ - Method: "overlaps", - Attribute: &attribute, - Values: &values, - }) + vals := toArray(value) + return parseQuery(queryOptions{ + Method: "overlaps", + Attribute: &attribute, + Values: &vals, + }) } -func NotOverlaps(attribute string, values []interface{}) string { +func NotOverlaps(attribute string, value interface{}) string { - return parseQuery(queryOptions{ - Method: "notOverlaps", - Attribute: &attribute, - Values: &values, - }) + vals := toArray(value) + return parseQuery(queryOptions{ + Method: "notOverlaps", + Attribute: &attribute, + Values: &vals, + }) } -func Touches(attribute string, values []interface{}) string { +func Touches(attribute string, value interface{}) string { - return parseQuery(queryOptions{ - Method: "touches", - Attribute: &attribute, - Values: &values, - }) + vals := toArray(value) + return parseQuery(queryOptions{ + Method: "touches", + Attribute: &attribute, + Values: &vals, + }) } -func NotTouches(attribute string, values []interface{}) string { - return parseQuery(queryOptions{ - Method: "notTouches", - Attribute: &attribute, - Values: &values, - }) -} +func NotTouches(attribute string, value interface{}) string { + vals := toArray(value) + return parseQuery(queryOptions{ + Method: "notTouches", + Attribute: &attribute, + Values: &vals, + }) +}
321-351
: Fix payload shape and align API with existing helpers (wrap payload, accept single/multi value).Current Values builds
[values, distance, meters]
directly and forces[]interface{}
. Expected shape is[[toArray(value), distance, meters]]
, and other helpers acceptinterface{}
+toArray
. Update all four Distance* funcs accordingly.-func DistanceEqual(attribute string, values []interface{}, distance float64, meters bool) string { - return parseQuery(queryOptions{ - Method: "distanceEqual", - Attribute: &attribute, - Values: &[]interface{}{values, distance, meters}, - }) -} +func DistanceEqual(attribute string, value interface{}, distance float64, meters bool) string { + payload := []interface{}{toArray(value), distance, meters} + wrapped := []interface{}{payload} + return parseQuery(queryOptions{ + Method: "distanceEqual", + Attribute: &attribute, + Values: &wrapped, + }) +} -func DistanceNotEqual(attribute string, values []interface{}, distance float64, meters bool) string { - return parseQuery(queryOptions{ - Method: "distanceNotEqual", - Attribute: &attribute, - Values: &[]interface{}{values, distance, meters}, - }) -} +func DistanceNotEqual(attribute string, value interface{}, distance float64, meters bool) string { + payload := []interface{}{toArray(value), distance, meters} + wrapped := []interface{}{payload} + return parseQuery(queryOptions{ + Method: "distanceNotEqual", + Attribute: &attribute, + Values: &wrapped, + }) +} -func DistanceGreaterThan(attribute string, values []interface{}, distance float64, meters bool) string { - return parseQuery(queryOptions{ - Method: "distanceGreaterThan", - Attribute: &attribute, - Values: &[]interface{}{values, distance, meters}, - }) -} +func DistanceGreaterThan(attribute string, value interface{}, distance float64, meters bool) string { + payload := []interface{}{toArray(value), distance, meters} + wrapped := []interface{}{payload} + return parseQuery(queryOptions{ + Method: "distanceGreaterThan", + Attribute: &attribute, + Values: &wrapped, + }) +} -func DistanceLessThan(attribute string, values []interface{}, distance float64, meters bool) string { - return parseQuery(queryOptions{ - Method: "distanceLessThan", - Attribute: &attribute, - Values: &[]interface{}{values, distance, meters}, - }) -} +func DistanceLessThan(attribute string, value interface{}, distance float64, meters bool) string { + payload := []interface{}{toArray(value), distance, meters} + wrapped := []interface{}{payload} + return parseQuery(queryOptions{ + Method: "distanceLessThan", + Attribute: &attribute, + Values: &wrapped, + }) +}
🧹 Nitpick comments (1)
templates/go/query.go.twig (1)
321-351
: Nit: rename param tovalue
for clarity.Singular matches the rest of the file and avoids confusion between the outer
values
field vs. inner payload.Also applies to: 353-415
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
templates/go/query.go.twig
(1 hunks)tests/Base.php
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- tests/Base.php
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: 1
♻️ Duplicate comments (3)
tests/languages/dotnet/Tests.cs (1)
175-182
: Confirm .NET Query Distance overloads and trailing bool semantics.*Ensure the generated Query class exposes both point and point[] overloads and that the trailing bool indeed toggles meters (name may be meters/isMeters). Adds confidence before merge.
#!/bin/bash # Verify .NET spatial Distance* method signatures and boolean parameter name rg -nP -C2 'class\s+Query\b' templates/dotnet/Package/Query.cs.twig rg -nP -C2 'public\s+static\s+\S+\s+Distance(Equal|NotEqual|GreaterThan|LessThan)\(' templates/dotnet/Package/Query.cs.twig rg -nP -C1 'Distance(Equal|NotEqual|GreaterThan|LessThan)\([^)]*bool\s+(\w+)' templates/dotnet/Package/Query.cs.twig # Show test call sites for cross-check rg -n -C1 'Distance(Equal|NotEqual|GreaterThan|LessThan)\(' tests/languages/dotnet/Tests.cstemplates/react-native/src/query.ts.twig (2)
226-263
: Drop unsafe casts; add proper geometry/distance types (parity with web).Current
[values, distance, meters] as QueryTypesList
is unsound and can mask type bugs. Use explicit tuple/geometry types and remove casts. Mirrors prior feedback; updated here to include meters.Apply within this block:
- static distanceEqual = (attribute: string, values: any[], distance: number, meters: boolean = false): string => - new Query("distanceEqual", attribute, [values, distance, meters] as QueryTypesList).toString(); + static distanceEqual = (attribute: string, values: GeometryValues, distance: number, meters: boolean = false): string => + new Query("distanceEqual", attribute, [values, distance, meters]).toString(); - static distanceNotEqual = (attribute: string, values: any[], distance: number, meters: boolean = false): string => - new Query("distanceNotEqual", attribute, [values, distance, meters] as QueryTypesList).toString(); + static distanceNotEqual = (attribute: string, values: GeometryValues, distance: number, meters: boolean = false): string => + new Query("distanceNotEqual", attribute, [values, distance, meters]).toString(); - static distanceGreaterThan = (attribute: string, values: any[], distance: number, meters: boolean = false): string => - new Query("distanceGreaterThan", attribute, [values, distance, meters] as QueryTypesList).toString(); + static distanceGreaterThan = (attribute: string, values: GeometryValues, distance: number, meters: boolean = false): string => + new Query("distanceGreaterThan", attribute, [values, distance, meters]).toString(); - static distanceLessThan = (attribute: string, values: any[], distance: number, meters: boolean = false): string => - new Query("distanceLessThan", attribute, [values, distance, meters] as QueryTypesList).toString(); + static distanceLessThan = (attribute: string, values: GeometryValues, distance: number, meters: boolean = false): string => + new Query("distanceLessThan", attribute, [values, distance, meters]).toString();Update JSDoc param types accordingly in this hunk.
272-343
: Type the spatial predicates (values
) and keep consistency.Use the same GeometryValues alias; remove casts elsewhere if added later.
- static intersects = (attribute: string, values: any[]): string => + static intersects = (attribute: string, values: GeometryValues): string => new Query("intersects", attribute, values).toString(); - static notIntersects = (attribute: string, values: any[]): string => + static notIntersects = (attribute: string, values: GeometryValues): string => new Query("notIntersects", attribute, values).toString(); - static crosses = (attribute: string, values: any[]): string => + static crosses = (attribute: string, values: GeometryValues): string => new Query("crosses", attribute, values).toString(); - static notCrosses = (attribute: string, values: any[]): string => + static notCrosses = (attribute: string, values: GeometryValues): string => new Query("notCrosses", attribute, values).toString(); - static overlaps = (attribute: string, values: any[]): string => + static overlaps = (attribute: string, values: GeometryValues): string => new Query("overlaps", attribute, values).toString(); - static notOverlaps = (attribute: string, values: any[]): string => + static notOverlaps = (attribute: string, values: GeometryValues): string => new Query("notOverlaps", attribute, values).toString(); - static touches = (attribute: string, values: any[]): string => + static touches = (attribute: string, values: GeometryValues): string => new Query("touches", attribute, values).toString(); - static notTouches = (attribute: string, values: any[]): string => + static notTouches = (attribute: string, values: GeometryValues): string => new Query("notTouches", attribute, values).toString();Add the supporting types near the top (outside this hunk):
// Types type QueryTypesSingle = string | number | boolean; export type GeometryValues = unknown[]; // keep broad; align with web template if it defines GeoJSON export type DistanceValues = [GeometryValues, number, boolean?]; export type QueryTypesList = | string[] | number[] | boolean[] | Query[] | GeometryValues | DistanceValues; export type QueryTypes = QueryTypesSingle | QueryTypesList;
🧹 Nitpick comments (12)
tests/languages/deno/tests.ts (5)
193-193
: Avoid duplicate coordinates in multi-point distance test.Using the same point twice weakens coverage. Swap the second point to a different location.
- console.log(Query.distanceEqual("location", [[40.7128, -74], [40.7128, -74]], 1000)); + console.log(Query.distanceEqual("location", [[40.7128, -74], [34.0522, -118.2437]], 1000));If backend expects [lng, lat] instead of [lat, lng], use this alternative:
- console.log(Query.distanceEqual("location", [[40.7128, -74], [40.7128, -74]], 1000)); + console.log(Query.distanceEqual("location", [[-74, 40.7128], [-118.2437, 34.0522]], 1000));
193-200
: Cover both single-point and multi-point inputs consistently across all distance methods.Only distanceEqual exercises an array-of-points; mirror that for the other three to validate both overloads.
console.log(Query.distanceNotEqual("location", [40.7128, -74], 1000)); + console.log(Query.distanceNotEqual("location", [[40.7128, -74], [34.0522, -118.2437]], 1000)); console.log(Query.distanceGreaterThan("location", [40.7128, -74], 1000)); + console.log(Query.distanceGreaterThan("location", [[40.7128, -74], [34.0522, -118.2437]], 1000)); console.log(Query.distanceLessThan("location", [40.7128, -74], 1000)); + console.log(Query.distanceLessThan("location", [[40.7128, -74], [34.0522, -118.2437]], 1000));
203-210
: Use appropriate geometry for spatial predicates (beyond points).crosses/overlaps typically apply to lines/polygons. Add at least one LineString and Polygon case to exercise valid semantics.
- console.log(Query.crosses("location", [40.7128, -74])); + // Example LineString crossing test + const line = [[-74.02, 40.70], [-73.98, 40.75]]; + console.log(Query.crosses("location", line)); - console.log(Query.overlaps("location", [40.7128, -74])); + // Example Polygon overlap test (closed ring) + const polygon = [[-74.02, 40.70], [-74.02, 40.75], [-73.98, 40.75], [-73.98, 40.70], [-74.02, 40.70]]; + console.log(Query.overlaps("location", polygon));
192-201
: Exercise meters flag and boundary cases.Add tests for omitted meters (default), meters=false, zero/negative distance, and out-of-range coordinates to validate input handling.
+ // meters omitted (default) + console.log(Query.distanceEqual("location", [40.7128, -74], 1000)); + // meters explicitly false + console.log(Query.distanceEqual("location", [40.7128, -74], 1000, false)); + // boundary/invalid examples (should throw or be rejected upstream) + // console.log(Query.distanceLessThan("location", [95, -200], 1000)); // invalid lat/lng + // console.log(Query.distanceGreaterThan("location", [40.7128, -74], -5)); // invalid distance
192-210
: Reduce duplication with shared fixtures.Extract the point and radius into constants to improve readability and avoid typos.
TypeScript snippet to add near the top of the query tests:
const NYC = [40.7128, -74] as const; // swap order if backend expects [lng, lat] const LA = [34.0522, -118.2437] as const; const R1000 = 1000;Then use NYC/LA/R1000 in the calls here.
tests/languages/dotnet/Tests.cs (2)
174-193
: Reduce duplication; clarify coord order; exercise explicit bool path.Minor cleanup and clarity. Also adds one explicit false-case to cover both boolean paths.
- // Spatial Distance query tests - TestContext.WriteLine(Query.DistanceEqual("location", new List<List<object>> { new List<object> { 40.7128, -74 }, new List<object> { 40.7128, -74 } }, 1000)); - TestContext.WriteLine(Query.DistanceEqual("location", new List<object> { 40.7128, -74 }, 1000, true)); - TestContext.WriteLine(Query.DistanceNotEqual("location", new List<object> { 40.7128, -74 }, 1000)); - TestContext.WriteLine(Query.DistanceNotEqual("location", new List<object> { 40.7128, -74 }, 1000, true)); - TestContext.WriteLine(Query.DistanceGreaterThan("location", new List<object> { 40.7128, -74 }, 1000)); - TestContext.WriteLine(Query.DistanceGreaterThan("location", new List<object> { 40.7128, -74 }, 1000, true)); - TestContext.WriteLine(Query.DistanceLessThan("location", new List<object> { 40.7128, -74 }, 1000)); - TestContext.WriteLine(Query.DistanceLessThan("location", new List<object> { 40.7128, -74 }, 1000, true)); + // Spatial Distance query tests + // NOTE: Coordinates below are [lat, lon]. If the API expects [lon, lat], swap order. + var point = new List<object> { 40.7128, -74 }; + var points = new List<List<object>> { point, point }; // exercise point[] overload + TestContext.WriteLine(Query.DistanceEqual("location", points, 1000)); + TestContext.WriteLine(Query.DistanceEqual("location", point, 1000, true)); + TestContext.WriteLine(Query.DistanceEqual("location", point, 1000, false)); // explicit boolean path + TestContext.WriteLine(Query.DistanceNotEqual("location", point, 1000)); + TestContext.WriteLine(Query.DistanceNotEqual("location", point, 1000, true)); + TestContext.WriteLine(Query.DistanceGreaterThan("location", point, 1000)); + TestContext.WriteLine(Query.DistanceGreaterThan("location", point, 1000, true)); + TestContext.WriteLine(Query.DistanceLessThan("location", point, 1000)); + TestContext.WriteLine(Query.DistanceLessThan("location", point, 1000, true)); @@ - // Spatial query tests - TestContext.WriteLine(Query.Intersects("location", new List<object> { 40.7128, -74 })); - TestContext.WriteLine(Query.NotIntersects("location", new List<object> { 40.7128, -74 })); - TestContext.WriteLine(Query.Crosses("location", new List<object> { 40.7128, -74 })); - TestContext.WriteLine(Query.NotCrosses("location", new List<object> { 40.7128, -74 })); - TestContext.WriteLine(Query.Overlaps("location", new List<object> { 40.7128, -74 })); - TestContext.WriteLine(Query.NotOverlaps("location", new List<object> { 40.7128, -74 })); - TestContext.WriteLine(Query.Touches("location", new List<object> { 40.7128, -74 })); - TestContext.WriteLine(Query.NotTouches("location", new List<object> { 40.7128, -74 })); + // Spatial query tests (point geometry) + TestContext.WriteLine(Query.Intersects("location", point)); + TestContext.WriteLine(Query.NotIntersects("location", point)); + TestContext.WriteLine(Query.Crosses("location", point)); + TestContext.WriteLine(Query.NotCrosses("location", point)); + TestContext.WriteLine(Query.Overlaps("location", point)); + TestContext.WriteLine(Query.NotOverlaps("location", point)); + TestContext.WriteLine(Query.Touches("location", point)); + TestContext.WriteLine(Query.NotTouches("location", point));
185-192
: Validate point geometry is acceptable for spatial predicates; consider polygon/line coverage.If predicates like Crosses/Overlaps require non-point geometries, add one polygon/line example once supported; otherwise add a brief comment clarifying that points are valid inputs.
templates/android/library/src/main/java/io/package/Query.kt.twig (1)
316-349
: Validate non-negative distance and avoid silent bad input.Guard against invalid negative distances to prevent server-side errors and to fail fast in SDKs.
Apply to all four distance* methods:
-fun distanceEqual(attribute: String, values: List<Any>, distance: Number, meters: Boolean = false) = Query("distanceEqual", attribute, listOf(values, distance, meters)).toJson() +fun distanceEqual(attribute: String, values: List<Any>, distance: Number, meters: Boolean = false): String { + require(distance.toDouble() >= 0) { "distance must be >= 0" } + return Query("distanceEqual", attribute, listOf(values, distance, meters)).toJson() +} -fun distanceNotEqual(attribute: String, values: List<Any>, distance: Number, meters: Boolean = false) = Query("distanceNotEqual", attribute, listOf(values, distance, meters)).toJson() +fun distanceNotEqual(attribute: String, values: List<Any>, distance: Number, meters: Boolean = false): String { + require(distance.toDouble() >= 0) { "distance must be >= 0" } + return Query("distanceNotEqual", attribute, listOf(values, distance, meters)).toJson() +} -fun distanceGreaterThan(attribute: String, values: List<Any>, distance: Number, meters: Boolean = false) = Query("distanceGreaterThan", attribute, listOf(values, distance, meters)).toJson() +fun distanceGreaterThan(attribute: String, values: List<Any>, distance: Number, meters: Boolean = false): String { + require(distance.toDouble() >= 0) { "distance must be >= 0" } + return Query("distanceGreaterThan", attribute, listOf(values, distance, meters)).toJson() +} -fun distanceLessThan(attribute: String, values: List<Any>, distance: Number, meters: Boolean = false) = Query("distanceLessThan", attribute, listOf(values, distance, meters)).toJson() +fun distanceLessThan(attribute: String, values: List<Any>, distance: Number, meters: Boolean = false): String { + require(distance.toDouble() >= 0) { "distance must be >= 0" } + return Query("distanceLessThan", attribute, listOf(values, distance, meters)).toJson() +}templates/react-native/src/query.ts.twig (1)
214-215
: Add basic validation: non-negative distance.Lightweight runtime guard helps catch obvious mistakes early.
- static distanceEqual = (attribute: string, values: GeometryValues, distance: number, meters: boolean = false): string => - new Query("distanceEqual", attribute, [values, distance, meters]).toString(); + static distanceEqual = (attribute: string, values: GeometryValues, distance: number, meters: boolean = false): string => { + if (distance < 0) throw new Error("distance must be >= 0"); + return new Query("distanceEqual", attribute, [values, distance, meters]).toString(); + }Repeat for the other three distance helpers.
Also applies to: 217-225
templates/swift/Sources/Query.swift.twig (3)
96-119
: Factor mapping into a reusable helper to reduce duplication.Extract the nested mapping into a small helper (recursive) for readability and reuse.
// Outside this hunk: private static func convertAnyToQueryValue(_ item: Any) -> QueryValue? { switch item { case let v as String: return .string(v) case let v as Int: return .int(v) case let v as Double: return .double(v) case let v as Bool: return .bool(v) case let v as Query: return .query(v) case let v as [Any]: let mapped = v.compactMap { convertAnyToQueryValue($0) } return .array(mapped) default: return nil } } // Then here: case let anyArray as [Any]: let nestedValues = anyArray.compactMap { convertAnyToQueryValue($0) } return nestedValues
447-477
: Guard against negative distance.Fail fast on invalid input; keeps behavior consistent across SDKs.
- public static func distanceEqual(_ attribute: String, values: [Any], distance: Double, meters: Bool = false) -> String { + public static func distanceEqual(_ attribute: String, values: [Any], distance: Double, meters: Bool = false) -> String { + precondition(distance >= 0, "distance must be non-negative") return Query( method: "distanceEqual", attribute: attribute, values: [values, distance, meters] ).description }Repeat for the other three distance* methods in this block.
479-541
: Add missing Swift tests for nested spatial and distance payloads
- Distance builders: add a test for
values: [[x, y], [x2, y2]]
withmeters: true
to verify the JSON shape.- Spatial builders (
intersects
,crosses
,overlaps
,touches
and their negations): add tests asserting JSON for nested polygon arrays (e.g.values: [[[x1, y1], [x2, y2], …]]
).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (28)
templates/android/library/src/main/java/io/package/Query.kt.twig
(1 hunks)templates/dart/lib/query.dart.twig
(1 hunks)templates/deno/src/query.ts.twig
(1 hunks)templates/dotnet/Package/Query.cs.twig
(1 hunks)templates/go/query.go.twig
(1 hunks)templates/kotlin/src/main/kotlin/io/appwrite/Query.kt.twig
(1 hunks)templates/php/src/Query.php.twig
(1 hunks)templates/python/package/query.py.twig
(1 hunks)templates/react-native/src/query.ts.twig
(1 hunks)templates/ruby/lib/container/query.rb.twig
(1 hunks)templates/swift/Sources/Query.swift.twig
(5 hunks)templates/web/src/query.ts.twig
(1 hunks)tests/Base.php
(1 hunks)tests/languages/android/Tests.kt
(1 hunks)tests/languages/apple/Tests.swift
(1 hunks)tests/languages/dart/tests.dart
(2 hunks)tests/languages/deno/tests.ts
(1 hunks)tests/languages/dotnet/Tests.cs
(1 hunks)tests/languages/flutter/tests.dart
(1 hunks)tests/languages/go/tests.go
(1 hunks)tests/languages/kotlin/Tests.kt
(1 hunks)tests/languages/node/test.js
(1 hunks)tests/languages/php/test.php
(1 hunks)tests/languages/python/tests.py
(1 hunks)tests/languages/ruby/tests.rb
(1 hunks)tests/languages/swift/Tests.swift
(1 hunks)tests/languages/web/index.html
(1 hunks)tests/languages/web/node.js
(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- tests/languages/web/index.html
🚧 Files skipped from review as they are similar to previous changes (22)
- tests/Base.php
- tests/languages/kotlin/Tests.kt
- tests/languages/go/tests.go
- tests/languages/python/tests.py
- tests/languages/ruby/tests.rb
- tests/languages/swift/Tests.swift
- templates/php/src/Query.php.twig
- tests/languages/apple/Tests.swift
- templates/ruby/lib/container/query.rb.twig
- tests/languages/node/test.js
- templates/deno/src/query.ts.twig
- tests/languages/android/Tests.kt
- tests/languages/php/test.php
- templates/go/query.go.twig
- tests/languages/flutter/tests.dart
- templates/dart/lib/query.dart.twig
- templates/kotlin/src/main/kotlin/io/appwrite/Query.kt.twig
- tests/languages/web/node.js
- templates/python/package/query.py.twig
- templates/web/src/query.ts.twig
- templates/dotnet/Package/Query.cs.twig
- tests/languages/dart/tests.dart
🔇 Additional comments (4)
tests/languages/deno/tests.ts (2)
192-211
: Nice addition: new spatial query coverage looks good.These calls exercise the new builders and keep parity with other languages.
193-200
: Confirm coordinate order for spatial inputs. The SDK simply serializes the arrays you pass; verify against the service documentation whether coordinates must be[lat, lng]
or[lng, lat]
, otherwise your filters will be silently wrong.templates/android/library/src/main/java/io/package/Query.kt.twig (1)
351-421
: Confirm nested/heterogeneous array serialization works with toJson.These methods pass values as [List, Number, Boolean]. Ensure the Android/Kotlin serializer supports nested mixed-type arrays; Swift needed a custom variant to avoid dropping values.
If not supported, mirror Swift’s approach (custom encoder for nested arrays) or flatten the payload contract.
templates/swift/Sources/Query.swift.twig (1)
9-10
: LGTM: nested array support fixes dropped distance payloads.Adding QueryValue.array + encode/decode resolves the heterogeneous array serialization gap noted earlier.
Also applies to: 24-26, 47-49
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: 0
🧹 Nitpick comments (3)
templates/dotnet/Package/Query.cs.twig (3)
213-231
: DRY the distance-query builders with a tiny helperAll four distance methods duplicate the same payload construction. Centralize to reduce maintenance risk.
Apply within the current methods:
- return new Query("distanceEqual", attribute, new List<object> { values, distance, meters }).ToString(); + return BuildDistance("distanceEqual", attribute, values, distance, meters);- return new Query("distanceNotEqual", attribute, new List<object> { values, distance, meters }).ToString(); + return BuildDistance("distanceNotEqual", attribute, values, distance, meters);- return new Query("distanceGreaterThan", attribute, new List<object> { values, distance, meters }).ToString(); + return BuildDistance("distanceGreaterThan", attribute, values, distance, meters);- return new Query("distanceLessThan", attribute, new List<object> { values, distance, meters }).ToString(); + return BuildDistance("distanceLessThan", attribute, values, distance, meters);Add this helper inside the class (outside the changed hunk):
private static string BuildDistance(string method, string attribute, object values, double distance, bool meters) { return new Query(method, attribute, new List<object> { values, distance, meters }).ToString(); }
213-231
: Non-negative distance guard (optional)Consider an early check to prevent negative distances; it’s a fast fail and clearer error than a backend 4xx.
Example:
- public static string DistanceEqual(string attribute, object values, double distance, bool meters = false) + public static string DistanceEqual(string attribute, object values, double distance, bool meters = false) { + if (distance < 0) throw new ArgumentOutOfRangeException(nameof(distance), "Distance must be >= 0."); return BuildDistance("distanceEqual", attribute, values, distance, meters); }(Repeat for the other three distance methods.)
213-271
: Add XML docs for new public APIsThese are new surface area; brief remarks help IDE users and keep parity with other SDKs.
Example:
/// Builds a spatial distance-equality filter. /// values: point [lon, lat] or compatible geometry. distance: numeric radius. meters: interpret distance in meters if true, else default units. public static string DistanceEqual(...)(Replicate concise summaries for all 12 methods.)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
templates/dotnet/Package/Query.cs.twig
(1 hunks)tests/languages/dotnet/Tests.cs
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- tests/languages/dotnet/Tests.cs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (18)
- GitHub Check: build (8.3, Swift56)
- GitHub Check: build (8.3, WebNode)
- GitHub Check: build (8.3, WebChromium)
- GitHub Check: build (8.3, Ruby30)
- GitHub Check: build (8.3, Node18)
- GitHub Check: build (8.3, Python311)
- GitHub Check: build (8.3, Python310)
- GitHub Check: build (8.3, Ruby27)
- GitHub Check: build (8.3, Python39)
- GitHub Check: build (8.3, PHP83)
- GitHub Check: build (8.3, DotNet80)
- GitHub Check: build (8.3, Node20)
- GitHub Check: build (8.3, KotlinJava8)
- GitHub Check: build (8.3, Go112)
- GitHub Check: build (8.3, FlutterBeta)
- GitHub Check: build (8.3, FlutterStable)
- GitHub Check: build (8.3, Android5Java17)
- GitHub Check: build (8.3, Android14Java17)
🔇 Additional comments (1)
templates/dotnet/Package/Query.cs.twig (1)
233-271
: Approve existing spatial predicate serialization
Current implementation correctly emits geometries as flat arrays (e.g."values":[40.7128,-74]
), matching the in-repo tests forIntersects
,Crosses
,Overlaps
, andTouches
.
templates/android/library/src/main/java/io/package/Query.kt.twig
Outdated
Show resolved
Hide resolved
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: 0
♻️ Duplicate comments (1)
tests/Base.php (1)
123-138
: Swap coordinates to [longitude, latitude] for GeoJSON complianceThe coordinates are currently in [lat, lon]. Please standardize on [lon, lat] across all spatial tests to avoid cross-SDK inconsistencies and align with GeoJSON/RFC 7946. (datatracker.ietf.org, macwright.com)
Apply this diff:
- '{"method":"distanceEqual","attribute":"location","values":[[[40.7128, -74],[40.7128, -74]],1000,true]}', - '{"method":"distanceEqual","attribute":"location","values":[[40.7128,-74],1000,true]}', - '{"method":"distanceNotEqual","attribute":"location","values":[[40.7128,-74],1000,true]}', - '{"method":"distanceNotEqual","attribute":"location","values":[[40.7128,-74],1000,true]}', - '{"method":"distanceGreaterThan","attribute":"location","values":[[40.7128,-74],1000,true]}', - '{"method":"distanceGreaterThan","attribute":"location","values":[[40.7128,-74],1000,true]}', - '{"method":"distanceLessThan","attribute":"location","values":[[40.7128,-74],1000,true]}', - '{"method":"distanceLessThan","attribute":"location","values":[[40.7128,-74],1000,true]}', - '{"method":"intersects","attribute":"location","values":[40.7128,-74]}', - '{"method":"notIntersects","attribute":"location","values":[40.7128,-74]}', - '{"method":"crosses","attribute":"location","values":[40.7128,-74]}', - '{"method":"notCrosses","attribute":"location","values":[40.7128,-74]}', - '{"method":"overlaps","attribute":"location","values":[40.7128,-74]}', - '{"method":"notOverlaps","attribute":"location","values":[40.7128,-74]}', - '{"method":"touches","attribute":"location","values":[40.7128,-74]}', - '{"method":"notTouches","attribute":"location","values":[40.7128,-74]}', + '{"method":"distanceEqual","attribute":"location","values":[[[-74, 40.7128],[-74, 40.7128]],1000,true]}', + '{"method":"distanceEqual","attribute":"location","values":[[-74,40.7128],1000,true]}', + '{"method":"distanceNotEqual","attribute":"location","values":[[-74,40.7128],1000,true]}', + '{"method":"distanceNotEqual","attribute":"location","values":[[-74,40.7128],1000,true]}', + '{"method":"distanceGreaterThan","attribute":"location","values":[[-74,40.7128],1000,true]}', + '{"method":"distanceGreaterThan","attribute":"location","values":[[-74,40.7128],1000,true]}', + '{"method":"distanceLessThan","attribute":"location","values":[[-74,40.7128],1000,true]}', + '{"method":"distanceLessThan","attribute":"location","values":[[-74,40.7128],1000,true]}', + '{"method":"intersects","attribute":"location","values":[-74,40.7128]}', + '{"method":"notIntersects","attribute":"location","values":[-74,40.7128]}', + '{"method":"crosses","attribute":"location","values":[-74,40.7128]}', + '{"method":"notCrosses","attribute":"location","values":[-74,40.7128]}', + '{"method":"overlaps","attribute":"location","values":[-74,40.7128]}', + '{"method":"notOverlaps","attribute":"location","values":[-74,40.7128]}', + '{"method":"touches","attribute":"location","values":[-74,40.7128]}', + '{"method":"notTouches","attribute":"location","values":[-74,40.7128]}',
🧹 Nitpick comments (5)
tests/Base.php (1)
123-130
: Clarify distance payload shape; duplicates look unintendedLine 123 passes two points inside values ([[p1, p2], distance, meters]) while the rest use a single point ([p, distance, meters]). Please confirm the intended contract and make all SDKs/tests consistent. Also, each operator appears twice with identical payloads—dedupe or vary one (e.g., different meters flag) as appropriate. Current Appwrite public docs don’t list distance/spatial operators; if these are new, link spec/PR in code comments. (appwrite.io)
templates/ruby/lib/container/query.rb.twig (2)
163-177
: Document units, coordinate order, and payload expectations for distance_ methods*Add brief YARD docs stating that coordinates must be [lon, lat] (GeoJSON order) and what the meters flag controls. Without docs, misuse is likely. (datatracker.ietf.org)
Apply this diff:
def distance_equal(attribute, values, distance, meters = true) - return Query.new("distanceEqual", attribute, [values, distance, meters]).to_s + # @param attribute [String] Name of the spatial attribute + # @param values [Array] Geometry reference (e.g., [-74.0, 40.7128]) in [lon, lat] order + # @param distance [Numeric] Radius/threshold + # @param meters [Boolean] If true, distance is interpreted in meters + return Query.new("distanceEqual", attribute, [values, distance, meters]).to_s endRepeat similar YARD notes for the other distance_* methods in this block.
179-209
: Add minimal docs for geometry predicates (intersects/crosses/…); define accepted geometry shapesState whether values accepts a point pair [lon, lat], GeoJSON geometry, or arrays thereof. Align this with tests and other SDKs. (datatracker.ietf.org)
Apply this diff starter:
def intersects(attribute, values) - return Query.new("intersects", attribute, values).to_s + # @param values [Array|Hash] Geometry in [lon, lat] or GeoJSON geometry object + return Query.new("intersects", attribute, values).to_s endtemplates/dart/lib/query.dart.twig (2)
178-192
: Clarify coordinate order and units in distanceEqual/NotEqual/GreaterThan/LessThan docsAdd one line to each doc: coordinates are [longitude, latitude] per RFC 7946; meters controls unit interpretation. (datatracker.ietf.org)
Apply this diff pattern:
- /// Filter resources where [attribute] is at a specific distance from the given coordinates. + /// Filter resources where [attribute] is at a specific distance from the given geometry. + /// Coordinates must be [longitude, latitude] per RFC 7946.
194-224
: Document accepted geometry shapes for intersects/notIntersects/crosses/...Specify whether values should be a single point [lon, lat], GeoJSON geometry, or arrays of geometries, and keep this consistent with tests. (datatracker.ietf.org)
Apply this diff pattern:
- /// Filter resources where [attribute] intersects with the given geometry. + /// Filter resources where [attribute] intersects with the given geometry. + /// Pass a point as `[-74.0, 40.7128]` ([lon, lat]) or a GeoJSON geometry object.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (13)
templates/android/library/src/main/java/io/package/Query.kt.twig
(1 hunks)templates/dart/lib/query.dart.twig
(1 hunks)templates/deno/src/query.ts.twig
(1 hunks)templates/dotnet/Package/Query.cs.twig
(1 hunks)templates/go/query.go.twig
(1 hunks)templates/kotlin/src/main/kotlin/io/appwrite/Query.kt.twig
(1 hunks)templates/php/src/Query.php.twig
(1 hunks)templates/python/package/query.py.twig
(1 hunks)templates/react-native/src/query.ts.twig
(1 hunks)templates/ruby/lib/container/query.rb.twig
(1 hunks)templates/swift/Sources/Query.swift.twig
(5 hunks)templates/web/src/query.ts.twig
(1 hunks)tests/Base.php
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (10)
- templates/kotlin/src/main/kotlin/io/appwrite/Query.kt.twig
- templates/php/src/Query.php.twig
- templates/dotnet/Package/Query.cs.twig
- templates/python/package/query.py.twig
- templates/react-native/src/query.ts.twig
- templates/go/query.go.twig
- templates/deno/src/query.ts.twig
- templates/web/src/query.ts.twig
- templates/android/library/src/main/java/io/package/Query.kt.twig
- templates/swift/Sources/Query.swift.twig
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
- GitHub Check: build (8.3, WebChromium)
- GitHub Check: build (8.3, KotlinJava8)
- GitHub Check: build (8.3, PHP83)
- GitHub Check: build (8.3, KotlinJava17)
- GitHub Check: build (8.3, Node20)
- GitHub Check: build (8.3, KotlinJava11)
- GitHub Check: build (8.3, FlutterBeta)
- GitHub Check: build (8.3, Android14Java17)
- GitHub Check: build (8.3, DartStable)
- GitHub Check: build (8.3, FlutterStable)
- GitHub Check: build (8.3, DartBeta)
- GitHub Check: build (8.3, Android5Java17)
🔇 Additional comments (2)
templates/ruby/lib/container/query.rb.twig (1)
163-209
: Confirm server support for new operators or mark as experimentalAppwrite’s public Queries docs (as of Sep 5, 2025) don’t list distance/spatial operators. If these are server-backed, link the backend spec or mark these helpers experimental in comments to avoid user confusion until docs land. (appwrite.io)
templates/dart/lib/query.dart.twig (1)
178-224
: Verify backend support before publishingSame note as Ruby: these operators are not in the public Queries docs yet. If they’re slated for the next server release, consider adding an “Experimental” note in the docstrings to set expectations. (appwrite.io)
What does this PR do?
(Provide a description of what this PR does.)
Test Plan
(Write your test plan here. If you changed any code, please provide us with clear instructions on how you verified your changes work.)
Related PRs and Issues
(If this PR is related to any other PR or resolves any issue or related to any issue link all related PR and issues here.)
Have you read the Contributing Guidelines on issues?
(Write your answer here.)
Summary by CodeRabbit
New Features
Tests