Skip to content

Commit

Permalink
Introduce Tarantool client DSL
Browse files Browse the repository at this point in the history
This DSL includes set of request builders that can be used as a public
API to construct requests. The main idea here is to provide more
natural DSL-like approach to build operations instead of current
abstract types like List<?> or List<Object>.

Closes: #212
  • Loading branch information
nicktorwald committed Nov 20, 2019
1 parent 567851c commit 63f1dee
Show file tree
Hide file tree
Showing 19 changed files with 1,096 additions and 114 deletions.
192 changes: 78 additions & 114 deletions src/main/java/org/tarantool/AbstractTarantoolOps.java
Original file line number Diff line number Diff line change
@@ -1,200 +1,164 @@
package org.tarantool;

import static org.tarantool.TarantoolRequestArgumentFactory.cacheLookupValue;
import static org.tarantool.TarantoolRequestArgumentFactory.value;

import static org.tarantool.dsl.Requests.callRequest;
import static org.tarantool.dsl.Requests.deleteRequest;
import static org.tarantool.dsl.Requests.evalRequest;
import static org.tarantool.dsl.Requests.insertRequest;
import static org.tarantool.dsl.Requests.pingRequest;
import static org.tarantool.dsl.Requests.replaceRequest;
import static org.tarantool.dsl.Requests.selectRequest;
import static org.tarantool.dsl.Requests.updateRequest;
import static org.tarantool.dsl.Requests.upsertRequest;

import org.tarantool.dsl.Operation;
import org.tarantool.dsl.TarantoolRequestSpec;
import org.tarantool.logging.Logger;
import org.tarantool.logging.LoggerFactory;
import org.tarantool.schema.TarantoolSchemaMeta;

import java.util.Arrays;
import java.util.List;

