Skip to content

Commit

Permalink
API for object pagination, count(*) (#288)
Browse files Browse the repository at this point in the history
Former-commit-id: a389687
  • Loading branch information
silvanheller authored Apr 26, 2022
1 parent 4169bcd commit 3de8017
Show file tree
Hide file tree
Showing 46 changed files with 545 additions and 342 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ allprojects {
group = 'org.vitrivr'

/* Our current version, on dev branch this should always be release+1-SNAPSHOT */
version = '3.11.0'
version = '3.11.1'

apply plugin: 'java-library'
apply plugin: 'maven-publish'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@
import org.vitrivr.cineast.api.rest.handlers.actions.feature.FindSegmentFeaturesGetHandler;
import org.vitrivr.cineast.api.rest.handlers.actions.feature.FindSegmentTextGetHandler;
import org.vitrivr.cineast.api.rest.handlers.actions.feature.FindTagsForElementGetHandler;
import org.vitrivr.cineast.api.rest.handlers.actions.bool.CountRowsGetHandler;
import org.vitrivr.cineast.api.rest.handlers.actions.mediaobject.FindObjectAllGetHandler;
import org.vitrivr.cineast.api.rest.handlers.actions.mediaobject.FindObjectByIdPostHandler;
import org.vitrivr.cineast.api.rest.handlers.actions.mediaobject.FindObjectGetHandler;
import org.vitrivr.cineast.api.rest.handlers.actions.mediaobject.FindObjectPaginationGetHandler;
import org.vitrivr.cineast.api.rest.handlers.actions.metadata.FindObjectMetadataByDomainGetHandler;
import org.vitrivr.cineast.api.rest.handlers.actions.metadata.FindObjectMetadataByDomainPostHandler;
import org.vitrivr.cineast.api.rest.handlers.actions.metadata.FindObjectMetadataByKeyGetHandler;
Expand Down Expand Up @@ -401,6 +403,7 @@ private void registerRestOperations() {
new FindObjectAllGetHandler(),
new FindObjectByIdPostHandler(),
new FindObjectGetHandler(),
new FindObjectPaginationGetHandler(),
/* Segments */
new FindSegmentByIdPostHandler(),
new FindSegmentsByIdGetHandler(),
Expand All @@ -427,6 +430,7 @@ private void registerRestOperations() {
/* Boolean */
new FindDistinctElementsByColumnPostHandler(),
new SelectFromTablePostHandler(),
new CountRowsGetHandler(),
/* Status */
new StatusInvocationHandler()
));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.vitrivr.cineast.api.messages.general;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

public class IntegerMessage {

private final int value;

@JsonCreator
public IntegerMessage(@JsonProperty("value") int value) {
this.value = value;
}

public int getValue() {
return value;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package org.vitrivr.cineast.api.rest.handlers.actions.bool;

import static org.vitrivr.cineast.api.util.APIConstants.TABLE_NAME;

import io.javalin.http.Context;
import io.javalin.plugin.openapi.dsl.OpenApiBuilder;
import io.javalin.plugin.openapi.dsl.OpenApiDocumentation;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.vitrivr.cineast.api.messages.general.IntegerMessage;
import org.vitrivr.cineast.api.rest.handlers.interfaces.GetRestHandler;
import org.vitrivr.cineast.standalone.config.Config;

public class CountRowsGetHandler implements GetRestHandler<IntegerMessage> {

public static final String ROUTE = "count/table/{" + TABLE_NAME + "}";

private static final Logger LOGGER = LogManager.getLogger(CountRowsGetHandler.class);

@Override
public IntegerMessage doGet(Context ctx) {
try (final var selector = Config.sharedConfig().getDatabase().getSelectorSupplier().get()) {
var tableName = ctx.pathParam(TABLE_NAME);
selector.open(tableName);
var count = selector.rowCount();
LOGGER.trace("counted {} objects in table {}", count, tableName);
return new IntegerMessage(count);
}
}

@Override
public Class<IntegerMessage> outClass() {
return IntegerMessage.class;
}

@Override
public String route() {
return ROUTE;
}

@Override
public OpenApiDocumentation docs() {
return OpenApiBuilder.document()
.operation(op -> {
op.summary("Count objects");
op.description("Equivalent to calling SELECT count(*) FROM table. Used to determined #pages for pagination in a frontend or statistical purposes");
op.operationId("countRows");
op.addTagsItem("Misc");
})
.json("200", outClass());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
import org.vitrivr.cineast.api.rest.handlers.interfaces.GetRestHandler;
import org.vitrivr.cineast.api.util.QueryUtil;

public class FindSegmentFeaturesGetHandler implements
GetRestHandler<FeaturesAllCategoriesQueryResult> {
public class FindSegmentFeaturesGetHandler implements GetRestHandler<FeaturesAllCategoriesQueryResult> {

public static final String ROUTE = "find/feature/all/by/id/{" + ID_QUALIFIER + "}";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,20 @@
import io.javalin.http.Context;
import io.javalin.plugin.openapi.dsl.OpenApiBuilder;
import io.javalin.plugin.openapi.dsl.OpenApiDocumentation;
import java.util.List;
import org.vitrivr.cineast.api.messages.result.MediaObjectQueryResult;
import org.vitrivr.cineast.api.rest.handlers.interfaces.GetRestHandler;
import org.vitrivr.cineast.core.data.entities.MediaObjectDescriptor;
import org.vitrivr.cineast.core.db.dao.reader.MediaObjectReader;
import org.vitrivr.cineast.standalone.config.Config;

public class FindObjectAllGetHandler implements GetRestHandler<MediaObjectQueryResult> {


public static final String TYPE_NAME = "type";

public static final String ROUTE = "find/objects/all/"; // The more honest route
// public static final String ROUTE = "find/objects/all/:"+TYPE_NAME;

@Override
public MediaObjectQueryResult doGet(Context ctx) {
// TODO :type is not being used
final MediaObjectReader ol = new MediaObjectReader(Config.sharedConfig().getDatabase().getSelectorSupplier().get());
final List<MediaObjectDescriptor> multimediaobjectIds = ol.getAllObjects();
ol.close();
return new MediaObjectQueryResult("", multimediaobjectIds);
try (final MediaObjectReader ol = new MediaObjectReader(Config.sharedConfig().getDatabase().getSelectorSupplier().get())) {
return new MediaObjectQueryResult("", ol.getAllObjects());
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,12 @@ public class FindObjectByIdPostHandler implements ParsingPostRestHandler<IdList,

@Override
public MediaObjectQueryResult performPost(IdList context, Context ctx) {
final Map<String, String> parameters = ctx.pathParamMap();
if (context == null || context.getIds().length == 0) {
return new MediaObjectQueryResult("", new ArrayList<>(0));
}
final MediaObjectReader ol = new MediaObjectReader(Config.sharedConfig().getDatabase().getSelectorSupplier().get());
final Map<String, MediaObjectDescriptor> objects = ol.lookUpObjects(Arrays.asList(context.getIds()));
ol.close();
return new MediaObjectQueryResult("", new ArrayList<>(objects.values()));
try (final MediaObjectReader ol = new MediaObjectReader(Config.sharedConfig().getDatabase().getSelectorSupplier().get())) {
return new MediaObjectQueryResult("", new ArrayList<>(ol.lookUpObjects(Arrays.asList(context.getIds())).values()));
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package org.vitrivr.cineast.api.rest.handlers.actions.mediaobject;

import static org.vitrivr.cineast.api.util.APIConstants.ATTRIBUTE_NAME;
import static org.vitrivr.cineast.api.util.APIConstants.VALUE_NAME;

import com.google.common.collect.Lists;
import io.javalin.http.Context;
import io.javalin.plugin.openapi.dsl.OpenApiBuilder;
Expand All @@ -15,44 +18,38 @@

public class FindObjectGetHandler implements GetRestHandler<MediaObjectQueryResult> {

public static final String ATTRIBUTE_NAME = "attribute";
public static final String VALUE_NAME = "value";

public static final String ROUTE = "find/object/by/{" + ATTRIBUTE_NAME + "}/{" + VALUE_NAME + "}";

private static final Logger LOGGER = LogManager.getLogger(FindObjectGetHandler.class);


@Override
public MediaObjectQueryResult doGet(Context ctx) {
final Map<String, String> parameters = ctx.pathParamMap();

final String attribute = parameters.get(ATTRIBUTE_NAME);
final String value = parameters.get(VALUE_NAME);

final MediaObjectReader ol = new MediaObjectReader(Config.sharedConfig().getDatabase().getSelectorSupplier().get());
MediaObjectDescriptor object = null;

switch (attribute.toLowerCase()) {
case "id": {
object = ol.lookUpObjectById(value);
break;
}
case "name": {
object = ol.lookUpObjectByName(value);
break;
}
case "path": {
object = ol.lookUpObjectByPath(value);
break;
}
default: {
LOGGER.error("Unknown attribute '{}' in FindObjectByActionHandler", attribute);
try (final MediaObjectReader ol = new MediaObjectReader(Config.sharedConfig().getDatabase().getSelectorSupplier().get())) {
MediaObjectDescriptor object = null;
switch (attribute.toLowerCase()) {
case "id": {
object = ol.lookUpObjectById(value);
break;
}
case "name": {
object = ol.lookUpObjectByName(value);
break;
}
case "path": {
object = ol.lookUpObjectByPath(value);
break;
}
default: {
LOGGER.error("Unknown attribute '{}' in FindObjectByActionHandler", attribute);
}
}
return new MediaObjectQueryResult("", Lists.newArrayList(object));
}

ol.close();
return new MediaObjectQueryResult("", Lists.newArrayList(object));
}

@Override
Expand All @@ -75,6 +72,7 @@ public OpenApiDocumentation docs() {
op.addTagsItem("Object");
})
.pathParam(ATTRIBUTE_NAME, String.class, p -> p.description("The attribute type of the value. One of: id, name, path"))
.pathParam(VALUE_NAME, String.class, p -> p.description("The actual value that you want to filter for"))
.json("200", outClass());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package org.vitrivr.cineast.api.rest.handlers.actions.mediaobject;

import static org.vitrivr.cineast.api.util.APIConstants.LIMIT_NAME;
import static org.vitrivr.cineast.api.util.APIConstants.SKIP_NAME;

import io.javalin.http.Context;
import io.javalin.plugin.openapi.dsl.OpenApiBuilder;
import io.javalin.plugin.openapi.dsl.OpenApiDocumentation;
import java.util.ArrayList;
import java.util.Map;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.vitrivr.cineast.api.messages.result.MediaObjectQueryResult;
import org.vitrivr.cineast.api.rest.handlers.interfaces.GetRestHandler;
import org.vitrivr.cineast.core.db.dao.reader.MediaObjectReader;
import org.vitrivr.cineast.standalone.config.Config;

public class FindObjectPaginationGetHandler implements GetRestHandler<MediaObjectQueryResult> {

public static final String ROUTE = "find/object/all/{" + SKIP_NAME + "}/{" + LIMIT_NAME + "}";

private static final Logger LOGGER = LogManager.getLogger(FindObjectPaginationGetHandler.class);

@Override
public MediaObjectQueryResult doGet(Context ctx) {
final Map<String, String> parameters = ctx.pathParamMap();

try (final MediaObjectReader ol = new MediaObjectReader(Config.sharedConfig().getDatabase().getSelectorSupplier().get())) {
final var skipParam = parameters.get(SKIP_NAME);
final var skip = skipParam == null ? 0 : Integer.parseInt(skipParam);
final var limitParam = parameters.get(LIMIT_NAME);
final var limit = limitParam == null ? Integer.MAX_VALUE : Integer.parseInt(limitParam);

var result = ol.getAllObjects(skip, limit);
LOGGER.trace("returning {} elements for skip {} and limit {}", result.size(), skip, limit);
return new MediaObjectQueryResult("", result);
} catch (Exception e) {
LOGGER.error("Error during request", e);
return new MediaObjectQueryResult("", new ArrayList<>());
}
}

@Override
public Class<MediaObjectQueryResult> outClass() {
return MediaObjectQueryResult.class;
}

@Override
public String route() {
return ROUTE;
}

@Override
public OpenApiDocumentation docs() {
return OpenApiBuilder.document()
.operation(op -> {
op.summary("Get a fixed amount of objects from the sorted list");
op.description("Equivalent to calling SELECT * FROM multimediaobject ORDER BY objectid ASC LIMIT limit SKIP skip. Mostly used for pagination when wanting to retrieve all objects");
op.operationId("findObjectsPagination");
op.addTagsItem("Object");
})
.pathParam(LIMIT_NAME, Integer.class, p -> p.description("How many object at most should be fetched"))
.pathParam(SKIP_NAME, Integer.class, p -> p.description("How many objects should be skipped"))
.json("200", outClass());
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.vitrivr.cineast.api.rest.handlers.actions.metadata;

import static org.vitrivr.cineast.api.rest.handlers.actions.metadata.FindObjectMetadataFullyQualifiedGetHandler.DOMAIN_NAME;
import static org.vitrivr.cineast.api.rest.handlers.actions.metadata.FindObjectMetadataFullyQualifiedGetHandler.OBJECT_ID_NAME;
import static org.vitrivr.cineast.api.util.APIConstants.DOMAIN_NAME;

import io.javalin.http.Context;
import io.javalin.plugin.openapi.dsl.OpenApiBuilder;
Expand All @@ -21,17 +21,15 @@
public class FindObjectMetadataByDomainGetHandler implements GetRestHandler<MediaObjectMetadataQueryResult> {


public static final String ROUTE = "find/metadata/in/{" + DOMAIN_NAME + "}/by/id/{" + APIConstants.ID_QUALIFIER
+ "}";
public static final String ROUTE = "find/metadata/in/{" + DOMAIN_NAME + "}/by/id/{" + APIConstants.ID_QUALIFIER + "}";

@Override
public MediaObjectMetadataQueryResult doGet(Context ctx) {
final Map<String, String> parameters = ctx.pathParamMap();
final String objectId = parameters.get(OBJECT_ID_NAME);
final String domain = parameters.get(DOMAIN_NAME);
final MetadataRetrievalService service = new MetadataRetrievalService();
return new MediaObjectMetadataQueryResult("",
service.findByDomain(objectId, domain));
return new MediaObjectMetadataQueryResult("", service.findByDomain(objectId, domain));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.vitrivr.cineast.api.rest.handlers.actions.metadata;

import static org.vitrivr.cineast.api.rest.handlers.actions.metadata.FindObjectMetadataFullyQualifiedGetHandler.DOMAIN_NAME;
import static org.vitrivr.cineast.api.util.APIConstants.DOMAIN_NAME;

import io.javalin.http.Context;
import io.javalin.plugin.openapi.dsl.OpenApiBuilder;
Expand Down Expand Up @@ -33,8 +33,7 @@ public MediaObjectMetadataQueryResult performPost(IdList ids, Context ctx) {
}
final String domain = parameters.get(DOMAIN_NAME);
final MetadataRetrievalService service = new MetadataRetrievalService();
return new MediaObjectMetadataQueryResult("",
service.findByDomain(ids.getIdList(), domain));
return new MediaObjectMetadataQueryResult("", service.findByDomain(ids.getIdList(), domain));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.vitrivr.cineast.api.rest.handlers.actions.metadata;

import static org.vitrivr.cineast.api.rest.handlers.actions.metadata.FindObjectMetadataFullyQualifiedGetHandler.KEY_NAME;
import static org.vitrivr.cineast.api.util.APIConstants.KEY_NAME;
import static org.vitrivr.cineast.api.rest.handlers.actions.metadata.FindObjectMetadataFullyQualifiedGetHandler.OBJECT_ID_NAME;

import io.javalin.http.Context;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.vitrivr.cineast.api.rest.handlers.actions.metadata;

import static org.vitrivr.cineast.api.rest.handlers.actions.metadata.FindObjectMetadataFullyQualifiedGetHandler.KEY_NAME;
import static org.vitrivr.cineast.api.util.APIConstants.KEY_NAME;

import io.javalin.http.Context;
import io.javalin.plugin.openapi.dsl.OpenApiBuilder;
Expand Down
Loading

0 comments on commit 3de8017

Please sign in to comment.