Skip to content

Commit

Permalink
Merge pull request #101 from fauna/release-0.1.0-M4
Browse files Browse the repository at this point in the history
Release 0.1.0-M4.
  • Loading branch information
findgriffin authored Aug 13, 2024
2 parents 8007415 + 0571c00 commit 144eb98
Show file tree
Hide file tree
Showing 39 changed files with 900 additions and 371 deletions.
12 changes: 6 additions & 6 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@

### Change types
<!--- What types of changes does your code introduce? Put an `x` in any boxes that apply: -->
- [ ] Bug fix (non-breaking change that fixes an issue)
- [ ] New feature (non-breaking change that adds functionality)
- [ ] Breaking change (backwards-incompatible fix or feature)
* - [ ] Bug fix (non-breaking change that fixes an issue)
* - [ ] New feature (non-breaking change that adds functionality)
* - [ ] Breaking change (backwards-incompatible fix or feature)

### Checklist:
<!--- Review the following points. Put an `x` in any boxes that apply. -->
<!--- If you're unsure, don't hesitate to ask. We're here to help! -->
- [ ] My code follows the code style of this project.
- [ ] My change requires a change to Fauna documentation.
- [ ] My change requires a change to the README, and I have updated it accordingly.
* - [ ] My code follows the code style of this project.
* - [ ] My change requires a change to Fauna documentation.
* - [ ] My change requires a change to the README, and I have updated it accordingly.

----
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
42 changes: 39 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,41 @@ API. This helps prevent injection attacks.

<!-- TODO: Subqueries -->

## Pagination
Use `paginate()` to asynchronously iterate through sets that contain more than one page of results.

