From d03a2d7da931b5f460a4b5c587bc31d09d846c1f Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sun, 7 May 2023 15:50:19 +0100 Subject: [PATCH] Resource statuses moved to the db, so they don't have to be calculated on demand for every API call. --- .../api/gateway/resource/GatewayResource.java | 2 +- .../api/resource/ArbitraryResource.java | 17 +-- .../ArbitraryDataBuildQueueItem.java | 4 + .../qortal/arbitrary/ArbitraryDataReader.java | 2 +- .../arbitrary/ArbitraryDataResource.java | 32 +++-- .../PirateChainWalletController.java | 2 +- .../arbitrary/ArbitraryDataBuilderThread.java | 12 ++ .../data/arbitrary/ArbitraryResourceData.java | 21 ++++ .../arbitrary/ArbitraryResourceStatus.java | 39 ++++-- .../repository/ArbitraryRepository.java | 2 + .../hsqldb/HSQLDBArbitraryRepository.java | 112 +++++++++++------- .../hsqldb/HSQLDBDatabaseUpdates.java | 2 +- .../transaction/ArbitraryTransaction.java | 8 ++ .../utils/ArbitraryTransactionUtils.java | 25 +--- 14 files changed, 176 insertions(+), 104 deletions(-) diff --git a/src/main/java/org/qortal/api/gateway/resource/GatewayResource.java b/src/main/java/org/qortal/api/gateway/resource/GatewayResource.java index 9c77753f..7d76be3d 100644 --- a/src/main/java/org/qortal/api/gateway/resource/GatewayResource.java +++ b/src/main/java/org/qortal/api/gateway/resource/GatewayResource.java @@ -70,7 +70,7 @@ public class GatewayResource { } ArbitraryDataResource resource = new ArbitraryDataResource(name, ResourceIdType.NAME, service, identifier); - return resource.getStatus(false); + return resource.getStatus(); } diff --git a/src/main/java/org/qortal/api/resource/ArbitraryResource.java b/src/main/java/org/qortal/api/resource/ArbitraryResource.java index 9a2fceaa..2b3b986f 100644 --- a/src/main/java/org/qortal/api/resource/ArbitraryResource.java +++ b/src/main/java/org/qortal/api/resource/ArbitraryResource.java @@ -141,10 +141,6 @@ public class ArbitraryResource { return new ArrayList<>(); } - if (includeStatus != null && includeStatus) { - resources = ArbitraryTransactionUtils.addStatusToResources(resources); - } - return resources; } catch (DataException e) { @@ -212,10 +208,6 @@ public class ArbitraryResource { return new ArrayList<>(); } - if (includeStatus != null && includeStatus) { - resources = ArbitraryTransactionUtils.addStatusToResources(resources); - } - return resources; } catch (DataException e) { @@ -243,7 +235,7 @@ public class ArbitraryResource { if (!Settings.getInstance().isQDNAuthBypassEnabled()) Security.requirePriorAuthorizationOrApiKey(request, name, service, null, apiKey); - return ArbitraryTransactionUtils.getStatus(service, name, null, build); + return ArbitraryTransactionUtils.getStatus(service, name, null, build, true); } @GET @@ -290,7 +282,7 @@ public class ArbitraryResource { if (!Settings.getInstance().isQDNAuthBypassEnabled()) Security.requirePriorAuthorizationOrApiKey(request, name, service, identifier, apiKey); - return ArbitraryTransactionUtils.getStatus(service, name, identifier, build); + return ArbitraryTransactionUtils.getStatus(service, name, identifier, build, true); } @@ -482,7 +474,6 @@ public class ArbitraryResource { @ApiErrors({ApiError.REPOSITORY_ISSUE}) public List getHostedResources( @HeaderParam(Security.API_KEY_HEADER) String apiKey, - @Parameter(description = "Include status") @QueryParam("includestatus") Boolean includeStatus, @Parameter(ref = "limit") @QueryParam("limit") Integer limit, @Parameter(ref = "offset") @QueryParam("offset") Integer offset, @QueryParam("query") String query) { @@ -513,10 +504,6 @@ public class ArbitraryResource { } } - if (includeStatus != null && includeStatus) { - resources = ArbitraryTransactionUtils.addStatusToResources(resources); - } - return resources; } catch (DataException e) { diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataBuildQueueItem.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataBuildQueueItem.java index 4a02f092..465d1391 100644 --- a/src/main/java/org/qortal/arbitrary/ArbitraryDataBuildQueueItem.java +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataBuildQueueItem.java @@ -4,6 +4,7 @@ import org.qortal.arbitrary.exception.MissingDataException; import org.qortal.arbitrary.ArbitraryDataFile.*; import org.qortal.arbitrary.misc.Service; import org.qortal.repository.DataException; +import org.qortal.utils.ArbitraryTransactionUtils; import org.qortal.utils.NTP; import java.io.IOException; @@ -51,6 +52,9 @@ public class ArbitraryDataBuildQueueItem extends ArbitraryDataResource { arbitraryDataReader.loadSynchronously(true); } finally { this.buildEndTimestamp = NTP.getTime(); + + // Update status after build + ArbitraryTransactionUtils.getStatus(service, resourceId, identifier, false, true); } } diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataReader.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataReader.java index b9e62e56..f281cec5 100644 --- a/src/main/java/org/qortal/arbitrary/ArbitraryDataReader.java +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataReader.java @@ -240,7 +240,7 @@ public class ArbitraryDataReader { try { Files.createDirectories(this.workingPath); } catch (IOException e) { - throw new DataException("Unable to create temp directory"); + throw new DataException(String.format("Unable to create temp directory %s: %s", this.workingPath, e.getMessage())); } } diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataResource.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataResource.java index a4650dfc..4aed21fc 100644 --- a/src/main/java/org/qortal/arbitrary/ArbitraryDataResource.java +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataResource.java @@ -9,6 +9,7 @@ import org.qortal.arbitrary.misc.Service; import org.qortal.controller.arbitrary.ArbitraryDataBuildManager; import org.qortal.controller.arbitrary.ArbitraryDataManager; import org.qortal.controller.arbitrary.ArbitraryDataStorageManager; +import org.qortal.data.arbitrary.ArbitraryResourceData; import org.qortal.data.arbitrary.ArbitraryResourceStatus; import org.qortal.data.transaction.ArbitraryTransactionData; import org.qortal.repository.DataException; @@ -57,17 +58,34 @@ public class ArbitraryDataResource { this.identifier = identifier; } - public ArbitraryResourceStatus getStatus(boolean quick) { - // Calculate the chunk counts - // Avoid this for "quick" statuses, to speed things up - if (!quick) { - this.calculateChunkCounts(); + public ArbitraryResourceStatus getStatusAndUpdateCache(boolean updateCache) { + ArbitraryResourceStatus arbitraryResourceStatus = this.getStatus(); - if (!this.exists) { - return new ArbitraryResourceStatus(Status.NOT_PUBLISHED, this.localChunkCount, this.totalChunkCount); + if (updateCache) { + // Update cache if possible + ArbitraryResourceStatus.Status status = arbitraryResourceStatus != null ? arbitraryResourceStatus.getStatus() : null; + ArbitraryResourceData arbitraryResourceData = new ArbitraryResourceData(this.service, this.resourceId, this.identifier); + + try (final Repository repository = RepositoryManager.getRepository()) { + repository.getArbitraryRepository().setStatus(arbitraryResourceData, status); + repository.saveChanges(); + + } catch (DataException e) { + LOGGER.info("Unable to update status cache for resource {}: {}", arbitraryResourceData, e.getMessage()); } } + return arbitraryResourceStatus; + } + + public ArbitraryResourceStatus getStatus() { + // Calculate the chunk counts + this.calculateChunkCounts(); + + if (!this.exists) { + return new ArbitraryResourceStatus(Status.NOT_PUBLISHED, this.localChunkCount, this.totalChunkCount); + } + if (resourceIdType != ResourceIdType.NAME) { // We only support statuses for resources with a name return new ArbitraryResourceStatus(Status.UNSUPPORTED, this.localChunkCount, this.totalChunkCount); diff --git a/src/main/java/org/qortal/controller/PirateChainWalletController.java b/src/main/java/org/qortal/controller/PirateChainWalletController.java index 90e65329..e009d531 100644 --- a/src/main/java/org/qortal/controller/PirateChainWalletController.java +++ b/src/main/java/org/qortal/controller/PirateChainWalletController.java @@ -187,7 +187,7 @@ public class PirateChainWalletController extends Thread { // Check its status ArbitraryResourceStatus status = ArbitraryTransactionUtils.getStatus( - t.getService(), t.getName(), t.getIdentifier(), false); + t.getService(), t.getName(), t.getIdentifier(), false, true); if (status.getStatus() != ArbitraryResourceStatus.Status.READY) { LOGGER.info("Not ready yet: {}", status.getTitle()); diff --git a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataBuilderThread.java b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataBuilderThread.java index 0fb685a3..a2165a9e 100644 --- a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataBuilderThread.java +++ b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataBuilderThread.java @@ -5,13 +5,17 @@ import org.apache.logging.log4j.Logger; import org.qortal.arbitrary.ArbitraryDataBuildQueueItem; import org.qortal.arbitrary.exception.MissingDataException; import org.qortal.controller.Controller; +import org.qortal.data.arbitrary.ArbitraryResourceStatus; import org.qortal.repository.DataException; +import org.qortal.utils.ArbitraryTransactionUtils; import org.qortal.utils.NTP; import java.io.IOException; import java.util.Comparator; import java.util.Map; +import static org.qortal.data.arbitrary.ArbitraryResourceStatus.Status.*; + public class ArbitraryDataBuilderThread implements Runnable { @@ -69,6 +73,14 @@ public class ArbitraryDataBuilderThread implements Runnable { continue; } + // Get status before build + ArbitraryResourceStatus arbitraryResourceStatus = ArbitraryTransactionUtils.getStatus(queueItem.getService(), queueItem.getResourceId(), queueItem.getIdentifier(), false, true); + if (arbitraryResourceStatus.getStatus() == NOT_PUBLISHED) { + // No point in building a non-existent resource + this.removeFromQueue(queueItem); + continue; + } + // Set the start timestamp, to prevent other threads from building it at the same time queueItem.prepareForBuild(); } diff --git a/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceData.java b/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceData.java index 4f636177..ffd30209 100644 --- a/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceData.java +++ b/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceData.java @@ -6,6 +6,8 @@ import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import java.util.Objects; +import static org.qortal.data.arbitrary.ArbitraryResourceStatus.Status; + @XmlAccessorType(XmlAccessType.FIELD) public class ArbitraryResourceData { @@ -22,11 +24,30 @@ public class ArbitraryResourceData { public ArbitraryResourceData() { } + public ArbitraryResourceData(Service service, String name, String identifier) { + if (identifier == null) { + identifier = "default"; + } + + this.service = service; + this.name = name; + this.identifier = identifier; + } + @Override public String toString() { return String.format("%s %s %s", name, service, identifier); } + public void setStatus(Status status) { + if (status == null) { + this.status = null; + } + else { + this.status = new ArbitraryResourceStatus(status); + } + } + @Override public boolean equals(Object o) { if (o == this) diff --git a/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceStatus.java b/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceStatus.java index 54dd2af6..6513776a 100644 --- a/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceStatus.java +++ b/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceStatus.java @@ -2,29 +2,46 @@ package org.qortal.data.arbitrary; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; +import java.util.Map; + +import static java.util.Arrays.stream; +import static java.util.stream.Collectors.toMap; @XmlAccessorType(XmlAccessType.FIELD) public class ArbitraryResourceStatus { public enum Status { - PUBLISHED("Published", "Published but not yet downloaded"), - NOT_PUBLISHED("Not published", "Resource does not exist"), - DOWNLOADING("Downloading", "Locating and downloading files..."), - DOWNLOADED("Downloaded", "Files downloaded"), - BUILDING("Building", "Building..."), - READY("Ready", "Ready"), - MISSING_DATA("Missing data", "Unable to locate all files. Please try again later"), - BUILD_FAILED("Build failed", "Build failed. Please try again later"), - UNSUPPORTED("Unsupported", "Unsupported request"), - BLOCKED("Blocked", "Name is blocked so content cannot be served"); + // Note: integer values must not be updated, as they are stored in the db + PUBLISHED(1, "Published", "Published but not yet downloaded"), + NOT_PUBLISHED(2, "Not published", "Resource does not exist"), + DOWNLOADING(3, "Downloading", "Locating and downloading files..."), + DOWNLOADED(4, "Downloaded", "Files downloaded"), + BUILDING(5, "Building", "Building..."), + READY(6, "Ready", "Ready"), + MISSING_DATA(7, "Missing data", "Unable to locate all files. Please try again later"), + BUILD_FAILED(8, "Build failed", "Build failed. Please try again later"), + UNSUPPORTED(9, "Unsupported", "Unsupported request"), + BLOCKED(10, "Blocked", "Name is blocked so content cannot be served"); + public int value; private String title; private String description; - Status(String title, String description) { + private static final Map map = stream(Status.values()) + .collect(toMap(status -> status.value, status -> status)); + + Status(int value, String title, String description) { + this.value = value; this.title = title; this.description = description; } + + public static Status valueOf(Integer value) { + if (value == null) { + return null; + } + return map.get(value); + } } private Status status; diff --git a/src/main/java/org/qortal/repository/ArbitraryRepository.java b/src/main/java/org/qortal/repository/ArbitraryRepository.java index 63729e46..7a21a1a2 100644 --- a/src/main/java/org/qortal/repository/ArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/ArbitraryRepository.java @@ -3,6 +3,7 @@ package org.qortal.repository; import org.qortal.arbitrary.misc.Service; import org.qortal.data.arbitrary.ArbitraryResourceData; import org.qortal.data.arbitrary.ArbitraryResourceMetadata; +import org.qortal.data.arbitrary.ArbitraryResourceStatus; import org.qortal.data.transaction.ArbitraryTransactionData; import org.qortal.data.transaction.ArbitraryTransactionData.*; @@ -44,6 +45,7 @@ public interface ArbitraryRepository { // Arbitrary resources cache save/load public void save(ArbitraryResourceData arbitraryResourceData) throws DataException; + public void setStatus(ArbitraryResourceData arbitraryResourceData, ArbitraryResourceStatus.Status status) throws DataException; public void delete(ArbitraryResourceData arbitraryResourceData) throws DataException; public void save(ArbitraryResourceMetadata metadata) throws DataException; diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java index 3061b7b0..5564d1d3 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java @@ -7,6 +7,7 @@ import org.qortal.arbitrary.misc.Category; import org.qortal.arbitrary.misc.Service; import org.qortal.data.arbitrary.ArbitraryResourceData; import org.qortal.data.arbitrary.ArbitraryResourceMetadata; +import org.qortal.data.arbitrary.ArbitraryResourceStatus; import org.qortal.data.transaction.ArbitraryTransactionData; import org.qortal.data.transaction.ArbitraryTransactionData.*; import org.qortal.data.transaction.BaseTransactionData; @@ -327,7 +328,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { return null; } - sql.append("SELECT name, service, identifier, size, created_when, updated_when, " + + sql.append("SELECT name, service, identifier, size, status, created_when, updated_when, " + "title, description, category, tag1, tag2, tag3, tag4, tag5 " + "FROM ArbitraryResourcesCache " + "LEFT JOIN ArbitraryMetadataCache USING (service, name, identifier) " + @@ -352,18 +353,19 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { Service serviceResult = Service.valueOf(resultSet.getInt(2)); String identifierResult = resultSet.getString(3); Integer sizeResult = resultSet.getInt(4); - Long created = resultSet.getLong(5); - Long updated = resultSet.getLong(6); + Integer status = resultSet.getInt(5); + Long created = resultSet.getLong(6); + Long updated = resultSet.getLong(7); // Optional metadata fields - String title = resultSet.getString(7); - String description = resultSet.getString(8); - String category = resultSet.getString(9); - String tag1 = resultSet.getString(10); - String tag2 = resultSet.getString(11); - String tag3 = resultSet.getString(12); - String tag4 = resultSet.getString(13); - String tag5 = resultSet.getString(14); + String title = resultSet.getString(8); + String description = resultSet.getString(9); + String category = resultSet.getString(10); + String tag1 = resultSet.getString(11); + String tag2 = resultSet.getString(12); + String tag3 = resultSet.getString(13); + String tag4 = resultSet.getString(14); + String tag5 = resultSet.getString(15); if (Objects.equals(identifierResult, "default")) { // Map "default" back to null. This is optional but probably less confusing than returning "default". @@ -375,6 +377,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { arbitraryResourceData.service = serviceResult; arbitraryResourceData.identifier = identifierResult; arbitraryResourceData.size = sizeResult; + arbitraryResourceData.setStatus(ArbitraryResourceStatus.Status.valueOf(status)); arbitraryResourceData.created = created; arbitraryResourceData.updated = (updated == 0) ? null : updated; @@ -405,7 +408,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { StringBuilder sql = new StringBuilder(512); List bindParams = new ArrayList<>(); - sql.append("SELECT name, service, identifier, size, created_when, updated_when, " + + sql.append("SELECT name, service, identifier, size, status, created_when, updated_when, " + "title, description, category, tag1, tag2, tag3, tag4, tag5 " + "FROM ArbitraryResourcesCache " + "LEFT JOIN ArbitraryMetadataCache USING (service, name, identifier) " + @@ -428,18 +431,19 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { Service serviceResult = Service.valueOf(resultSet.getInt(2)); String identifierResult = resultSet.getString(3); Integer sizeResult = resultSet.getInt(4); - Long created = resultSet.getLong(5); - Long updated = resultSet.getLong(6); + Integer status = resultSet.getInt(5); + Long created = resultSet.getLong(6); + Long updated = resultSet.getLong(7); // Optional metadata fields - String title = resultSet.getString(7); - String description = resultSet.getString(8); - String category = resultSet.getString(9); - String tag1 = resultSet.getString(10); - String tag2 = resultSet.getString(11); - String tag3 = resultSet.getString(12); - String tag4 = resultSet.getString(13); - String tag5 = resultSet.getString(14); + String title = resultSet.getString(8); + String description = resultSet.getString(9); + String category = resultSet.getString(10); + String tag1 = resultSet.getString(11); + String tag2 = resultSet.getString(12); + String tag3 = resultSet.getString(13); + String tag4 = resultSet.getString(14); + String tag5 = resultSet.getString(15); if (Objects.equals(identifierResult, "default")) { // Map "default" back to null. This is optional but probably less confusing than returning "default". @@ -451,6 +455,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { arbitraryResourceData.service = serviceResult; arbitraryResourceData.identifier = identifierResult; arbitraryResourceData.size = sizeResult; + arbitraryResourceData.setStatus(ArbitraryResourceStatus.Status.valueOf(status)); arbitraryResourceData.created = created; arbitraryResourceData.updated = (updated == 0) ? null : updated; @@ -487,7 +492,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { StringBuilder sql = new StringBuilder(512); List bindParams = new ArrayList<>(); - sql.append("SELECT name, service, identifier, size, created_when, updated_when, " + + sql.append("SELECT name, service, identifier, size, status, created_when, updated_when, " + "title, description, category, tag1, tag2, tag3, tag4, tag5 " + "FROM ArbitraryResourcesCache " + "LEFT JOIN ArbitraryMetadataCache USING (service, name, identifier) " + @@ -571,18 +576,19 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { Service serviceResult = Service.valueOf(resultSet.getInt(2)); String identifierResult = resultSet.getString(3); Integer sizeResult = resultSet.getInt(4); - Long created = resultSet.getLong(5); - Long updated = resultSet.getLong(6); + Integer status = resultSet.getInt(5); + Long created = resultSet.getLong(6); + Long updated = resultSet.getLong(7); // Optional metadata fields - String title = resultSet.getString(7); - String description = resultSet.getString(8); - String category = resultSet.getString(9); - String tag1 = resultSet.getString(10); - String tag2 = resultSet.getString(11); - String tag3 = resultSet.getString(12); - String tag4 = resultSet.getString(13); - String tag5 = resultSet.getString(14); + String title = resultSet.getString(8); + String description = resultSet.getString(9); + String category = resultSet.getString(10); + String tag1 = resultSet.getString(11); + String tag2 = resultSet.getString(12); + String tag3 = resultSet.getString(13); + String tag4 = resultSet.getString(14); + String tag5 = resultSet.getString(15); if (Objects.equals(identifierResult, "default")) { // Map "default" back to null. This is optional but probably less confusing than returning "default". @@ -594,6 +600,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { arbitraryResourceData.service = serviceResult; arbitraryResourceData.identifier = identifierResult; arbitraryResourceData.size = sizeResult; + arbitraryResourceData.setStatus(ArbitraryResourceStatus.Status.valueOf(status)); arbitraryResourceData.created = created; arbitraryResourceData.updated = (updated == 0) ? null : updated; @@ -633,7 +640,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { StringBuilder sql = new StringBuilder(512); List bindParams = new ArrayList<>(); - sql.append("SELECT name, service, identifier, size, created_when, updated_when, " + + sql.append("SELECT name, service, identifier, size, status, created_when, updated_when, " + "title, description, category, tag1, tag2, tag3, tag4, tag5 " + "FROM ArbitraryResourcesCache " + "LEFT JOIN ArbitraryMetadataCache USING (service, name, identifier) " + @@ -747,18 +754,19 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { Service serviceResult = Service.valueOf(resultSet.getInt(2)); String identifierResult = resultSet.getString(3); Integer sizeResult = resultSet.getInt(4); - Long created = resultSet.getLong(5); - Long updated = resultSet.getLong(6); + Integer status = resultSet.getInt(5); + Long created = resultSet.getLong(6); + Long updated = resultSet.getLong(7); // Optional metadata fields - String title = resultSet.getString(7); - String description = resultSet.getString(8); - String category = resultSet.getString(9); - String tag1 = resultSet.getString(10); - String tag2 = resultSet.getString(11); - String tag3 = resultSet.getString(12); - String tag4 = resultSet.getString(13); - String tag5 = resultSet.getString(14); + String title = resultSet.getString(8); + String description = resultSet.getString(9); + String category = resultSet.getString(10); + String tag1 = resultSet.getString(11); + String tag2 = resultSet.getString(12); + String tag3 = resultSet.getString(13); + String tag4 = resultSet.getString(14); + String tag5 = resultSet.getString(15); if (Objects.equals(identifierResult, "default")) { // Map "default" back to null. This is optional but probably less confusing than returning "default". @@ -770,6 +778,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { arbitraryResourceData.service = serviceResult; arbitraryResourceData.identifier = identifierResult; arbitraryResourceData.size = sizeResult; + arbitraryResourceData.setStatus(ArbitraryResourceStatus.Status.valueOf(status)); arbitraryResourceData.created = created; arbitraryResourceData.updated = (updated == 0) ? null : updated; @@ -809,6 +818,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { public void save(ArbitraryResourceData arbitraryResourceData) throws DataException { HSQLDBSaver saveHelper = new HSQLDBSaver("ArbitraryResourcesCache"); + // "status" isn't saved here as we update this field separately saveHelper.bind("service", arbitraryResourceData.service.value).bind("name", arbitraryResourceData.name) .bind("identifier", arbitraryResourceData.identifier).bind("size", arbitraryResourceData.size) .bind("created_when", arbitraryResourceData.created).bind("updated_when", arbitraryResourceData.updated); @@ -820,6 +830,20 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository { } } + @Override + public void setStatus(ArbitraryResourceData arbitraryResourceData, ArbitraryResourceStatus.Status status) throws DataException { + if (status == null) { + return; + } + String updateSql = "UPDATE ArbitraryResourcesCache SET status = ? WHERE service = ? AND name = ? AND identifier = ?"; + + try { + this.repository.executeCheckedUpdate(updateSql, status.value, arbitraryResourceData.service.value, arbitraryResourceData.name, arbitraryResourceData.identifier); + } catch (SQLException e) { + throw new DataException("Unable to set status for arbitrary resource", e); + } + } + @Override public void delete(ArbitraryResourceData arbitraryResourceData) throws DataException { // NOTE: arbitrary metadata are deleted automatically by the database thanks to "ON DELETE CASCADE" diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java index e3c705e8..b54f4b08 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java @@ -1008,7 +1008,7 @@ public class HSQLDBDatabaseUpdates { stmt.execute("CREATE TABLE ArbitraryResourcesCache (service SMALLINT NOT NULL, " + "name RegisteredName NOT NULL, identifier VARCHAR(64), size INT NOT NULL, " - + "created_when EpochMillis NOT NULL, updated_when EpochMillis, " + + "status INTEGER, created_when EpochMillis NOT NULL, updated_when EpochMillis, " + "PRIMARY KEY (service, name, identifier))"); // For finding resources by service. stmt.execute("CREATE INDEX ArbitraryResourcesServiceIndex ON ArbitraryResourcesCache (service)"); diff --git a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java index 2a3c78af..b2954dd9 100644 --- a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java +++ b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java @@ -8,6 +8,7 @@ import java.util.stream.Collectors; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.qortal.account.Account; +import org.qortal.arbitrary.ArbitraryDataResource; import org.qortal.arbitrary.metadata.ArbitraryDataTransactionMetadata; import org.qortal.arbitrary.misc.Service; import org.qortal.block.BlockChain; @@ -18,6 +19,7 @@ import org.qortal.crypto.MemoryPoW; import org.qortal.data.PaymentData; import org.qortal.data.arbitrary.ArbitraryResourceData; import org.qortal.data.arbitrary.ArbitraryResourceMetadata; +import org.qortal.data.arbitrary.ArbitraryResourceStatus; import org.qortal.data.naming.NameData; import org.qortal.data.transaction.ArbitraryTransactionData; import org.qortal.data.transaction.TransactionData; @@ -405,6 +407,12 @@ public class ArbitraryTransaction extends Transaction { // Save repository.getArbitraryRepository().save(arbitraryResourceData); + + // Update status + ArbitraryDataResource resource = new ArbitraryDataResource(name, ArbitraryDataFile.ResourceIdType.NAME, service, identifier); + ArbitraryResourceStatus arbitraryResourceStatus = resource.getStatus(); + ArbitraryResourceStatus.Status status = arbitraryResourceStatus != null ? arbitraryResourceStatus.getStatus() : null; + repository.getArbitraryRepository().setStatus(arbitraryResourceData, status); } public void updateArbitraryMetadataCache() throws DataException { diff --git a/src/main/java/org/qortal/utils/ArbitraryTransactionUtils.java b/src/main/java/org/qortal/utils/ArbitraryTransactionUtils.java index 15ade240..bf7e2aa6 100644 --- a/src/main/java/org/qortal/utils/ArbitraryTransactionUtils.java +++ b/src/main/java/org/qortal/utils/ArbitraryTransactionUtils.java @@ -393,7 +393,7 @@ public class ArbitraryTransactionUtils { * @param build * @return */ - public static ArbitraryResourceStatus getStatus(Service service, String name, String identifier, Boolean build) { + public static ArbitraryResourceStatus getStatus(Service service, String name, String identifier, Boolean build, boolean updateCache) { // If "build" has been specified, build the resource before returning its status if (build != null && build == true) { @@ -408,27 +408,6 @@ public class ArbitraryTransactionUtils { } ArbitraryDataResource resource = new ArbitraryDataResource(name, ArbitraryDataFile.ResourceIdType.NAME, service, identifier); - return resource.getStatus(false); - } - - public static List addStatusToResources(List resources) { - // Determine and add the status of each resource - List updatedResources = new ArrayList<>(); - for (ArbitraryResourceData resourceInfo : resources) { - try { - ArbitraryDataResource resource = new ArbitraryDataResource(resourceInfo.name, ArbitraryDataFile.ResourceIdType.NAME, - resourceInfo.service, resourceInfo.identifier); - ArbitraryResourceStatus status = resource.getStatus(true); - if (status != null) { - resourceInfo.status = status; - } - updatedResources.add(resourceInfo); - - } catch (Exception e) { - // Catch and log all exceptions, since some systems are experiencing 500 errors when including statuses - LOGGER.info("Caught exception when adding status to resource {}: {}", resourceInfo, e.toString()); - } - } - return updatedResources; + return resource.getStatusAndUpdateCache(updateCache); } }