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

MODINVSTOR-1284 User can delete local Subject types/sources when it linked to Instance #1119

Merged
merged 28 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
5367813
MODINVSTOR-1284 User can delete local Subject types/sources when it l…
JavokhirAbdullayev Nov 27, 2024
c23fc00
add test
JavokhirAbdullayev Nov 27, 2024
57c293c
Merge branch 'master' into MODINVSTOR-1284
JavokhirAbdullayev Nov 27, 2024
4c83421
fix checkstyle
JavokhirAbdullayev Nov 27, 2024
51501f7
Merge remote-tracking branch 'origin/MODINVSTOR-1284' into MODINVSTOR…
JavokhirAbdullayev Nov 27, 2024
306c7e4
add additional test
JavokhirAbdullayev Nov 27, 2024
a50135c
upd msg
JavokhirAbdullayev Nov 28, 2024
c365bc0
code review
JavokhirAbdullayev Dec 3, 2024
01b0774
fix codestyle
JavokhirAbdullayev Dec 3, 2024
5a9a3b9
add indexes
JavokhirAbdullayev Dec 4, 2024
f9c45f9
add indexes
JavokhirAbdullayev Dec 4, 2024
2c14d86
remove redundant changes
JavokhirAbdullayev Dec 6, 2024
75da8ee
Merge branch 'master' into MODINVSTOR-1284
JavokhirAbdullayev Dec 6, 2024
65822c2
some changes for clean up
JavokhirAbdullayev Dec 6, 2024
b432b01
increase coverage
JavokhirAbdullayev Dec 10, 2024
d825183
increase coverage
JavokhirAbdullayev Dec 10, 2024
47d937f
Update NEWS.md
JavokhirAbdullayev Dec 10, 2024
c521ce2
pr review
JavokhirAbdullayev Dec 10, 2024
4d6aa91
Merge remote-tracking branch 'origin/MODINVSTOR-1284' into MODINVSTOR…
JavokhirAbdullayev Dec 10, 2024
57d6c96
clean up
JavokhirAbdullayev Dec 10, 2024
986be9a
add batch operations
JavokhirAbdullayev Dec 10, 2024
ddb394e
fix checkstyle
JavokhirAbdullayev Dec 10, 2024
aa90f35
add more test, update create batch instances
JavokhirAbdullayev Dec 11, 2024
ad93982
Merge branch 'master' into MODINVSTOR-1284
JavokhirAbdullayev Dec 11, 2024
64a6c1d
make creation of instance and linking subjects transactional
JavokhirAbdullayev Dec 13, 2024
4991881
checkstyle
JavokhirAbdullayev Dec 13, 2024
e5b78f1
issues with asyn migration job
JavokhirAbdullayev Dec 13, 2024
05eb880
decrease number of recs in async test, to prevent timeout errors
JavokhirAbdullayev Dec 14, 2024
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
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* Requires `API_NAME vX.Y`