`paginate()` accepts the same [query options](#query-options) as `query()` and `asyncQuery()`.

```java
import com.fauna.client.Fauna;
import com.fauna.client.FaunaClient;
import com.fauna.client.PageIterator;

public class App {
public static void main(String[] args) {
FaunaClient client = Fauna.client();

// `paginate()` will make an async request to Fauna.
PageIterator<Product> iter1 = client.paginate(fql("Product.all()"), Product.class);

// Handle each page. `PageIterator` extends the Java Iterator interface.
while (iter1.hasNext()) {
Page<Product> page = iter1.next();
List<Product> pageData = page.data();
// Do something with your data.
}

PageIterator<Product> iter2 = client.paginate(fql("Product.all()"), Product.class);

// Use the `flatten()` on PageIterator to iterate over every item in a set.
Iterator<Product> productIter = iter2.flatten();
List<Product> products = new ArrayList<>();

// Iterate over Product elements without worrying about pages.
iter2.forEachRemaining((Product p) -> products.add(p));
}
}
```

## Query statistics

Expand All @@ -274,20 +309,21 @@ package org.example;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

import com.fauna.client.Fauna;
import com.fauna.client.FaunaClient;
import com.fauna.client.FaunaConfig;
import com.fauna.exception.FaunaException;
import com.fauna.exception.ServiceException;
import com.fauna.query.builder.Query;
import static com.fauna.query.builder.Query.fql;
import com.fauna.response.QueryResponse;
import com.fauna.response.QuerySuccess;

import static com.fauna.query.builder.Query.fql;

public class App {
public static void main(String[] args) {
try {
FaunaClient client = new FaunaClient(FaunaConfic.builder().secret("FAUNA_SECRET").build());
FaunaConfig config = FaunaConfig.builder().secret("FAUNA_SECRET").build();
FaunaClient client = Fauna.client(config);

Query query = fql("'Hello world'");

Expand Down
24 changes: 18 additions & 6 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ group = 'com.fauna'
compileJava {
options.encoding = 'UTF-8'
}

java {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
Expand All @@ -21,12 +22,6 @@ repositories {
mavenCentral()
}

task printVersion {
doLast {
println project.version
}
}

dependencies {
implementation "com.fasterxml.jackson.core:jackson-core:${jacksonVersion}"
implementation "com.fasterxml.jackson.core:jackson-databind:${jacksonVersion}"
Expand Down Expand Up @@ -78,3 +73,20 @@ mavenPublishing {
}
}
}

// tasks

task printVersion {
doLast {
println project.version
}
}

task writeProps(type: WriteProperties) {
outputFile = file("src/main/resources/version.properties")
encoding = 'UTF-8'
property('version', project.version)
property('name', project.name)
property('group', project.group)
}
processResources.dependsOn(writeProps)
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version=0.1.0-M3
version=0.1.0-M4
junitVersion=5.10.0
mockitoVersion=5.6.0
jacksonVersion=2.15.3
Expand Down
3 changes: 0 additions & 3 deletions src/main/java/com/fauna/annotation/FaunaField.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.fauna.annotation;

import com.fauna.enums.FaunaType;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
Expand All @@ -16,6 +15,4 @@
String name() default "";

boolean nullable() default false;

FaunaType type() default FaunaType.STRING;
}
5 changes: 0 additions & 5 deletions src/main/java/com/fauna/annotation/FaunaFieldImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,6 @@ public boolean nullable() {
return annotation != null ? annotation.nullable() : false;
}

@Override
public FaunaType type() {
return (annotation != null) ? annotation.type() : null;
}

@Override
public Class<? extends java.lang.annotation.Annotation> annotationType() {
return FaunaField.class;
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/com/fauna/client/FaunaClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -261,4 +261,12 @@ public <E> QuerySuccess<E> query(Query fql, ParameterizedOf<E> parameterizedType
}
}
//endregion

public <E> PageIterator<E> paginate(Query fql, Class<E> resultClass) {
return new PageIterator<>(this, fql, resultClass, null);
}

public <E> PageIterator<E> paginate(Query fql, Class<E> resultClass, QueryOptions options) {
return new PageIterator<>(this, fql, resultClass, options);
}
}
129 changes: 129 additions & 0 deletions src/main/java/com/fauna/client/PageIterator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package com.fauna.client;


import com.fauna.exception.FaunaException;
import com.fauna.query.QueryOptions;
import com.fauna.query.builder.Query;
import com.fauna.response.QuerySuccess;
import com.fauna.serialization.generic.PageOf;
import com.fauna.types.Page;

import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;

import static com.fauna.query.builder.Query.fql;

/**
* PageIterator iterates over paged responses from Fauna, the default page size is 16.
* @param <E>
*/
public class PageIterator<E> implements Iterator<Page<E>> {
private static final String PAGINATE_QUERY = "Set.paginate(${after})";
private final FaunaClient client;
private final QueryOptions options;
private final PageOf<E> pageClass;
private CompletableFuture<QuerySuccess<Page<E>>> queryFuture;
private Page<E> latestResult;

/**
* Construct a new PageIterator.
* @param client A client that makes requests to Fauna.
* @param fql The FQL query.
* @param resultClass The class of the elements returned from Fauna (i.e. the rows).
* @param options (optionally) pass in QueryOptions.
*/
public PageIterator(FaunaClient client, Query fql, Class<E> resultClass, QueryOptions options) {
this.client = client;
this.pageClass = new PageOf<>(resultClass);
this.options = options;
// Initial query;
this.queryFuture = client.asyncQuery(fql, this.pageClass, options);
this.latestResult = null;
}

public PageIterator(FaunaClient client, Page<E> page, Class<E> resultClass, QueryOptions options) {
this.client = client;
this.pageClass = new PageOf<>(resultClass);
this.options = options;
this.queryFuture = null;
this.latestResult = page;
}

private void completeFuture() {
if (this.queryFuture != null && this.latestResult == null) {
try {
this.latestResult = queryFuture.join().getData();
} catch (CompletionException e) {
if (e.getCause() != null && e.getCause() instanceof FaunaException) {
throw (FaunaException) e.getCause();
} else {
throw e;
}
}
this.queryFuture = null;
}
}

@Override
public boolean hasNext() {
completeFuture();
return this.latestResult != null;
}



/**
* Get the next Page.
* @return The next Page of elements E.
*/
@Override
public Page<E> next() {
completeFuture();
if (this.latestResult != null) {
Page<E> page = this.latestResult;
this.latestResult = null;
if (page.after() != null) {
Map<String, Object> args = Map.of("after", page.after());
this.queryFuture = client.asyncQuery(fql(PAGINATE_QUERY, args), pageClass, options);
}
return page;
} else {
throw new NoSuchElementException();
}
}

/**
* Return an iterator that iterates directly over the items that make up the page contents.
* @return An iterator of E.
*/
public Iterator<E> flatten() {
return new Iterator<>() {
private final PageIterator<E> pageIterator = PageIterator.this;
private Iterator<E> thisPage = pageIterator.hasNext() ? pageIterator.next().data().iterator() : null;
@Override
public boolean hasNext() {
return thisPage != null && (thisPage.hasNext() || pageIterator.hasNext());
}

@Override
public E next() {
if (thisPage == null) {
throw new NoSuchElementException();
}
try {
return thisPage.next();
} catch (NoSuchElementException e) {
if (pageIterator.hasNext()) {
this.thisPage = pageIterator.next().data().iterator();
return thisPage.next();
} else {
throw e;
}
}
}
};
}
}
32 changes: 32 additions & 0 deletions src/main/java/com/fauna/codec/ClassCodec.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.fauna.codec;

import com.fauna.mapping.MappingContext;
import com.fauna.mapping.MappingInfo;
import com.fauna.serialization.UTF8FaunaGenerator;
import com.fauna.serialization.UTF8FaunaParser;

import java.io.IOException;

public class ClassCodec<T> implements Codec<T> {

private final MappingInfo info;

public ClassCodec(MappingInfo info) {
this.info = info;
}

@Override
public T decode(UTF8FaunaParser parser) throws IOException {
return null;
}

@Override
public void encode(UTF8FaunaGenerator writer, T obj, MappingContext context) throws IOException {

}

@Override
public Class<T> getCodecClass() {
return null;
}
}
17 changes: 17 additions & 0 deletions src/main/java/com/fauna/codec/Codec.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.fauna.codec;

import com.fauna.mapping.MappingContext;
import com.fauna.serialization.UTF8FaunaGenerator;
import com.fauna.serialization.UTF8FaunaParser;

import java.io.IOException;


public interface Codec<T> {

T decode(UTF8FaunaParser parser) throws IOException;

void encode(UTF8FaunaGenerator gen, T obj, MappingContext context) throws IOException;

Class<T> getCodecClass();
}
6 changes: 6 additions & 0 deletions src/main/java/com/fauna/codec/CodecProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.fauna.codec;

public interface CodecProvider {
<T> Codec<T> get(CodecRegistry registry, Class<T> clazz);
<T,K> Codec<T> get(CodecRegistry registry, Class<T> clazz, Class<K> subClazz);
}
9 changes: 9 additions & 0 deletions src/main/java/com/fauna/codec/CodecRegistry.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.fauna.codec;

public interface CodecRegistry {

<T> Codec<T> get(CodecRegistryKey key);
<T> void add(CodecRegistryKey key, Codec<T> codec);
boolean contains(CodecRegistryKey key);

}
16 changes: 16 additions & 0 deletions src/main/java/com/fauna/codec/CodecRegistryKey.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.fauna.codec;

public class CodecRegistryKey {
private final Class<?> base;
private final Class<?> subtype;
public <T> CodecRegistryKey(Class<?> clazz, Class<?> subtype) {
base = clazz;
this.subtype = subtype;
}

public static <T> CodecRegistryKey from(Class<?> clazz, Class<?> subtype) {
return new CodecRegistryKey(clazz, subtype);
}

// TODO: Override equals/hash
}
Loading

0 comments on commit 144eb98

Please sign in to comment.