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

request pagination #5207

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
12 changes: 9 additions & 3 deletions src/main/java/org/traccar/api/resource/UserResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.warrenstrange.googleauth.GoogleAuthenticator;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.DefaultValue;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.core.Context;
import org.traccar.api.BaseObjectResource;
Expand All @@ -31,6 +32,7 @@
import org.traccar.storage.StorageException;
import org.traccar.storage.query.Columns;
import org.traccar.storage.query.Condition;
import org.traccar.storage.query.Pagination;
import org.traccar.storage.query.Request;

import jakarta.annotation.security.PermitAll;
Expand Down Expand Up @@ -61,18 +63,22 @@ public UserResource() {
}

@GET
public Collection<User> get(@QueryParam("userId") long userId) throws StorageException {
public Collection<User> get(@QueryParam("userId") long userId, @QueryParam("skip") @DefaultValue("0") int skip, @QueryParam("limit") @DefaultValue("0") int limit) throws StorageException {
if (userId > 0) {
permissionsService.checkUser(getUserId(), userId);
return storage.getObjects(baseClass, new Request(
new Columns.All(),
new Condition.Permission(User.class, userId, ManagedUser.class).excludeGroups()));
new Condition.Permission(User.class, userId, ManagedUser.class).excludeGroups(),
null,
new Pagination(skip, limit)));
} else if (permissionsService.notAdmin(getUserId())) {
return storage.getObjects(baseClass, new Request(
new Columns.All(),
new Condition.Permission(User.class, getUserId(), ManagedUser.class).excludeGroups()));
} else {
return storage.getObjects(baseClass, new Request(new Columns.All()));
return storage.getObjects(baseClass, new Request(
new Columns.All(),
new Pagination(skip, limit)));
}
}

Expand Down
4 changes: 3 additions & 1 deletion src/main/java/org/traccar/database/CommandsManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.traccar.storage.query.Columns;
import org.traccar.storage.query.Condition;
import org.traccar.storage.query.Order;
import org.traccar.storage.query.Pagination;
import org.traccar.storage.query.Request;

import jakarta.annotation.Nullable;
Expand Down Expand Up @@ -108,7 +109,8 @@ public Collection<Command> readQueuedCommands(long deviceId, int count) {
var commands = storage.getObjects(QueuedCommand.class, new Request(
new Columns.All(),
new Condition.Equals("deviceId", deviceId),
new Order("id", false, count)));
new Order("id", false),
new Pagination(0, count)));
Map<Event, Position> events = new HashMap<>();
for (var command : commands) {
storage.removeObject(QueuedCommand.class, new Request(
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/org/traccar/handler/FilterHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.traccar.storage.query.Columns;
import org.traccar.storage.query.Condition;
import org.traccar.storage.query.Order;
import org.traccar.storage.query.Pagination;
import org.traccar.storage.query.Request;

import jakarta.inject.Inject;
Expand Down Expand Up @@ -99,7 +100,8 @@ private Position getPrecedingPosition(long deviceId, Date date) throws StorageEx
new Condition.And(
new Condition.Equals("deviceId", deviceId),
new Condition.Compare("fixTime", "<=", "time", date)),
new Order("fixTime", true, 1)));
new Order("fixTime", true),
new Pagination(0, 1)));
}

private boolean filterInvalid(Position position) {
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/org/traccar/helper/model/UserUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.traccar.storage.StorageException;
import org.traccar.storage.query.Columns;
import org.traccar.storage.query.Order;
import org.traccar.storage.query.Pagination;
import org.traccar.storage.query.Request;

import java.util.Date;
Expand All @@ -36,7 +37,8 @@ private UserUtil() {
public static boolean isEmpty(Storage storage) throws StorageException {
return storage.getObjects(User.class, new Request(
new Columns.Include("id"),
new Order("id", false, 1))).isEmpty();
new Order("id", false),
new Pagination(0, 1))).isEmpty();
}

public static String getDistanceUnit(Server server, User user) {
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/org/traccar/reports/SummaryReportProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.traccar.storage.query.Columns;
import org.traccar.storage.query.Condition;
import org.traccar.storage.query.Order;
import org.traccar.storage.query.Pagination;
import org.traccar.storage.query.Request;

import jakarta.inject.Inject;
Expand Down Expand Up @@ -72,7 +73,8 @@ private Position getEdgePosition(long deviceId, Date from, Date to, boolean end)
new Condition.And(
new Condition.Equals("deviceId", deviceId),
new Condition.Between("fixTime", "from", from, "to", to)),
new Order("fixTime", end, 1)));
new Order("fixTime", end),
new Pagination(0, 1)));
}