### Features
* Unable to delete local Subject types/sources when they are linked to an Instance ([MODINVSTOR-1284](https://folio-org.atlassian.net/browse/MODINVSTOR-1284))
* Modify endpoint for bulk instances upsert with publish events flag ([MODINVSTOR-1283](https://folio-org.atlassian.net/browse/MODINVSTOR-1283))
* Change Kafka event publishing keys for holdings and items ([MODINVSTOR-1281](https://folio-org.atlassian.net/browse/MODINVSTOR-1281))
* Merge custom ECS TLR feature branch into master ([MODINVSTOR-1262](https://folio-org.atlassian.net/browse/MODINVSTOR-1262))
Expand Down
101 changes: 101 additions & 0 deletions src/main/java/org/folio/persist/InstanceRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import io.vertx.core.Future;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.pgclient.PgException;
import io.vertx.sqlclient.Row;
import io.vertx.sqlclient.RowSet;
import io.vertx.sqlclient.RowStream;
Expand All @@ -20,12 +21,14 @@
import java.util.stream.Collectors;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.apache.commons.lang3.tuple.Pair;
import org.folio.cql2pgjson.CQL2PgJSON;
import org.folio.cql2pgjson.exception.FieldException;
import org.folio.dbschema.ObjectMapperTool;
import org.folio.rest.exceptions.BadRequestException;
import org.folio.rest.jaxrs.model.Instance;
import org.folio.rest.jaxrs.model.ResultInfo;
import org.folio.rest.persist.Conn;
import org.folio.rest.persist.SQLConnection;
import org.folio.rest.persist.cql.CQLQueryValidationException;
import org.folio.rest.persist.cql.CQLWrapper;
Expand All @@ -35,11 +38,109 @@ public class InstanceRepository extends AbstractRepository<Instance> {
private static final String INSTANCE_SET_VIEW = "instance_set";
private static final String INSTANCE_HOLDINGS_ITEM_VIEW = "instance_holdings_item_view";
private static final String INVENTORY_VIEW_JSONB_FIELD = "inventory_view.jsonb";
private static final String INSTANCE_SUBJECT_SOURCE_TABLE = "instance_subject_source";
private static final String INSTANCE_SUBJECT_TYPE_TABLE = "instance_subject_type";


public InstanceRepository(Context context, Map<String, String> okapiHeaders) {
super(postgresClient(context, okapiHeaders), INSTANCE_TABLE, Instance.class);
}

public Future<RowSet<Row>> unlinkInstanceFromSubjectSource(Conn conn, String instanceId) {
try {
String sql = unlinkInstanceFromSubjectSql(INSTANCE_SUBJECT_SOURCE_TABLE, instanceId);
return conn.execute(sql);
} catch (PgException e) {
return Future.failedFuture(new BadRequestException(e.getMessage()));
}
}

public Future<RowSet<Row>> unlinkInstanceFromSubjectType(Conn conn, String instanceId) {
try {
String sql = unlinkInstanceFromSubjectSql(INSTANCE_SUBJECT_TYPE_TABLE, instanceId);
return conn.execute(sql);
} catch (PgException e) {
return Future.failedFuture(new BadRequestException(e.getMessage()));
}
}

private String unlinkInstanceFromSubjectSql(String table, String id) {
return String.format("DELETE FROM %s WHERE instance_id = '%s'; ",
postgresClientFuturized.getFullTableName(table), id);
}

public Future<RowSet<Row>> batchLinkSubjectSource(Conn conn, List<Pair<String, String>> sourcePairs) {
try {
String sql = """
INSERT INTO %s (instance_id, source_id)
VALUES %s
ON CONFLICT DO NOTHING;
"""
.formatted(
postgresClientFuturized.getFullTableName(INSTANCE_SUBJECT_SOURCE_TABLE),
sourcePairs.stream()
.map(pair -> String.format("('%s', '%s')", pair.getKey(), pair.getValue()))
.collect(Collectors.joining(", "))
);
return conn.execute(sql);
} catch (PgException e) {
return Future.failedFuture(new BadRequestException(e.getMessage()));
}
}

public Future<RowSet<Row>> batchLinkSubjectType(Conn conn, List<Pair<String, String>> typePairs) {
try {
String sql = """
INSERT INTO %s (instance_id, type_id)
VALUES %s
ON CONFLICT DO NOTHING;
"""
.formatted(
postgresClientFuturized.getFullTableName(INSTANCE_SUBJECT_TYPE_TABLE),
typePairs.stream()
.map(pair -> String.format("('%s', '%s')", pair.getKey(), pair.getValue()))
.collect(Collectors.joining(", "))
);
return conn.execute(sql);
} catch (PgException e) {
return Future.failedFuture(new BadRequestException(e.getMessage()));
}

}

public Future<RowSet<Row>> batchUnlinkSubjectSource(Conn conn, String instanceId, List<String> sourceIds) {
try {
String sql = """
DELETE FROM %s WHERE instance_id = '%s' AND source_id IN ( %s );
"""
.formatted(
postgresClientFuturized.getFullTableName(INSTANCE_SUBJECT_SOURCE_TABLE),
instanceId,
sourceIds.stream().map(id -> "'" + id + "'").collect(Collectors.joining(", "))
);
return conn.execute(sql);
} catch (PgException e) {
return Future.failedFuture(new BadRequestException(e.getMessage()));
}
}

public Future<RowSet<Row>> batchUnlinkSubjectType(Conn conn, String instanceId, List<String> typeIds) {
try {
String sql = """
DELETE FROM %s WHERE instance_id = '%s' AND type_id IN ( %s );
"""
.formatted(
postgresClientFuturized.getFullTableName(INSTANCE_SUBJECT_TYPE_TABLE),
instanceId,
typeIds.stream().map(id -> "'" + id + "'")
.collect(Collectors.joining(", "))
);
return conn.execute(sql);
} catch (PgException e) {
return Future.failedFuture(new BadRequestException(e.getMessage()));
}
}

public Future<RowStream<Row>> getAllIds(SQLConnection connection) {
return postgresClientFuturized.selectStream(connection,
"SELECT id FROM " + postgresClientFuturized.getFullTableName(INSTANCE_TABLE));
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/folio/rest/impl/InstanceBatchSyncApi.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.folio.rest.impl;

import static org.folio.rest.jaxrs.resource.InstanceStorageBatchSynchronous.PostInstanceStorageBatchSynchronousResponse.respond500WithTextPlain;
import static org.folio.rest.support.EndpointFailureHandler.handleFailure;

import io.vertx.core.AsyncResult;
import io.vertx.core.Context;
Expand All @@ -26,7 +26,7 @@ public void postInstanceStorageBatchSynchronous(boolean upsert, InstancesPost en

new InstanceService(vertxContext, okapiHeaders)
.createInstances(instances.getInstances(), upsert, true, true)
.otherwise(cause -> respond500WithTextPlain(cause.getMessage()))
.onFailure(handleFailure(asyncResultHandler))
.onComplete(asyncResultHandler);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.folio.rest.impl;

import static org.folio.rest.jaxrs.resource.InstanceStorageBatchSynchronousUnsafe.PostInstanceStorageBatchSynchronousUnsafeResponse.respond500WithTextPlain;
import static org.folio.rest.support.EndpointFailureHandler.handleFailure;

import io.vertx.core.AsyncResult;
import io.vertx.core.Context;
Expand All @@ -25,7 +25,7 @@ public void postInstanceStorageBatchSynchronousUnsafe(InstancesPost entity, Map<

new InstanceService(vertxContext, okapiHeaders)
.createInstances(instances.getInstances(), true, false, true)
.otherwise(cause -> respond500WithTextPlain(cause.getMessage()))
.onFailure(handleFailure(asyncResultHandler))
.onComplete(asyncResultHandler);
}
}
Loading