Skip to content
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

Feat json queries #766

Merged
merged 64 commits into from
Feb 5, 2024
Merged
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
d8f06da
Android JSON queries
abnegate Jan 11, 2024
24ead02
Merge remote-tracking branch 'origin/feat-json-queries' into feat-que…
lohanidamodar Jan 22, 2024
9942ab9
dart/flutter implementation for updated query
lohanidamodar Jan 22, 2024
bdb9bb9
Merge remote-tracking branch 'origin/1.5.x' into feat-json-queries
abnegate Jan 22, 2024
0e30c8f
Merge remote-tracking branch 'origin/feat-json-queries' into feat-que…
lohanidamodar Jan 22, 2024
ad6c220
update query test
lohanidamodar Jan 22, 2024
833dff5
rearrange attribute
lohanidamodar Jan 22, 2024
1c6b856
fix tests
lohanidamodar Jan 22, 2024
8ef3c22
Merge pull request #761 from appwrite/feat-queries-update
abnegate Jan 22, 2024
53747c5
Add Android or + contains queries
abnegate Jan 22, 2024
d2430f2
Add base tests for contains + or queries
abnegate Jan 22, 2024
e73f417
fix json encode and import
lohanidamodar Jan 22, 2024
f4cab05
or and contains test for query
lohanidamodar Jan 22, 2024
0c42e4e
fix query helper responses
lohanidamodar Jan 22, 2024
c479f89
Fix Android tests
abnegate Jan 22, 2024
d4624e3
Fix list type
abnegate Jan 22, 2024
9bd8fff
Fix closing brace
abnegate Jan 22, 2024
c119f9f
Fix collection literals
abnegate Jan 22, 2024
bbea69d
Fix missing toString
abnegate Jan 22, 2024
c7ffa64
add missing query tests to Flutter
lohanidamodar Jan 23, 2024
8564591
Merge pull request #762 from appwrite/feat-fix-queries-tests
lohanidamodar Jan 23, 2024
d965d7c
feat: json queries web, node, deno, php
loks0n Feb 1, 2024
c39abbc
feat: ruby python kotlin json queries
loks0n Feb 1, 2024
8e2852d
fix: tests for node, deno, web
loks0n Feb 1, 2024
6f3e17e
fix: most python tests
loks0n Feb 1, 2024
2eb6c74
fix: ruby tests
loks0n Feb 1, 2024
db9d3d9
fix: php tests
loks0n Feb 1, 2024
0bf6b36
fix: deno tests
loks0n Feb 1, 2024
f38a5ee
fix: web tests use prototype
loks0n Feb 1, 2024
23c0f54
fix: web chromium tests
loks0n Feb 1, 2024
9f29b57
fix: python tests
loks0n Feb 1, 2024
2c33a19
fix: dotnet tests
loks0n Feb 1, 2024
27639c9
fix: kotlin tests
loks0n Feb 1, 2024
3c94b9f
fix: swift tests 😎
loks0n Feb 1, 2024
4373381
feat: js use Query[] type
loks0n Feb 1, 2024
a0a8df6
fix: failing tests
loks0n Feb 2, 2024
86c4d59
feat: `and` queries
loks0n Feb 2, 2024
e5e74a3
fix: android ruby tests
loks0n Feb 2, 2024
d9892d1
fix: js serialisation
loks0n Feb 2, 2024
9faa6e2
fix: serialisation js
loks0n Feb 2, 2024
ef5547a
fix: ruby tests
loks0n Feb 2, 2024
5cd2a6a
fix: types check
loks0n Feb 2, 2024
3568423
chore: swift hacks - forgive me
loks0n Feb 2, 2024
029c92a
chore: fmt
loks0n Feb 2, 2024
d6f6161
chore: remove brackets for ruby if
loks0n Feb 2, 2024
2b2d5ea
fix: remove test count
loks0n Feb 2, 2024
12ba380
chore: swift improvements
loks0n Feb 2, 2024
9bb0a78
feat: js serialise in flatten
loks0n Feb 2, 2024
945a2e8
fix: deno
loks0n Feb 2, 2024
8d61a2d
fix: web flatten
loks0n Feb 2, 2024
e5043f1
chore: ruby simplify
loks0n Feb 2, 2024
e99e74d
chor: dotnet use List<object>
loks0n Feb 2, 2024
6287998
Inline convert queries to JSON to avoid changing method parameter types
abnegate Feb 5, 2024
9658d32
Update tests
abnegate Feb 5, 2024
78efd59
Don't double escape
abnegate Feb 5, 2024
9799984
Fix refs
abnegate Feb 5, 2024
1e30fde
Decode and re-encode and/or queries to fix double escaping
abnegate Feb 5, 2024
971f5bc
Fix dart types
abnegate Feb 5, 2024
25b9e34
Fix deno types
abnegate Feb 5, 2024
b03af24
Fix PHP loop
abnegate Feb 5, 2024
862849e
Fix .NET tests
abnegate Feb 5, 2024
3b12eb5
Fix web tests
abnegate Feb 5, 2024
ecaf6e0
Fix dart/flutter to string
abnegate Feb 5, 2024
677a61c
Fix swift init from decoder visibility
abnegate Feb 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/SDK/Language/Deno.php
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ public function getTypeName(array $parameter, array $spec = []): string
if (!empty($parameter['enumValues'])) {
return \ucfirst($parameter['name']);
}
if (!empty($parameter['name']) && $parameter['name'] === 'queries') {
return 'Query[]';
}
return match ($parameter['type']) {
self::TYPE_INTEGER => 'number',
self::TYPE_STRING => 'string',
Expand Down
4 changes: 3 additions & 1 deletion src/SDK/Language/JS.php
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,9 @@ public function getTypeName(array $parameter, array $spec = []): string
if (!empty($parameter['enumValues'])) {
return \ucfirst($parameter['name']);
}

if (!empty($parameter['name']) && $parameter['name'] === 'queries') {
return 'Query[]';
}
switch ($parameter['type']) {
case self::TYPE_INTEGER:
case self::TYPE_NUMBER:
Expand Down
3 changes: 3 additions & 0 deletions src/SDK/Language/Node.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ public function getTypeName(array $parameter, array $spec = []): string
if (!empty($parameter['enumValues'])) {
return \ucfirst($parameter['name']);
}
if (!empty($parameter['name']) && $parameter['name'] === 'queries') {
return 'Query[]';
}
return match ($parameter['type']) {
self::TYPE_INTEGER,
self::TYPE_NUMBER => 'number',
Expand Down
3 changes: 3 additions & 0 deletions src/SDK/Language/Web.php
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,9 @@ public function getTypeName(array $parameter, array $method = []): string
if (!empty($parameter['enumValues'])) {
return \ucfirst($parameter['name']);
}
if (!empty($parameter['name']) && $parameter['name'] === 'queries') {
return 'Query[]';
}
abnegate marked this conversation as resolved.
Show resolved Hide resolved
switch ($parameter['type']) {
case self::TYPE_INTEGER:
case self::TYPE_NUMBER:
Expand Down
80 changes: 43 additions & 37 deletions templates/android/library/src/main/java/io/appwrite/Query.kt.twig
Original file line number Diff line number Diff line change
@@ -1,60 +1,66 @@
package {{ sdk.namespace | caseDot }}

class Query {
companion object {
fun equal(attribute: String, value: Any) = addQuery(attribute, "equal", value)
import com.google.gson.Gson

fun notEqual(attribute: String, value: Any) = Query.addQuery(attribute, "notEqual", value)
class Query(
val method: String,
val attribute: String? = null,
val values: List<Any>? = null,
) {
override fun toString() = gson.toJson(this)

fun lessThan(attribute: String, value: Any) = Query.addQuery(attribute, "lessThan", value)
companion object {
private val gson = Gson()

fun lessThanEqual(attribute: String, value: Any) = Query.addQuery(attribute, "lessThanEqual", value)
fun equal(attribute: String, value: Any) = Query("equal", attribute, parseValue(value))

fun greaterThan(attribute: String, value: Any) = Query.addQuery(attribute, "greaterThan", value)
fun notEqual(attribute: String, value: Any) = Query("notEqual", attribute, listOf(value))

fun greaterThanEqual(attribute: String, value: Any) = Query.addQuery(attribute, "greaterThanEqual", value)

fun search(attribute: String, value: String) = Query.addQuery(attribute, "search", value)
fun lessThan(attribute: String, value: Any) = Query("lessThan", attribute, listOf(value))

fun isNull(attribute: String) = "isNull(\"${attribute}\")"
fun lessThanEqual(attribute: String, value: Any) = Query("lessThanEqual", attribute, listOf(value))

fun isNotNull(attribute: String) = "isNotNull(\"${attribute}\")"
fun greaterThan(attribute: String, value: Any) = Query("greaterThan", attribute, listOf(value))

fun between(attribute: String, start: Int, end: Int) = "between(\"${attribute}\", ${start}, ${end})"
fun greaterThanEqual(attribute: String, value: Any) = Query("greaterThanEqual", attribute, listOf(value))

fun between(attribute: String, start: Double, end: Double) = "between(\"${attribute}\", ${start}, ${end})"
fun search(attribute: String, value: String) = Query("search", attribute, listOf(value))

fun between(attribute: String, start: String, end: String) = "between(\"${attribute}\", \"${start}\", \"${end}\")"
fun isNull(attribute: String) = Query("isNull", attribute)

fun startsWith(attribute: String, value: String) = Query.addQuery(attribute, "startsWith", value)
fun isNotNull(attribute: String) = Query("isNotNull", attribute)

fun endsWith(attribute: String, value: String) = Query.addQuery(attribute, "endsWith", value)
fun between(attribute: String, start: Any, end: Any) = Query("between", attribute, listOf(start, end))

fun select(attributes: List<String>) = "select([${attributes.joinToString(",") { "\"$it\"" }}])"
fun startsWith(attribute: String, value: String) = Query("startsWith", attribute, listOf(value))

fun orderAsc(attribute: String) = "orderAsc(\"${attribute}\")"
fun endsWith(attribute: String, value: String) = Query("endsWith", attribute, listOf(value))

fun orderDesc(attribute: String) = "orderDesc(\"${attribute}\")"
fun select(attributes: List<String>) = Query("select", null, attributes)

fun cursorBefore(documentId: String) = "cursorBefore(\"${documentId}\")"
fun orderAsc(attribute: String) = Query("orderAsc", attribute)

fun cursorAfter(documentId: String) = "cursorAfter(\"${documentId}\")"
fun orderDesc(attribute: String) = Query("orderDesc", attribute)

fun limit(limit: Int) = "limit(${limit})"
fun cursorBefore(documentId: String) = Query("cursorBefore", null, listOf(documentId))

fun offset(offset: Int) = "offset(${offset})"
fun cursorAfter(documentId: String) = Query("cursorAfter", null, listOf(documentId))

private fun addQuery(attribute: String, method: String, value: Any): String {
return when (value) {
is List<*> -> "${method}(\"${attribute}\", [${value.map{it -> parseValues(it!!)}.joinToString(",")}])"
else -> "${method}(\"${attribute}\", [${Query.parseValues(value)}])"
}
}
private fun parseValues(value: Any): String {
return when (value) {
is String -> "\"${value}\""
else -> "${value}"
}
fun limit(limit: Int) = Query("limit", null, listOf(limit))

fun offset(offset: Int) = Query("offset", null, listOf(offset))

fun contains(attribute: String, value: Any) = Query("contains", attribute, parseValue(value))

fun or(queries: List<Query>) = Query("or", null, queries)

fun and(queries: List<Query>) = Query("and", null, queries)

private fun parseValue(value: Any): List<Any> {
return when (value) {
is List<*> -> value as List<Any>
else -> listOf(value)
}
}
}
}
}
}
1 change: 1 addition & 0 deletions templates/dart/lib/package.dart.twig
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ library {{ language.params.packageName }};

import 'dart:async';
import 'dart:typed_data';
import 'dart:convert';

import 'src/enums.dart';
import 'src/service.dart';
Expand Down
106 changes: 64 additions & 42 deletions templates/dart/lib/query.dart.twig
Original file line number Diff line number Diff line change
@@ -1,99 +1,121 @@
part of {{ language.params.packageName }};


/// Helper class to generate query strings.
class Query {
Query._();
final String method;
final String? attribute;
final dynamic values;

Query._(this.method, [this.attribute = null, this.values = null]);

Map<String, dynamic> toJson() {
final map = <String, dynamic>{
'method': method,
};

if(attribute != null) {
map['attribute'] = attribute;
}

if(values != null) {
map['values'] = values is List ? values : [values];
}

return map;
}

@override
String toString() => jsonEncode(toJson());

/// Filter resources where [attribute] is equal to [value].
///
/// [value] can be a single value or a list. If a list is used
/// the query will return resources where [attribute] is equal
/// to any of the values in the list.
static String equal(String attribute, dynamic value) =>
_addQuery(attribute, 'equal', value);
static Query equal(String attribute, dynamic value) =>
Query._('equal', attribute, value);

/// Filter resources where [attribute] is not equal to [value].
///
/// [value] can be a single value or a list. If a list is used
/// the query will return resources where [attribute] is equal
/// to any of the values in the list.
static String notEqual(String attribute, dynamic value) =>
_addQuery(attribute, 'notEqual', value);
static Query notEqual(String attribute, dynamic value) =>
Query._('notEqual', attribute, [value]);

/// Filter resources where [attribute] is less than [value].
static String lessThan(String attribute, dynamic value) =>
_addQuery(attribute, 'lessThan', value);
static Query lessThan(String attribute, dynamic value) =>
Query._('lessThan', attribute, value);

/// Filter resources where [attribute] is less than or equal to [value].
static String lessThanEqual(String attribute, dynamic value) =>
_addQuery(attribute, 'lessThanEqual', value);
static Query lessThanEqual(String attribute, dynamic value) =>
Query._('lessThanEqual', attribute, value);

/// Filter resources where [attribute] is greater than [value].
static String greaterThan(String attribute, dynamic value) =>
_addQuery(attribute, 'greaterThan', value);
static Query greaterThan(String attribute, dynamic value) =>
Query._('greaterThan', attribute, value);

/// Filter resources where [attribute] is greater than or equal to [value].
static String greaterThanEqual(String attribute, dynamic value) =>
_addQuery(attribute, 'greaterThanEqual', value);
static Query greaterThanEqual(String attribute, dynamic value) =>
Query._('greaterThanEqual', attribute, value);

/// Filter resources where by searching [attribute] for [value].
static String search(String attribute, String value) =>
_addQuery(attribute, 'search', value);
static Query search(String attribute, String value) =>
Query._('search', attribute, value);

/// Filter resources where [attribute] is null.
static String isNull(String attribute) => 'isNull("$attribute")';
static Query isNull(String attribute) => Query._('isNull', attribute);

/// Filter resources where [attribute] is not null.
static String isNotNull(String attribute) => 'isNotNull("$attribute")';
static Query isNotNull(String attribute) => Query._('isNotNull', attribute);

/// Filter resources where [attribute] is between [start] and [end] (inclusive).
static String between(String attribute, dynamic start, dynamic end) =>
'between("$attribute", ${_parseValues(start)}, ${_parseValues(end)})';
static Query between(String attribute, dynamic start, dynamic end) =>
Query._('between', attribute, [start, end]);

/// Filter resources where [attribute] starts with [value].
static String startsWith(String attribute, String value) =>
_addQuery(attribute, 'startsWith', value);
static Query startsWith(String attribute, String value) =>
Query._('startsWith', attribute, value);

/// Filter resources where [attribute] ends with [value].
static String endsWith(String attribute, String value) =>
_addQuery(attribute, 'endsWith', value);
static Query endsWith(String attribute, String value) =>
Query._('endsWith', attribute, value);

/// Filter resouorces where [attribute] contains [value]
/// [value] can be a single value or a list.
static Query contains(String attribute, dynamic value) =>
Query._('contains', attribute, value);

static Query or(List<Query> queries) => Query._('or', null, queries);

static Query and(List<Query> queries) => Query._('and', null, queries);

/// Specify which attributes should be returned by the API call.
static String select(List<String> attributes) =>
'select([${attributes.map((attr) => "\"$attr\"").join(",")}])';
static Query select(List<String> attributes) =>
Query._('select', null, attributes);

/// Sort results by [attribute] ascending.
static String orderAsc(String attribute) => 'orderAsc("$attribute")';
static Query orderAsc(String attribute) => Query._('orderAsc', attribute);

/// Sort results by [attribute] descending.
static String orderDesc(String attribute) => 'orderDesc("$attribute")';
static Query orderDesc(String attribute) => Query._('orderDesc', attribute);

/// Return results before [id].
///
/// Refer to the [Cursor Based Pagination]({{sdk.url}}/docs/pagination#cursor-pagination)
/// docs for more information.
static String cursorBefore(String id) => 'cursorBefore("$id")';
static Query cursorBefore(String id) => Query._('cursorBefore', null, id);

/// Return results after [id].
///
/// Refer to the [Cursor Based Pagination]({{sdk.url}}/docs/pagination#cursor-pagination)
/// docs for more information.
static String cursorAfter(String id) => 'cursorAfter("$id")';
static Query cursorAfter(String id) => Query._('cursorAfter', null, id);

/// Return only [limit] results.
static String limit(int limit) => 'limit($limit)';
static Query limit(int limit) => Query._('limit', null, limit);

/// Return results from [offset].
///
/// Refer to the [Offset Pagination]({{sdk.url}}/docs/pagination#offset-pagination)
/// docs for more information.
static String offset(int offset) => 'offset($offset)';

static String _addQuery(String attribute, String method, dynamic value) => (value
is List)
? '$method("$attribute", [${value.map((item) => _parseValues(item)).join(",")}])'
: '$method("$attribute", [${_parseValues(value)}])';
static Query offset(int offset) => Query._('offset', null, offset);

static String _parseValues(dynamic value) =>
(value is String) ? '"$value"' : '$value';
}
Loading
Loading