private Collection<SummaryReportItem> calculateDeviceResult(
Expand Down
21 changes: 17 additions & 4 deletions src/main/java/org/traccar/storage/DatabaseStorage.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.traccar.storage.query.Columns;
import org.traccar.storage.query.Condition;
import org.traccar.storage.query.Order;
import org.traccar.storage.query.Pagination;
import org.traccar.storage.query.Request;

import jakarta.inject.Inject;
Expand Down Expand Up @@ -68,6 +69,7 @@ public <T> List<T> getObjects(Class<T> clazz, Request request) throws StorageExc
query.append(" FROM ").append(getStorageName(clazz));
query.append(formatCondition(request.getCondition()));
query.append(formatOrder(request.getOrder()));
query.append(formatPagination(request.getPagination()));
try {
QueryBuilder builder = QueryBuilder.create(config, dataSource, objectMapper, query.toString());
for (Map.Entry<String, Object> variable : getConditionVariables(request.getCondition()).entrySet()) {
Expand Down Expand Up @@ -307,14 +309,25 @@ private String formatOrder(Order order) {
if (order.getDescending()) {
result.append(" DESC");
}
if (order.getLimit() > 0) {
if (databaseType.equals("Microsoft SQL Server")) {
}
return result.toString();
}

private String formatPagination(Pagination pagination) {
StringBuilder result = new StringBuilder();
if (pagination != null) {
if(pagination.getSkip() > 0) {
result.append(" OFFSET ");
result.append(pagination.getSkip());
}
if (pagination.getLimit() > 0) {
if (databaseType.equals("Microsoft SQL Server")) {
result.append(" OFFSET 0 ROWS FETCH FIRST ");
result.append(order.getLimit());
result.append(pagination.getLimit());
result.append(" ROWS ONLY");
} else {
result.append(" LIMIT ");
result.append(order.getLimit());
result.append(pagination.getLimit());
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which databases have you tested?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PG so far

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to test at least H2, MySQL, Postgres and MS SQL. Is there an SQL standard for it?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code wise, the path is correct?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only did a brief look, but I think it makes sense. I would separate database changes and report changes though.

}
}
Expand Down
12 changes: 3 additions & 9 deletions src/main/java/org/traccar/storage/query/Order.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,16 @@ public class Order {

private final String column;
private final boolean descending;
private final int limit;

public Order(String column) {
this(column, false, 0);
this(column, false);
}

public Order(String column, boolean descending, int limit) {
public Order(String column, boolean descending) {
this.column = column;
this.descending = descending;
this.limit = limit;
}

public String getColumn() {
return column;
}
Expand All @@ -39,8 +37,4 @@ public boolean getDescending() {
return descending;
}

public int getLimit() {
return limit;
}

}
36 changes: 36 additions & 0 deletions src/main/java/org/traccar/storage/query/Pagination.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright 2022 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.traccar.storage.query;

public class Pagination {

private final int limit;
private final int skip;

public Pagination(int skip, int limit) {
this.skip = skip;
this.limit = limit;
}

public int getSkip() {
return skip;
}

public int getLimit() {
return limit;
}

}
24 changes: 19 additions & 5 deletions src/main/java/org/traccar/storage/query/Request.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,37 @@ public class Request {
private final Columns columns;
private final Condition condition;
private final Order order;
private final Pagination pagination;

public Request(Columns columns) {
this(columns, null, null);
this(columns, null, null, null);
}

public Request(Condition condition) {
this(null, condition, null);
this(null, condition, null, null);
}

public Request(Columns columns, Condition condition) {
this(columns, condition, null);
this(columns, condition, null, null);
}

public Request(Columns columns, Order order) {
this(columns, null, order);
this(columns, null, order, null);
}

public Request(Columns columns, Pagination pagination) {
this(columns, null, null, pagination);
}

public Request(Columns columns, Order order, Pagination pagination) {
this(columns, null, order, pagination);
}

public Request(Columns columns, Condition condition, Order order) {
public Request(Columns columns, Condition condition, Order order, Pagination pagination) {
this.columns = columns;
this.condition = condition;
this.order = order;
this.pagination = pagination;
}

public Columns getColumns() {
Expand All @@ -54,5 +64,9 @@ public Condition getCondition() {
public Order getOrder() {
return order;
}

public Pagination getPagination() {
return pagination;
}

}