public abstract class AbstractTarantoolOps<Result>
implements TarantoolClientOps<List<?>, Object, Result> {

private static final Logger LOGGER = LoggerFactory.getLogger(AbstractTarantoolOps.class);

private Code callCode = Code.CALL;

protected abstract Result exec(TarantoolRequest request);

protected abstract TarantoolSchemaMeta getSchemaMeta();

public Result select(Integer space, Integer index, List<?> key, int offset, int limit, Iterator iterator) {
return select(space, index, key, offset, limit, iterator.getValue());
return execute(
selectRequest(space, index)
.key(key)
.offset(offset).limit(limit)
.iterator(iterator)
);
}

@Override
public Result select(String space, String index, List<?> key, int offset, int limit, Iterator iterator) {
return select(space, index, key, offset, limit, iterator.getValue());
return execute(
selectRequest(space, index)
.key(key)
.offset(offset).limit(limit)
.iterator(iterator)
);
}

@Override
public Result select(Integer space, Integer index, List<?> key, int offset, int limit, int iterator) {
return exec(
new TarantoolRequest(
Code.SELECT,
value(Key.SPACE), value(space),
value(Key.INDEX), value(index),
value(Key.KEY), value(key),
value(Key.ITERATOR), value(iterator),
value(Key.LIMIT), value(limit),
value(Key.OFFSET), value(offset)
)
return execute(
selectRequest(space, index)
.key(key)
.offset(offset).limit(limit)
.iterator(iterator)
);
}

@Override
public Result select(String space, String index, List<?> key, int offset, int limit, int iterator) {
return exec(
new TarantoolRequest(
Code.SELECT,
value(Key.SPACE), cacheLookupValue(() -> getSchemaMeta().getSpace(space).getId()),
value(Key.INDEX), cacheLookupValue(() -> getSchemaMeta().getSpaceIndex(space, index).getId()),
value(Key.KEY), value(key),
value(Key.ITERATOR), value(iterator),
value(Key.LIMIT), value(limit),
value(Key.OFFSET), value(offset)
)
return execute(
selectRequest(space, index)
.key(key)
.offset(offset).limit(limit)
.iterator(iterator)
);
}

@Override
public Result insert(Integer space, List<?> tuple) {
return exec(new TarantoolRequest(
Code.INSERT,
value(Key.SPACE), value(space),
value(Key.TUPLE), value(tuple)
)
);
return execute(insertRequest(space, tuple));
}

@Override
public Result insert(String space, List<?> tuple) {
return exec(
new TarantoolRequest(
Code.INSERT,
value(Key.SPACE), cacheLookupValue(() -> getSchemaMeta().getSpace(space).getId()),
value(Key.TUPLE), value(tuple)
)
);
return execute(insertRequest(space, tuple));
}

@Override
public Result replace(Integer space, List<?> tuple) {
return exec(
new TarantoolRequest(
Code.REPLACE,
value(Key.SPACE), value(space),
value(Key.TUPLE), value(tuple)
)
);
return execute(replaceRequest(space, tuple));
}

@Override
public Result replace(String space, List<?> tuple) {
return exec(
new TarantoolRequest(
Code.REPLACE,
value(Key.SPACE), cacheLookupValue(() -> getSchemaMeta().getSpace(space).getId()),
value(Key.TUPLE), value(tuple)
)
);
return execute(replaceRequest(space, tuple));
}

@Override
public Result update(Integer space, List<?> key, Object... operations) {
return exec(
new TarantoolRequest(
Code.UPDATE,
value(Key.SPACE), value(space),
value(Key.KEY), value(key),
value(Key.TUPLE), value(operations)
)
);
Operation[] ops = Arrays.stream(operations)
.map(Operation::fromArray)
.toArray(org.tarantool.dsl.Operation[]::new);
return execute(updateRequest(space, key, ops));
}

@Override
public Result update(String space, List<?> key, Object... operations) {
return exec(
new TarantoolRequest(
Code.UPDATE,
value(Key.SPACE), cacheLookupValue(() -> getSchemaMeta().getSpace(space).getId()),
value(Key.KEY), value(key),
value(Key.TUPLE), value(operations)
)
);
Operation[] ops = Arrays.stream(operations)
.map(Operation::fromArray)
.toArray(org.tarantool.dsl.Operation[]::new);
return execute(updateRequest(space, key, ops));
}

@Override
public Result upsert(Integer space, List<?> key, List<?> defTuple, Object... operations) {
return exec(
new TarantoolRequest(
Code.UPSERT,
value(Key.SPACE), value(space),
value(Key.KEY), value(key),
value(Key.TUPLE), value(defTuple),
value(Key.UPSERT_OPS), value(operations)
)
);
Operation[] ops = Arrays.stream(operations)
.map(Operation::fromArray)
.toArray(Operation[]::new);
return execute(upsertRequest(space, key, defTuple, ops));
}

@Override
public Result upsert(String space, List<?> key, List<?> defTuple, Object... operations) {
return exec(
new TarantoolRequest(
Code.UPSERT,
value(Key.SPACE), cacheLookupValue(() -> getSchemaMeta().getSpace(space).getId()),
value(Key.KEY), value(key),
value(Key.TUPLE), value(defTuple),
value(Key.UPSERT_OPS), value(operations)
)
);
Operation[] ops = Arrays.stream(operations)
.map(Operation::fromArray)
.toArray(Operation[]::new);
return execute(upsertRequest(space, key, defTuple, ops));
}

@Override
public Result delete(Integer space, List<?> key) {
return exec(
new TarantoolRequest(
Code.DELETE,
value(Key.SPACE), value(space),
value(Key.KEY), value(key)
)
);
return execute(deleteRequest(space, key));
}

@Override
public Result delete(String space, List<?> key) {
return exec(
new TarantoolRequest(
Code.DELETE,
value(Key.SPACE), cacheLookupValue(() -> getSchemaMeta().getSpace(space).getId()),
value(Key.KEY), value(key)
)
);
return execute(deleteRequest(space, key));
}

@Override
public Result call(String function, Object... args) {
return exec(
new TarantoolRequest(
callCode,
value(Key.FUNCTION), value(function),
value(Key.TUPLE), value(args)
)
return execute(
callRequest(function)
.arguments(args)
.useCall16(callCode == Code.OLD_CALL)
);
}

@Override
public Result eval(String expression, Object... args) {
return exec(
new TarantoolRequest(
Code.EVAL,
value(Key.EXPRESSION), value(expression),
value(Key.TUPLE), value(args)
)
);
return execute(evalRequest(expression).arguments(args));
}

@Override
public void ping() {
exec(new TarantoolRequest(Code.PING));
execute(pingRequest());
}

@Override
public Result execute(TarantoolRequestSpec requestSpec) {
TarantoolSchemaMeta schemaMeta = null;
try {
schemaMeta = getSchemaMeta();
} catch (Exception cause) {
LOGGER.warn(() -> "Could not get Tarantool schema meta-info", cause);
}
return exec(requestSpec.toTarantoolRequest(schemaMeta));
}

public void setCallCode(Code callCode) {
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/org/tarantool/TarantoolClientOps.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.tarantool;

import org.tarantool.dsl.TarantoolRequestSpec;

public interface TarantoolClientOps<O, P, R> {
R select(Integer space, Integer index, O key, int offset, int limit, int iterator);

Expand Down Expand Up @@ -33,7 +35,10 @@ public interface TarantoolClientOps<O, P, R> {

R eval(String expression, Object... args);

R execute(TarantoolRequestSpec requestSpec);

void ping();

void close();

}
46 changes: 46 additions & 0 deletions src/main/java/org/tarantool/dsl/AbstractRequestSpec.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package org.tarantool.dsl;

import org.tarantool.Code;
import org.tarantool.TarantoolRequest;
import org.tarantool.schema.TarantoolSchemaMeta;

import java.time.Duration;

public abstract class AbstractRequestSpec<B extends AbstractRequestSpec<B>>
implements TarantoolRequestSpec {

final Code code;
Duration duration = Duration.ZERO;
boolean useDefaultTimeout = true;

AbstractRequestSpec(Code code) {
this.code = code;
}

AbstractRequestSpec(Code code, Duration duration) {
this.code = code;
this.duration = duration;
}

@SuppressWarnings("unchecked")
public B timeout(Duration duration) {
this.duration = duration;
this.useDefaultTimeout = false;
return (B) this;
}

@SuppressWarnings("unchecked")
public B useDefaultTimeout() {
this.duration = Duration.ZERO;
this.useDefaultTimeout = true;
return (B) this;
}

@Override
public TarantoolRequest toTarantoolRequest(TarantoolSchemaMeta schemaMeta) {
TarantoolRequest request = new TarantoolRequest(code);
request.setTimeout(useDefaultTimeout ? null : duration);
return request;
}

}

0 comments on commit 63f1dee

Please sign in to comment.